View Full Version : Tradestation to NT Intrabar Orders
glenng
10-13-2007, 01:26 PM
I am writing a simple strategy in TS that fires orders to NT using the DLL interface. I want my strategy to set a range based on the high and low of the first bar of the day, and then fire off an order the first time either side of the range is taken out. It only executes once per day. The order cannot wait for the bar to close. It must execute as soon as the range is violated.
The following code does this just fine, except TS sends more than one order for the triggering bar when intrabarordering is set to true. This raises two questions regarding this interface:
How can I get just a single order processed?
Why can't NTMarketPosition see that the first intrabar order is placed and prevent the second from being generated.
[IntraBarOrderGeneration = TRUE]
{DefineDLLFunc: "NTDirect.dll", int, "Setup", lpstr, int;}
inputs: numContracts(2);
variables: nHigh(9999999), nLow(-1);
variables: success(0);
if Date = {CurrentDate} 1071012 then begin
if Date <> Date[1] then
begin
nHigh = High;
nLow = Low;
end;
if NTConnected(1) then
begin
{go long if price > high of 1st bar }
if High > nHigh and NTMarketPosition("") = 0 then
begin
success = NTBuyMarket("FirstBar",numContracts);
nHigh = 99999999;
nLow = -1;
end;
if Low < nLow and NTMarketPosition("") = 0 then
begin
success = NTSellMarket("FirstBar",numContracts);
Print(File("c:\mydata.txt"), "SELL ",CurrentBar, "Date " ,Date, Time, Close, "High: ", High, " LOW: ", Low," NHigh: ", nHigh, " NLOW: ", nLow );
nHigh = 99999999;
nLow = -1;
end;
end;
end; {currentdate}
NinjaTrader_Josh
10-13-2007, 01:51 PM
The reason NTMarketPosition can't stop it is because even though the order is sent you won't have a position right away. In a fast moving market there will be several more ticks that will violate the threshold before you get filled on your first order thus the submission of subsequent orders.
To workaround this you could work with a simple bool variable. Do something similar to this pseudo-code.
if thisBool is true
then
submit orders and set bool to false
glenng
10-13-2007, 02:45 PM
Thanks for taking a look. I have already done essentially that by setting nHigh to 99999999 - so the next time around, High will not be greater than nHigh so another order should not fire off. It looks as if the new value for the variable is not set until after the bar is closed. Not sure though. If that is the case, does it mean intrabar orders are impossible? There must be a way.
NinjaTrader_Josh
10-13-2007, 02:54 PM
I am unfamiliar with the way TS executes its code. Your code should work from what I can tell. Perhaps try using some print commands with time outputs to see when exactly the variable values are set.
glenng
10-13-2007, 03:01 PM
Looks like each bar is processed four times and the variables set after the fourth. Perhaps its time to learn Ninja code. I would still be interested in hearing from anyone who has a solution though.
Thanks for the help.
glenng
10-13-2007, 04:27 PM
So, would this be the equivalent NinjaScript code? Just play the breakout of the first bar, and you are done for the day. Or are there any gotcha's I need to worry about.
#region Using declarations
#endregion
namespace NinjaTrader.Strategy
{
///<summary>
/// First Bar Breakout
///</summary>
[Description("First Bar Breakout")]
[Gui.Design.DisplayName("First Bar")]
publicclass FirstBar : Strategy
{
#region Variables
// Wizard generated variables
privateint numContracts = 2; // Default setting for NumContracts
// User defined variables (add any user defined variables below)
double nHigh = 99999999;
double nLow = -1;
int success = 1;
bool DoneForTheDay = false;
#endregion
///<summary>
/// This method is used to configure the strategy and is called once before any strategy method is called.
///</summary>
protectedoverridevoid Initialize()
{
CalculateOnBarClose = false;
}
///<summary>
/// Called on each bar update event (incoming tick)
///</summary>
protectedoverridevoid OnBarUpdate()
{
// Condition set 1
if (Position.MarketPosition == MarketPosition.Flat && ! DoneForTheDay)
{
if (Bars.FirstBarOfSession)
{ nHigh = High[0];
nLow = Low[0]; }
else
{
if (High[0] > nHigh)
{ DoneForTheDay = true;
AtmStrategyCreate(Action.Buy, OrderType.Market,0,0,TimeInForce.Day,GetAtmStrateg yUniqueId(),"FirstBar",GetAtmStrategyUniqueId());
}
if (Low[0] < nLow)
{
DoneForTheDay = true;
AtmStrategyCreate(Action.Sell, OrderType.Market,0,0,TimeInForce.Day,GetAtmStrateg yUniqueId(),"FirstBar",GetAtmStrategyUniqueId());
}
}
}
}
#region Properties
[Description("")]
[Category("Parameters")]
publicint NumContracts
{
get { return numContracts; }
set { numContracts = Math.Max(1, value); }
}
#endregion
}
}
NinjaTrader_Josh
10-13-2007, 04:38 PM
Seems all correct to me.
glenng
10-14-2007, 07:17 AM
I am still working on my TS version while learning about Ninja, and I have worked out the TS problems. I have now modified my code to use the ntcommand function so that I can place the order and activate an existing NT strategy to manage it. The strategy name in the example is FirstBar.
success = ntCommand("PLACE", "Sim101", "SELL", numContracts, "MARKET", 0,0 , "DAY", "", "FirstBarID", "FirstBar", "");
This shows up in the Ninja log as:
10/14/2007 9:08:04 AM,ATI,AT, 'PLACE;Sim101;@ER2;SELL;2;MARKET;0;0;DAY;;FirstBar ID;FirstBar;' processing ,
but it doesnt execute. What exactly is happening here? I have reviewed the documentation and a number of forum entries, but to no avail.
NinjaTrader_Ray
10-14-2007, 08:32 AM
Try passing in "ER 12-07" and see if that makes a difference.
NinjaTrader_Ray
10-14-2007, 08:32 AM
Try passing in "ER2 12-07" and see if that makes a difference.
glenng
10-14-2007, 08:54 AM
I tried that but it is not clear how. There is nowhere in the ntCommand syntax to pass an instrument as far as I can see, and in TS the symbol is ER2Z07, which I tried using on the chart, with the same result.
When I use NTBuyMarket with @ER in TS, NT can make the conversion to ER2 12-07 automatically. But ntBuyMarket doesn't let me run my strategy, so that is of no use.
Your help guide is actually in error on this issue. If you go to the TradeStation Functions page, the syntax shown for NTCommand does not provide for an instrument parameter. If you then click the link in the NTCommand description for "Commands and Valid Parameters", that page shows an Instrument parameter for the PLACE command and says it is Required - which makes sense. But if you include an instrument parameter in the code, between account and action, the DLL throws an error.
Please look at the line of code I presented and tell me where in the parameter list an instrument should go.
NinjaTrader_Ray
10-14-2007, 09:09 AM
If NTBuyMarket() works but NTCommand() does not, then I would ammend the functions to print out the data to see what is different. NTBuyMarket() is just a wrapper for NTCommand(). Printing out the actualy data will help zone in on the what is different/missing.
Thanks for the tip on the Help Guide. Will check it out.
glenng
10-14-2007, 09:34 AM
Thanks Ray. NTCommand is using GetSymbolName to pass the instrument automatically from the Chart to COMMAND, so that is working fine. After a little trial and error I have determined that if I pass "Sim101" as the account, the order is not placed and it sits in the log as Processing...
If I change "Sim101" to "", it works fine and places the order in the default account.
Shouldn't "Sim101" work?
NinjaTrader_Josh
10-14-2007, 12:15 PM
That is interesting glenng. I would assume that "Sim101" should work. Are there any error messages sitting in the log that might give a hint to why it doesn't like that account name?
NinjaTrader_Ray
10-14-2007, 12:42 PM
Sim101 requires market data. Please make sure you are connected and have a market data stream coming in for the market you want to trade.
glenng
10-14-2007, 02:40 PM
I just restarted everything so I could reproduce the problem, and everything worked fine. Go figure. It works with NT on the same machine as TS, and across the network. So that's it - tomorrow AM will be a live test and we'll see if TS shoots off the order intrabar.
Thanks for all the help.
glenng
10-15-2007, 10:39 AM
I ran the strategy real time today with the trigger as Date = CurrentDate (see code below) and nothing happend. Later on I forced it to fire by changing the code to Date = 1071015 and it triggered. No order was generated, so I changed the Acct from Sim101 to "", and tried again. No order, so I set it back to Sim101 and it fired off. The strategy was on a ER3 chart, but the log shows something different. Can you help?
AT 'PLACE;;@YM.D;BUY;2;MARKET;0;0;DAY;;FirstBarID;Fir stBar;' processing
OIF 'PLACE;Sim101;$SPINX;SELL;2;MARKET;0;0;DAY;;FirstB arID;FirstBar;' holds unknown instrument '$SPINX'
AT 'PLACE;Sim101;$SPINX;SELL;2;MARKET;0;0;DAY;;FirstB arID;FirstBar;' processing
OIF'PLACE;Sim101;$SPINX;SELL;2;MARKET;0;0;DAY;;Fir stBarID;FirstBar;' holds unknown instrument '$SPINX'
AT 'PLACE;Sim101;$SPINX;SELL;2;MARKET;0;0;DAY;;FirstB arID;FirstBar;' processing
NinjaTrader_Ray
10-15-2007, 11:09 AM
That's a TS issue when it subsitutes an incorrect instrument. I can't recall how to resolve this within TS.
What you can do is change the NTCommand() function to pass in "ER2 12-07" for the instrument and it should work.
glenng
10-17-2007, 04:13 PM
I replaced Getsymbol name with an input and now the strategy executes well in testing. Realtime is another story. I create a text file when the first bar closes with the prefix INIT and another right after a buy or sell is executed. Here is today's:
\
INIT: 1301.00 932.00Date 1071017.00 933.00 835.50High: 836.70 LOW: 835.30 NHigh: 836.70 NLOW: 835.30
BUY: 1302.00 933.00Date 1071017.00 935.0014067.00High: 14073.00 LOW: 14067.00 NHigh: 99999999.00 NLOW: -1.00
The strategy was installed on an ER2 chart. The init record shows the High of the opening bar as 837.7 and the low as 835.3 But look at the high and low right after calling the ntCommand function - High is 14073, and low is 14067. These look like YM numbers although the strategy was installed only on a ER2 chart. There was a YM chart in another workspace, but not related in any way to this strategy. Any ideas? BTW, this happened yesterday and today.
NinjaTrader_Ray
10-17-2007, 04:27 PM
Unfortunately I don't have any ideas. Looks like a TS bug to me!
glenng
10-18-2007, 10:00 AM
I took out the references to SetUp(), NTConnected(1), NTMarketPosition, and ntCommand and the strategy worked fine. The values for High and Low were exactly right.
Now, I don't know whether that means there is a but in TS or in NT, but it seems neither partner in this venture is very interested in fixing it. TS deleted my post entirely.
Is it possible that your DLL has a problem with Ts 8.3, which is what I am running? I am going to put back the references to the NT functions, one a day, and will report back to you.
glenng
10-18-2007, 10:09 AM
I got an answer faster than expected. The problem is with Setup() - when its in, it messes up TS's internals. When its out, TS is fine. By TS internals I mean their built in "High" and "Low" functions that return data from the current bar. Shifts to the wrong symbol entirely.