Topics
Replies
lec0456
12 Dec 2017, 23:09
I am answering my own question but its the best thing i did for me cBots so I figured I would share the solution.
3 steps: create a struct, create a function to poputlate the fields, declare the struct variable, call the function onTick or onBar.
Create a simple struct:
public struct idata { public int t0, t1, t2, t3; public int LondonHour, NYHour, SydneyHour, TokyoHour; public int LondonHour1, NYHour1, SydneyHour1, TokyoHour1; public int DateDifference; public int LstPkWkly; public double pchigh0, pchigh1, pchigh2, pchigh3; public double pclow0, pclow1, pclow2, pclow3; public double pccenter0, pccenter1; public double pcWidth0, pcWidth1, pcWidth2, pcWidth3; public double pcWidth0D; //public double pcWidth0W; public double smaWidth; public double high0, high1, high2, high3; //public double high0H, high1H, high2H, high3H; public double high0D, high1D; public double high0W, high1W; public double highSMA; public double low0, low1, low2, low3; //public double low0H, low1H, low2H, low3H; public double low0D, low1D; public double low0W, low1W; public double lowSMA; public double vol0, vol1, vol2; public double open0, open1, open2, open3; public double open0D; public double open0W; public double close0, close1, close2, close3; public double ocdiff0, ocdiff1, ocdiff2, ocdiff3; public double ocdiff1H, ocdiff2H; public double ocdiff0D, ocdiff1D; public double Uwick1, Uwick2, Uwick3; public double Lwick1, Lwick2, Lwick3; public double sto0, sto1,sto2, sto3; public double cyc0, cyc1, cyc2, cyc3; public double ma1t0, ma1t1, ma1t2, ma1t3; public double ma2t0, ma2t1, ma2t2, ma2t3; public double ma3t0, ma4t0; public double ma1_ma2, ma1_ma3, ma1_ma4, ma2_ma3, ma2_ma4, ma3_ma4; public double ssum24_0, ssum24_1, ssum24_2, ssum24_3; public double ssum96_0, ssum96_1, ssum96_2, ssum96_3; public double ma1slp0, ma2slp0, ma3slp0, ma4slp0; public double ma1slp1, ma2slp1, ma3slp1, ma4slp1; public double ma1pk0,ma2pk0,ma3pk0,ma4pk0; public double ma1pk1,ma2pk1,ma3pk1,ma4pk1; public double ma24x0,ma24x1; public double WklyHighDiff, WklyLowDiff; }
Then create a function to populate the fields:
idata GetIndicatorData() { idata indicatordata; int t0 = MarketSeries.Close.Count - 1; int t1 = t0 - 1; int t2 = t1 - 1; int t3 = t2 - 1; var weeklyindex = Weekly.OpenTime.GetIndexByTime(MarketSeries.OpenTime[t0]); var dailyindex = Daily.OpenTime.GetIndexByTime(MarketSeries.OpenTime[t0]); var hourlyindex = Hourly.OpenTime.GetIndexByTime(MarketSeries.OpenTime[t0]); var _15minindex = _15min.OpenTime.GetIndexByTime(MarketSeries.OpenTime[t0]); indicatordata.t0 = t0; indicatordata.t1 = t0 - 1; indicatordata.t2 = t1 - 1; indicatordata.t3 = t2 - 1; indicatordata.pchigh0 = pc.Upper[t0]; indicatordata.pchigh1 = pc.Upper[t1]; indicatordata.pchigh2 = pc.Upper[t2]; indicatordata.pchigh3 = pc.Upper[t3]; indicatordata.pclow0 = pc.Lower[t0]; indicatordata.pclow1 = pc.Lower[t1]; indicatordata.pclow2 = pc.Lower[t2]; indicatordata.pclow3 = pc.Lower[t3]; indicatordata.pccenter0 = pc.Center[t0]; indicatordata.pccenter1 = pc.Center[t1]; indicatordata.pcWidth0D = PipDiff(Daily.High[dailyindex], Daily.Low[dailyindex]); indicatordata.pcWidth0 = Math.Round(pcw.Result[t0], 2); indicatordata.pcWidth1 = Math.Round(pcw.Result[t1], 2); indicatordata.pcWidth2 = Math.Round(pcw.Result[t2], 2); indicatordata.pcWidth3 = Math.Round(pcw.Result[t3], 2); indicatordata.smaWidth=SMABandDist(); indicatordata.high0 = MarketSeries.High[t0]; indicatordata.high1 = MarketSeries.High[t1]; indicatordata.high2 = MarketSeries.High[t2]; indicatordata.high3 = MarketSeries.High[t3]; indicatordata.high0D = Daily.High[dailyindex]; indicatordata.high1D = Daily.High[dailyindex-1]; indicatordata.high0W = Weekly.High[weeklyindex]; indicatordata.high1W = Weekly.High[weeklyindex-1]; indicatordata.highSMA = HighSMA(); indicatordata.low0 = MarketSeries.Low[t0]; indicatordata.low1 = MarketSeries.Low[t1]; indicatordata.low2 = MarketSeries.Low[t2]; indicatordata.low3 = MarketSeries.Low[t3]; indicatordata.lowSMA = LowSMA(); indicatordata.low0D = Daily.Low[dailyindex]; indicatordata.low1D = Daily.Low[dailyindex-1]; indicatordata.low0W = Weekly.Low[weeklyindex]; indicatordata.low1W = Weekly.Low[weeklyindex-1]; indicatordata.vol0 = MarketSeries.TickVolume[t0]; indicatordata.vol1 = MarketSeries.TickVolume[t1]; indicatordata.vol2 = MarketSeries.TickVolume[t2]; indicatordata.open0 = MarketSeries.Open[t0]; indicatordata.open1 = MarketSeries.Open[t1]; indicatordata.open2 = MarketSeries.Open[t2]; indicatordata.open3 = MarketSeries.Open[t3]; indicatordata.open0D = Daily.Open[dailyindex]; indicatordata.open0W = Weekly.Open[weeklyindex]; indicatordata.close0 = MarketSeries.Close[t0]; indicatordata.close1 = MarketSeries.Close[t1]; indicatordata.close2 = MarketSeries.Close[t2]; indicatordata.close3 = MarketSeries.Close[t3]; indicatordata.ocdiff0 = Math.Round((MarketSeries.Close[t0] - MarketSeries.Open[t0]) / Symbol.PipSize, 2); indicatordata.ocdiff1 = Math.Round((MarketSeries.Close[t1] - MarketSeries.Open[t1]) / Symbol.PipSize, 2); indicatordata.ocdiff2 = Math.Round((MarketSeries.Close[t2] - MarketSeries.Open[t2]) / Symbol.PipSize, 2); indicatordata.ocdiff3 = Math.Round((MarketSeries.Close[t3] - MarketSeries.Open[t3]) / Symbol.PipSize, 2); indicatordata.ocdiff0D = PipDiff(Daily.Close[dailyindex], Daily.Open[dailyindex]); indicatordata.ocdiff1D = PipDiff(Daily.Close[dailyindex - 1], Daily.Open[dailyindex - 1]); indicatordata.Uwick1 = indicatordata.ocdiff1 > 0 ? (MarketSeries.High[t1] - MarketSeries.Close[t1]) / Symbol.PipSize : (MarketSeries.High[t1] - MarketSeries.Open[t1]) / Symbol.PipSize; indicatordata.Uwick2 = indicatordata.ocdiff2 > 0 ? (MarketSeries.High[t2] - MarketSeries.Close[t2]) / Symbol.PipSize : (MarketSeries.High[t2] - MarketSeries.Open[t2]) / Symbol.PipSize; indicatordata.Uwick3 = indicatordata.ocdiff3 > 0 ? (MarketSeries.High[t3] - MarketSeries.Close[t3]) / Symbol.PipSize : (MarketSeries.High[t3] - MarketSeries.Open[t3]) / Symbol.PipSize; indicatordata.Lwick1 = indicatordata.ocdiff1 > 0 ? (MarketSeries.Open[t1] - MarketSeries.Low[t1]) / Symbol.PipSize : (MarketSeries.Close[t1] - MarketSeries.Low[t1]) / Symbol.PipSize; indicatordata.Lwick2 = indicatordata.ocdiff2 > 0 ? (MarketSeries.Open[t2] - MarketSeries.Low[t2]) / Symbol.PipSize : (MarketSeries.Close[t2] - MarketSeries.Low[t2]) / Symbol.PipSize; indicatordata.Lwick3 = indicatordata.ocdiff3 > 0 ? (MarketSeries.Open[t3] - MarketSeries.Low[t3]) / Symbol.PipSize : (MarketSeries.Close[t3] - MarketSeries.Low[t3]) / Symbol.PipSize; indicatordata.sto0 = Math.Round(sto.PercentK[t0], 2); indicatordata.sto1 = Math.Round(sto.PercentK[t1], 2); indicatordata.sto2 = Math.Round(sto.PercentK[t2], 2); indicatordata.sto3 = Math.Round(sto.PercentK[t3], 2); indicatordata.cyc0 = Math.Round(sto.PercentKcyc[t0], 2); indicatordata.cyc1 = Math.Round(sto.PercentKcyc[t1], 2); indicatordata.cyc2 = Math.Round(sto.PercentKcyc[t2], 2); indicatordata.cyc3 = Math.Round(sto.PercentKcyc[t3], 2); indicatordata.ma1t0 = smoothsma1.Result[t0]; indicatordata.ma1t1 = smoothsma1.Result[t1]; indicatordata.ma1t2 = smoothsma1.Result[t2]; indicatordata.ma1t3 = smoothsma1.Result[t3]; indicatordata.ma2t0 = smoothsma2.Result[t0]; indicatordata.ma2t1 = smoothsma2.Result[t1]; indicatordata.ma2t2 = smoothsma2.Result[t2]; indicatordata.ma2t3 = smoothsma2.Result[t3]; indicatordata.ma3t0 = smoothsma3.Result[t0]; indicatordata.ma4t0 = smoothsma4.Result[t0]; indicatordata.ma1_ma2 = (smoothsma1.Result[t0] - smoothsma2.Result[t0]) / Symbol.PipSize; indicatordata.ma1_ma3 = (smoothsma1.Result[t0] - smoothsma3.Result[t0]) / Symbol.PipSize; indicatordata.ma1_ma4 = (smoothsma1.Result[t0] - smoothsma4.Result[t0]) / Symbol.PipSize; indicatordata.ma2_ma3 = (smoothsma2.Result[t0] - smoothsma3.Result[t0]) / Symbol.PipSize; indicatordata.ma2_ma4 = (smoothsma2.Result[t0] - smoothsma4.Result[t0]) / Symbol.PipSize; indicatordata.ma3_ma4 = (smoothsma3.Result[t0] - smoothsma4.Result[t0]) / Symbol.PipSize; indicatordata.LondonHour = double.IsNaN(markethours.London[t0]) ? 0 : (int)markethours.London[t0]; indicatordata.NYHour = double.IsNaN(markethours.NewYork[t0]) ? 0 : (int)markethours.NewYork[t0]; indicatordata.SydneyHour = double.IsNaN(markethours.Sydney[t0]) ? 0 : (int)markethours.Sydney[t0]; indicatordata.TokyoHour = double.IsNaN(markethours.Tokyo[t0]) ? 0 : (int)markethours.Tokyo[t0]; indicatordata.LondonHour1 = double.IsNaN(markethours.London[t1]) ? 0 : (int)markethours.London[t1]; indicatordata.NYHour1 = double.IsNaN(markethours.NewYork[t1]) ? 0 : (int)markethours.NewYork[t1]; indicatordata.SydneyHour1 = double.IsNaN(markethours.Sydney[t1]) ? 0 : (int)markethours.Sydney[t1]; indicatordata.TokyoHour1 = double.IsNaN(markethours.Tokyo[t1]) ? 0 : (int)markethours.Tokyo[t1]; indicatordata.ocdiff1H = (Hourly.Close[hourlyindex - 1] - Hourly.Open[hourlyindex - 1]) / Symbol.PipSize; indicatordata.ocdiff2H = (Hourly.Close[hourlyindex - 2] - Hourly.Open[hourlyindex - 2]) / Symbol.PipSize; indicatordata.WklyHighDiff = PipDiff(Weekly.High[weeklyindex], MarketSeries.Close[t0]); indicatordata.WklyLowDiff = PipDiff(MarketSeries.Close[t0], Weekly.Low[weeklyindex]); indicatordata.DateDifference = (int)(EESTDate(MarketSeries.OpenTime[t0]).Date - EESTDate(MarketSeries.OpenTime[t1]).Date).TotalDays; indicatordata.ssum24_0 = slopesum24.SlopeSum[t0]; indicatordata.ssum24_1 = slopesum24.SlopeSum[t1]; indicatordata.ssum24_2 = slopesum24.SlopeSum[t2]; indicatordata.ssum24_3 = slopesum24.SlopeSum[t3]; indicatordata.ssum96_0 = slopesum96.SlopeSum[t0]; indicatordata.ssum96_1 = slopesum96.SlopeSum[t1]; indicatordata.ssum96_2 = slopesum96.SlopeSum[t2]; indicatordata.ssum96_3 = slopesum96.SlopeSum[t3]; indicatordata.ma1slp0 = slopesum24.ma1Slope[t0]; indicatordata.ma2slp0 = slopesum24.ma2Slope[t0]; indicatordata.ma3slp0 = slopesum96.ma1Slope[t0]; indicatordata.ma4slp0 = slopesum96.ma2Slope[t0]; indicatordata.ma1slp1 = slopesum24.ma1Slope[t1]; indicatordata.ma2slp1 = slopesum24.ma2Slope[t1]; indicatordata.ma3slp1 = slopesum96.ma1Slope[t1]; indicatordata.ma4slp1 = slopesum96.ma2Slope[t1]; indicatordata.ma1pk0=mapeaks24.maPeakDiff[t0]; indicatordata.ma2pk0=mapeaks48.maPeakDiff[t0]; indicatordata.ma3pk0=mapeaks96.maPeakDiff[t0]; indicatordata.ma4pk0=mapeaks192.maPeakDiff[t0]; indicatordata.ma1pk1=mapeaks24.maPeakDiff[t1]; indicatordata.ma2pk1=mapeaks48.maPeakDiff[t1]; indicatordata.ma3pk1=mapeaks96.maPeakDiff[t1]; indicatordata.ma4pk1=mapeaks192.maPeakDiff[t1]; indicatordata.ma24x0=madiffs24.Xsignal[t0]; indicatordata.ma24x1=madiffs24.Xsignal[t1]; int WavePositionWkly = 0; for (int i = 0; i <= int.MaxValue; i++) { if ((t0-i)<0){break;} else if (MarketSeries.High[t0 - i] == indicatordata.high0W) { WavePositionWkly = (i + 1) * up; break; } else if (MarketSeries.Low[t0 - i] == indicatordata.low0W) { WavePositionWkly = (i + 1) * dn; break; } } indicatordata.LstPkWkly = WavePositionWkly; return indicatordata; }
Declare the struct variable outside the onTick event:
idata id;
Call the function:
protected override void OnTick() { id = GetIndicatorData(); }
@lec0456
lec0456
23 Nov 2017, 19:24
It definately affects the behavior of the results of the cBot. It can change the average price of multiple positions and cause them not to close in realtime while closing just fine during a backtest.
I knew the agent's response was not accurate, but I was not going to agrue with him. I don't think I could convince him that the feed was his data.
However, if cAlgo has confirmed that there is an issue that can be fixed, that is great news. I am curious to know what exactly is the issue?
@lec0456
lec0456
22 Nov 2017, 21:45
Look at the response from the broker below. Incredible...beware!
Sam (OctaFX)
Nov 22, 08:44 EET
Dear Louis Ernest Cespedes,
As I already said, I will forward your feedback and Spotware company might integrate quotes from our liquidity providers in future.
But at the moment there is nothing we can do right now and it remains the same way.
Thank you for understanding.
Best regards,
Sam
Trade Compliance Department
Louis Cespedes
Nov 22, 08:33 EET
That is not how any other broker operates. Your backtest data should come from the same place. Backtesting an algorithm should provide exactly the same results as the actual market when using tick data. You can't design an algorithm using approximate data. There is real money at stake here.
________________________________
Sam (OctaFX)
Nov 22, 08:18 EET
Dear Louis Ernest Cespedes,
Please note that backtesting in cAlgo is not using quotes from our liquidity providers. That's why you may see such difference in prices.
I can forward your feedback to the Department in charge but at the moment these prices are different.
Bear in mind that backtesting is aimed to let you test your cBot’s performance in general.
Best regards,
Sam
Trade Compliance Department
@lec0456
lec0456
21 Nov 2017, 06:04
Yes it seems like the live data is consistently .4 pips under the backtest data. Itcompletely destroys the value of backtesting if the data is different.
One thing I noticed was that the server identified for cAlgo and cTrader are different. One points to Amsterdam-2 and the other Amsterda-4.
But in cAlgo, if you look at the live trading tab, it is also different from the backtest tab within the same cAlgo App. So, the server it is using doesn't seem to be making the difference.
@lec0456
lec0456
15 Nov 2017, 08:45
RE:
irmscher9 said:
By the way, does a powerful processor speed up the backtesting process?
Is there a difference between i5 and i7?
Its the ghz that will speed up backtesting. More CPU cores does nothing to backtesting because the process will only use one processor no matter what. The only thing having more cores will do it make sure other software doesn't interfere. Or for running 3 backtests at the same time. Realize that sometimes its the Broker that is slowing things down. If you suddenly have slow backtest performance, try backtesting with a different broker and see if it is faster.
@lec0456
lec0456
07 Sep 2017, 23:54
There is no real code to speak of. Just a print statment, that shows the counter at zero when positons are closed at the same price. So, you can't have any conditional statements based on the position.count because it is not accurate. the PositionOnClosed fires for the first position that is closed and then the second, but not before it is physically closed. Or so it seems.
I can't count the positions within the PositionsOnClosed event because it will produce the same result.
I guess could add code to maintain my own position count but this seems rather onerous and prone to error.
@lec0456
lec0456
05 Sep 2017, 03:04
TO duplicate this behavior just put a print statement in the PositionOnclosed Event and set 2 positions to close at the same price. it prints zero for position count for all positions closd at the same price eventhough they are technically closing at different times.
@lec0456
lec0456
22 Jul 2017, 20:51
If you wanted to place a trade everyday at 8:15 UTC, for example, you could just say:
If (Server.Time.Hour==8 && Server.Time.minute==15)
Execute Trade...
you get the daily series by:
Daily = MarketData.GetSeries(TimeFrame.Daily);
And the index by:
var dailyindex = Daily.OpenTime.GetIndexByTime(MarketSeries.OpenTime[t0]);
and get yesterdays high by:
Daily.High[dailyindex-1];
@lec0456
lec0456
17 Dec 2017, 04:15
here is an indicator that might help:
/algos/indicators/show/235
@lec0456