Calling an Optimization in a Strategy - NinjaTrader Programming | futures io social day trading
futures io futures trading


Calling an Optimization in a Strategy
Updated: Views / Replies:4,190 / 17
Created: by serac Attachments:0

Welcome to futures io.

(If you already have an account, login at the top of the page)

futures io is the largest futures trading community on the planet, with over 90,000 members. At futures io, our goal has always been and always will be to create a friendly, positive, forward-thinking community where members can openly share and discuss everything the world of trading has to offer. The community is one of the friendliest you will find on any subject, with members going out of their way to help others. Some of the primary differences between futures io and other trading sites revolve around the standards of our community. Those standards include a code of conduct for our members, as well as extremely high standards that govern which partners we do business with, and which products or services we recommend to our members.

At futures io, our focus is on quality education. No hype, gimmicks, or secret sauce. The truth is: trading is hard. To succeed, you need to surround yourself with the right support system, educational content, and trading mentors Ė all of which you can find on futures io, utilizing our social trading environment.

With futures io, you can find honest trading reviews on brokers, trading rooms, indicator packages, trading strategies, and much more. Our trading review process is highly moderated to ensure that only genuine users are allowed, so you donít need to worry about fake reviews.

We are fundamentally different than most other trading sites:
  • We are here to help. Just let us know what you need.
  • We work extremely hard to keep things positive in our community.
  • We do not tolerate rude behavior, trolling, or vendors advertising in posts.
  • We firmly believe in and encourage sharing. The holy grail is within you, we can help you find it.
  • We expect our members to participate and become a part of the community. Help yourself by helping others.

You'll need to register in order to view the content of the threads and start contributing to our community.  It's free and simple.

-- Big Mike, Site Administrator

Reply
 
Thread Tools Search this Thread
 

Calling an Optimization in a Strategy

  #11 (permalink)
Elite Member
Toronto, Canada
 
Futures Experience: Intermediate
Platform: NinjaTrader, IB
Favorite Futures: what's liquid, trending, and predictable
 
Posts: 34 since Aug 2011
Thanks: 15 given, 36 received

Also looking to do the same thing

Hi,

I was about to post in the Hire a Programmer section, but thought I would post here in case anyone has tried this since the original posting.

I am looking to do the same thing as the original poster. I am not concerned much with performance since the optimization period and parameters would all be within a narrow range... like the past week.

According to NinjaTrader it is 'technically possible' to optimize a strategy within the strategy while it is running. Does anyone have any idea at all how this might be accomplished? NinjaTrader of course is not supporting this and the lack of documentation is a little frustrating.


cheers -Dave

Reply With Quote
The following user says Thank You to d416 for this post:
 
  #12 (permalink)
Elite Member
Arizona, USA
 
Futures Experience: Intermediate
Platform: NinjaTrader
Broker/Data: MB Trading
Favorite Futures: Cello
 
serac's Avatar
 
Posts: 116 since Jan 2011
Thanks: 321 given, 137 received


d416 View Post
I was about to post in the Hire a Programmer section, but thought I would post here in case anyone has tried this since the original posting.

I completely forgot about this thread...

I am doing this now. The most desirable approach would be the method mentioned above by bnichols. What I am doing works and is stable, but will win no speed records.

If you want to do it my way, here is what you need to do:

1. Write your strategy to work on bar N instead of the current bar. This means using Close[N] instead of Close[0]. Either pass to each function, or make as globals, the current bar N and a flag to denote if you are running "for real" or in your virtual environment.

2. Write a wrapper around the event functions in NT. This is a lot easier if you write dumb strategies like me and do everything synchronously around OnBarUpdate. I use a surrogate called OnBarUpdateVirtual. OnBarUpdateVirtual functions exactly like OnBarUpdate normally would. This way, I can call OnBarUpdateVirtual from the strategy itself. My actual OnBarUpdate function is a one-liner that merely calls OnBarUpdateVirtual.

3. Write your own backtest and fill algorithm. This is fairly easy. Just handle conditions for stops, targets, and specified trade exits, and make up logic to estimate a fill and slippage. If you know your starting date, you can find how many bars back it is. A backtesting algorithm will simply loop through bars, calling OnBarUpdateVirtual. You'll also have to keep track of stats, trades, and profits and losses. This sounds harder than it is.

4. Write your own optimization algorithm. I use particle swarm optimization. Pick your flavor. You'll also have to write your own performance metric to gauge your virtual backtest results.

That's it. My strategies are set for a periodic self-optimization, or if performance falls below a threshold. At a given time, the strategy optimizes itself, automatically adjusting whatever strategy parameters I specified. It actually works quite well.

If the above doesn't scare you, then you can do it. I have a background in optimization and engineering. But not programming. There may be a more elegant or smarter way. But, this method works for me.

Please note. For some strategies, periodic reoptimization works great. For others, very much not. You can do a lot of first-order testing by using the built in Walk-Forward tool in NT.

Good luck!

Reply With Quote
The following 3 users say Thank You to serac for this post:
 
  #13 (permalink)
Elite Member
Toronto, Canada
 
Futures Experience: Intermediate
Platform: NinjaTrader, IB
Favorite Futures: what's liquid, trending, and predictable
 
Posts: 34 since Aug 2011
Thanks: 15 given, 36 received


thanks a lot for those details serac, it really helps. Quite an interesting approach too: simple and effective.. just how it should be.

the logic seems straight forward... although I'm thinking the implementation might be another story.... for example, I'm assuming during optimization/backtest you can't test a trade in the traditional way using Enter/xitLong() because you wouldn't want your optimization to submit live orders during backtesting, which means you can't use the TradeCollection or systemperformance to analyze your metrics, which, as you say, means all those calculations for things like MAE/MFE, fill prices, stop losses, etc. would need to be scoped and programmed... if done from scratch, the QA testing on this alone would be quite protracted to ensure there are no bugs.

I was secretly hoping that the existing optimizer/backfill classes in NinjaTrader could be called somehow from within a strategy or other class, but it appears this is not the case (?) it would be a lot easier to use the existing optimizer types and methods and keep everything tidy, but hey at least there's a way to do it, so may as well get started. I'd just really hate to see this implemented in NinjaTrader 8 after spending 80 hours to code and test


Thanks again!!

Reply With Quote
The following user says Thank You to d416 for this post:
 
  #14 (permalink)
Elite Member
Arizona, USA
 
Futures Experience: Intermediate
Platform: NinjaTrader
Broker/Data: MB Trading
Favorite Futures: Cello
 
serac's Avatar
 
Posts: 116 since Jan 2011
Thanks: 321 given, 137 received

Exactly.

Wrappers around everything. I am passing a "isReal" Boolean to almost every function. Ideally, you want to minimize the forking in logic between the real and virtual trades. But, when you actually implement it, the forking is all over the place: anywhere you call a NT specific function, you likely need a fork.

Honestly, I find the concept of a strategy calling itself somewhat elegant. The actual implementation is cumbersome, but not complex.Ideally, this could be put into a nice overloaded package by someone like NJAMC. This is not a project for me.

I pushed NT support pretty hard about exactly what I could and could not do with leveraging NT's built-in backtesting capabilities. The answer was a definite "no." Backtesting cannot be invoked within a strategy (perhaps, explicitly so to avoid runaway recursion).

The real downer is the NT disables distributed for/while loops. So, anything you run (i.e. an optimization) runs on one processor. Stuff like this is highly parallel, and would shine if you could utilize more than one processor. Maybe NT8? One can hope...

Reply With Quote
The following user says Thank You to serac for this post:
 
  #15 (permalink)
Trading Apprentice
Rotterdam, Netherlands
 
Futures Experience: Intermediate
Platform: Ninjatrader
Favorite Futures: ES
 
Posts: 1 since Jul 2013
Thanks: 0 given, 0 received

An example would really help

Hi Serec,

I`ve also been trying to include some form of optimisation in my strategy but can`t get it to work.
Conceptually I understand your method of writing a wrapper around the event functions in NT.
However, I am not sure how to program this. Especially the part of the OnBarUpdateVirtual puzzles me, how do you program this in NT? Second thing is that I am not known with a backtest and fill algorithm code that I can use.

So, I was hoping you could maybe post some example code in order to learn how this would look like. Can understand if you do not want to post your exact code but an example would help.

Regards,
Michel

Reply With Quote
 
  #16 (permalink)
Elite Member
Arizona, USA
 
Futures Experience: Intermediate
Platform: NinjaTrader
Broker/Data: MB Trading
Favorite Futures: Cello
 
serac's Avatar
 
Posts: 116 since Jan 2011
Thanks: 321 given, 137 received

Michel,

Unfortunately, it would be very difficult for me to post example code. I'm not sure how helpful it would be anyway. This method results in very confusing code.

Basically, you need to write replacements for almost all the NinjaTrader functions your strategy uses. Everything - EnterLong, SetStopLoss, even Close[0]. Your new replacement functions have two branches. One branch calls the original NT function, the other branch calls some surrogate function you have written. You will have a master Boolean that controls each branch. If your strategy is running in "real life," it will use the actual NT functions. If it is backtesting/optimizing itself, it is calling the surrogate functions. If you are careful, you minimize the differences between each branch, so that the surrogate functionality is as close to the NT functionality as possible.

Next, you will need to write backtesting and optimization functions. Optimization functions can be lifted from many good sources on the net. I prefer Particle Swarm optimization, but this is by no means a holy grail. A backtesting function is remarkably simple - simply loop from a starting bar to and ending bar, and call OnBarUpdate. But remember, you have written a wrapper around OnBarUpdate. So, when your backtesting loop calls the OnBarUpdate surrogate, your entire strategy is executed, not in real life, but in an imaginary backtest.

There are lots of intricacies, such as a fill model for your backtest. My fill model is fairly crude. It cheats by looking ahead to the next bar (that hasn't happened yet). It then takes the worst fill of either the enter bar or the next bar. You can chose your model.

I am not a sophisticated coder. There is nothing I haven't described. The idea is straightforward, but it get complicated very quickly because your strategy is calling itself. I've tried more sophisticated approaches, such as breaking the strategy off into another thread. NT always locks up when I try to do this (which would be nice, because then you could run the optimization on multiple threads - something all optimizations cry out for).

I've implemented this approach on several strategies. On a fairly simple moving average crossover strategy, the total number of code lines was well above 1000. Not because of any inherent complexity, but because so much has to be written to take care of what NT usually does.

So, do answer your question, I approached OnBarUpdate such as this:
 
Code
        // The real OnBarUpdate.
        protected override void OnBarUpdate()
        {
			if      ( Historical && !isBacktest)                   { return;                                  }
			else if (!Historical && IsMBTradingRollover()) { return;                                  }
                        else if (BarsInProgress != 0)                        { return;                                  }
			else if (panicMode)                                      { ProcessScrewUp();                 }
			else                                                           { OnBarUpdateInternal(true, 0); }
        }
To walk you through it, the first if statement returns if I am running real time and the date are historical. The Boolean isBacktest is set by a #define. I have to recompile to switch between running real time and backtesting in NT. The second line simply takes care of the nasty MBTrading rollover time. I prefer to go brain-dead during this period, and do not trade. The third line allows me to only run on the main/primary bar. ProcessScrewUp() is a fail-safe function that looks for overfills. Finally, the last branch of the if/then statement directs me to OnBarUpdateInternal(). The function OnBarUpdateInternal() contains the backbone of the strategy. Notice that I am passing "true" and "0" to OnBarUpdateInternal. The "true" means that I am telling OnBarUpdateInternal() to run for real life (not self-optimization). The "0" means that OnBarUpdateInternal is to use the 0th, or current bar. Additional functions within the strategy periodically kick off the optimization routine, which calls the backtesting function. This backtesting function calls OnBarUpdateInternal(false, backtestBarNum), for a loop of: "backtestBarNum = initBacktestBar; backtestBarNum >= 0; backtestBarNum--". When OnBarUpdateInternal is called with "false", it uses the surrogate functions, and not the NT functions.

Does this all make sense?


Last edited by serac; April 4th, 2014 at 06:13 PM. Reason: typos!
Reply With Quote
The following 3 users say Thank You to serac for this post:
 
  #17 (permalink)
Elite Member
Toronto, Canada
 
Futures Experience: Intermediate
Platform: NinjaTrader, IB
Favorite Futures: what's liquid, trending, and predictable
 
Posts: 34 since Aug 2011
Thanks: 15 given, 36 received

my approach to realtime optimization (RTO)

Wow... hard to believe a year has passed since I tackled this based on Serac's original suggestions (thanks Serac!) I've been meaning to post my results so good job digging up this thread.

I tried to implement it close to your approach Serac... I'm sure there's a wrong turn somewhere.

Anyway, here are my notes on the subject... hopefully to the benefit of anyone attempting this...

1) My implementation uses brute-force optimization... the reason is because i wanted to test within a narrow range of parameters which wouldn't require much processing power, and my coding skills aren't good enough to implement PSO or similar optimization algorithms... (at least not within a reasonable amount of time or within my patience threshold : )

2) My strategies are mainly cross-over strategies that use custom bars and a series of custom predictive moving averages. With cross-over strategies, with real-time optimization, you can actually see the difference between trending patterns and distribution selling (sideways trading) within your profit (equity) curve.

3) The only way I personally benefited from real time optimization is I became a better code, and it helped me understand the patterns that evolve over certain periods of an instrument.

4) Is real time optimization feasible? For me, I would say yes, insofar as your strategy requires it. It's no secret here that over-optimization can lead to 'curve fitting', and this real time approach is no different. What could make it feasible is to either a) incorporate a walk-forward step to mitigate the curve fitting and/or b) choose a strategy that benefits from curve fitting, such as historical pattern recognition.

Here is my optimize/backtest routine for a simple moving average strategy (excluding variable declarations and onbarupdate code)... I worked on this off/on for the past year... hopefully it helps save time for anyone else trying to do the same thing...

-Dave


 
Code
private void optimize()  //========OPTIMIZEr
	{

		//========================== OPTIMIZE ============================= start
			bestProfit = 0; // tracking best profit for the optimization
		
	
   for (int Period1idx = 2; Period1idx <= Period1;   Period1idx+=incrementPeriod1)  //  OUTER LOOP - Period1 optimization
	{			
		for (int Period2idx = 2; Period2idx <= Period2; Period2idx+=incrementPeriod2)  // inner loop - Period2 optimization
		{
			// reset all cumulative variables before each backfill
			PnL = 0; //  PnL for the trade
			cumulativeProfit = 0; // total profit for the parameters backtested
			longshort=0; // used to track the position of the virtual trade. 1=long, 2=short, 0=flat
		
			indicatorOPT1 = SMA(Period1idx); // set up the SMA and assign it the two values currently in the loop 
			indicatorOPT2 = SMA(Period2idx);
			
			for (int idx = lookBackPeriod; idx <= CurrentBar; idx++) // backtest/fill loop:  traversing along the lookback period
			{
				golong = (indicatorOPT1[idx-2] < indicatorOPT2[idx-2] && indicatorOPT1[idx-1] > indicatorOPT2[idx-1] ); // similates NT's CrossAbove() function
				goshort = (indicatorOPT1[idx-2] > indicatorOPT2[idx-2] && indicatorOPT1[idx-1] < indicatorOPT2[idx-1] );// simulates NT's CrossBelow() function

				if (golong)				
				{
					if (longshort != 1) // if 'flat' (i.e. first trade) then take position but don't run through profit calculation
					{
						PnL = ((Open[EntryBar] - slippage) - (Open[idx] + slippage));
						cumulativeProfit += PnL;
					}
					EntryBar = idx;  // the bar that the virtual position is taken
					longshort = 1; // trade is long

				} // end long logic
				
				else if (goshort)	
				{
						if (longshort != 2)
						{
							PnL = ((Open[idx] - slippage) - (Open[EntryBar] + slippage));
							cumulativeProfit += PnL;
						}
						
						EntryBar = idx;
						longshort = 2;  // virtual trade now short
						
				} //end short logic
					
				
				// close out final position and add to PnL - similar to NT's 'exit on close' on a backtest
				
				if (longshort == 2)
				{
						PnL = (Open[EntryBar] - Close[idx] + slippage);
						cumulativeProfit += PnL;
				}
				else if (longshort == 1)
				{
							PnL = (Open[idx] - Close[EntryBar] - slippage);
							cumulativeProfit += PnL;
				}
				
				
				
			} //--- END backtest/fill
		
				/// Store parameters based on best net profit of the backtest
				if (cumulativeProfit > bestProfit)
				{
					bestProfit = cumulativeProfit;
					bestPeriod1 = Period1idx;
					bestPeriod2 = Period2idx;
				}

		}//=== END Inner Loop (Period1 optimization)
	} // END OUTER LOOP -  Period2 optimization
				

		} //--end optimize() =========================== OPTIMIZE ============ end

Reply With Quote
The following 3 users say Thank You to d416 for this post:
 
  #18 (permalink)
Elite Member
Victoria, BC
 
Futures Experience: Master
Platform: Tradestation Multicharts
Favorite Futures: es
 
Posts: 17 since Oct 2011
Thanks: 6 given, 13 received

Dakota

Hello -
I have the same objective as the posters on this thread, I think it is beyond the scope of most retail traders because the technology has to be home built, except potentially in one case. I wonder if anyone on this thread has used/considered a product called Dakota by Biocomp (google it)? The product does walk forward swarm adaption for trading signals.
I am in no way associated with this company and certainly do not want to promote it. I am considering using it as an avenue to achieve what the posters in this thread are attempting and would value opinions.
If the moderator sees this as spam (hopefully not) then feel free to remove it.
Thanks

Reply With Quote

Reply



futures io > > > > > Calling an Optimization in a Strategy

Thread Tools Search this Thread
Search this Thread:

Advanced Search



Upcoming Webinars and Events (4:30PM ET unless noted)

Linda Bradford Raschke: Reading The Tape

Elite only

Adam Grimes: TBA

Elite only

NinjaTrader: TBA

January

Ran Aroussi: TBA

Elite only
     

Similar Threads
Thread Thread Starter Forum Replies Last Post
VIDEO: MultiCharts vs. NinjaTrader strategy backtesting and optimization Big Mike MultiCharts 53 June 12th, 2016 02:34 PM
Gold - I'm calling the top cpi65 Commodities Futures Trading 65 February 19th, 2012 05:32 AM
Strategy Optimization and trusting the results petronick Elite Automated NinjaTrader Trading 11 July 31st, 2011 02:50 AM
Calling GomiCD into GomiLadder kashter NinjaTrader Programming 2 May 9th, 2011 07:35 PM
Combining strategy optimization types caprica NinjaTrader Programming 0 July 27th, 2009 05:52 AM


All times are GMT -4. The time now is 10:39 PM.

Copyright © 2017 by futures io, s.a., Av Ricardo J. Alfaro, Century Tower, Panama, +507 833-9432, info@futures.io
All information is for educational use only and is not investment advice.
There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
no new posts
Page generated 2017-12-10 in 0.16 seconds with 19 queries on phoenix via your IP 54.221.73.186