Nasty bug in optimization
Nasty bug in optimization
30 Mar 2019, 10:37
Dear Panagiotis!
There must be sum bug in optimizations.
I will put three charts here and a zip of the bot
Optimization and backtesting show complitely different results, even thou all the condititons according to "apply
"
Replies
alexander.n.fedorov
30 Mar 2019, 10:50
( Updated at: 21 Dec 2023, 09:21 )
RE: RE:
alexander.n.fedorov said:
alexander.n.fedorov said:
Dear Panagiotis!
There must be sum bug in optimizations.
I will put three charts here and a zip of the bot
Optimization and backtesting show complitely different results, even thou all the condititons according to "apply
"
in both cases parameteres are the same, 1 minuter data,dates are the same, only one timeframe
What is interesting, sometimes it repeats perfectly
Sometimes - nothing in common.
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.RussianStandardTime, AccessRights = AccessRights.None)] public class VolatilityBreakout4 : Robot { [Parameter("Source")] public DataSeries Source { get; set; } [Parameter("Risk", MaxValue = 10, MinValue = 0.5, DefaultValue = 1)] public double Risk { get; set; } [Parameter("Squeeze bars number", MaxValue = 180, MinValue = 5, Step = 1, DefaultValue = 20)] public int SqueezeBarsNumber { get; set; } [Parameter("Squeeze in pips", MaxValue = 300, MinValue = 1, Step = 0.1, DefaultValue = 20)] public double Squeeze { get; set; } [Parameter("TP multiple", MaxValue = 8, MinValue = 1, Step = 0.1, DefaultValue = 2)] public double TpMultiple { get; set; } [Parameter("Close Trade Hour", DefaultValue = 23)] public int CloseTradesHour { get; set; } [Parameter("Close Trade Minute", DefaultValue = 30)] public int CloseTradesMinute { get; set; } [Parameter("Open Trade Hour", DefaultValue = 2)] public int OpenTradesHour { get; set; } private string instance; private MarketSeries ms; private double range, high, low, volume, barsRange, SL, TP, minVolume, risk; private int pipDigits, n; private DateTime squeezeFirstBarTime, squeezeLastBarTime; private TimeSpan ts; protected override void OnStart() { instance = ToString() + ", " + Symbol.Code + ", " + TimeFrame + ", " + Account.BrokerName + ", " + Account.Number; range = Squeeze * Symbol.PipSize; ms = MarketData.GetSeries(TimeFrame); minVolume = Symbol.VolumeInUnitsMin; ts = CandleOpenTime(0) - CandleOpenTime(2); risk = Risk * 0.01; pipDigits = Symbol.Digits - (int)Math.Log10(1 / Symbol.PipSize); Positions.Opened += Positions_Opened; Positions.Closed += PositionsOnClosed; squeezeFirstBarTime = CandleOpenTime(2 + SqueezeBarsNumber); squeezeLastBarTime = CandleOpenTime(2); } protected override void OnBar() { if ((CandleOpenTime(0).Hour >= CloseTradesHour && CandleOpenTime(0).Minute >= CloseTradesMinute) || CandleOpenTime(0).Hour < OpenTradesHour) { return; } squeezeFirstBarTime = CandleOpenTime(1 + SqueezeBarsNumber); squeezeLastBarTime = CandleOpenTime(1); high = CandleHigh(1); low = CandleLow(1); barsRange = CandleClose(1) > (1) ? MarketSeries.Close.Last(1) - MarketSeries.Open.Last(1) : MarketSeries.Open.Last(1) - MarketSeries.Close.Last(1); for (int i = 0; i < SqueezeBarsNumber; i++) { high = CandleHigh(i + 1) > high ? CandleHigh(i + 1) : high; low = CandleLow(i + 1) < low ? CandleLow(i + 1) : low; barsRange = high - low; } //Chart.RemoveAllObjects(); //Chart.DrawTrendLine("sHigh", squeezeFirstBarTime, high, squeezeLastBarTime, high, Color.Aqua, 1, LineStyle.Solid); //Chart.DrawTrendLine("sLow", squeezeFirstBarTime, low, squeezeLastBarTime, low, Color.Red, 1, LineStyle.Solid); //double barRangePips = Math.Round(barsRange / Symbol.PipSize, 1); //string text = "Squeeze = " + Squeeze + " , barRange = " + barRangePips; //Chart.DrawStaticText("Current range", text, VerticalAlignment.Bottom, HorizontalAlignment.Right, Color.Aquamarine); var position = Positions.Find(instance); if (position != null) { return; } n = 0; foreach (var order in PendingOrders) { if (order.Label == instance) { n = n + 1; } } if (position == null) { if (n == 0) { if (high - low < range) { double longPrice = high; double shortPrice = low; SL = (high - low) / Symbol.PipSize; volume = Math.Floor(((Account.Equity * risk) / SL) / Symbol.PipValue / minVolume) * minVolume; SL = Math.Round(SL, pipDigits, MidpointRounding.AwayFromZero); TP = SL * TpMultiple; PlaceStopOrder(TradeType.Buy, Symbol, volume, longPrice, instance, SL, TP); PlaceStopOrder(TradeType.Sell, Symbol, volume, shortPrice, instance, SL, TP); } } } } private void Positions_Opened(PositionOpenedEventArgs args) { var position = args.Position; if (position.Label == instance) { foreach (var order in PendingOrders) { if (order.Label == instance) CancelPendingOrder(order); } } } private void PositionsOnClosed(PositionClosedEventArgs args) { var position = args.Position; if (args.Reason == PositionCloseReason.TakeProfit) { //if (Server.Time - position.EntryTime < ts) //{ // ExecuteMarketOrder(position.TradeType, Symbol, volume, instance, SL, SL); //} //// foreach (var order in PendingOrders) // { // if (order.Label == instance) // CancelPendingOrder(order); // } //} } } #region Candles Processing #region Candle Type private bool CandleTypeBullish(int k) { if (ms.Open.Last(k) > ms.Close.Last(k)) { return false; } return true; } #endregion #region Candle Range(int k) private double CandleRange(int k) { return ms.High.Last(k) - ms.Low.Last(k); } #endregion #region Candle body bottom private double CandleBodyBottom(int k) { return (ms.Open.Last(k) < ms.Close.Last(k)) ? ms.Open.Last(k) : ms.Close.Last(k); } #endregion #region Candle body Top private double CandleBodyTop(int k) { return (ms.Open.Last(k) > ms.Close.Last(k)) ? ms.Open.Last(k) : ms.Close.Last(k); } #endregion #region Candle high private double CandleHigh(int k) { return ms.High.Last(k); } #endregion #region Candle low private double CandleLow(int k) { return ms.Low.Last(k); } #endregion #region Candle body private double CandleBody(int k) { return Math.Abs((ms.Open.Last(k) - ms.Close.Last(k))); } #endregion #region Candle Close private double CandleClose(int k) { if (CandleTypeBullish(k)) { return CandleBodyTop(k); } return CandleBodyBottom(k); } #endregion #region Candle Open private double CandleOpen(int k) { if (CandleTypeBullish(k)) { return CandleBodyBottom(k); } return CandleBodyTop(k); } #endregion #region Candle Sinus private double CandleSinus(int k) { return Math.Abs((ms.Open.Last(k) - ms.Close.Last(k))) / CandleRange(k) * (ms.Close.Last(k) > ms.Open.Last(k) ? 1 : -1); } #endregion #region Trend Angle private double TrendAngle(int CandlesInTrend) { double absBody = 0; double bodiesRange = 0; for (int i = 0; i <= CandlesInTrend; i++) { if (CandleTypeBullish(i)) { bodiesRange = bodiesRange + CandleBody(i); } if (!CandleTypeBullish(i)) { bodiesRange = bodiesRange - CandleBody(i); } absBody = absBody + CandleBody(i); } var trendSinus = bodiesRange / absBody; return Math.Asin(trendSinus) * 180 / Math.PI; } #endregion #region Candle OpenTime private DateTime CandleOpenTime(int k) { return ms.OpenTime.Last(k); } #endregion #region No k Candles on the left High private bool NoLeftCandlesHigh(int k) { for (int i = 1; i < k; i++) { if (CandleHigh(1) > CandleLow(1 + i) && CandleHigh(1) < CandleHigh(1 + i)) { return false; } if (CandleHigh(1) < CandleLow(1 + i) || CandleHigh(1) > CandleHigh(1 + i)) { continue; } } return true; } #endregion #region No k Candles on the left Low private bool NoLeftCandlesLow(int k) { for (int i = 1; i < k; i++) { if (CandleLow(1) < CandleHigh(1 + i) && CandleLow(1) > CandleLow(1 + i)) { return false; } if (CandleLow(1) < CandleHigh(1 + i) || CandleLow(1) > CandleLow(1 + i)) { continue; } } return true; } #endregion #endregion } }
I think Spotware have to do smth about it, otherwise the whole idea of cTrader Algos is becoming useless
Regadrs
Alexander
@alexander.n.fedorov
alexander.n.fedorov
30 Mar 2019, 10:57
( Updated at: 21 Dec 2023, 09:21 )
RE: RE: RE:
alexander.n.fedorov said:
alexander.n.fedorov said:
alexander.n.fedorov said:
Dear Panagiotis!
There must be sum bug in optimizations.
I will put three charts here and a zip of the bot
Optimization and backtesting show complitely different results, even thou all the condititons according to "apply
"
in both cases parameteres are the same, 1 minuter data,dates are the same, only one timeframe
What is interesting, sometimes it repeats perfectly
Sometimes - nothing in common.
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.RussianStandardTime, AccessRights = AccessRights.None)] public class VolatilityBreakout4 : Robot { [Parameter("Source")] public DataSeries Source { get; set; } [Parameter("Risk", MaxValue = 10, MinValue = 0.5, DefaultValue = 1)] public double Risk { get; set; } [Parameter("Squeeze bars number", MaxValue = 180, MinValue = 5, Step = 1, DefaultValue = 20)] public int SqueezeBarsNumber { get; set; } [Parameter("Squeeze in pips", MaxValue = 300, MinValue = 1, Step = 0.1, DefaultValue = 20)] public double Squeeze { get; set; } [Parameter("TP multiple", MaxValue = 8, MinValue = 1, Step = 0.1, DefaultValue = 2)] public double TpMultiple { get; set; } [Parameter("Close Trade Hour", DefaultValue = 23)] public int CloseTradesHour { get; set; } [Parameter("Close Trade Minute", DefaultValue = 30)] public int CloseTradesMinute { get; set; } [Parameter("Open Trade Hour", DefaultValue = 2)] public int OpenTradesHour { get; set; } private string instance; private MarketSeries ms; private double range, high, low, volume, barsRange, SL, TP, minVolume, risk; private int pipDigits, n; private DateTime squeezeFirstBarTime, squeezeLastBarTime; private TimeSpan ts; protected override void OnStart() { instance = ToString() + ", " + Symbol.Code + ", " + TimeFrame + ", " + Account.BrokerName + ", " + Account.Number; range = Squeeze * Symbol.PipSize; ms = MarketData.GetSeries(TimeFrame); minVolume = Symbol.VolumeInUnitsMin; ts = CandleOpenTime(0) - CandleOpenTime(2); risk = Risk * 0.01; pipDigits = Symbol.Digits - (int)Math.Log10(1 / Symbol.PipSize); Positions.Opened += Positions_Opened; Positions.Closed += PositionsOnClosed; squeezeFirstBarTime = CandleOpenTime(2 + SqueezeBarsNumber); squeezeLastBarTime = CandleOpenTime(2); } protected override void OnBar() { if ((CandleOpenTime(0).Hour >= CloseTradesHour && CandleOpenTime(0).Minute >= CloseTradesMinute) || CandleOpenTime(0).Hour < OpenTradesHour) { return; } squeezeFirstBarTime = CandleOpenTime(1 + SqueezeBarsNumber); squeezeLastBarTime = CandleOpenTime(1); high = CandleHigh(1); low = CandleLow(1); barsRange = CandleClose(1) > (1) ? MarketSeries.Close.Last(1) - MarketSeries.Open.Last(1) : MarketSeries.Open.Last(1) - MarketSeries.Close.Last(1); for (int i = 0; i < SqueezeBarsNumber; i++) { high = CandleHigh(i + 1) > high ? CandleHigh(i + 1) : high; low = CandleLow(i + 1) < low ? CandleLow(i + 1) : low; barsRange = high - low; } //Chart.RemoveAllObjects(); //Chart.DrawTrendLine("sHigh", squeezeFirstBarTime, high, squeezeLastBarTime, high, Color.Aqua, 1, LineStyle.Solid); //Chart.DrawTrendLine("sLow", squeezeFirstBarTime, low, squeezeLastBarTime, low, Color.Red, 1, LineStyle.Solid); //double barRangePips = Math.Round(barsRange / Symbol.PipSize, 1); //string text = "Squeeze = " + Squeeze + " , barRange = " + barRangePips; //Chart.DrawStaticText("Current range", text, VerticalAlignment.Bottom, HorizontalAlignment.Right, Color.Aquamarine); var position = Positions.Find(instance); if (position != null) { return; } n = 0; foreach (var order in PendingOrders) { if (order.Label == instance) { n = n + 1; } } if (position == null) { if (n == 0) { if (high - low < range) { double longPrice = high; double shortPrice = low; SL = (high - low) / Symbol.PipSize; volume = Math.Floor(((Account.Equity * risk) / SL) / Symbol.PipValue / minVolume) * minVolume; SL = Math.Round(SL, pipDigits, MidpointRounding.AwayFromZero); TP = SL * TpMultiple; PlaceStopOrder(TradeType.Buy, Symbol, volume, longPrice, instance, SL, TP); PlaceStopOrder(TradeType.Sell, Symbol, volume, shortPrice, instance, SL, TP); } } } } private void Positions_Opened(PositionOpenedEventArgs args) { var position = args.Position; if (position.Label == instance) { foreach (var order in PendingOrders) { if (order.Label == instance) CancelPendingOrder(order); } } } private void PositionsOnClosed(PositionClosedEventArgs args) { var position = args.Position; if (args.Reason == PositionCloseReason.TakeProfit) { //if (Server.Time - position.EntryTime < ts) //{ // ExecuteMarketOrder(position.TradeType, Symbol, volume, instance, SL, SL); //} //// foreach (var order in PendingOrders) // { // if (order.Label == instance) // CancelPendingOrder(order); // } //} } } #region Candles Processing #region Candle Type private bool CandleTypeBullish(int k) { if (ms.Open.Last(k) > ms.Close.Last(k)) { return false; } return true; } #endregion #region Candle Range(int k) private double CandleRange(int k) { return ms.High.Last(k) - ms.Low.Last(k); } #endregion #region Candle body bottom private double CandleBodyBottom(int k) { return (ms.Open.Last(k) < ms.Close.Last(k)) ? ms.Open.Last(k) : ms.Close.Last(k); } #endregion #region Candle body Top private double CandleBodyTop(int k) { return (ms.Open.Last(k) > ms.Close.Last(k)) ? ms.Open.Last(k) : ms.Close.Last(k); } #endregion #region Candle high private double CandleHigh(int k) { return ms.High.Last(k); } #endregion #region Candle low private double CandleLow(int k) { return ms.Low.Last(k); } #endregion #region Candle body private double CandleBody(int k) { return Math.Abs((ms.Open.Last(k) - ms.Close.Last(k))); } #endregion #region Candle Close private double CandleClose(int k) { if (CandleTypeBullish(k)) { return CandleBodyTop(k); } return CandleBodyBottom(k); } #endregion #region Candle Open private double CandleOpen(int k) { if (CandleTypeBullish(k)) { return CandleBodyBottom(k); } return CandleBodyTop(k); } #endregion #region Candle Sinus private double CandleSinus(int k) { return Math.Abs((ms.Open.Last(k) - ms.Close.Last(k))) / CandleRange(k) * (ms.Close.Last(k) > ms.Open.Last(k) ? 1 : -1); } #endregion #region Trend Angle private double TrendAngle(int CandlesInTrend) { double absBody = 0; double bodiesRange = 0; for (int i = 0; i <= CandlesInTrend; i++) { if (CandleTypeBullish(i)) { bodiesRange = bodiesRange + CandleBody(i); } if (!CandleTypeBullish(i)) { bodiesRange = bodiesRange - CandleBody(i); } absBody = absBody + CandleBody(i); } var trendSinus = bodiesRange / absBody; return Math.Asin(trendSinus) * 180 / Math.PI; } #endregion #region Candle OpenTime private DateTime CandleOpenTime(int k) { return ms.OpenTime.Last(k); } #endregion #region No k Candles on the left High private bool NoLeftCandlesHigh(int k) { for (int i = 1; i < k; i++) { if (CandleHigh(1) > CandleLow(1 + i) && CandleHigh(1) < CandleHigh(1 + i)) { return false; } if (CandleHigh(1) < CandleLow(1 + i) || CandleHigh(1) > CandleHigh(1 + i)) { continue; } } return true; } #endregion #region No k Candles on the left Low private bool NoLeftCandlesLow(int k) { for (int i = 1; i < k; i++) { if (CandleLow(1) < CandleHigh(1 + i) && CandleLow(1) > CandleLow(1 + i)) { return false; } if (CandleLow(1) < CandleHigh(1 + i) || CandleLow(1) > CandleLow(1 + i)) { continue; } } return true; } #endregion #endregion } }
I think Spotware have to do smth about it, otherwise the whole idea of cTrader Algos is becoming useless
Regadrs
Alexander
P.S. What is interesting, this effect appeared just recently. Before my previous mail everything worked allright. May it is one of the constant upgrades?
@alexander.n.fedorov
alexander.n.fedorov
30 Mar 2019, 11:18
I just tryied to do optimization on tick data. Result is the same. Optimization and the backtest - absolutely different results
@alexander.n.fedorov
tradermatrix
30 Mar 2019, 15:52
Hi
I think the problem is here;
SL = Math.Round(SL, pipDigits, MidpointRounding.AwayFromZero);
I just replaced ("MidpointRounding.AwayFromZero") with 0 and it works
SL = Math.Round(SL, pipDigits, 0);
TP = SL * TpMultiple;
PlaceStopOrder(TradeType.Buy, Symbol, volume, longPrice, instance, SL, TP);
PlaceStopOrder(TradeType.Sell, Symbol, volume, shortPrice, instance, SL, TP);
cordially
@tradermatrix
alexander.n.fedorov
31 Mar 2019, 10:30
RE:
tradermatrix said:
Hi
I think the problem is here;
SL = Math.Round(SL, pipDigits, MidpointRounding.AwayFromZero);
I just replaced ("MidpointRounding.AwayFromZero") with 0 and it works
SL = Math.Round(SL, pipDigits, 0);
TP = SL * TpMultiple;
PlaceStopOrder(TradeType.Buy, Symbol, volume, longPrice, instance, SL, TP);
PlaceStopOrder(TradeType.Sell, Symbol, volume, shortPrice, instance, SL, TP);cordially
Thank you. Let me try
Also before I tryied I wannted to say it is not working on tick either
@alexander.n.fedorov
alexander.n.fedorov
31 Mar 2019, 10:43
( Updated at: 21 Dec 2023, 09:21 )
I tryied, I changed to "0"
the results
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.RussianStandardTime, AccessRights = AccessRights.FullAccess)] public class VolatilityBreakout4 : Robot { [Parameter("Source")] public DataSeries Source { get; set; } [Parameter("Risk", MaxValue = 10, MinValue = 0.5, DefaultValue = 1)] public double Risk { get; set; } [Parameter("Squeeze bars number", MaxValue = 180, MinValue = 5, Step = 1, DefaultValue = 20)] public int SqueezeBarsNumber { get; set; } [Parameter("Squeeze in pips", MaxValue = 300, MinValue = 1, Step = 0.1, DefaultValue = 20)] public double Squeeze { get; set; } [Parameter("TP multiple", MaxValue = 8, MinValue = 1, Step = 0.1, DefaultValue = 2)] public double TpMultiple { get; set; } [Parameter("Close on Profit %", Step = 0.1, DefaultValue = 4.0)] public double CloseOnProfit { get; set; } [Parameter("Close Trade Hour", DefaultValue = 23)] public int CloseTradesHour { get; set; } [Parameter("Close Trade Minute", DefaultValue = 30)] public int CloseTradesMinute { get; set; } [Parameter("Open Trade Hour", DefaultValue = 2)] public int OpenTradesHour { get; set; } private string instance; private MarketSeries ms; private double range, high, low, volume, barsRange, SL, TP, minVolume, risk, longPrice; private double shortPrice, closeOnProfit; private int pipDigits, n; private DateTime squeezeFirstBarTime, squeezeLastBarTime; protected override void OnStart() { instance = ToString() + ", " + Symbol.Code + ", " + TimeFrame + ", " + Account.BrokerName + ", " + Account.Number; range = Squeeze * Symbol.PipSize; ms = MarketData.GetSeries(TimeFrame); minVolume = Symbol.VolumeInUnitsMin; risk = Risk * 0.01; closeOnProfit = CloseOnProfit * 0.01; pipDigits = Symbol.Digits - (int)Math.Log10(1 / Symbol.PipSize); Positions.Opened += Positions_Opened; Positions.Closed += PositionsOnClosed; squeezeFirstBarTime = CandleOpenTime(2 + SqueezeBarsNumber); squeezeLastBarTime = CandleOpenTime(2); } protected override void OnBar() { var position = Positions.Find(instance); var spread = Symbol.Spread / Symbol.PipSize; if (position == null) { if (spread > 2) { return; } if ((CandleOpenTime(0).Hour >= CloseTradesHour && CandleOpenTime(0).Minute >= CloseTradesMinute) || CandleOpenTime(0).Hour < OpenTradesHour) { return; } squeezeFirstBarTime = CandleOpenTime(1 + SqueezeBarsNumber); squeezeLastBarTime = CandleOpenTime(1); high = CandleHigh(1); low = CandleLow(1); barsRange = CandleClose(1) > (1) ? MarketSeries.Close.Last(1) - MarketSeries.Open.Last(1) : MarketSeries.Open.Last(1) - MarketSeries.Close.Last(1); for (int i = 0; i < SqueezeBarsNumber; i++) { high = CandleHigh(i + 1) > high ? CandleHigh(i + 1) : high; low = CandleLow(i + 1) < low ? CandleLow(i + 1) : low; barsRange = high - low; } //Chart.RemoveAllObjects(); //Chart.DrawTrendLine("sHigh", squeezeFirstBarTime, high, squeezeLastBarTime, high, Color.Aqua, 1, LineStyle.Solid); //Chart.DrawTrendLine("sLow", squeezeFirstBarTime, low, squeezeLastBarTime, low, Color.Red, 1, LineStyle.Solid); //double barRangePips = Math.Round(barsRange / Symbol.PipSize, 1); //string text = "Squeeze = " + Squeeze + " , barRange = " + barRangePips; //Chart.DrawStaticText("Current range", text, VerticalAlignment.Bottom, HorizontalAlignment.Right, Color.Aquamarine); n = 0; foreach (var order in PendingOrders) { if (order.Label == instance) { n = n + 1; } } if (n == 0) { if (high - low < range) { { longPrice = high; shortPrice = low; SL = (high - low) / Symbol.PipSize + 1; volume = Math.Floor(((Account.Equity * risk) / SL) / Symbol.PipValue / minVolume) * minVolume; SL = Math.Round(SL, pipDigits, 0); TP = Math.Round(SL * TpMultiple, pipDigits, 0); PlaceStopOrder(TradeType.Buy, Symbol, volume, longPrice, instance, null, TP); PlaceStopOrder(TradeType.Sell, Symbol, volume, shortPrice, instance, null, TP); //Chart.DrawHorizontalLine(longPrice.ToString(), longPrice - SL * Symbol.PipSize, Color.Crimson, 1, LineStyle.DotsRare); //Chart.DrawHorizontalLine(shortPrice.ToString(), shortPrice + SL * Symbol.PipSize, Color.Crimson, 1, LineStyle.DotsRare); } } } } if (position != null) { if (spread > 2) { return; } if (position.TradeType == TradeType.Buy) { if (CandleClose(1) < position.EntryPrice - SL * Symbol.PipSize) { ClosePosition(position); //Chart.RemoveAllObjects(); } } if (position.TradeType == TradeType.Sell) { if (CandleClose(1) > position.EntryPrice + SL * Symbol.PipSize) { ClosePosition(position); //Chart.RemoveAllObjects(); } } } } protected override void OnTick() { if (Account.UnrealizedNetProfit > Account.Balance * closeOnProfit) foreach (var position in Positions) { ClosePositionAsync(position); } } private void Positions_Opened(PositionOpenedEventArgs args) { var position = args.Position; if (position.Label == instance) { foreach (var order in PendingOrders) { if (order.Label == instance) CancelPendingOrder(order); } if (position.TradeType == TradeType.Buy) { //Chart.RemoveObject(shortPrice.ToString()); } if (position.TradeType == TradeType.Sell) { //Chart.RemoveObject(longPrice.ToString()); } } } private void PositionsOnClosed(PositionClosedEventArgs args) { var position = args.Position; if (args.Reason == PositionCloseReason.TakeProfit) { // } } #region Candles Processing #region Candle Type private bool CandleTypeBullish(int k) { if (ms.Open.Last(k) > ms.Close.Last(k)) { return false; } return true; } #endregion #region Candle Range(int k) private double CandleRange(int k) { return ms.High.Last(k) - ms.Low.Last(k); } #endregion #region Candle body bottom private double CandleBodyBottom(int k) { return (ms.Open.Last(k) < ms.Close.Last(k)) ? ms.Open.Last(k) : ms.Close.Last(k); } #endregion #region Candle body Top private double CandleBodyTop(int k) { return (ms.Open.Last(k) > ms.Close.Last(k)) ? ms.Open.Last(k) : ms.Close.Last(k); } #endregion #region Candle high private double CandleHigh(int k) { return ms.High.Last(k); } #endregion #region Candle low private double CandleLow(int k) { return ms.Low.Last(k); } #endregion #region Candle body private double CandleBody(int k) { return Math.Abs((ms.Open.Last(k) - ms.Close.Last(k))); } #endregion #region Candle Close private double CandleClose(int k) { if (CandleTypeBullish(k)) { return CandleBodyTop(k); } return CandleBodyBottom(k); } #endregion #region Candle Open private double CandleOpen(int k) { if (CandleTypeBullish(k)) { return CandleBodyBottom(k); } return CandleBodyTop(k); } #endregion #region Candle Sinus private double CandleSinus(int k) { return Math.Abs((ms.Open.Last(k) - ms.Close.Last(k))) / CandleRange(k) * (ms.Close.Last(k) > ms.Open.Last(k) ? 1 : -1); } #endregion #region Trend Angle private double TrendAngle(int CandlesInTrend) { double absBody = 0; double bodiesRange = 0; for (int i = 0; i <= CandlesInTrend; i++) { if (CandleTypeBullish(i)) { bodiesRange = bodiesRange + CandleBody(i); } if (!CandleTypeBullish(i)) { bodiesRange = bodiesRange - CandleBody(i); } absBody = absBody + CandleBody(i); } var trendSinus = bodiesRange / absBody; return Math.Asin(trendSinus) * 180 / Math.PI; } #endregion #region Candle OpenTime private DateTime CandleOpenTime(int k) { return ms.OpenTime.Last(k); } #endregion #region No k Candles on the left High private bool NoLeftCandlesHigh(int k) { for (int i = 1; i < k; i++) { if (CandleHigh(1) > CandleLow(1 + i) && CandleHigh(1) < CandleHigh(1 + i)) { return false; } if (CandleHigh(1) < CandleLow(1 + i) || CandleHigh(1) > CandleHigh(1 + i)) { continue; } } return true; } #endregion #region No k Candles on the left Low private bool NoLeftCandlesLow(int k) { for (int i = 1; i < k; i++) { if (CandleLow(1) < CandleHigh(1 + i) && CandleLow(1) > CandleLow(1 + i)) { return false; } if (CandleLow(1) < CandleHigh(1 + i) || CandleLow(1) > CandleLow(1 + i)) { continue; } } return true; } #endregion #endregion } }
I commented the charts. Charts do not work on optimization.
I also introduced the OnTick logic, as it may improve the working with portfolio
But the poin is that about a month ago everthing was working perfectly
Now - not
during this time there were some updates on the software. Could that be the reason?
Regards,
Alexander
@alexander.n.fedorov
alexander.n.fedorov
31 Mar 2019, 11:37
( Updated at: 21 Dec 2023, 09:21 )
I put two charts. Both have the same parameters, both OnTick , same period
first, optimization
Second - Backtesting
As you can see, they are quite different
????
@alexander.n.fedorov
alexander.n.fedorov
31 Mar 2019, 11:39
( Updated at: 21 Dec 2023, 09:21 )
Sorry , the second one was wrong
the correct one is this:
@alexander.n.fedorov
tradermatrix
31 Mar 2019, 11:57
Hello
I downloaded the last code you tested ... and at home it works in bar mode and tick mode .. no difference between backesting and optimization
I think the cause is an update ..
I downloaded last upgrade to a newer version of .Net framework.
can be a try ...
https://dotnet.microsoft.com/download/dotnet-framework/net472
@tradermatrix
alexander.n.fedorov
31 Mar 2019, 13:05
Hi!
Because I am quite new to the programming in C# I do not quite understand what shall I do with the link?
Shall I just down load the runtime? I am using Visual Studio for writing a code
Regards
Alexander
@alexander.n.fedorov
alexander.n.fedorov
31 Mar 2019, 13:21
Hi, TraDerMaTrix
I really appreciate your concern. I downloaded and installed the the developer pack
But results are the same
May be you could be very kind and call my Skype number:
alexander.n.fedorov
Regards,
Alexander
@alexander.n.fedorov
alexander.n.fedorov
31 Mar 2019, 13:56
Hi, TraDerMaTrix
I installed the developer pack per your link on a VPS server (dedicated, very good) and on my notebook
Rebuilt the code
Tryid it again on both machines
It is not working. It gives different results
Can you help? You look like you know whay you are doing
Regards,
Alexander
@alexander.n.fedorov
alexander.n.fedorov
31 Mar 2019, 18:10
There is very interesting thing I discovered.
If TimeFrame is included into optimization of this algo, then I have all the problems
If I use only one TimeFrame - no problem!
It must be a bug
@alexander.n.fedorov
PanagiotisCharalampous
02 Apr 2019, 11:37
Hi Sasha,
It should be the same issue we discussed here.
Best Regards,
Panagiotis
@PanagiotisCharalampous
alexander.n.fedorov
30 Mar 2019, 10:44 ( Updated at: 21 Dec 2023, 09:21 )
RE:
alexander.n.fedorov said:
in both cases parameteres are the same, 1 minuter data,dates are the same, only one timeframe
What is interesting, sometimes it repeats perfectly
Sometimes - nothing in common.
@alexander.n.fedorov