Backtesting stopps unexpectedly
Backtesting stopps unexpectedly
13 Feb 2018, 04:08
Here is the cBot log I got
01/11/2017 03:00:00.000 | Backtesting started
01/11/2017 03:00:00.000 | symbol pipsize 0.0001
01/11/2017 03:00:00.000 | _ATR is 0.000903659654142933
01/11/2017 15:25:00.000 | Executing Market Order to Sell 10000 EURUSD (SL: 26)
01/11/2017 15:25:00.000 | → Executing Market Order to Sell 10000 EURUSD (SL: 26) SUCCEEDED, Position PID1
02/11/2017 04:20:00.000 | Closing position PID1
02/11/2017 04:20:00.000 | → Closing position PID1 SUCCEEDED, Position PID1
02/11/2017 04:20:00.000 | Sorry
02/11/2017 04:20:00.000 | There have to be a second try stop order (Buy of Sell)
02/11/2017 04:20:00.000 | Placing Stop Order to Sell 10000 EURUSD (Price: 1.16356, SL: 6.45015692013447, ExpireTime: 04.11.2017 16:20:00)
02/11/2017 04:20:00.000 | → Placing Stop Order to Sell 10000 EURUSD (Price: 1.16356, SL: 6.45015692013447, ExpireTime: 04.11.2017 16:20:00) SUCCEEDED, PendingOrder OID2
02/11/2017 04:20:00.000 | Second Try order ID is 2
02/11/2017 04:20:00.000 | Backtesting was stopped
and here is the breakout cBot based on Doncian channels
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.RussianStandardTime, AccessRights = AccessRights.FullAccess)]
public class Donci2a : Robot
{
#region Parameter Declarations
[Parameter("Instance Name", DefaultValue = "Blue")]
public string InstanceName { get; set; }
//[Parameter("Source")]
//public DataSeries Source { get; set; }
[Parameter("SL ATR multiple", DefaultValue = 1.5)]
public double ATRfactor { get; set; }
[Parameter("Hi Periods", DefaultValue = 20)]
public int HiPer { get; set; }
[Parameter("Low Periods", DefaultValue = 10)]
public int LowPer { get; set; }
[Parameter("Quantity (Lots)", DefaultValue = 0.1, MinValue = 0.01, Step = 0.01)]
public double Quantity { get; set; }
[Parameter("Include Break-Even", DefaultValue = true)]
public bool IncludeBreakEven { get; set; }
[Parameter("Break-Even Trigger (ATR)", DefaultValue = 1.6)]
public double Trigger { get; set; }
[Parameter("Break-Even Extra (pips)", DefaultValue = 1.0, MinValue = 0.0)]
public double ExtraPips { get; set; }
[Parameter("Include Trailing Stop", DefaultValue = true)]
public bool IncludeTrailingStop { get; set; }
[Parameter("Trailing Stop Trigger (ATR)", DefaultValue = 1.9, MinValue = 1.0, Step = 0.1)]
public double TrailingStopTrigger { get; set; }
[Parameter("Trailing Stop Step (ATR)", DefaultValue = 1.2, MinValue = 0.5, Step = 0.1)]
public double TrailingStopStep { get; set; }
[Parameter("Second Try ", DefaultValue = false)]
public bool SecondTry { get; set; }
[Parameter("Secon Try ATR factor", DefaultValue = 1)]
public double _ATR_FactorST { get; set; }
public double SL;
private double _ATR;
private DonchianChannel DCH;
private DonchianChannel DCL;
private AverageTrueRange ATR;
private DateTime BarOpenTime;
private int _ID;
private DateTime expiry;
private double _price;
private TradeType _tradetype;
private bool StoppedByRobot = false;
#endregion
#region cTrader events
protected override void OnStart()
{
Print("symbol pipsize {0} ", Symbol.PipSize);
Positions.Closed += PositionsOnClosed;
ATR = Indicators.AverageTrueRange(LowPer, MovingAverageType.Exponential);
DCH = Indicators.DonchianChannel(HiPer);
DCL = Indicators.DonchianChannel(LowPer);
_ATR = ATR.Result.LastValue;
Print("_ATR is {0}", _ATR);
}
protected override void OnTick()
{
var position = Positions.Find(InstanceName, Symbol);
if (position == null)
{
// if (InstanceName == "Blue")
// {
if (DCH.Top.LastValue < Symbol.Bid)
{
InstanceName = "Blue";
_tradetype = TradeType.Buy;
StoppedByRobot = false;
Open(_tradetype);
}
else if (DCH.Bottom.LastValue > Symbol.Bid)
{
InstanceName = "Blue";
_tradetype = TradeType.Sell;
StoppedByRobot = false;
Open(_tradetype);
}
// }
}
else if (position != null)
{
if (position.Label == "Blue")
{
if ((position.TradeType == TradeType.Buy && DCL.Bottom.LastValue > Symbol.Bid) || (position.TradeType == TradeType.Sell && DCL.Top.LastValue < Symbol.Bid))
{
StoppedByRobot = false;
ClosePosition(position);
}
}
if (position.Label == "Red")
{
if ((position.TradeType == TradeType.Sell && DCH.Bottom.LastValue >= Symbol.Bid) || (position.TradeType == TradeType.Buy && DCH.Bottom.LastValue <= Symbol.Bid))
{
StoppedByRobot = true;
ClosePosition(position);
}
}
}
if (IncludeBreakEven == true)
GoToBreakEven();
if (IncludeTrailingStop == true)
SetTrailingStop();
// TrailStopOrders();
}
#endregion
#region Open trade
void Open(TradeType tradeType)
{
var volumeInUnits = Symbol.QuantityToVolume(Quantity);
SL = ATR.Result.LastValue * ATRfactor / Symbol.PipSize;
ExecuteMarketOrder(tradeType, Symbol, volumeInUnits, InstanceName, SL, null);
}
#endregion
#region Break Even
void GoToBreakEven()
{
var position = Positions.Find(InstanceName, Symbol);
if (position != null)
{
var entryPrice = position.EntryPrice;
var distance = 0.0;
var adjEntryPrice = 0.0;
if (position.TradeType == TradeType.Buy)
{
adjEntryPrice = entryPrice + ExtraPips * Symbol.PipSize;
distance = Symbol.Bid - entryPrice;
}
else
{
adjEntryPrice = entryPrice - ExtraPips * Symbol.PipSize;
distance = entryPrice - Symbol.Ask;
}
// Print("Distance {0}", distance);
if (distance >= Trigger * ATR.Result.LastValue)
{
if (position.TradeType == TradeType.Sell && position.StopLoss > adjEntryPrice)
ModifyPosition(position, adjEntryPrice, null);
if (position.TradeType == TradeType.Buy && position.StopLoss < adjEntryPrice)
ModifyPosition(position, adjEntryPrice, null);
}
}
}
#endregion
#region Position Closed
private void PositionsOnClosed(PositionClosedEventArgs args)
{
var position = args.Position;
if ((position.Pips > (1 + 0.1) * -SL && position.Pips < (1 - 0.1) * -SL) || (position.Pips > (1 + 0.1) * SL && position.Pips < (1 - 0.1) * SL))
StoppedByRobot = true;
if (StoppedByRobot == false)
{
Print("Sorry");
Stop();
}
if (SecondTry == true)
{
if (PendingOrders.Count == 0)
{
if (InstanceName == "Blue")
{
BarOpenTime = MarketSeries.OpenTime.LastValue;
Print("There have to be a second try stop order (Buy of Sell)");
_ATR = ATR.Result.LastValue;
expiry = Server.Time.AddHours(60);
var volumeInUnits = Symbol.QuantityToVolume(Quantity);
_price = position.TradeType == TradeType.Buy ? Symbol.Ask + _ATR / 2 : Symbol.Bid - _ATR / 2;
InstanceName = "Red";
var result = PlaceStopOrder(position.TradeType, Symbol, volumeInUnits, _price, InstanceName, _ATR / 2 / Symbol.PipSize, null, expiry);
var order = result.PendingOrder;
_ID = order.Id;
Print("Second Try order ID is {0}", _ID);
}
else if (position.Label == "Red")
{
Print("The second try is over for the {0} ", position.Id);
StoppedByRobot = true;
}
}
}
}
#endregion
#region Trailing Stop
private void SetTrailingStop()
{
var sellPositions = Positions.FindAll(InstanceName, Symbol, TradeType.Sell);
foreach (Position position in sellPositions)
{
double distance = position.EntryPrice - Symbol.Ask;
if (distance < TrailingStopTrigger * _ATR)
continue;
double newStopLossPrice = Symbol.Ask + TrailingStopStep * _ATR;
if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
var buyPositions = Positions.FindAll(InstanceName, Symbol, TradeType.Buy);
foreach (Position position in buyPositions)
{
double distance = Symbol.Bid - position.EntryPrice;
if (distance < TrailingStopTrigger * _ATR)
continue;
double newStopLossPrice = Symbol.Bid - TrailingStopStep * _ATR;
if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
#endregion
#region Trail Stop Orders
//private void TrailStopOrders()
//{
// if (PendingOrders.Count > 0)
// {
// if (BarOpenTime == MarketSeries.OpenTime.LastValue)
// foreach (var order in PendingOrders)
// {
// expiry = Server.Time.AddHours(12);
// _priceShift = order.TradeType == TradeType.Buy ? _ATR / 2 : -_ATR / 2;
// _price = Symbol.Bid + _priceShift;
// // if (order.TradeType == TradeType.Sell && Symbol.Bid - _ATR / 2 > order.TargetPrice)
// ModifyPendingOrder(order, _price, _ATR / Symbol.PipSize / 2, _ATR / Symbol.PipSize / 2, expiry);
// //else if (order.TradeType == TradeType.Buy && Symbol.Bid + _ATR / 2 < order.TargetPrice)
// // ModifyPendingOrder(order, Symbol.Bid + _ATR / 2, order.StopLoss, order.TakeProfitPips, expiry);
// }
// }
}
#endregion
}
Could you please help me understand why the backtesting is stopped and what shall I do to prevent it from stopping.
As you can see from the log the pending order is placed and has an ID, and then something happens.
Please, help me.
Replies
alexander.n.fedorov
13 Feb 2018, 10:32
Backtesting
Dear Panagiotis.
I will do in about an hour
@alexander.n.fedorov
alexander.n.fedorov
13 Feb 2018, 10:51
Backtesting
In addition to timing info, which was tonight and is available from the cBot log, broker is ICMarkets, timeframe - 1 hr, lot=0.01
@alexander.n.fedorov
PanagiotisCharalampous
13 Feb 2018, 11:10
Hi Alexander,
The cBot stops because of this condition
if (StoppedByRobot == false) { Print("Sorry"); Stop(); }
What was your intention writing this part?
Best Regards,
Panagiotis
@PanagiotisCharalampous
alexander.n.fedorov
13 Feb 2018, 11:16
Backtesting
I am trying to not stop the order or position manually, but when I did have the above part, when I closed position by hand, it started to generate orders, because of event
I tryied to protect against closing by Stop Loss and Take Profit
I think it was either breakeven, or trailing, which I think I now should try how to handle. In any case, you very good, and thank's a lot.
But I will be righting to you in the future
Alexander
@alexander.n.fedorov
PanagiotisCharalampous
13 Feb 2018, 10:30
Hi Alexander,
Can I have your exact backtesting configuration (broker, timeframe, start and end dates, cbot parameters, starting volume etc) so that I can reproduce and see if I can advise you on this?
Best Regards,
Panagiotis
@PanagiotisCharalampous