Backtesting Bug: Profit after open Trade not plausible, Support plz assist
Backtesting Bug: Profit after open Trade not plausible, Support plz assist
15 Jun 2016, 00:25
Hallo all,
I am encontering a strange behaviour Backtesting an EA.
I am using an Algo with different States. Basically the functionality works like this
'State1' if(TradeConditionsLong == true) { ExecuteMarketOrder(...); SetNextState(State2); } 'State2' if (OpenTrade.Position.Pips > BreakSafePips) // BreakSafePips=30 { ExecuteMarketOrder(...) }
The Problem is, that imediately after opening the new Trade, the Position.Pips Value equals 30.6 pips! The Candle itself (EURUSD 02.06.2015 13:03:16) is increasing by over 30 Pips but over a Series of Ticks. The Pips Value should not be that high imediately! This causes a Loop because every new Trade seems to be profitable imediately causing the backtest to hang up ...
Has anybody experienced similar Problems?
Replies
Mikro
15 Jun 2016, 23:18
All right,
didn't expect negative Spread to be possible, despite I'd gladly accept a Bonus just for executing a Trade ;)
I added an Condition to the opening parameters for new Trades
If(OpenTrade == true && Symbol.Spread > 0) { ExecuteMarketOrder() }
That sorts out the bad Spread Data.
Why is there negative Spread???
@Mikro
Jiri
15 Jun 2016, 23:35
Again, I advice you to exclude entire day. Position can be executed when spread is above 0 but it can go negative on following tick and make your TakeProfit get hit immediately. Your backtest would give you pretty much the same results.
using System.Collections.Generic; using System.Linq; private List<DateTime> excludedDates = new List<DateTime>(); protected override void OnStart() { excludedDates.Add(new DateTime(2015, 6, 2)); excludedDates.Add(new DateTime(2015, 6, 8)); } protected override void OnTick() { foreach (DateTime excluded in excludedDates) { if (Time.Date == excluded.Date) { return; } } }
@Jiri
Jiri
16 Jun 2016, 00:41
I quickly wrote this algo which finds all negative spreads and if there is more than defined per day it will save it into collection, when it stops your dates will be printed into log.
Run it as regular backtest with tick data and find all negative spreads. :)
using System; using System.Collections.Generic; using System.Linq; using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class NegativeSpreadAnalyzer : Robot { [Parameter(DefaultValue = 10)] public int SpreadsToGetFiltered { get; set; } public class DateWithNegativeSpread { public DateTime DateTime { get; set; } public int Spreads { get; set; } } private List<DateWithNegativeSpread> dates = new List<DateWithNegativeSpread>(); private DateTime last; private int negativeSpreads = 0; protected override void OnStart() { last = Time.Date; } protected override void OnTick() { if (Time.Date >= last.AddDays(1).Date) { negativeSpreads = 0; last = Time.Date; } else if (Symbol.Spread < 0) { negativeSpreads++; } if (negativeSpreads > SpreadsToGetFiltered) { if (dates.Exists(x => x.DateTime.Date == Time.Date)) { dates[dates.FindIndex(x => x.DateTime.Date == Time.Date)].Spreads = negativeSpreads; } else { dates.Add(new DateWithNegativeSpread { DateTime = Time.Date, Spreads = negativeSpreads }); } } } protected override void OnStop() { foreach (var date in dates) { string text = string.Format("{0}\tNegative spreads: {1}", date.DateTime.ToString("d"), date.Spreads); Print(text); } } } }
@Jiri
Jiri
16 Jun 2016, 00:58
Maybe sum of negative spreads in pips per day is even better approach for this solution.
using System; using System.Collections.Generic; using System.Linq; using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class NegativeSpreadAnalyzer : Robot { [Parameter(DefaultValue = 100)] public int MinNegativeSpreadInPipsPerDay { get; set; } public class DateWithNegativeSpread { public DateTime DateTime { get; set; } public double NegativeSpreadInPips { get; set; } } private List<DateWithNegativeSpread> dates = new List<DateWithNegativeSpread>(); private DateTime lastDay; private double negativeSpreadInPipsThisDay = 0; protected override void OnStart() { lastDay = Time.Date; } protected override void OnTick() { if (Time.Date >= lastDay.AddDays(1).Date) { negativeSpreadInPipsThisDay = 0; lastDay = Time.Date; } else if (Symbol.Spread < 0) { negativeSpreadInPipsThisDay -= Symbol.Spread / Symbol.PipSize; } if (negativeSpreadInPipsThisDay >= MinNegativeSpreadInPipsPerDay) { if (dates.Exists(x => x.DateTime.Date == Time.Date)) { dates[dates.FindIndex(x => x.DateTime.Date == Time.Date)].NegativeSpreadInPips = negativeSpreadInPipsThisDay; } else { dates.Add(new DateWithNegativeSpread { DateTime = Time.Date, NegativeSpreadInPips = negativeSpreadInPipsThisDay }); } } } protected override void OnStop() { foreach (var date in dates) { string text = string.Format("{0}\tNegative spread: {1} pips", date.DateTime.ToString("d"), Math.Round(date.NegativeSpreadInPips, 1)); Print(text); } } } }
@Jiri
Jiri
16 Jun 2016, 01:05
( Updated at: 21 Dec 2023, 09:20 )
Results for unnamed broker.
Filter set to 10000 pips.
19/01/2014 22:01:00.784 | Backtesting started 13/06/2016 23:59:59.747 | 25/05/2015 Negative spread: 63373.4 pips 13/06/2016 23:59:59.747 | 26/05/2015 Negative spread: 218132.6 pips 13/06/2016 23:59:59.747 | 27/05/2015 Negative spread: 202081.6 pips 13/06/2016 23:59:59.747 | 28/05/2015 Negative spread: 11550.1 pips 13/06/2016 23:59:59.747 | 29/05/2015 Negative spread: 290066.3 pips 13/06/2016 23:59:59.747 | 01/06/2015 Negative spread: 234630.1 pips 13/06/2016 23:59:59.747 | 02/06/2015 Negative spread: 377209.2 pips 13/06/2016 23:59:59.747 | 03/06/2015 Negative spread: 310437.4 pips 13/06/2016 23:59:59.747 | 04/06/2015 Negative spread: 390877.4 pips 13/06/2016 23:59:59.747 | 08/06/2015 Negative spread: 840852.4 pips 13/06/2016 23:59:59.747 | 09/06/2015 Negative spread: 10165.3 pips 13/06/2016 23:59:59.747 | 10/06/2015 Negative spread: 321649.7 pips 13/06/2016 23:59:59.747 | 11/06/2015 Negative spread: 233851.6 pips 13/06/2016 23:59:59.747 | 12/06/2015 Negative spread: 356911.1 pips 13/06/2016 23:59:59.747 | 15/06/2015 Negative spread: 302088.4 pips 13/06/2016 23:59:59.747 | 16/06/2015 Negative spread: 241474.1 pips 13/06/2016 23:59:59.747 | 17/06/2015 Negative spread: 518948.3 pips 13/06/2016 23:59:59.747 | 22/06/2015 Negative spread: 295252.5 pips 13/06/2016 23:59:59.747 | 23/06/2015 Negative spread: 261165 pips 13/06/2016 23:59:59.747 | 24/06/2015 Negative spread: 290066.6 pips 13/06/2016 23:59:59.747 | 25/06/2015 Negative spread: 207009.1 pips 13/06/2016 23:59:59.747 | 26/06/2015 Negative spread: 122347.6 pips 13/06/2016 23:59:59.747 | 01/07/2015 Negative spread: 257227 pips 13/06/2016 23:59:59.747 | 02/07/2015 Negative spread: 382292.1 pips 13/06/2016 23:59:59.747 | 03/07/2015 Negative spread: 94580.1 pips 13/06/2016 23:59:59.747 | 05/07/2015 Negative spread: 38531.3 pips 13/06/2016 23:59:59.747 | 06/07/2015 Negative spread: 163594.2 pips 13/06/2016 23:59:59.747 | 09/07/2015 Negative spread: 122429.8 pips 13/06/2016 23:59:59.747 | 10/07/2015 Negative spread: 139864.2 pips 13/06/2016 23:59:59.747 | 13/07/2015 Negative spread: 256186.6 pips 13/06/2016 23:59:59.747 | 14/07/2015 Negative spread: 276936.4 pips 13/06/2016 23:59:59.747 | 15/07/2015 Negative spread: 171471.6 pips 13/06/2016 23:59:59.747 | 16/07/2015 Negative spread: 108603.5 pips 13/06/2016 23:59:59.747 | 17/07/2015 Negative spread: 124232.1 pips 13/06/2016 23:59:59.747 | Backtesting finished
@Jiri
Jiri
15 Jun 2016, 03:27 ( Updated at: 21 Dec 2023, 09:20 )
Yes. I recommend excluding several dates with such a huge negative spreads for you backtests.
@Jiri