How do I add a "move to profit the SL to protect the positions"?
Created at 07 Apr 2016, 17:51
RO
How do I add a "move to profit the SL to protect the positions"?
07 Apr 2016, 17:51
Hello coders,
the following is a good bot if only the SL and trailing would work.
It gets the price movements pretty accurately.
How do I add a "move to profit the SL to protect the positions"?
using System; using cAlgo.API; using cAlgo.API.Internals; namespace cAlgo.Robots { [Robot("Robot Forex", AccessRights = AccessRights.None)] public class Robot_Forex : Robot { [Parameter(DefaultValue = 10000, MinValue = 1000)] public int FirstLot { get; set; } [Parameter(DefaultValue = 10000, MinValue = 1000)] public int LotStep { get; set; } //[Parameter(DefaultValue = 300)] //public int PipStep { get; set; } [Parameter("Stop_Loss", DefaultValue = 50, MinValue = 0)] public int Stop_Loss { get; set; } [Parameter("Take_Profit", DefaultValue = 180, MinValue = 10)] public int TakeProfit { get; set; } [Parameter("Tral_Start", DefaultValue = 50, MinValue = 10)] public int Tral_Start { get; set; } [Parameter("Tral_Stop", DefaultValue = 50, MinValue = 10)] public int Tral_Stop { get; set; } [Parameter(DefaultValue = 5, MinValue = 2)] public int MaxOrders { get; set; } private Position position; private bool RobotStopped; private string botLabel; protected override void OnStart() { botLabel = ToString(); // The stop loss must be greater than tral stop //Stop_Loss = Math.Max(Tral_Stop, Stop_Loss); Positions.Opened += OnPositionOpened; } protected override void OnTick() { double Bid = Symbol.Bid; double Ask = Symbol.Ask; double Point = Symbol.TickSize; if (Trade.IsExecuting) return; if (Positions.Count > 0 && RobotStopped) return; else RobotStopped = false; if (Positions.Count == 0) SendFirstOrder(FirstLot); else ControlSeries(); foreach (var position in Positions) { if (position.SymbolCode == Symbol.Code) { if (position.TradeType == TradeType.Buy) { if (Bid - GetAveragePrice(TradeType.Buy) >= Tral_Start * Point) if (Bid - Tral_Stop * Point >= position.StopLoss) ModifyPosition(position, Bid - Tral_Stop * Point, position.TakeProfit); } if (position.TradeType == TradeType.Sell) { if (GetAveragePrice(TradeType.Sell) - Ask >= Tral_Start * Point) if (Ask + Tral_Stop * Point <= position.StopLoss || position.StopLoss == 0) ModifyPosition(position, Ask + Tral_Stop * Point, position.TakeProfit); } } } } protected override void OnError(Error CodeOfError) { if (CodeOfError.Code == ErrorCode.NoMoney) { RobotStopped = true; Print("ERROR!!! No money for order open, robot is stopped!"); } else if (CodeOfError.Code == ErrorCode.BadVolume) { RobotStopped = true; Print("ERROR!!! Bad volume for order open, robot is stopped!"); } } private void SendFirstOrder(int OrderVolume) { int Signal = GetStdIlanSignal(); if (!(Signal < 0)) switch (Signal) { case 0: ExecuteMarketOrder(TradeType.Buy, Symbol, OrderVolume, botLabel); break; case 1: ExecuteMarketOrder(TradeType.Sell, Symbol, OrderVolume, botLabel); break; } } private void OnPositionOpened(PositionOpenedEventArgs args) { double? StopLossPrice = null; double? TakeProfitPrice = null; if (Positions.Count == 1) { position = args.Position; if (position.TradeType == TradeType.Buy) TakeProfitPrice = position.EntryPrice + TakeProfit * Symbol.TickSize; if (position.TradeType == TradeType.Sell) TakeProfitPrice = position.EntryPrice - TakeProfit * Symbol.TickSize; } else switch (GetPositionsSide()) { case 0: TakeProfitPrice = GetAveragePrice(TradeType.Buy) + TakeProfit * Symbol.TickSize; break; case 1: TakeProfitPrice = GetAveragePrice(TradeType.Sell) - TakeProfit * Symbol.TickSize; break; } for (int i = 0; i < Positions.Count; i++) { position = Positions[i]; if (StopLossPrice != null || TakeProfitPrice != null) ModifyPosition(position, position.StopLoss, TakeProfitPrice); } } private double GetAveragePrice(TradeType TypeOfTrade) { double Result = Symbol.Bid; double AveragePrice = 0; long Count = 0; for (int i = 0; i < Positions.Count; i++) { position = Positions[i]; if (position.TradeType == TypeOfTrade) { AveragePrice += position.EntryPrice * position.Volume; Count += position.Volume; } } if (AveragePrice > 0 && Count > 0) Result = AveragePrice / Count; return Result; } private int GetPositionsSide() { int Result = -1; int i, BuySide = 0, SellSide = 0; for (i = 0; i < Positions.Count; i++) { if (Positions[i].TradeType == TradeType.Buy) BuySide++; if (Positions[i].TradeType == TradeType.Sell) SellSide++; } if (BuySide == Positions.Count) Result = 0; if (SellSide == Positions.Count) Result = 1; return Result; } /// <summary> /// The gradient variable is a dynamic value that represente an equidistant grid between /// the high value and the low value of price. /// </summary> /// private void ControlSeries() { const int BarCount = 25; int gradient = MaxOrders - 1; foreach (Position position in Positions.FindAll(botLabel, Symbol)) { if (-position.Pips > Stop_Loss) ClosePosition(position); } //if (PipStep == 0) int _pipstep = GetDynamicPipstep(BarCount, gradient); //else // _pipstep = PipStep; if (Positions.Count < MaxOrders) { //int rem; long NewVolume = Symbol.NormalizeVolume(FirstLot + FirstLot * Positions.Count, RoundingMode.ToNearest); int positionSide = GetPositionsSide(); switch (positionSide) { case 0: if (Symbol.Ask < FindLastPrice(TradeType.Buy) - _pipstep * Symbol.TickSize) { //NewVolume = Math.DivRem((int)(FirstLot + FirstLot * Positions.Count), LotStep, out rem) * LotStep; if (NewVolume >= LotStep) ExecuteMarketOrder(TradeType.Buy, Symbol, NewVolume, botLabel); } break; case 1: if (Symbol.Bid > FindLastPrice(TradeType.Sell) + _pipstep * Symbol.TickSize) { //NewVolume = Math.DivRem((int)(FirstLot + FirstLot * Positions.Count), LotStep, out rem) * LotStep; if (NewVolume >= LotStep) ExecuteMarketOrder(TradeType.Sell, Symbol, NewVolume, botLabel); } break; } } } private int GetDynamicPipstep(int CountOfBars, int gradient) { int Result; double HighestPrice = 0, LowestPrice = 0; int StartBar = MarketSeries.Close.Count - 2 - CountOfBars; int EndBar = MarketSeries.Close.Count - 2; for (int i = StartBar; i < EndBar; i++) { if (HighestPrice == 0 && LowestPrice == 0) { HighestPrice = MarketSeries.High[i]; LowestPrice = MarketSeries.Low[i]; continue; } if (MarketSeries.High[i] > HighestPrice) HighestPrice = MarketSeries.High[i]; if (MarketSeries.Low[i] < LowestPrice) LowestPrice = MarketSeries.Low[i]; } Result = (int)((HighestPrice - LowestPrice) / Symbol.TickSize / gradient); return Result; } private double FindLastPrice(TradeType TypeOfTrade) { double LastPrice = 0; for (int i = 0; i < Positions.Count; i++) { position = Positions[i]; if (TypeOfTrade == TradeType.Buy) if (position.TradeType == TypeOfTrade) { if (LastPrice == 0) { LastPrice = position.EntryPrice; continue; } if (position.EntryPrice < LastPrice) LastPrice = position.EntryPrice; } if (TypeOfTrade == TradeType.Sell) if (position.TradeType == TypeOfTrade) { if (LastPrice == 0) { LastPrice = position.EntryPrice; continue; } if (position.EntryPrice > LastPrice) LastPrice = position.EntryPrice; } } return LastPrice; } private int GetStdIlanSignal() { int Result = -1; int LastBarIndex = MarketSeries.Close.Count - 2; int PrevBarIndex = LastBarIndex - 1; if (MarketSeries.Close[LastBarIndex] > MarketSeries.Open[LastBarIndex]) if (MarketSeries.Close[PrevBarIndex] > MarketSeries.Open[PrevBarIndex]) Result = 0; if (MarketSeries.Close[LastBarIndex] < MarketSeries.Open[LastBarIndex]) if (MarketSeries.Close[PrevBarIndex] < MarketSeries.Open[PrevBarIndex]) Result = 1; return Result; } protected override double GetFitness(GetFitnessArgs args) { //maximize count of winning trades and minimize count of losing trades return args.WinningTrades / args.LosingTrades; } } }
croucrou
10 Apr 2016, 19:23
See this:
@croucrou