Welcome to NexusFi: the best trading community on the planet, with over 150,000 members Sign Up Now for Free
Genuine reviews from real traders, not fake reviews from stealth vendors
Quality education from leading professional traders
We are a friendly, helpful, and positive community
We do not tolerate rude behavior, trolling, or vendors advertising in posts
We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community. It's free for basic access, or support us by becoming an Elite Member -- see if you qualify for a discount below.
-- Big Mike, Site Administrator
(If you already have an account, login at the top of the page)
I'm learning how to code and I'm really new to it. Right now I'm just trying to make this simple strategy but it isn't going very well so if anyone out there is kind enough to take a look and tell me what I'm doing wrong I would be quite grateful seeing as how ninjatrader's support has been less than stellar.
The strategy is simple, first break the market up into equal risk reward chunks, if you were to visualize it it would most likely look like the brick bar type without the wicks - essentially a renko with a 1x reversal instead of 2x. Next just go long after each green bar unless you are already long then just stay that way and go short after each red bar or stay short if you already are just reversing when the bars reverse. I know this strategy won't be profitable as is and there are a lot of other things I want to do to it but you can't build a house without a foundation so please just code advice here, thanks.
So the pseudo code logic is this:
if flat then go long 1 and set entry price to baseprice
if long then create a reversal order at (baseprice - piplength) - also if long and current price is greater than or equal to (benchprice + piplength) then set benchprice to (benchprice + piplength)
if short do the opposite of whats in the if long
the problem with my actual code is when I go to backtest it and it shows that it goes long 1 but then never changes direction and never makes any other trades besides the first and I can't tell why. Are my order types wrong or in the wrong direction? Is it only reading the if flat part? If there is a totally different way to write all this that might work better I'm open to that too
#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
namespace NinjaTrader.NinjaScript.Strategies{
public class SecondTest : Strategy{
private double Baseprice;
protected override void OnStateChange(){
if (State == State.SetDefaults){
Description = @"En";
Name = "SecondTest";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = false;
ExitOnSessionCloseSeconds = 60;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
OrderFillResolution = OrderFillResolution.High;
OrderFillResolutionType = BarsPeriodType.Minute;
OrderFillResolutionValue = 1; Slippage = 0;
StartBehavior = StartBehavior.ImmediatelySubmit;
TimeInForce = TimeInForce.Gtc;
TraceOrders = true;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 0;
IsInstantiatedOnEachOptimizationIteration = true;
Piplength = 100;
Baseprice = 1;
}
else if (State == State.Configure){}
}
protected override void OnBarUpdate()
{
if (Position.MarketPosition == MarketPosition.Flat);{
EnterLong(1);
Baseprice = Position.AveragePrice;
}
if (Position.MarketPosition == MarketPosition.Long);{
if (Close[0] >= (Baseprice + Piplength));{
Baseprice += Piplength;
}
1. You are comparing apples to oranges. When evaluated it looks something like this:
if (14.25 >= (14.00+100)) which evaluates to:
if (14.25 >= 114.00) which always returns false.
To fix it you want to use eg.:
int HowManyTicks = 10;
2. Notice in the above code there is no semicolon ; before {}. That's how it should be - semicolon is terminating the expression while curly braces {} enclose the code to be evaluated further.
3. Use Print to avoid mistakes like in 1. If you would do it you would quickly notice the comparison doesn't make any sense, eg.:
now my strategy is actually opening and closing positions in a backtest, however they still aren't where I am trying to tell the computer to place them, further it was giving martingale results when i was trying to put the order in for double the position size but thats not what I wanted, I wanted to go 1 long to 1 short and vice versa but putting in an order for 1 should only close out the other and not get me in unless its double the size (in this case 2x1 should be 2 so an order for 2 short when you are 1 long should get you 1 net short) so it makes no sense to me why I had to change that but here is the new code
#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
//This namespace holds Strategies in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Strategies
{
public class ThirdTest : Strategy
{
private double Baseprice;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"3";
Name = "ThirdTest";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = false;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
OrderFillResolution = OrderFillResolution.High;
OrderFillResolutionType = BarsPeriodType.Minute;
OrderFillResolutionValue = 1; Slippage = 0;
StartBehavior = StartBehavior.ImmediatelySubmitSynchronizeAccount;
TimeInForce = TimeInForce.Gtc;
TraceOrders = false;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 0;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
Piplength = 0.1;
Baseprice = 1;
}
else if (State == State.Configure)
{
}
}
and I've attached the output
it seems like its not getting the initial baseprice being set to 1 or the command after to set it to the average position price but instead seems like its starting it at 0 and increasing by the piplength amount every time instead of decreasing at least some of the time like I'm trying to tell it to in part of the code, not sure where I am messing up, thanks again to anyone and everyone helping, when I get better at all this I'll definitely pay it forward helping other coding newbies
@SellBlock1138 I recommend you join the webinar by Scott that starts in an hour. Scott has been here from the beginning and you will definitely learn a few things regarding strategy writing in NT.
As to your strategy - try using more meaningful messages in your Print statements, eg.:
Print(Current Position: " + Position.MarketPosition + " Entering Long at price: " + (BasePrice));
Also: you can always use Exit... methods to make sure you are flat before entering a new trade.
ok using the print it seems to me that the issue is that my double value named Baseprice is not actually getting set equal to the position entry price after the first entry, can anyone tell me what I'm missing that could be causing this? thanks
#region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion
//This namespace holds Strategies in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Strategies
{
public class ThirdTest : Strategy
{
private double Baseprice;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"3";
Name = "ThirdTest";
Calculate = Calculate.OnEachTick;
EntriesPerDirection = 1;
EntryHandling = EntryHandling.AllEntries;
IsExitOnSessionCloseStrategy = false;
ExitOnSessionCloseSeconds = 30;
IsFillLimitOnTouch = false;
MaximumBarsLookBack = MaximumBarsLookBack.Infinite;
OrderFillResolution = OrderFillResolution.High;
OrderFillResolutionType = BarsPeriodType.Minute;
OrderFillResolutionValue = 1; Slippage = 0;
StartBehavior = StartBehavior.ImmediatelySubmitSynchronizeAccount;
TimeInForce = TimeInForce.Gtc;
TraceOrders = true;
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
StopTargetHandling = StopTargetHandling.PerEntryExecution;
BarsRequiredToTrade = 0;
// Disable this property for performance gains in Strategy Analyzer optimizations
// See the Help Guide for additional information
IsInstantiatedOnEachOptimizationIteration = true;
Piplength = 0.1;
Baseprice = 1;
}
else if (State == State.Configure)
{
}
}
Without testing your code, I can't say for sure, but my guess is that when you call:
You are expecting that the order has been filled immediately after the EnterLong(1) method is called and the Position object has been populated. Due to multi-threading in NT8, this may not be the case. The only way you can know if an order has been filled is when the OnExecutionUpdate function has been called by the engine. As soon as that function is called, the engine then calls OnPositionUpdate where the Position object is populated.
You can see this in your code because when you execute Baseprice = (Position.AveragePrice), Position.AveragePrice is 0 because the Position object has not been populated.
I would recommend reading about how the Managed Approach works for strategies in the NT8 help guide to see what functions are called by engine and in what order they are called when an order entry is executed. This in the Ninjascript->Language Reference->Strategy->Order Methods section of the help guide.