TS code using “date of next bar” command with two data sources

Discussion in 'Data Sets and Feeds' started by Jock, Mar 26, 2007.

  1. Jock


    I’m carrying out testing in TradeStation using 5-minute data and need to refer to daily data for a daily True Range calculation.

    Normally this would not be a problem as I place 5-minute data in Data1 and daily data as Data2. However in my coding I need to use the “date of next bar” command and when I do, TS cannot refer to any data other than Data1.

    For example, with an entry using a simple Opening Range Breakout…

    {data1 is 5-minute data, data2 is daily data, ATR[20] =  AverageTrueRange(20) of daily data}
    vars: DATR(0);
    DATR = AvgTrueRange(20) of data2;
    If date < date of next bar then Buy at Open of next bar + 0.3*DATR stop;
    {If it's the last 5-minute bar of today, 
    place a stop order at Open of Tomorrow + 0.3*ATR[20]. 
    Cannot use OpenD(0) here, 
    because OpenD(0) uses the Open of Today rather than the Open of tomorrow}
    If date = date of next bar and @entrydate(1) <> date then Buy at OpenD(0) + 0.3*DATR stop;
    {If next 5-minute bar is still within the same day, place an stop order at Open of Today + 0.3*ATR[20]}
    I get an error message saying “cannot mix next bar prices with data streams other than data1”.

    Since I need to use "date of next bar" to define the correct opening price, is there anyway that I can calculate the daily ATR within the system coding as well as being able to use the “date of next bar” command?
  2. I would issue the stop order on the first 5min bar of the day rather than issuing it the previous afternoon. This way, "date of next bar" is not needed.

    So you can use the US Stock session, 9:30 to 4:00 EST, and say:

    If time = 935 then buy next bar at Open + 0.3*DATR stop;

    This will be using the opening price of the session as it is the open of the first 5min bar of the day. This would only miss entries that occur in the first 5 minutes, which would be rare.

    Alternatively, you could cut the timeframe to 1min, use the same logic, and then only the 1st minute would be missed. Hope that helps...
  3. Jock


    TrueStory, thanks for your input. My preference is not to miss trades that may occur on the first bar of the day. As you suggest I could reduce the timeframe to 1-minute bars, which would reduce the number of missed trades.

    However, even if I were to do this and then use your suggested time session to identify entry, e.g.

    If time >= 935 then buy next bar at OpenD(0) + 0.3*DATR stop;

    This avoids the use of "date of next bar", but is a problem in the last bar of today. When at the last bar of today (time >= 935), it will place an order on the first bar of “Tomorrow” using the Open of “Today” + 0.3*DATR, because "OpenD(0)" will get the Open of today, and "Open" will get the open of next bar.

    So if it’s the last 1-minute bar of Monday, the code will place an order to buy on the first bar of Tuesday using Monday’s open instead of Tuesday’s.
  4. Jock,

    I see what you mean. Try this:

    You can set the 9:30 EST Open as your chosen value by assigning a variable:


    If Time = 931 then MyOpen = Open; (this is for 1min bars)
    If Time = 935 then MyOpen = Open; (this is for 5min bars)

    This will keep the opening price as the variable. You can then set the buy order as:

    Buy next bar at MyOpen + 0.3*DATR stop;

    Hope that works for you...
  5. You can't reference data of tomorrow. You can only reference data up to the present.

    You need to study EL logic a little more. Maybe look at lots of code samples.

    Many ways to accomplish these tasks...

    If date<>date[1] then begin...

    If time>=9:31 and time<15:45 then begin...

    If date<>date[1] then begin

    If time<15:45 and (data2 condition here) then buy next bar at myopen+whatever stop;

    But you can't say...open of tomorrow or next open.

  6. Jock


    Thanks for the advice, but this still has the same problem with the last bar. When it’s the last bar of today, it will use MyOpen (Open of today) to place a stop order on the 1st bar of Tomorrow.
  7. risktaker's advice solves that problem...

    if time >= 931 and time < some time late in the day then buy next bar at 0.3*DATR stop;

    Each day, the variable MyOpen will be reassigned to the open of the first bar of the day.
  8. Jock


    You’re right on that one, however I’ve looked at your suggestions and this is what I come up with…

    Both of these suggestions still do not solve the problem with the last bar of the day, i.e. if it’s the last 1-minute bar of Monday, the code will place an order to buy on the first bar of Tuesday using Monday’s open instead of Tuesday’s.

    This code will work and solves the last bar problem. I’ve tried something similar to this previously, works fine, “except” for half-days or days when the exchange closes anytime earlier than the normal 15:45. It is for this reason that I have been using the "date of next bar" command to define the correct opening price. But of course if I use the "date of next bar" command I can’t then refer to data2. So seemingly back to where we started.

    Not too sure what you’re getting at with this one?
  9. Hi Jock,

    Use Array. Go to the TradeStation help index tab and type in the word, array. There are three listings. Read them to get an understanding.

    Var: Counter(0), Sum(0), DTH(0), DTL(0), DATR(0);
    Array: DTR[19](0);

    With the above statement, the DTR array has 20 elements from 0 to 19 all with the initial value of 0.

    At the last 5-min bar of the day, do the following:

    Use a loop to move the 2nd element (DTR[1] ) thru 20th (DTR[19]) elements in the array backward. This will drop the value in oldest one (DTR[0]) and also make room in DTR[19] for the new one.

    {Shift DTR backwards to make room for latest}
    For Counter = 0 to 18 Begin
    DTR[Counter] = DTR[Counter + 1];

    Calculate your 20th element DTR[19] from the 5-min using CloseD(1), HighD(0), LowD(0) and store it in DTR[19].

    {Daily TrueHigh}
    DTH = MaxList(CloseD(1),HighD(0));

    {Daily TrueLow}
    DTL = MinList(CloseD(1),LowD(0));

    {Daily TrueRange}
    DTR[19] = DTH - DTL;

    Divide the sum of DTR[0] to DTR[19] by 20 to get the 20DATR.

    {Initialise Sum to zero}
    Sum = 0;

    {Sum all the DTR}
    For Counter = 0 to 19 Begin
    Sum = Sum + DTR[Counter];

    {Daily ATR}
    DATR = Sum/20;

    I think this may do the trick for you. You don't need Data2 for the daily data.
  10. Jock


    ChoSingKum, thanks very much. This use of Array does exactly what I need, in that I no longer need to refer to data2 and can therefore use the "date of next bar" command.

    My only concern is that if I need to calculate a very long daily ATR value, for example ATR(200) then the array may take some time to run.

    Meantime I have actually come up with a way of being able to refer to data2 without using the "date of next bar" command …

    If (marketposition = 0 and entrydate(1) < date) then buy at OpenD(0) + 0.3*AvgTrueRange(1) of data2 stop;

    The only problem with this simple code is that it won’t take a trade on the very first bar of the day.
    #10     Mar 28, 2007