Limit Order with Trailing Stop

admin's avatar

admin since: 30 Nov -0001;

  21 Mar 2013, 12:53
Limit Order with Trailing Stop
// -------------------------------------------------------------------------------------------------
//
//    This robot is intended to be used as a sample and does not guarantee any particular outcome or
//    profit of any kind. Use it at your own risk
//
//    The "Sample Limit Trailing Stop" Robot places a Buy or Sell Limit order according to user input.  
//    When the order is filled it implements trailing stop loss.
//
// -------------------------------------------------------------------------------------------------

using System;
using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot("Sample Limit Trailing Stop")]
    public class SampleLimitTrailingStop : Robot
    {
        [Parameter("Position Label", DefaultValue = "Limit Trailing Stop")]
        public string MyLabel { get; set; }

        [Parameter("Buy", DefaultValue = true)]
        public bool TradeTypeBuy { get; set; }
        
        [Parameter(DefaultValue = 10000)]
        public int Volume { get; set; }

        [Parameter("Target Price (pips)", DefaultValue = 10, MinValue = 1)]
        public int TargetPricePips { get; set; }

        [Parameter()]
        public double Price { get; set; }

        [Parameter("Stop Loss (pips)", DefaultValue = 50, MinValue = 1)]
        public int StopLossPips { get; set; }

        [Parameter("Take Profit (pips)", DefaultValue = 50, MinValue = 1)]
        public int TakeProfitPips { get; set; }

        [Parameter("Trigger (pips)", DefaultValue = 20)]
        public int Trigger { get; set; }

        [Parameter("Trailing Stop (pips)", DefaultValue = 10)]
        public int TrailingStop { get; set; }


        protected override void OnStart()
        {
            Positions.Closed += PositionsOnClosed;

            double targetPrice = ValidatePrice();
            var tradeType = TradeTypeBuy ? TradeType.Buy : TradeType.Sell;
            PlaceLimitOrder(tradeType, Symbol, Volume, targetPrice, MyLabel, StopLossPips, TakeProfitPips);
            
        }

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            if (args.Position.Label == MyLabel)
                Stop();
        }

        private double ValidatePrice()
        {
            double targetPrice;

            if (TradeTypeBuy)
            {
                var buyPrice = Symbol.Ask - TargetPricePips*Symbol.PipSize;
                targetPrice = Price==0.0? buyPrice: Math.Min(Price, buyPrice);
            }
            else
            {
                var sellPrice = Symbol.Bid + TargetPricePips * Symbol.PipSize;
                targetPrice = Price == 0.0 ? sellPrice : Math.Max(Price, sellPrice);
            }
            
            return targetPrice;

        }


        protected override void OnTick()
        {
            var position = Positions.Find(MyLabel);
            if (position == null) return;

            double profit = TradeTypeBuy
                                  ? Symbol.Bid - position.EntryPrice
                                  : position.EntryPrice - Symbol.Ask;
            if (profit >= Trigger*Symbol.PipSize)
                AdjustStopLoss();
        }

        private void AdjustStopLoss()
        {
            double newStopLossPrice = TradeTypeBuy
                              ? Symbol.Bid - TrailingStop * Symbol.PipSize
                              : Symbol.Ask + TrailingStop * Symbol.PipSize;
            
            Position position = Positions.Find(MyLabel);
            bool modify = TradeTypeBuy
                                     ? newStopLossPrice > position.StopLoss
                                     : newStopLossPrice < position.StopLoss;
            if (modify)
            {
                ModifyPosition(position, newStopLossPrice, position.TakeProfit);
            }
        }

    }
}
TRADERS FIRSTâ„¢