Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Help With Strategy

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #16
    Unfortunately there is no other solution. Backtesting is not meant for CalculateOnBarClose = false and to try and "mimic" it requires significant coding.
    Josh P.NinjaTrader Customer Service

    Comment


      #17
      Originally posted by NinjaTrader_Josh View Post
      Unfortunately there is no other solution. Backtesting is not meant for CalculateOnBarClose = false and to try and "mimic" it requires significant coding.
      Josh can you elaborate? If it doesn't involve changing indicator code I'm willing to attempt anything at this point.


      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


        #18
        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


          #19
          Originally posted by NinjaTrader_Josh View Post
          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.
          Hi Josh,

          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


            #20
            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


              #21
              Originally posted by NinjaTrader_Josh View Post
              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 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


                #22
                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


                  #23
                  Originally posted by NinjaTrader_Josh View Post
                  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.
                  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:

                  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


                    #24
                    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:
                    Code:
                    private ArrayList dailyCloses = new ArrayList();
                    
                    while (x < 20)
                    {
                         dailyCloses.Add(Closes[1][x]);
                         x++;
                    }
                    if (ToTime(Time[0]) == 135900)
                         dailyCloses.Add(Close[0]);
                    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.
                    Josh P.NinjaTrader Customer Service

                    Comment


                      #25
                      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


                        #26
                        Yes, I've added using System.Collections; --- the values differ.

                        Comment


                          #27
                          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


                            #28
                            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:

                            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]);
                            Thanks again for all the help, support here is top notch.

                            Comment


                              #29
                              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


                                #30
                                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 it
                                Last 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 Geovanny Suaza  
                                Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                                0 responses
                                379 views
                                1 like
                                Last Post Geovanny Suaza  
                                Started by Mindset, 02-09-2026, 11:44 AM
                                0 responses
                                111 views
                                0 likes
                                Last Post Mindset
                                by Mindset
                                 
                                Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                                0 responses
                                576 views
                                1 like
                                Last Post Geovanny Suaza  
                                Started by RFrosty, 01-28-2026, 06:49 PM
                                0 responses
                                582 views
                                1 like
                                Last Post RFrosty
                                by RFrosty
                                 
                                Working...
                                X