Site Administrator Swing Trader Data Scientist & DevOps
Manta, Ecuador
Experience: Advanced
Platform: My own custom solution
Trading: Emini Futures
Posts: 49,778 since Jun 2009
Thanks: 32,304 given,
97,558
received
In this video tutorial I show how to create a strategy from scratch (not using the wizard, which I never use).
The strategy contains a few optimizable parameters such as SMA length, EMA length, HMA length, three different targets with custom tick settings on each, a stop size, and the option to move target 2 to breakeven after target 1 is hit, as well as move target 3 to breakeven after target 2 is hit.
The strategy is just an example! It took all of 10 minutes to write. Even though it says it made 20k in 90 days over 700 trades, it will likely fail going forward. Simple strategies are usually best, but this one is too simple to work fully automated. Most strategies I write for customers take me hours of work (this one took 10 minutes), so don't just go and copy this strategy and expect good results.
Instead, I created this so you could get your feet wet and learn some of the basics of a more advanced strategy than what Ninja includes with the base install. I also created it so if someone shows you backtest results where it makes tons of money, you can see just how easy it is to produce those results.
Also, don't forget that optimizing based on net profit is virtually worthless. I've spent two years tweaking my custom optimizer type and it considers everything you can imagine such as balanced longs/shorts, trade counts, commission costs, profit factors, expectancy, trade duration, and a bunch of other stuff I don't want to go into because I am not giving it away.
With the normal drop-down list of optimizer types in NT, you don't want to just pick the result that shows the most net profit. You should factor in as many other variables as you can. Unless you're going to do what I did with the custom optimizer, the easiest way is to dump the results to an Excel spreadsheet (feature is built-in to NinjaTrader) and then work some analysis there.
Nice video, Mike. Thanks. I guess you are finding optimization to be a wee bit quicker in NT7 .
You mentioned that you would use the same trail stop for all contracts... but I was under the impression we had no choice.
If I code this:
It works. I've tried something like this:
... but I got compiler errors which I thought meant SetTrailStop only can take two arguments (Calcmode, value).
I was trying to find a way to have different targets/stops on my shorts/longs, and using ToTime to also have different targets/stops depending on time of day.
Did I miss something obvious with SetTrail Stop?
As always, thanks for sharing your knowledge.
The following user says Thank You to MXASJ for this post:
Site Administrator Swing Trader Data Scientist & DevOps
Manta, Ecuador
Experience: Advanced
Platform: My own custom solution
Trading: Emini Futures
Posts: 49,778 since Jun 2009
Thanks: 32,304 given,
97,558
received
SetTrailStop is very limited. I don't use it. What I meant was coding your own trailing stop, and controlling it for each target. You also should do it on a small time frame, which means adding a second dataseries to the strategy (mtf).
Thanks for this valuable basis for strategy writing and development.
I took the liberty to code what you demonstrated into v6.5 as I'm not yet using v7. I think every serious student of strategies should go through this exercise, partly for understanding the outline of the code as well as logic and syntax among other things.
If I may, I would like to post this for the next step of learning regarding strat writing. If you feel this shouldn't be done in this particular thread, please remove and/or place in a more appropriate location.
I'm hoping others wanting to provide additional help / suggestions will be able to share and develop this into an even more detailed or advanced code.
"gregid" has set up a new futures.io (formerly BMT) community group here: https://futures.io/groups/automated-strategies.html He has helped me with some issues in a Strat I'm writing involving IOrder and other advanced portions of code. I appreciated the issues you mentioned regarding CalculationMode and not using "Ticks" for this piece of code.
There's alot more to be learned for optimization and limit order entry.
Looking forward to your next tutorial on Strat writing!
Kirk
The following 14 users say Thank You to zeller4 for this post:
Those first three lines have me intrigued as I've never seen that before. How does that work? Is it assigning the value SMA(SMAlength) to SMA variable (?) smav? I can see how that makes typing easier and less error prone... one would only need to type "smav" instead of "SMA(SMAlength)" in all later references to that.
Is that a correct interpretation of what you did and why you did it? I know its basic C# stuff but I'm still learning.
Thanks for the video Just wondering if you could explain your comments on why this particular optimization gives positive results but isn't actually profitable. I have only done a little optimization (on a different trading platform) and I'm wondering what is the point of optimization if the results can be so varied?
Would your next step be to forward test an optimized strategy to ensure it works? Just interested in your work flow.
TIA
The following user says Thank You to Treggs for this post:
Site Administrator Swing Trader Data Scientist & DevOps
Manta, Ecuador
Experience: Advanced
Platform: My own custom solution
Trading: Emini Futures
Posts: 49,778 since Jun 2009
Thanks: 32,304 given,
97,558
received
There are a few reasons.
1) Not enough backtesting data. You need to really backtest for > 1 year, in my opinion.
2) Yes, you need to forward test in live market.
3) Simple is usually better, but in this case, the strategy is too simple to work. Efficiency is required to be profitable, and this strategy isn't very efficient in my opinion.
Thank you for making videos like this. For those of us that is not very experienced in making ninja strategies, it is very usefull to watch and learn. One video like that, saves me for many hours of reading. I hope you can make more of them to us.
Broker: Tradestation/Tradestation, NinjaTrader, FXCM and Tallinex
Trading: ES, CL, EUR/USD, TF
Posts: 181 since Aug 2009
Thanks: 103 given,
56
received
Mike
thanks for posting this video. It is really great for us who are learning programming to see videos like this as there are literally none on the internet for NinjaTrader.
Thank you for this video. I have no experience with strategies and have been hesitant to jump in. I found your walk-through on writing a strategy very encouraging. It seems to be one of those programming things that NT doesn't like to discuss in their videos.
The following user says Thank You to LostTrader for this post:
So which is correct? (Sorry if this question was already covered or I missed something here.)
I've spent some time now and then trying to understand NinjaScript. I appreciate this video greatly. There
is just no way whatsoever I could have put together this strategy. I have altered it to remove the moving
averages, which never seem to help, and added some other very basic code.
It compiles so it must work. (hee hee)
I just ran MyMoneyMaker_BigMike in the Optimizer. I'm not positive of what I see in the
attachment (included). Is the 1L, 2L, 3L in the 'executions' what one would expect? I'm thinking
that 3L means there are 3 long contracts in the market. I thought the strategy would only allow
one long (or short) at a time. (I'm extremely new to the Optimizer.)
I don't know if this thread is still active or not. If anyone wants to comment that's fine.
From post #11:
Hi Mike,
Thanks for the video Just wondering if you could explain your comments on why this particular optimization gives positive results but isn't actually profitable. I have only done a little optimization (on a different trading platform) and I'm wondering what is the point of optimization if the results can be so varied?
Would your next step be to forward test an optimized strategy to ensure it works? Just interested in your work flow.
TIA
There are a few reasons.
1) Not enough backtesting data. You need to really backtest for > 1 year, in my opinion.
I'm don't like moving averages in general, but if someone used a system that was backtested with moving
averages, and it was found to be profitable over the last, let's say 13 weeks (quarter year), then why wouldn't
optimizing it daily, always looking back 13 weeks (ie. 65 trading days) work to keep the system profitable?
It seems I'm having trouble fully understanding the code of the video. The attachment
enclosed (YM) shows a long trade taken that was profitable and unprofitable at the same time.
One can see the green dots and red dots. I think I'm making a basic mistake regarding understanding
order placement and or quantity.
I thought the profitable long trade entered at the beginning of the day would be exited much much sooner.
Or maybe it is??
Ok. What I thought was happening was that the stoploss became a breakeven stop which
later became a trailing stop. Are you saying that all 3 stops are setup from the get-go? With
each one relaying off to the next? which is what seems to be happening here as I look more closely.
Also, it seems that if the system is long, it will not go short even if the 3 moving averages are
falling, IF none of the stops have been triggered. Is this correct?
Site Administrator Swing Trader Data Scientist & DevOps
Manta, Ecuador
Experience: Advanced
Platform: My own custom solution
Trading: Emini Futures
Posts: 49,778 since Jun 2009
Thanks: 32,304 given,
97,558
received
I'm sorry, I don't recall the particulars of it and no longer have it and don't do any NinjaTrader programming any more. My suggestion is to look at the Hurley thread, there are hundreds and hundreds of replies with advanced order management, break even stops, etc. You will learn a lot from the thread, just take some time and read through it.
Mike in this video warn about using the default optimizer and used PH Generic and used his own parameter called _mike_preferred. I searched the forum to find this to download but no success. How can I implement this for my own optimization? Side note: I tried simple optimization for 2 month data, NT7 crashed. I have used my notebook without any upgrades. Is this typical. I am travelling now and this is what I have access to.
Thanks much. I am in the process to upgrade to elite but my paypal acct have been inactive for years. working on it.
The following user says Thank You to sam1197 for this post:
(My first post as a new member -- hi everyone! Mike, this site is amazing, so much quality content...)
This video was very helpful for me, simply by going through the entire process from start to finish in a straightforward fashion. I appreciate that you took the time to capture a legible HD video. +1 for high-speed typing and compile-from-the-hip.
Now armed with some programming experience, and this video, I'm off to write my first ninjascript strategy.
(again: This site! Think of the dollars and years you've saved everyone by bringing this together in one spot...)
Hey - I am a newbie to Ninja trader platform. I have entered EXACTLY what Big Mike showed in the video but when I compile, I get this error no matter what I do:
Strategy\NewTest.cs The name 'be3' does not exist in the current context CS0103 - click for info 115 26
Strategy\NewTest.cs The name 'be3' does not exist in the current context CS0103 - click for info 116 19
Line 115 and 116 don't contain 'be3'. Is there some simple newbie thing I am missing?! Even if I completely remove be3 from the script and replace it with something else, I still get the same error. So I am mightily confused. Any help would be much appreciated .... Thanks!
Thanks Mikewbjoh998 - I figured that part out, and checked everything. Still possible, of course (been down that road many times win other programming environments) but I'm guessing not. When I load a standard indicator like Bollinger and try to compile I get a similar error message, which leads me to believe something is wrong in general with my installation.
The following user says Thank You to WBJo for this post:
Hi Mike, Thank you for this video, it was really helpful.
I am wondering how I could program my own set of rule to "optimize on" like you did with " _mike_preferred" I don't have problem to program in C# and I already did some strategies who look profitable when I test them in the market replay.
But I would really like to be able to set my own set of rule for optimization.
Please help me with that.
You should be able to delete the following line because you don't enter a position with a similar name:
SetProfitTarget("target2", CalculationMode.Price, Close[0] + ((Target1+Target2)*TickSize));
SetProfitTarget("target3", CalculationMode.Price, Close[0] + ((Target1+Target2+Target3)*TickSize));
I couldn't find a description of what you were trying to do, but that seems correct with a single target.
Can you describe what it is you are trying to do?
hi NJAMC, apolgs for the late reply [went on a vaca ]
what i'm trying to do is:
buy one contract when my buy conditions are true, set my initial stoploss 12 ticks away, and have three targets, once target1 is hit, I want to move my initial stoploss to my purchase price, once target2 is hit, i want to move my stoploss to target1 and once target 3 is hit, i want to exit. i thought that is what this script did but it's a bit different :/
Just an idea. Reversing the order of the statements and using "else" so that "SetStopLoss" is not set multiple times in the loop. I don't have a strategy setup currently to test it.
Cloudy, thank you for trying. Still no luck though :/
here is the complete code to the strategy:
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Big Mike - 1/26/10 - https://futures.io/beginners-introductions-tutorials/2512-video-tutorial-how-create-advanced-ninjatrader-strategy.html
/// </summary>
[Description("Make me millions Jan 27 2010")]
public class TargetES930 : Strategy
{
//#region Variables
private int target1 = 12;
private int target2 = 10;
private int target3 = 24;
private int stop = 12;
private bool be2 = true;
private bool be3 = true;
//#endregion
/// <summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
/// </summary>
protected override void Initialize()
{
CalculateOnBarClose = true;
EntryHandling = EntryHandling.UniqueEntries;
}
private void GoLong()
{
SetStopLoss("target1", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetProfitTarget("target1", CalculationMode.Price, Close[0] + ((Target1+Target2+Target3)*TickSize));
EnterLong("target1");
}
private void ManageOrders()
{
if (Position.MarketPosition == MarketPosition.Long)
{
if (High[0] > Position.AvgPrice + ((Target1+Target2+Target3)*TickSize))
SetStopLoss("target1", CalculationMode.Price, Position.AvgPrice + ((Target1+Target2)*TickSize), false);
else if (High[0] > Position.AvgPrice + ((Target1+Target2)*TickSize))
SetStopLoss("target1", CalculationMode.Price, Position.AvgPrice + (Target1*TickSize), false);
else if (High[0] > Position.AvgPrice + (Target1*TickSize))
SetStopLoss("target1", CalculationMode.Price, Position.AvgPrice, false);
}
}
/// <summary>
/// Called on each bar update event (incoming tick)
/// </summary>
protected override void OnBarUpdate()
{
EntryHandling = EntryHandling.UniqueEntries;
ManageOrders();
if (CrossBelow(CCI(14), 250, 1))
EnterLong();
}
//#region Properties
[Description("")]
[Category("Parameters")]
public int Target1
{
get { return target1; }
set { target1 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target2
{
get { return target2; }
set { target2 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target3
{
get { return target3; }
set { target3 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Stop
{
get { return stop; }
set { stop = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public bool BE2
{
get { return be2; }
set { be2 = value; }
}
[Description("")]
[Category("Parameters")]
public bool BE3
{
get { return be3; }
set { be3 = value; }
}
//#endregion
}
}
The following user says Thank You to calhawk01 for this post:
Alright i'm going to give up on this unless someone helps me lol
I've tried to play around with this for the past several days but it does not seem to work properly
Current code I have, does not seem to call the "manage order();" properly.
It enters the positions, but the stoploss only changes ONCE when target1 is hit, the stoploss moves to avg price, but when target2 is hit, stoploss is never moved to target1 and so on..
Thanks in advance for looking at the code:
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Big Mike - 1/26/10 - https://futures.io/beginners-introductions-tutorials/2512-video-tutorial-how-create-advanced-ninjatrader-strategy.html
/// </summary>
[Description("Make me millions Jan 27 2010")]
public class TargetES930 : Strategy
{
//#region Variables
private int target1 = 12;
private int target2 = 10;
private int target3 = 24;
private int stop = 12;
private bool be2 = true;
private bool be3 = true;
//#endregion
/// <summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
/// </summary>
protected override void Initialize()
{
CalculateOnBarClose = false;
EntryHandling = EntryHandling.UniqueEntries;
}
private void GoLong()
{
SetStopLoss("target1", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetProfitTarget("target1", CalculationMode.Price, Close[0] + (Target2*TickSize));
}
private void ManageOrders()
{
if (Position.MarketPosition == MarketPosition.Long)
{
if (High[0] > Position.AvgPrice + (Target1*TickSize))
SetStopLoss("target1", CalculationMode.Price, Position.AvgPrice, false);
if (High[0] > Position.AvgPrice + ((Target1+Target2)*TickSize))
SetStopLoss("target2", CalculationMode.Price, Position.AvgPrice + (Target1*TickSize), false);
if (High[0] > Position.AvgPrice + ((Target1+Target2+Target3)*TickSize))
SetStopLoss("target3", CalculationMode.Price, Position.AvgPrice + ((Target1+Target2)*TickSize), false);
}
}
/// <summary>
/// Called on each bar update event (incoming tick)
/// </summary>
protected override void OnBarUpdate()
{
EntryHandling = EntryHandling.UniqueEntries;
GoLong();
ManageOrders();
if (Position.MarketPosition != MarketPosition.Flat) return;
if (........ENTER ANY TRADING LOGIC.................))
EnterLong("target1");
GoLong();
if (ToTime(Time[0]) == ToTime(15, 56, 0))
ExitLong("", "");
}
//#region Properties
[Description("")]
[Category("Parameters")]
public int Target1
{
get { return target1; }
set { target1 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target2
{
get { return target2; }
set { target2 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target3
{
get { return target3; }
set { target3 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Stop
{
get { return stop; }
set { stop = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public bool BE2
{
get { return be2; }
set { be2 = value; }
}
[Description("")]
[Category("Parameters")]
public bool BE3
{
get { return be3; }
set { be3 = value; }
}
//#endregion
}
}
Broker: Tradestation/Tradestation, NinjaTrader, FXCM and Tallinex
Trading: ES, CL, EUR/USD, TF
Posts: 181 since Aug 2009
Thanks: 103 given,
56
received
calhawk01
Alright i'm going to give up on this unless someone helps me lol
I've tried to play around with this for the past several days but it does not seem to work properly
Current code I have, does not seem to call the "manage order();" properly.
It enters the positions, but the stoploss only changes ONCE when target1 is hit, the stoploss moves to avg price, but when target2 is hit, stoploss is never moved to target1 and so on..
Thanks in advance for looking at the code:
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Big Mike - 1/26/10 - https://futures.io/beginners-introductions-tutorials/2512-video-tutorial-how-create-advanced-ninjatrader-strategy.html
/// </summary>
[Description("Make me millions Jan 27 2010")]
public class TargetES930 : Strategy
{
//#region Variables
private int target1 = 12;
private int target2 = 10;
private int target3 = 24;
private int stop = 12;
private bool be2 = true;
private bool be3 = true;
//#endregion
/// <summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
/// </summary>
protected override void Initialize()
{
CalculateOnBarClose = false;
EntryHandling = EntryHandling.UniqueEntries;
}
private void GoLong()
{
SetStopLoss("target1", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetProfitTarget("target1", CalculationMode.Price, Close[0] + (Target2*TickSize));
}
private void ManageOrders()
{
if (Position.MarketPosition == MarketPosition.Long)
{
if (High[0] > Position.AvgPrice + (Target1*TickSize))
SetStopLoss("target1", CalculationMode.Price, Position.AvgPrice, false);
if (High[0] > Position.AvgPrice + ((Target1+Target2)*TickSize))
SetStopLoss("target2", CalculationMode.Price, Position.AvgPrice + (Target1*TickSize), false);
if (High[0] > Position.AvgPrice + ((Target1+Target2+Target3)*TickSize))
SetStopLoss("target3", CalculationMode.Price, Position.AvgPrice + ((Target1+Target2)*TickSize), false);
}
}
/// <summary>
/// Called on each bar update event (incoming tick)
/// </summary>
protected override void OnBarUpdate()
{
EntryHandling = EntryHandling.UniqueEntries;
GoLong();
ManageOrders();
if (Position.MarketPosition != MarketPosition.Flat) return;
if (........ENTER ANY TRADING LOGIC.................))
EnterLong("target1");
GoLong();
if (ToTime(Time[0]) == ToTime(15, 56, 0))
ExitLong("", "");
}
//#region Properties
[Description("")]
[Category("Parameters")]
public int Target1
{
get { return target1; }
set { target1 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target2
{
get { return target2; }
set { target2 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target3
{
get { return target3; }
set { target3 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Stop
{
get { return stop; }
set { stop = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public bool BE2
{
get { return be2; }
set { be2 = value; }
}
[Description("")]
[Category("Parameters")]
public bool BE3
{
get { return be3; }
set { be3 = value; }
}
//#endregion
}
}
Hey Calhawk01
it looks like in the method GoLong() you only have SetProfitTarget for "target1" and did not set it for "target2 and "target3. If you don't set them, then they don't exist.
or you are setting them the manageorders and bugs are then happening. Make sure when you first GoLong, you have Stops and all Profit Targets set. then when they are set, you can properly call manageorders. otherwise weird things happen and hard to trace. make a step by step list, then program it that way. It will take care of most of your problems.
actually, now that I look at it, if you are using 3 positions you need to call SetStopLoss 3 times.
here is the code you should start with as a template. It has been stripped down. If not using the optimizer, then you don't need B/E, if you are not going short, then you don't need short logic.
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Big Mike - 1/26/10 - https://futures.io/beginners-introductions-tutorials/2512-video-tutorial-how-create-advanced-ninjatrader-strategy.html
/// </summary>
[Description("Make me millions Jan 27 2010")] //modified by Spencer Davis as a simple template 05/30/2013.
public class MyMoneyMaker_BigMike : Strategy
{
private int target1 = 12;
private int target2 = 10;
private int target3 = 24;
private int stop = 12;
protected override void Initialize()
{
CalculateOnBarClose = true;
EntryHandling = EntryHandling.UniqueEntries;
}
private void GoLong()
{
SetStopLoss("target1", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetStopLoss("target2", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetStopLoss("target3", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetProfitTarget("target1", CalculationMode.Price, Close[0] + (Target1*TickSize));
SetProfitTarget("target2", CalculationMode.Price, Close[0] + ((Target1+Target2)*TickSize));
SetProfitTarget("target3", CalculationMode.Price, Close[0] + ((Target1+Target2+Target3)*TickSize));
EnterLong("target1");
EnterLong("target2");
EnterLong("target3");
}
private void ManageOrders()
{
if (Position.MarketPosition == MarketPosition.Long)
{
//Enter Trade management logic here for stop tightening
}
}
protected override void OnBarUpdate()
{
EntryHandling = EntryHandling.UniqueEntries;
ManageOrders();
if (Position.MarketPosition != MarketPosition.Flat) return;
//if ( enter reason for going long here )
// GoLong();
}
[Description("")]
[Category("Parameters")]
public int Target1
{
get { return target1; }
set { target1 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target2
{
get { return target2; }
set { target2 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target3
{
get { return target3; }
set { target3 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Stop
{
get { return stop; }
set { stop = Math.Max(1, value); }
}
}
}
hope this helps.
can you please describe your management strategy?
it looks like in the method GoLong() you only have SetProfitTarget for "target1" and did not set it for "target2 and "target3. If you don't set them, then they don't exist.
or you are setting them the manageorders and bugs are then happening. Make sure when you first GoLong, you have Stops and all Profit Targets set. then when they are set, you can properly call manageorders. otherwise weird things happen and hard to trace. make a step by step list, then program it that way. It will take care of most of your problems.
actually, now that I look at it, if you are using 3 positions you need to call SetStopLoss 3 times.
here is the code you should start with as a template. It has been stripped down. If not using the optimizer, then you don't need B/E, if you are not going short, then you don't need short logic.
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Big Mike - 1/26/10 - https://futures.io/beginners-introductions-tutorials/2512-video-tutorial-how-create-advanced-ninjatrader-strategy.html
/// </summary>
[Description("Make me millions Jan 27 2010")] //modified by Spencer Davis as a simple template 05/30/2013.
public class MyMoneyMaker_BigMike : Strategy
{
private int target1 = 12;
private int target2 = 10;
private int target3 = 24;
private int stop = 12;
protected override void Initialize()
{
CalculateOnBarClose = true;
EntryHandling = EntryHandling.UniqueEntries;
}
private void GoLong()
{
SetStopLoss("target1", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetStopLoss("target2", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetStopLoss("target3", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
SetProfitTarget("target1", CalculationMode.Price, Close[0] + (Target1*TickSize));
SetProfitTarget("target2", CalculationMode.Price, Close[0] + ((Target1+Target2)*TickSize));
SetProfitTarget("target3", CalculationMode.Price, Close[0] + ((Target1+Target2+Target3)*TickSize));
EnterLong("target1");
EnterLong("target2");
EnterLong("target3");
}
private void ManageOrders()
{
if (Position.MarketPosition == MarketPosition.Long)
{
//Enter Trade management logic here for stop tightening
}
}
protected override void OnBarUpdate()
{
EntryHandling = EntryHandling.UniqueEntries;
ManageOrders();
if (Position.MarketPosition != MarketPosition.Flat) return;
//if ( enter reason for going long here )
// GoLong();
}
[Description("")]
[Category("Parameters")]
public int Target1
{
get { return target1; }
set { target1 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target2
{
get { return target2; }
set { target2 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target3
{
get { return target3; }
set { target3 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Stop
{
get { return stop; }
set { stop = Math.Max(1, value); }
}
}
}
hope this helps.
can you please describe your management strategy?
Spencer
Hello Spencer, the above code enters three different positions. that's what i'm trying to change. the original code posted by bigmike also enters three different positions. I want to enter one position (one contract) with three different profit targets and stoplosses that move once profit targets are hit. initial stoploss 12 ticks, if target1 is hit then stoploss= avg price, if target2 is hit, then stoploss=target1, if target3 is hit, then stoploss= target2
the above creates three different positions/ buys three contracts
i figured the below would set the stoploss and target1 when the trade is first entered, but once target1 is hit, ManageOrder() would kick in and move the stoplosses. Ya know?
anyone? maybe I can paypal you some cash?? i really dont feel like dropping hundreds of dollars to one of the indicator creating companies! b/c i feel like i already have the correct code.. just needs some additional coding or move some parts around. need:
buy ONE contract when trade logic becomes true with the following trade management settings: initial stoploss 12 ticks, if target1 is hit then stoploss= avg price, if target2 is hit, then stoploss=target1, if target3 is hit, then stoploss= target2
Broker: Tradestation/Tradestation, NinjaTrader, FXCM and Tallinex
Trading: ES, CL, EUR/USD, TF
Posts: 181 since Aug 2009
Thanks: 103 given,
56
received
Hey,
Ok, I know what you mean now. So, I think in order to access the entry price, you need to create an IOrder object.
private IOrder _entry = null;
//then you can do this
_entry = EnterLong("tag you want to give");
//then later you can do this
if (High[0] >= (target1 * TickSize))
SetStopLoss(CaculationMode.Price, (_entry.AvgFillPrice);
I did not try it out yet. Look at Scott Shodsons Ninja Trader webinars. He uses IOrders a lot.
He has 2 webinars. They are very good.
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Big Mike - 1/26/10 - https://futures.io/beginners-introductions-tutorials/2512-video-tutorial-how-create-advanced-ninjatrader-strategy.html
/// </summary>
[Description("Make me millions Jan 27 2010")] //modified by Spencer Davis as a simple template 05/30/2013.
public class MyMoneyMaker_BigMike : Strategy
{
private int _target1 = 12;
private int _target2 = 10;
private int _target3 = 24;
private int _stop = 12;
private IOrder _entry = null;
protected override void Initialize()
{
CalculateOnBarClose = true;
EntryHandling = EntryHandling.UniqueEntries;
}
private void GoLong()
{
SetStopLoss("Enter_Position", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
_entry = EnterLong("Enter_Position");
}
private void ManageOrders()
{
if (Position.MarketPosition == MarketPosition.Long)
{
if(High[0] >= (_target1 * TickSize))
SetStopLoss(CalculationMode.Price, _entry.AvgFillPrice);
else if (High[0] >= (_target2 * TickSize))
SetStopLoss(CalculationMode.Price, (_entry.AvgFillPrice + (_target1 * TickSize)));
else if (High[0] >= (_target3 * TickSize))
SetStopLoss(CalculationMode.Price, (_entry.AvgFillPrice + (_target2 * TickSize)));
}
}
protected override void OnBarUpdate()
{
EntryHandling = EntryHandling.UniqueEntries;
ManageOrders();
if (Position.MarketPosition != MarketPosition.Flat) return;
//if ( enter reason for going long here )
// GoLong();
}
[Description("")]
[Category("Parameters")]
public int Target1
{
get { return _target1; }
set { _target1 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target2
{
get { return _target2; }
set { _target2 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target3
{
get { return _target3; }
set { _target3 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Stop
{
get { return _stop; }
set { _stop = Math.Max(1, value); }
}
}
}
Ok, I know what you mean now. So, I think in order to access the entry price, you need to create an IOrder object.
private IOrder _entry = null;
//then you can do this
_entry = EnterLong("tag you want to give");
//then later you can do this
if (High[0] >= (target1 * TickSize))
SetStopLoss(CaculationMode.Price, (_entry.AvgFillPrice);
I did not try it out yet. Look at Scott Shodsons Ninja Trader webinars. He uses IOrders a lot.
He has 2 webinars. They are very good.
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Big Mike - 1/26/10 - https://futures.io/beginners-introductions-tutorials/2512-video-tutorial-how-create-advanced-ninjatrader-strategy.html
/// </summary>
[Description("Make me millions Jan 27 2010")] //modified by Spencer Davis as a simple template 05/30/2013.
public class MyMoneyMaker_BigMike : Strategy
{
private int _target1 = 12;
private int _target2 = 10;
private int _target3 = 24;
private int _stop = 12;
private IOrder _entry = null;
protected override void Initialize()
{
CalculateOnBarClose = true;
EntryHandling = EntryHandling.UniqueEntries;
}
private void GoLong()
{
SetStopLoss("Enter_Position", CalculationMode.Price, Close[0] - (Stop*TickSize), false);
_entry = EnterLong("Enter_Position");
}
private void ManageOrders()
{
if (Position.MarketPosition == MarketPosition.Long)
{
if(High[0] >= (_target1 * TickSize))
SetStopLoss(CalculationMode.Price, _entry.AvgFillPrice);
else if (High[0] >= (_target2 * TickSize))
SetStopLoss(CalculationMode.Price, (_entry.AvgFillPrice + (_target1 * TickSize)));
else if (High[0] >= (_target3 * TickSize))
SetStopLoss(CalculationMode.Price, (_entry.AvgFillPrice + (_target2 * TickSize)));
}
}
protected override void OnBarUpdate()
{
EntryHandling = EntryHandling.UniqueEntries;
ManageOrders();
if (Position.MarketPosition != MarketPosition.Flat) return;
//if ( enter reason for going long here )
// GoLong();
}
[Description("")]
[Category("Parameters")]
public int Target1
{
get { return _target1; }
set { _target1 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target2
{
get { return _target2; }
set { _target2 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Target3
{
get { return _target3; }
set { _target3 = Math.Max(1, value); }
}
[Description("")]
[Category("Parameters")]
public int Stop
{
get { return _stop; }
set { _stop = Math.Max(1, value); }
}
}
}
hope this helps
I will code something later and test it.
Spencer
Spencer, I'm at work right now so won't be able to test it till later. Thank you for the help Spencer!
Broker: Tradestation/Tradestation, NinjaTrader, FXCM and Tallinex
Trading: ES, CL, EUR/USD, TF
Posts: 181 since Aug 2009
Thanks: 103 given,
56
received
hmm, actually I am still new to Ninjascript. It seems like Position.AvgPrice is the average representation of the fill price. from the documentation
{
// Raise stop loss to breakeven when there is at least 10 ticks in profit
if (Close[0] >= Position.AvgPrice + 10 * TickSize)
ExitLongStop(Position.Quantity, Position.AvgPrice);
}
So, we probably don't need IOrder, but I hear that most professionals will only use them with real live strategies. We can always take IOrder out and replace _entry.AvgFillPrice with Position.AvgPrice and just add a simple SMA cross strategy or something.
hmm, actually I am still new to Ninjascript. It seems like Position.AvgPrice is the average representation of the fill price. from the documentation
{
// Raise stop loss to breakeven when there is at least 10 ticks in profit
if (Close[0] >= Position.AvgPrice + 10 * TickSize)
ExitLongStop(Position.Quantity, Position.AvgPrice);
}
So, we probably don't need IOrder, but I hear that most professionals will only use them with real live strategies. We can always take IOrder out and replace _entry.AvgFillPrice with Position.AvgPrice and just add a simple SMA cross strategy or something.
Broker: Tradestation/Tradestation, NinjaTrader, FXCM and Tallinex
Trading: ES, CL, EUR/USD, TF
Posts: 181 since Aug 2009
Thanks: 103 given,
56
received
Hey calhawk01
I think this code pretty much works.
I did not use IOrders. You can always take out the reason to get long or short. You can also play with the drawLine things.
However, I believe it works or at least it is a general outline to what you were looking for
take care
Spencer
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/*
Author: Spencer Davis
This is an outline Trade Management strategy for using dynamic stops and targets
*/
[Description("A strategy that trails the stops")]
public class sdTM : Strategy
{
//periods
private int fastPeriod = 8;
private int slowPeriod = 34;
//trade management
private int stopLoss = 18;
private int target1 = 10;
private int target2 = 20;
private int target3 = 30;
private SMA fastSMA;
private SMA slowSMA;
private bool drawStop = false;
protected override void Initialize()
{
CalculateOnBarClose = true;
EntryHandling = EntryHandling.UniqueEntries;
fastSMA = SMA(FastPeriod);
slowSMA = SMA(SlowPeriod);
Add(slowSMA);
Add(fastSMA);
fastSMA.Plots[0].Pen.Width = 2;
fastSMA.Plots[0].Pen.Color = Color.Green;
slowSMA.Plots[0].Pen.Width = 2;
slowSMA.Plots[0].Pen.Color = Color.Red;
}
protected override void OnBarUpdate()
{
if (CurrentBar < 20) return; //make sure there is enough data
//buy conditions
if (CrossAbove(SMA(FastPeriod), SMA(SlowPeriod), 1)&& Flat)
GoLong();
else if (CrossBelow(SMA(FastPeriod),SMA(SlowPeriod),1) && Flat)
GoShort();
ManageTrade();
}
private void ManageTrade()
{
if(Long)
{
if (!drawStop)
this.DrawLine("StopLine"+CurrentBar, true, 0, (Position.AvgPrice - StopLoss*TickSize), -8, (Position.AvgPrice -StopLoss*TickSize), Color.Red, DashStyle.Dash, 2);
if (High[0] >= (Position.AvgPrice + Target1*TickSize) && High[0] < (Position.AvgPrice + Target2*TickSize))
{
SetStopLoss("EntryLong", CalculationMode.Price, Position.AvgPrice, false);
this.DrawLine("BreakEvenLong"+CurrentBar,true,0,(Position.AvgPrice + Target1*TickSize), -8, (Position.AvgPrice + Target1*TickSize), Color.Gray, DashStyle.Dash, 2);
}
if (High[0] >= (Position.AvgPrice + Target2*TickSize)&& High[0] < (Position.AvgPrice + Target3*TickSize))
{
SetStopLoss("EntryLong", CalculationMode.Price, Position.AvgPrice + Target1*TickSize, false);
this.DrawLine("Target1Long"+CurrentBar,true,0,(Position.AvgPrice + Target2*TickSize), -8, (Position.AvgPrice + Target2*TickSize), Color.Green, DashStyle.Dash, 2);
}
if (High[0] >= (Position.AvgPrice + Target3*TickSize))
{
ExitLong(1, "Exiting Long", "EntryLong");
this.DrawLine("Target2Long"+CurrentBar,true,0,(Position.AvgPrice + Target3*TickSize), -8, (Position.AvgPrice + Target3*TickSize), Color.Green, DashStyle.Dash, 2);
}
drawStop = true;
}
if(Short)
{
if (!drawStop)
this.DrawLine("StopLine"+CurrentBar, true, 0, (Position.AvgPrice + StopLoss*TickSize), -8, (Position.AvgPrice + StopLoss*TickSize), Color.Red, DashStyle.Dash, 2);
if (Low[0] <= (Position.AvgPrice - Target1*TickSize)&& Low[0] > (Position.AvgPrice - Target2*TickSize))
{
SetStopLoss("EntryShort", CalculationMode.Price, Position.AvgPrice, false);
this.DrawLine("BreakEvenShort"+CurrentBar,true,0,(Position.AvgPrice - Target1*TickSize), -8, (Position.AvgPrice - Target1*TickSize), Color.Gray, DashStyle.Dash, 2);
}
if (Low[0] <= (Position.AvgPrice - Target2*TickSize)&& Low[0] > (Position.AvgPrice - Target3*TickSize))
{
SetStopLoss("EntryShort", CalculationMode.Price, Position.AvgPrice - Target1*TickSize, false);
this.DrawLine("Target1Long"+CurrentBar,true,0,(Position.AvgPrice - Target2*TickSize), -8, (Position.AvgPrice - Target2*TickSize), Color.Green, DashStyle.Dash, 2);
}
if (Low[0] <= (Position.AvgPrice - Target3*TickSize))
{
ExitShort(1, "Exiting Short", "EntryShort");
this.DrawLine("Target2Long"+CurrentBar,true,0,(Position.AvgPrice - Target3*TickSize), -8, (Position.AvgPrice - Target3*TickSize), Color.Green, DashStyle.Dash, 2);
}
drawStop = true;
}
}
private void GoLong()
{
SetStopLoss("EntryLong", CalculationMode.Ticks, StopLoss, false);
EnterLong(1, "EntryLong");
drawStop = false;
}
private void GoShort()
{
SetStopLoss("EntryShort", CalculationMode.Ticks, StopLoss, false);
EnterShort(1, "EntryShort");
drawStop = false;
}
//returns current state of Flat, Long, or Short
#region TradeState
private bool Flat { get{ return Position.MarketPosition == MarketPosition.Flat; } }
private bool Long { get{ return Position.MarketPosition == MarketPosition.Long; } }
private bool Short { get{ return Position.MarketPosition == MarketPosition.Short; } }
#endregion
#region Properties
[Description("Fast Period")]
[GridCategory("Parameters")]
public int FastPeriod
{
get { return fastPeriod; }
set { fastPeriod = Math.Max(1, value); }
}
[Description("Slow Period")]
[GridCategory("Parameters")]
public int SlowPeriod
{
get { return slowPeriod; }
set { slowPeriod = Math.Max(1, value); }
}
[Description("Stop Loss")]
[GridCategory("Parameters")]
public int StopLoss
{
get { return stopLoss; }
set { stopLoss = Math.Max(1, value); }
}
[Description("1st Target")]
[GridCategory("Parameters")]
public int Target1
{
get { return target1; }
set { target1 = Math.Max(1, value); }
}
[Description("2nd Target")]
[GridCategory("Parameters")]
public int Target2
{
get { return target2; }
set { target2 = Math.Max(1, value); }
}
[Description("3rd Target")]
[GridCategory("Parameters")]
public int Target3
{
get { return target3; }
set { target3 = Math.Max(1, value); }
}
#endregion
}
}
The following user says Thank You to spinnybobo for this post:
In this video tutorial I show how to create a strategy from scratch (not using the wizard, which I never use).
The strategy contains a few optimizable parameters such as SMA length, EMA length, HMA length, three different targets with custom tick settings on each, a stop size, and the option to move target 2 to breakeven after target 1 is hit, as well as move target 3 to breakeven after target 2 is hit.
[Mike
I got the following Recursive Property error when I compiled the strategy (see code below):
Your strategy likely holds one or more recursive properties which could cause NinjaTrader to crash: EMAlength HMALENGTH TARGET1 TARGET2 TARGET3 BE2 BE3
Do you want to edit these properties?
I have attached the code I created. Please note I did not use the SMA. Can anyone please point out what I typed in wrong?
Thank you.
JLW
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Enter the description of your strategy here
/// </summary>
[Description("Create a strategy with optimizable variables")]
public class testbmt : Strategy
{
private int emalength = 20;
private int hmalength = 10;
private int target1 = 12;
private int target2 = 10;
private int target3 = 18;
/// <summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
/// </summary>
protected override void Initialize()
{
CalculateOnBarClose = true;
EntryHandling = EntryHandling.UniqueEntries;
}
Broker: Tradestation/Tradestation, NinjaTrader, FXCM and Tallinex
Trading: ES, CL, EUR/USD, TF
Posts: 181 since Aug 2009
Thanks: 103 given,
56
received
jlwade123
I got the following Recursive Property error when I compiled the strategy (see code below):
Your strategy likely holds one or more recursive properties which could cause NinjaTrader to crash: EMAlength HMALENGTH TARGET1 TARGET2 TARGET3 BE2 BE3
Do you want to edit these properties?
I have attached the code I created. Please note I did not use the SMA. Can anyone please point out what I typed in wrong?
Thank you.
JLW
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Indicator;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Strategy;
#endregion
// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
/// <summary>
/// Enter the description of your strategy here
/// </summary>
[Description("Create a strategy with optimizable variables")]
public class testbmt : Strategy
{
private int emalength = 20;
private int hmalength = 10;
private int target1 = 12;
private int target2 = 10;
private int target3 = 18;
/// <summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
/// </summary>
protected override void Initialize()
{
CalculateOnBarClose = true;
EntryHandling = EntryHandling.UniqueEntries;
}
This will probably give you a bunch of errors.
(....) are for functions and arguments
{....} is for blocks of code --- everything that goes inside of a method, class, namespace
Spencer
The following user says Thank You to spinnybobo for this post:
You mention in the video your running ninja on a virtual machine. Could you amplify on this. I guess more specifically
I am wondering if this gives some enhanced level of security for your code etc. From who, Ninja, Hackers etc.
and what virtual machine do you recommend?
You mention in the video your running ninja on a virtual machine. Could you amplify on this. I guess more specifically
I am wondering if this gives some enhanced level of security for your code etc. From who, Ninja, Hackers etc.
and what virtual machine do you recommend?
Thanks
Jerry
I am not sure if those are the reasons Big Mike does it, but the following advantages come to my mind when running it on a Virtual Machine:
1. You can run a 2. instance of NinjaTrader
2. Assuming you are connecting to a demo account on your VM: Your testing of strategies etc. won't interfere with your live trading accounts (depending on how you test this could happen if you test it on your primary NT connected to your live accounts)
Hence: you completely keep your live trading and your research separated
You mention in the video your running ninja on a virtual machine. Could you amplify on this. I guess more specifically
I am wondering if this gives some enhanced level of security for your code etc. From who, Ninja, Hackers etc.
and what virtual machine do you recommend?
Thanks
Jerry
I use Amazon S3 for free to house my Ninja data backup. I have been thinking increasing storage/memory from Amazon to use as a sandbox for my strategy development. Amazon is pretty cheap.
I know it's late to reply but the virtual machine is for Linux. Ninja runs native on windows. To run it on Linux you a virtual machine or some workaround. Big Mike mentioned he had a Cron backup running and that's a Linux scheduled task.
I'm a beginner and I'd like to input this on my Platform to improve ad see how it works.
Thank you
Big Mike
In this video tutorial I show how to create a strategy from scratch (not using the wizard, which I never use).
The strategy contains a few optimizable parameters such as SMA length, EMA length, HMA length, three different targets with custom tick settings on each, a stop size, and the option to move target 2 to breakeven after target 1 is hit, as well as move target 3 to breakeven after target 2 is hit.
The strategy is just an example! It took all of 10 minutes to write. Even though it says it made 20k in 90 days over 700 trades, it will likely fail going forward. Simple strategies are usually best, but this one is too simple to work fully automated. Most strategies I write for customers take me hours of work (this one took 10 minutes), so don't just go and copy this strategy and expect good results.
Instead, I created this so you could get your feet wet and learn some of the basics of a more advanced strategy than what Ninja includes with the base install. I also created it so if someone shows you backtest results where it makes tons of money, you can see just how easy it is to produce those results.
Also, don't forget that optimizing based on net profit is virtually worthless. I've spent two years tweaking my custom optimizer type and it considers everything you can imagine such as balanced longs/shorts, trade counts, commission costs, profit factors, expectancy, trade duration, and a bunch of other stuff I don't want to go into because I am not giving it away.
With the normal drop-down list of optimizer types in NT, you don't want to just pick the result that shows the most net profit. You should factor in as many other variables as you can. Unless you're going to do what I did with the custom optimizer, the easiest way is to dump the results to an Excel spreadsheet (feature is built-in to NinjaTrader) and then work some analysis there.
Hello Mike, kudos to you for the effort to sustain this forum over the years. I am a student of the trading game for 2 years now..anyhow, i have a question for you, what is the correct code to have 2 entires in ninja programming, , having them with 1 stop loss, and 2 different profit targets without trailing stops. I am trying to teach myself how to code my ideas correctly in order to backtest fast, because, although going through price bars 1 by 1 has it's benefits, i will grow BIG beard untill i complete 1-2 years of tests.
I'm curious about something that I've noticed for quite some time now but never addressed. I have always developed rules that apply to both longs and shorts. In other words, the rules for longs are exactly the same as for shorts. That is the …
The following 3 users say Thank You to Cloudy for this post:
The link to Mike's Video on Ninja Strategy is broken
yes. I stumbled over this thread because I want to learn the basics for indicator/strategy development but the video is not there anymore. Any help appreciated. Thank you
The link to Mike's Video on Ninja Strategy is broken
patricia
yes. I stumbled over this thread because I want to learn the basics for indicator/strategy development but the video is not there anymore. Any help appreciated. Thank you
Please note that this video was recorded in January 2010, so at best it applies to a very early version of NinjaTrader 7 -- I don't recall the relevant dates now, so perhaps NT 6.5 or earlier.
(I was just able to find a link on the NT support board dated Feb 25, 2010, stating "NT7 is currently in a closed beta. We are looking to do a public beta in the near future.")
Anything it contains will not be relevant to NT 8, which was extensively redesigned from the ground up, and probably not relevant to more current versions of NT 7 either.
Bob.
When one door closes, another opens.
-- Cervantes, Don Quixote
The following 2 users say Thank You to bobwest for this post: