Announcement
Collapse
No announcement yet.
Partner 728x90
Collapse
NinjaTrader
Help With Strategy
Collapse
X
-
Josh can you elaborate? If it doesn't involve changing indicator code I'm willing to attempt anything at this point.Originally posted by NinjaTrader_Josh View PostUnfortunately there is no other solution. Backtesting is not meant for CalculateOnBarClose = false and to try and "mimic" it requires significant coding.
Also, as a feature request - how hard would it be to have calculateonbarclose=false work in backtesting --- ie. MACD[daily] would be computed dynamically as long as your primary period is less than daily... seems like that should be possible?
Comment
-
Backtesting will not work with CalculateOnBarClose = false. Unfortunately it is inherently impossible. In a backtest you only have 4 data points per bar. Open, high, low, close. There is no way to simulate any price movement action inbetween that to generate values.
To do what you want you need to just bring over the logic for how to calculate a MACD over to your strategy. Then you need to just create yourself your own ArrayList or something like that containing the values you want to run the MACD calculation on with the prior day's prices + current day's price. Then just run through the MACD calculation that you brought over on that array of prices that you manually created. There is no need to be using a multi-time frame script as it will not work for trying what you are trying.Josh P.NinjaTrader Customer Service
Comment
-
Hi Josh,Originally posted by NinjaTrader_Josh View PostBacktesting will not work with CalculateOnBarClose = false. Unfortunately it is inherently impossible. In a backtest you only have 4 data points per bar. Open, high, low, close. There is no way to simulate any price movement action inbetween that to generate values.
To do what you want you need to just bring over the logic for how to calculate a MACD over to your strategy. Then you need to just create yourself your own ArrayList or something like that containing the values you want to run the MACD calculation on with the prior day's prices + current day's price. Then just run through the MACD calculation that you brought over on that array of prices that you manually created. There is no need to be using a multi-time frame script as it will not work for trying what you are trying.
I agree this is a viable strategy, but is there an easy way to compute this? For example, let's take the Stochastic Oscillator which has fast, slow and smooth input.
From googling I can find the formula is this:
%K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
%D = 3-day SMA of %K
Lowest Low = lowest low for the look-back period
Highest High = highest high for the look-back period
%K is multiplied by 100 to move the decimal point two places
I can get all of these values and compute %k and %d but can't find anywhere that explains how to tie in the fast/slow periods and smooth. Looking at the actual Stochastic indicator source code, it's rather complex. What would the easiest path be in computing this?
Thanks again
Comment
-
JohnnyCampo,
It is not as bad as it may initially seem.
%K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
%D = 3-day SMA of %K
You have very broad terms in there like "Lowest Low" and "Highest High" on %K. That is actually where the period for K belongs. How many bars do you want to consider into this "lowest low" criteria is what that period does.
Then on %D it says 3-day, but that 3 is actually what Period D is for.
So basically its just a matter of breaking down what components you want and what you want to use.Josh P.NinjaTrader Customer Service
Comment
-
Originally posted by NinjaTrader_Josh View PostJohnnyCampo,
It is not as bad as it may initially seem.
%K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
%D = 3-day SMA of %K
You have very broad terms in tehre like "Lowest Low" and "Highest High" on %K. That is actually where the period for K belongs. How many bars do you want to consider into this "lowest low" criteria is what that period does.
Then on %D it says 3-day, but that 3 is actually what Period D is for.
So basically its just a matter of breaking down what components you want and what you want to use.
ahhh, thanks Josh, I just wrote up a quick snipplet in case someone else needs this, does it look correct to you? Also where does smoothing come into play (the 15 below):
Let's say we're using:
Stochastics(10,20,15)
double lastClose = PriorDayOHLC().PriorClose[0];
double lowestLow = 1000000;
double highestHigh = -1;
for (int i=9; i>-1; i--)
{
if (Lows[dailyBars][i]<lowestLow)
lowestLow=Lows[dailyBars][i];
}
for (int i=9; i>-1; i--)
{
if (Highs[dailyBars][i]>highestHigh)
highestHigh=Highs[dailyBars][i];
}
double percentK = 100 * ((Closes[dailyBars][0]-lowestLow)/(highestHigh-lowestLow));
Comment
-
Smoothing is done on the %K.
%K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
That is just one single value. A "smoothed" Stochastic would calculate %K off of several of these %K calculations and then averaged. You can see how it is done in the Stochastics indicator by looking at the source code. You can see from the source code it has the numerator and the denominator for the fraction separated. Then you can see how it gets a sum of several numerator values and several denominator values. Then it divides them against each other. That would be how it smooths it.Josh P.NinjaTrader Customer Service
Comment
-
Thanks Josh, I'm getting really close - this seems like it should work but I keep getting back 0,50 or 100 for percent K:Originally posted by NinjaTrader_Josh View PostSmoothing is done on the %K.
%K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
That is just one single value. A "smoothed" Stochastic would calculate %K off of several of these %K calculations and then averaged. You can see how it is done in the Stochastics indicator by looking at the source code. You can see from the source code it has the numerator and the denominator for the fraction separated. Then you can see how it gets a sum of several numerator values and several denominator values. Then it divides them against each other. That would be how it smooths it.
Attempting to replicate Stochastics(10,20,15):
Code:double percentK; den = new DataSeries(Stochastics(BarsArray[dailyBars],10,20,15)); nom = new DataSeries(Stochastics(BarsArray[dailyBars],10,20,15)); nom.Set(Close[0] - MIN(Low, 10)[0]); den.Set(MAX(High, 10)[0] - MIN(Low, 10)[0]); double nomSum = SUM(nom, 15)[0]; double denSum = SUM(den, 15)[0]; nomSum = nomSum.Compare(0, 0.000000000001) == 0 ? 0 : nomSum; denSum = denSum.Compare(0, 0.000000000001) == 0 ? 0 : denSum; percentK = (Math.Min(100, 100 * nomSum / denSum));
Here is the actual indicator code for reference:
Code:nom.Set(Close[0] - MIN(Low, PeriodK)[0]); den.Set(MAX(High, PeriodK)[0] - MIN(Low, PeriodK)[0]); double nomSum = SUM(nom, Smooth)[0]; double denSum = SUM(den, Smooth)[0]; nomSum = nomSum.Compare(0, 0.000000000001) == 0 ? 0 : nomSum; denSum = denSum.Compare(0, 0.000000000001) == 0 ? 0 : denSum; if (denSum == 0) K.Set(CurrentBar == 0 ? 50 : K[1]); else K.Set(Math.Min(100, 100 * nomSum / denSum)); D.Set(SMA(K, PeriodD)[0]);Last edited by JohnnyChimpo; 06-29-2011, 12:20 PM.
Comment
-
Your code will not work. Even though you tied the den/nom DataSeries to the daily bars, you are not actually pulling values from the daily bars. You cannot use Close[0] or High[0] or things like that. You need to create your own set of data points. I do not think you should be using DataSeries at all. Just use an array of values corresponding to the period you want to use.
For instance:Some thing like that. There is a lot more code you will need to work through though to achieve what you want. Hopefully that gives you an idea of how to proceed.Code:private ArrayList dailyCloses = new ArrayList(); while (x < 20) { dailyCloses.Add(Closes[1][x]); x++; } if (ToTime(Time[0]) == 135900) dailyCloses.Add(Close[0]);Josh P.NinjaTrader Customer Service
Comment
-
Hi Josh, I've done as you suggested. Here I'm just trying to make sure my formula works (havent added current day info yet) but I can't seem to calculate the same value, does this look right to you (feel free to run it):
Code:double percentK; int k=10; int d=20; int smooth=15; int x=0; // noms ArrayList nom = new ArrayList(); x=0; while (x < d) { nom.Add(Closes[dailyBars][x] - MIN(Lows[dailyBars],k)[0]); x++; } // denoms ArrayList den = new ArrayList(); x=0; while (x < d) { den.Add(MAX(Highs[dailyBars],k)[0] - MIN(Lows[dailyBars],k)[0]); x++; } // nom sum double nomSum=0; for (int i=0; i<smooth; i++) { nomSum += (double)nom[i]; } // den sum double denSum=0; for (int i=0; i<smooth; i++) { denSum += (double)den[i]; } nomSum = nomSum.Compare(0, 0.000000000001) == 0 ? 0 : nomSum; denSum = denSum.Compare(0, 0.000000000001) == 0 ? 0 : denSum; percentK = (Math.Min(100, 100 * nomSum / denSum)); Print(Time[0] + " Calculated: " + percentK); Print(Time[0] + " Actual: " + Stochastics(BarsArray[dailyBars],k,d,smooth).K[0]);
Comment
-
-
Your actual print line is wrong for parameter sequencing. It is supposed to be Stochastics(PeriodD, PeriodK, Smooth) and not K first.
Also you are using incorrect [] index values for your nom and den. Should be this instead.
Code:ArrayList nom = new ArrayList(); x=0; while (x < d) { nom.Add(Closes[dailyBars][x] - MIN(Lows[dailyBars],k)[x]); x++; } // denoms ArrayList den = new ArrayList(); x=0; while (x < d) { den.Add(MAX(Highs[dailyBars],k)[x] - MIN(Lows[dailyBars],k)[x]); x++; }Josh P.NinjaTrader Customer Service
Comment
-
Josh, really appreciate the help - calculation is now working correctly when using the default MIN/MAX functions (btw dailyBars is just an int pointing to 2 since its my 2nd data series).
I'm now adding arrays of dailyCloses,dailyLows and dailyHighs but think I'm having trouble with my custom MIN and MAX functions (I've converted them to work with non data series):
Here is the part I think is wrong:
Code:ArrayList MinDailyLows = dailyLows; MinDailyLows.Reverse(); ArrayList MaxDailyHighs = dailyHighs; MaxDailyHighs.Sort();
Here is the full code:
Thanks again for all the help, support here is top notch.Code:double percentK; int k=20; int d=10; int smooth=15; int x=0; ArrayList dailyCloses = new ArrayList(); x=0; while (x < k) { dailyCloses.Add(Closes[dailyBars][x]); x++; } ArrayList dailyLows= new ArrayList(); x=0; while (x < k) { dailyLows.Add(Lows[dailyBars][x]); x++; } ArrayList dailyHighs= new ArrayList(); x=0; while (x < k) { dailyHighs.Add(Highs[dailyBars][x]); x++; } ArrayList MinDailyLows = dailyLows; MinDailyLows.Reverse(); ArrayList MaxDailyHighs = dailyHighs; MaxDailyHighs.Sort(); //dailyCloses.Add(Close[0]); // noms ArrayList nom = new ArrayList(); x=0; while (x < k) { nom.Add((double)dailyCloses[x] - (double)MinDailyLows[x]); x++; } // denoms ArrayList den = new ArrayList(); x=0; while (x < k) { den.Add((double)MaxDailyHighs[x] - (double)MinDailyLows[x]); x++; } // nom sum double nomSum=0; for (int i=0; i<smooth; i++) { nomSum += (double)nom[i]; } // den sum double denSum=0; for (int i=0; i<smooth; i++) { denSum += (double)den[i]; } nomSum = nomSum.Compare(0, 0.000000000001) == 0 ? 0 : nomSum; denSum = denSum.Compare(0, 0.000000000001) == 0 ? 0 : denSum; percentK = (Math.Min(100, 100 * nomSum / denSum)); Print(Time[0] + " Calculated: " + percentK); Print(Time[0] + " Actual: " + Stochastics(BarsArray[dailyBars],d,k,smooth).K[0]);
Comment
-
JohnnyChimpo,
I guess I do not know why you would need to create ArrayLists for dailyCloses, dailyLow, etc. since you are already grabbing that info to stuff into your nom/den from daily bars. It would only be necessary to create separate ArrayLists for them if you did not add a daily bars series via Add().
MIN and MAX will not run off of ArrayLists. But those indicators are really just basic math functions which should be fairly simple to just replicate the calculations via a loop through the ArrayList.Josh P.NinjaTrader Customer Service
Comment
-
Hi Josh, check out this code and Look for the /* JOSH */ comment
Code:ArrayList dailyCloses = new ArrayList(); x=0; while (x < k) { dailyCloses.Add(Closes[dailyBars][x]); x++; } ArrayList dailyLows= new ArrayList(); x=0; while (x < k) { dailyLows.Add(Lows[dailyBars][x]); x++; } ArrayList dailyHighs= new ArrayList(); x=0; while (x < k) { dailyHighs.Add(Highs[dailyBars][x]); x++; } /* JOSH EVENTUALLY RIGHT HERE WE WILL BE ADDING */ //dailyCloses.Add(Close[0]); //dailyLows.Add(currentday.low); //dailyHighs.Add(currentday.high) ArrayList MinDailyLows = new ArrayList(); foreach (object tmp in dailyLows) { MinDailyLows.Add(tmp); } MinDailyLows.Reverse(); ArrayList MaxDailyHighs= new ArrayList(); foreach (object tmp in dailyHighs) { MaxDailyHighs.Add(tmp); } MaxDailyHighs.Sort();
Remember at some point we have to add in the new "bar" -- so that means I need to create separate arrays for lows,highs and closes right? (we can no longer use the daily Closes/highs/lows)
The ArrayList.Reverse() function sorts the highs array so array[0] should be the highest of highs.
The ArrayList.Sort() functions performs a reverse sort, so array[0] should be the lowest of lows
EDIT: ^^^ problem with this logic, they arnt sorting correctly -- working on itLast edited by JohnnyChimpo; 06-29-2011, 02:31 PM.
Comment
Latest Posts
Collapse
| Topics | Statistics | Last Post | ||
|---|---|---|---|---|
|
Started by Geovanny Suaza, 02-11-2026, 06:32 PM
|
0 responses
672 views
0 likes
|
Last Post
|
||
|
Started by Geovanny Suaza, 02-11-2026, 05:51 PM
|
0 responses
379 views
1 like
|
Last Post
|
||
|
Started by Mindset, 02-09-2026, 11:44 AM
|
0 responses
111 views
0 likes
|
Last Post
by Mindset
02-09-2026, 11:44 AM
|
||
|
Started by Geovanny Suaza, 02-02-2026, 12:30 PM
|
0 responses
576 views
1 like
|
Last Post
|
||
|
Started by RFrosty, 01-28-2026, 06:49 PM
|
0 responses
582 views
1 like
|
Last Post
by RFrosty
01-28-2026, 06:49 PM
|

Comment