Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

ExitShort(9001) completely ignored?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    ExitShort(9001) completely ignored?

    I am having some major problems with the ExitShort and ExitLong functions at the moment.

    My strategy updates an int "T" in each call to OnBarUpdate() and then attempts to place orders which would make the Position.Quantity and Position.Side equal Math.Abs(T) and Math.Sign(T) [notwithstanding that MarketPosition is not an int].

    I.e. I want the strategy Position (and ultimately the account position) to track T.

    But when I try to do so, NT sometimes completly ignores my calls to ExitShort and ExitLong. But it does not always ignore them. I have not worked out what factors influence whether or not the calls are ignored.

    The output below shows the problem being generated by the example code below that. The program did output the string "ExitShort(9001)", so it must have called the function ExitShort(9001). The Position was 9001 short, so ExitShort(9001) should have closed the position.

    My question is... why was the call to ExitShort(9001) completely ignored by NT? There was not output to the log tab and no other indication of an error.

    Also, is there an easier way to make the strategy position track T?

    Thanks,
    Matthew.

    Output from program illustrating that ExitShort(9001) was called but not executed.... [no order was placed into the order list - it is not just that the order did not get filled, there is no ticket to fill].
    /*

    ...

    T:0
    P:-9001
    oldT:-9001
    D:9001
    C:False
    ExitShort(9001)

    T:10000
    P:-9001
    oldT:0
    D:19001
    C:True
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    EnterLong(10000)

    ...

    */
    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
    
    namespace NinjaTrader.Strategy
    {
        [Description("Enter the description of your strategy here")]
        public class trackPosition : Strategy
        {
            #region Variables
            #endregion
    
     
            protected override void Initialize()
            {
                CalculateOnBarClose = true;
            }
    
            int oldT = 0; 
            protected override void OnBarUpdate()
            {
                int T = (int) Math.Floor( 1000.0 * (Close[0]-Close[1]) / TickSize); // target position
                int P = Position.Quantity;
                int side = 0;
                    switch (this.Position.MarketPosition)
                    {
                        case MarketPosition.Short : { side = -1; break;}
                        case MarketPosition.Flat :  { side = 0; break;}
                        case MarketPosition.Long :  { side = 1; break;}
                    }
                P = P * side;
                
    
                int D = T - P;
                bool C = (Math.Sign(P) != Math.Sign(T)) && (T != 0);
                Print("  ");
                Print("T:" + T); // target position
                Print("P:" + P); // Current position
                Print("oldT:" + oldT); // what P should be                
                Print("D:" + D); // Change required
                Print("C:" + C); // Cross to other side?
                if(P != oldT) Print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");                
                oldT = T;    
                if(T > 0) {
                    if (C) {
                        Print ( "EnterLong("+T+")");
                        EnterLong(T);
                    } else {
                        if ( D > 0 ) {
                            Print ( "EnterLong("+D+")");
                            EnterLong(D);
                        }
                        if ( D < 0 ) {
                            Print ( "ExitLong("+(-D)+")");
                            ExitLong(-D);    
                        }
                    }
                }
                if(T < 0) {
                    if (C) {
                            Print ( "EnterShort("+(-T)+")");
                            EnterShort(-T);                        
                    } else {
                        if ( D > 0 ) {
                            Print ( "ExitShort("+D+")");
                            ExitShort(D);
                        }
                        if ( D < 0 ) {
                            Print ( "EnterShort("+(-D)+")");
                            EnterShort(-D);
                        }
                    }
                }
                if(T == 0) {
                    if (P>0) {
                        Print("ExitLong("+(-D)+")");
                        ExitLong(-D);
                    }
                    if(P<0) {
                        Print("ExitShort("+D+")");
                        ExitShort(D);
                    }
                }
            }
    
            #region Properties
            #endregion
        }
    }

    #2
    Hello mtthwbrnd,

    Thank you for your post.

    Positions will need to be synced properly even if using the Sim101 account. Check the settings for submission of Historical orders by clicking tools > Options> Strategies tab, then NinjaScript. Can set the strategy to wait until flat or immediately submit live working historical orders.

    Best approach here is to start simplifying things. Try using hard coded names rather than custom ones.

    If you can provide as simple a scenario as possible to reproduce this, we can better identify what's going on.
    Ryan M.NinjaTrader Customer Service

    Comment


      #3
      "Best approach here is to start simplifying things. Try using hard coded names rather than custom ones."

      I don't know what custom/hard coded names you are talking about. Which names do you mean?

      "If you can provide as simple a scenario as possible to reproduce this, we can better identify what's going on."

      I think this is about as simple as I can make it. The code comes up with a target position T and the rest of the code is attempting to place orders such that the Strategy Position, P, would equal T if the orders got filled immediately.

      If the program ever outputs "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" then a call to EnterLong, ExitLong, EnterShort or ExitShort did not work.

      It is clear from the output that ExitShort(9001) had been called but no corresponding order was placed in the orders tab.

      I have got "Wait Until Flat Before..." selected.

      Have I explained well what I am trying to do with the positions, i.e. I want to make the Strategy Position track the variable T. Is there a standard way to acheive this in NT?

      Thanks,
      Matthew.

      Comment


        #4
        Matthew, is this for NT 65 or 7? There are currently known issues in NT7 when you work with restoring persisted strategies and their positions, we expect it to be resolved in the next update.

        If you have 'Wait Until Flat' selected the strategy would take the next realtime generated entry signal to start executing, I suggest you also add visual checks to all your conditions to debug if / where you run into issues.

        If you look to track a strategy position of another strategy, then this would not be supported as strategies generally do not cross communicate.

        If I misunderstand you, please clarify further.

        Thanks
        BertrandNinjaTrader Customer Service

        Comment


          #5
          Hi Bertrand,

          I think that I did not explain very well what I am trying to do, apologies for any confusion.

          The trading idea I am trying to code up on NT does not define what orders to place. Instead it calculates what position it would like to be holding until the next tick. That is what "T" is in my code.

          As an example I gave a function which swaps sides frequently in order to test the code that places orders:

          Code:
           int T = (int) Math.Floor( 1000.0 * (Close[0]-Close[1]) / TickSize);
          So T is a variable inside OnBarUpdate() which changes on each call. It is the position I would like to obtain asap by placing orders.

          In order to know what orders to place, I need to know what the current Strategy position is:

          Code:
                      int P = Position.Quantity;
                      int side = 0;
                          switch (this.Position.MarketPosition)
                          {
                              case MarketPosition.Short : { side = -1; break;}
                              case MarketPosition.Flat :  { side = 0; break;}
                              case MarketPosition.Long :  { side = 1; break;}
                          }
                      P = P * side;
          P is the current Strategy position and T is the position that I want to hold.

          D = T - P is the change in position that I need to enact. The only thing I can come up with so far to acheive placing the correct orders to enact the change D in the position is by using a set of intricate rules.

          If D < 0 then I will be selling, if D > 0 then I will be buying.
          If P < 0 then I am already short, if P > 0 then I am already long.

          If P > 0 and D < 0 then I will be decreasing a long position so have to ExitLong(-D).

          But, hold on, because if Math.Abs(D) > Math.ABS(P) then I will be exiting the entire long positon and establishing a short position. In that case I have to EnterShort(-T). There are more rules to consider....

          So the rules I came up with are:

          Code:
                      int D = T - P;
                      bool C = (Math.Sign(P) != Math.Sign(T)) && (T != 0);
                      Print("  ");
                      Print("T:" + T); // target position
                      Print("P:" + P); // Current position
                      Print("oldT:" + oldT); // what P should be                
                      Print("D:" + D); // Change required
                      Print("C:" + C); // Cross to other side?
                      if(P != oldT) Print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");                
                      oldT = T;    
                      if(T > 0) {
                          if (C) {
                              Print ( "EnterLong("+T+")");
                              EnterLong(T);
                          } else {
                              if ( D > 0 ) {
                                  Print ( "EnterLong("+D+")");
                                  EnterLong(D);
                              }
                              if ( D < 0 ) {
                                  Print ( "ExitLong("+(-D)+")");
                                  ExitLong(-D);    
                              }
                          }
                      }
                      if(T < 0) {
                          if (C) {
                                  Print ( "EnterShort("+(-T)+")");
                                  EnterShort(-T);                        
                          } else {
                              if ( D > 0 ) {
                                  Print ( "ExitShort("+D+")");
                                  ExitShort(D);
                              }
                              if ( D < 0 ) {
                                  Print ( "EnterShort("+(-D)+")");
                                  EnterShort(-D);
                              }
                          }
                      }
                      if(T == 0) {
                          if (P>0) {
                              Print("ExitLong("+(-D)+")");
                              ExitLong(-D);
                          }
                          if(P<0) {
                              Print("ExitShort("+D+")");
                              ExitShort(D);
                          }
                      }
          The logic of the rules appears to work. The problem occurs when NT ignores an ExitShort or ExitLong call completely, seemingly at random [i.e. I have not worked out yet what triggers that]. It does not happen at the start so I don't think it is to do with the "wait until flat" flag.

          I am using NT7 to do this, but the same problem with the missed ExitShort or ExitLong occurs on NT6.5. I doubt it is a bug, more likely my misunderstanding the mechanics of NT orders.

          I am not restoring positions from persisted strategies, in fact I reset the sim101 account before running this each time.

          If you "paper trade" the strategy code I posted in post number 1 then hopefully you will see what is going on and what is wrong. I set EntriesperDirection = 99999 and use 5 second $GBPUSD bars for the example.

          Basically, I have designed a function which outputs values for T...

          int T = myPositionFunction();

          and the rest of the code in post number 1 is concerned only with trying to place orders such that the strategy position "tracks" T, and it would work were it not for the ignored ExitLong and ExitShort.

          Is there a better way to make the strategy position track the variable T? I'm sure there must be, because what I wrote is still embarrassingly ugly, even if ExitShort did place an order :-(.



          Thanks,
          Matthew.
          Last edited by mtthwbrnd; 04-09-2010, 12:57 PM.

          Comment


            #6
            Matthew,

            You are likely running into issues with signal tracking finding already closed positions. To find out you should use TraceOrders = true and see the ignoral messages for the reasons. If you are trying to manually control these kinds of things you would be better served using Unmanaged orders which will allow you full control without signal tracking rules.
            Josh P.NinjaTrader Customer Service

            Comment


              #7
              With traceorders=true I get output like:

              13/04/2010 15:37:31 CancelAllOrders: BarsInProgress=0
              13/04/2010 15:37:31 Entered internal PlaceOrder() method at 13/04/2010 15:37:31: Action=Sell OrderType=Market Quantity=2,500 LimitPrice=0 StopPrice=0 SignalName='' FromEntrySignal=''
              13/04/2010 15:37:31 Ignored PlaceOrder() method: Action=Sell OrderType=Market Quantity=2500 LimitPrice=0 StopPrice=0 SignalName=Sell' FromEntrySignal='' Reason='There already is a matching, filled exit order in place'
              The problem apparently is that "there is already a matching, filled exit order in place"... what does that mean exactly? How can I find out more about this "filled exit order" that it is moaning about?

              The thing is, I just want it to sell 2500. I don't care about order matching. If it is already long more than 2500, then it should reduce the long position by 2500. If it is already long by less than 2500 then it should close the long and open a short with the balance, if it is short then it should increase the short position by 2500. I have logic in my program to manage this (as posted previously) which correctly (?) results in the selection of ExitLong as the "way to do it".

              How can I tell NT that if the order is ignored then just sell the 2500 anyway? I don't understand this at all + don't think users should be dealing on this low-level. I just want the Strategy Position to track my int variable... This must be a very common requirement for program traders. Maybe "position tracking" functionality should be built into NT?

              Something like:

              NewPosition(int lots) - Will place market orders to try to make the strategy position equal "lots", regardless of what the current position is (long, short or flat, who care, just place the orders which make it equal to lots).

              NewPosition(int lots, OrderType.Limit, double limitPrice) - Will place limit orders to try to make the strategy position equal "lots".

              In trying to write these functions is where I am completely stumped... because everything I try results in exit orders being ignored. Nothing I try ever manages to keep the Strategy Position equal to my int variable. It is incredibly frustrating because I feel it should be easy (which it isn't) + I think I am having to write to much "low level" order management which perhaps NT should be handling (i.e. something like NewPosition(...) should be part of NT).

              thanks,
              Matthew.

              PS. I did not want to start going into SubmitOrder() yet because that seems an even lower level of order management which will introduce a whole new set of problems. Am hoping that I won't have to go there. I did have a little go at it but encountered problems.

              Comment


                #8
                Our managed orders are designed to tie an exit to a specific entry. If you don't want this, the only other option is with unmanaged orders. With managed orders you can't scale out unless you first scale in.

                You can also consider working with Iorder objects. You could then tie your variable count to a filled order state event rather than an Exit() statement that may or may not be filled.
                Ryan M.NinjaTrader Customer Service

                Comment


                  #9
                  Well, this is the best I can come up with at the moment... but it is not good enough. It works sometimes, but not always. Any cancelled orders are not dealt with. So a single cancel or ignore buggers it up completely. It works in the test example given below. It is definitely not stable enough to trade from.

                  Anyway, I am at a point now with NT that I cannot move forward with my project anymore using it. I am completely stumped. I find myself spending more and more and more and more and more time trying to write this low level order mananegement code for an order management system which I barely understand and whose details I don't think a user should need to know on such an intimate level.

                  I need a function that can make the Strategy Position track an integer variable as the below attempts to do. Without it, I cannot proceed using NT.

                  I don't understand why NT does not have a built in function to place orders such that the Strategy Position becomes equal to (tracks) some target int, and I don't understand why it is so difficult to make the Account Position remain equal to the Strategy Position without "waiting to be flat" - i.e. why can't NT just issue balancing orders to make the account position come up-to-date with the strategy position? What if I have an ultra slow system that maintains a long position for months and months? Would I have to wait for months before the yellow will turn green in order to for orders to start flowing?

                  These are two crucial, fundamental, requirements that many types of systematic strategy require. Without them, I don't know how you can trade a system. In fact, can anyone explain to me how you can trade a system without these two requirements being guaranteed? I mean, if you can't guarantee that the Strategy Position equals (tracks) the target position which your trading idea outputs and if you can't make the Account position equal (track) the Strategy Position, then how can you trade your system?

                  Backtesting is fantastic in NT and I managed to confirm my preliminary results from my own intergrator which I wrote in JSoftware. I hoped that by using NT I would avoid writing loads of low level stuff, but as it happens, I find myself now doing just that. But I am not good at that, I am crap at this type of programming. At least it forced me to learn C#, which is a great addition to my CV :-).

                  Moving to the paper trading phase on NT has proven too difficult because of the above issues. Sorry to be negative on this, but I am just so fed up of trying to write this low level order management code. It seems like it is all I do at the moment!

                  What I want is incredibly simple, I think. All I want is for the Strategy Position to track an int variable, but it is proving utterly impossible at the moment. I think the time is rapidly approaching for me to quit trying to move forward with NT and look for alternatives. Although I have no idea what that would be at this stage.

                  For what it is worth, here is the best I can come up with so far. As with all of my attempts at solving this simple problem, it does not work apart from simple test cases. I.e. if I hook it up to my actual strategy then after a while the Strategy Position ends up not equal to the position that I want to be holding and the Account Position ends up not equal to the Strategy Position. As I say, I do not understand why any systematic trader would ever want his Account Position to not be equal to his Strategy Position unless he was not a bona fida systematic trader and instead was mixing in some discretion.

                  The entire thing boils down to trying to provide a function:
                  Code:
                  void changePositionTo(int newPosition, double limitPrice)
                  which can be called and results in orders being generated such that the Strategy Position would equal newPosition if all of the orders got filled.

                  I think that NT should have such a function built-in as part of the high-level order management system.

                  Comment


                    #10
                    1st part of code:

                    Code:
                    /*
                    Class to do position tracking. I.e. Place managed orders such that the  Strategy Position tracks a variable.
                    */
                    
                    
                    #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;
                    using System.Collections.Generic;
                    #endregion
                    
                    namespace NinjaTrader.Strategy
                    {
                        public class trackPosition : Strategy
                        {
                            #region Variables
                            #endregion
                    
                    
                             public class positionTracker {
                                public class block {
                                    string _name;    // name of this block
                                    int _side;        // +1,0 or -1
                                    int _size;        // size of this block
                                    IOrder _entryOrder; // NT order for this block
                                    public string name { get {return _name; } }
                                    public int side { get {return _side;} }
                                    public int size { get { return _size;} }
                                    public IOrder entryOrder { get { return _entryOrder;} }
                                    public block() {
                                        _name = "";
                                        _side = 0;
                                        _size = 0;
                                        _entryOrder = null;
                                    }
                                    public block(string name, int size, int side, IOrder  entryOrder) {
                                        this._name = name;
                                        this._side = side;
                                        this._size = size;
                                        this._entryOrder = entryOrder;
                                    } 
                                }
                                Stack<block> _blocks;    // list of blocks comprising  current net position
                                int _side;                // side of the net position
                                int _size;                // size of the net position
                                Strategy _so;            // internal pointer to the NT  strategy
                                int _uniqueInt;            // provides a unique tag for  every potential order/block
                                bool _verbose;             // dump tracking info for  debugging
                                public Stack<block> blocks { get { return _blocks; }}
                                public int side {get {return _side; }}
                                public int size {get {return _size; }}
                                public bool verbose { get {return _verbose;} set { _verbose =  value; }}
                                public Strategy so { get { return _so; }} 
                                public int uniqueInt {get {return _uniqueInt; }}            
                                public positionTracker(Strategy strategyObject) {
                                    _blocks = new Stack<block>();
                                    _side = 0;
                                    _size = 0;
                                    _so = strategyObject;
                                    _uniqueInt = 0;
                                }
                                public void changePositionTo(int newPosition) {
                                    changePositionTo(newPosition, 0);
                                }
                                public void changePositionTo(int newPosition, double  limitPrice) {
                                    int newSize = Math.Abs(newPosition);
                                    int newSide = Math.Sign(newPosition);
                                    if (newSize == 0 ) newSide = 0;
                                    
                                    // determine which of the eight actions is to be  undertaken
                                    bool creatingLong = false;
                                    bool creatingShort = false;
                                    bool closingLong = false;
                                    bool closingShort = false;
                                    bool increasingLong = false;
                                    bool reducingLong = false;
                                    bool increasingShort = false;
                                    bool reducingShort = false;
                                    bool closingLongOpeningShort = false;
                                    bool closingShortOpeningLong = false;
                                    
                                    if ( (side == 0) && (newSide > 0) )  creatingLong = true;
                                    if ( (side == 0) && (newSide < 0) )  creatingShort = true;
                                    
                                    if ( (side > 0) && (newSide == 0) )  closingLong = true;
                                    if ( (side < 0) && (newSide == 0) )  closingShort = true;
                    
                                    if ( (side > 0) && (newSide > 0)  && (newSize > size) ) increasingLong = true;
                                    if ( (side > 0) && (newSide > 0)  && (newSize < size) ) reducingLong = true;
                    
                                    if ( (side < 0) && (newSide < 0)  && (newSize > size) ) increasingShort = true;
                                    if ( (side < 0) && (newSide < 0)  && (newSize < size) ) reducingShort = true;
                    
                                    if ( (side > 0) && (newSide < 0) )  closingLongOpeningShort = true;
                                    if ( (side < 0) && (newSide > 0) )  closingShortOpeningLong = true;
                                    
                                    // generate a unique new signal name which may or may  not be used
                                    _uniqueInt += 1;
                                    string signalName = so.Instrument.FullName + "_" +  Convert.ToString(uniqueInt);
                                    
                                    bool market = limitPrice == 0;
                                    
                                    if (creatingLong) {
                                        if(verbose) so.Print ( "creatingLong");
                                        if (market) 
                                            blocks.Push( new block(signalName, newSize,  newSide, so.EnterLong(newSize, signalName)));
                                        else
                                            blocks.Push( new block(signalName, newSize,  newSide, so.EnterLongLimit(newSize, limitPrice, signalName)));
                                    }
                                    
                                    if (creatingShort) {
                                        if(verbose) so.Print ( "creatingShort");
                                        if (market) 
                                            blocks.Push( new block(signalName, newSize,  newSide, so.EnterShort(newSize, signalName)));
                                        else
                                            blocks.Push( new block(signalName, newSize,  newSide, so.EnterShortLimit(newSize, limitPrice, signalName)));
                                    }

                    Comment


                      #11
                      2nd part of code [due to chacracter limit]:

                      Code:
                               
                                      if (closingLong) { 
                                          if(verbose) so.Print ( "closingLong");
                                          for (int i = 0; i<blocks.Count; i++) if (market)   so.ExitLong(blocks.Pop().name); else so.ExitLongLimit(limitPrice,   blocks.Pop().name);
                                      }
                                      
                                      if (closingShort) {
                                          if(verbose) so.Print ( "closingShort");
                                          for (int i = 0; i<blocks.Count; i++) if (market)   so.ExitShort(blocks.Pop().name); else so.ExitShortLimit(limitPrice,   blocks.Pop().name);
                                      }
                                      
                                      if (increasingLong) {
                                          if(verbose) so.Print ( "increasingLong");
                                          if (market)
                                              blocks.Push(new block( signalName, newSize-size,   1, so.EnterLong( newSize-size, signalName)));
                                          else 
                                              blocks.Push(new block( signalName, newSize-size,   1, so.EnterLongLimit( newSize-size, limitPrice, signalName)));
                                      }
                      
                                      if (increasingShort) {
                                          if(verbose) so.Print ( "increasingShort");
                                          if (market)
                                              blocks.Push(new block( signalName, newSize-size,   1, so.EnterShort( newSize-size, signalName)));
                                          else
                                              blocks.Push(new block( signalName, newSize-size,   1, so.EnterShortLimit( newSize-size, limitPrice, signalName)));
                                      }
                                      
                                      if (reducingLong) {
                                          if(verbose) so.Print ( "reducingLong");
                                          int remaining = size - newSize;
                                          while ( remaining > 0 ) {
                                              if(verbose) so.Print("remaining lots: " +   remaining);
                                              block tp = blocks.Pop();
                                              if(verbose) so.Print("tp.name:" + tp.name + "    tp.size:" + tp.size);
                                              if (tp.size < remaining ) {
                                                  if(verbose) so.Print("exiting a full block   ");
                                                  remaining = remaining - tp.size;
                                                  if (market) so.ExitLong(tp.name); else   so.ExitLongLimit(limitPrice, tp.name);
                                              } else {
                                                  if(verbose) so.Print ("Exiting partial block   " + tp.name + " and entering " + tp.name);
                                                  if (market) 
                                                      blocks.Push(new block(tp.name,   tp.size-remaining, 1, so.ExitLong(remaining, tp.name, tp.name)));
                                                  else
                                                      blocks.Push(new block(tp.name,   tp.size-remaining, 1, so.ExitLongLimit(remaining, limitPrice, tp.name,   tp.name)));                            
                                                  if (blocks.Peek().size == 0) { if(verbose)   so.Print("killing zero size block"); blocks.Pop(); }
                                                  remaining = 0;
                                              }
                                          }
                                      }
                                      if (reducingShort) {
                                          if(verbose) so.Print ( "reducingShort");
                                          int remaining = size - newSize;
                                          while ( remaining > 0 ) {
                                              if(verbose) so.Print("remaining lots: " +   remaining);
                                              block tp = blocks.Pop();
                                              if(verbose) so.Print("tp.name:" + tp.name + "    tp.size:" + tp.size);
                                              if (tp.size < remaining ) {
                                                  if(verbose) so.Print("exiting a full block   ");
                                                  remaining = remaining - tp.size;
                                                  if (market) so.ExitShort(tp.name); else   so.ExitShortLimit(limitPrice, tp.name);
                                              } else {
                                                  if(verbose) so.Print ("Exiting partial block   " + tp.name + " and entering " + tp.name);
                                                  if (market) 
                                                      blocks.Push(new block(tp.name,   tp.size-remaining, 1, so.ExitShort(remaining, tp.name, tp.name)));
                                                  else 
                                                      blocks.Push(new block(tp.name,   tp.size-remaining, 1, so.ExitShortLimit(remaining, limitPrice, tp.name,   tp.name)));
                                                  if (blocks.Peek().size == 0) { if(verbose)   so.Print("killing zero size block"); blocks.Pop(); }
                                                  remaining = 0;
                                              }
                                          }
                                      }
                                      if (closingLongOpeningShort) {
                                          if(verbose) so.Print ( "closingLongOpeningShort");
                                          blocks.Clear();
                                          if (market)
                                              blocks.Push( new block(signalName, newSize, -1,   so.EnterShort(newSize, signalName)));
                                          else 
                                              blocks.Push( new block(signalName, newSize, -1,   so.EnterShortLimit(newSize, limitPrice, signalName)));                          
                                      }
                                      if (closingShortOpeningLong) {
                                          if(verbose) so.Print ( "closingShortOpeningLong");
                                          blocks.Clear();
                                          if (market)
                                              blocks.Push( new block(signalName, newSize, 1,   so.EnterLong(newSize, signalName)));
                                          else 
                                              blocks.Push( new block(signalName, newSize, 1,   so.EnterLongLimit(newSize, limitPrice, signalName)));
                                      }
                                      _size = newSize;
                                      _side = newSide;
                                  }
                              }
                          
                              
                              positionTracker PT;
                              protected override void Initialize()
                              {
                                  CalculateOnBarClose = true;
                                  TraceOrders = true;
                                  EntriesPerDirection = 999999;
                                  ExitOnClose = false;
                                  timeCounter = 0;
                                  
                              }
                      
                              int oldT = 0;
                              int timeCounter;
                              protected override void OnBarUpdate()
                              {
                                  int T = (int) Math.Floor( 1000.0 * (Close[0]-Close[1]) /   TickSize); // "random" target positions for testing
                                  if( timeCounter == 0) { T = 0; PT = new   positionTracker(this); }    // on first call, create the  positiontracker
                                  
                                  // for first 16 calls do these position changes (just for   testing)
                                  if( timeCounter == 1) T = 1000;
                                  if( timeCounter == 2) T = 2000;
                                  if( timeCounter == 3) T = 3000;
                                  if( timeCounter == 4) T = 2500;
                                  if( timeCounter == 5) T = 1000;
                                  if( timeCounter == 6) T = 0;
                                  if( timeCounter == 7) T = -1000;
                                  if( timeCounter == 8) T = -2000;
                                  if( timeCounter == 9) T = -3000;
                                  if( timeCounter == 10) T = -2500;
                                  if( timeCounter == 11) T = -1000;
                                  if( timeCounter == 12) T = 0;
                                  if( timeCounter == 13) T = -10000;
                                  if( timeCounter == 14) T = 10000;
                                  if( timeCounter == 15) T = -10000;
                                  if( timeCounter == 16) T = 0;
                                  
                                  timeCounter += 1;
                                  Print("");
                                  Print("blocks:");
                                  foreach ( positionTracker.block tp in PT.blocks )   Print(tp.name + " " + tp.side + " " + tp.size);
                              
                                  Print("Target position:" + T + "     current position:" +   Position.Quantity + " " +  Position.MarketPosition);
                                  PT.changePositionTo(T);
                                  
                              }    
                              #region Properties
                              #endregion
                          }
                      }

                      Comment


                        #12
                        Hello Matthew,

                        Thanks for your suggestion on a method that would track this.

                        You will likely need to simplify your code in order to better understand the framework.

                        You can consider using the statement if (Historical) return; so that your strategy will only run on Real Time data. This might make it easier for you to track what's happening.

                        Generally NT support does not offer strategy debugging, but you may consider hiring a 3rd party NinjaScript consultant who can be hired for this purpose.
                        Last edited by NinjaTrader_RyanM1; 04-14-2010, 09:30 AM.
                        Ryan M.NinjaTrader Customer Service

                        Comment


                          #13
                          Hi Ryan,

                          I can simplify things...

                          Code:
                                protected override void OnBarUpdate()
                                  {
                                      int thePositionIWantToHold = (int) Math.Floor( 1000.0 * (Close[0]-Close[1]) / TickSize); // "random" target positions for testing
                                      
                                      // What sequence of EnterLong, ExitLong, EnterShort, ExitShort calls 
                                      // need to go here in order to make the Position.Quantity  equal to Math.Abs(thePositionIWantToHold)
                                      // and the Position.Side equal to Math.Sign(thePositionIWantToHold)?
                                      
                                      
                                  }    
                              }
                          What sequence of EnterLong etc... calls need to go in OnBarUpdate() to spit out the orders that will make the Strategy.Position track the integer thePositionIWantToHold?

                          Thanks,
                          Matthew.
                          Last edited by mtthwbrnd; 04-14-2010, 10:07 AM.

                          Comment


                            #14
                            Hi Matthew,

                            The issue here is that EnterLong(), ExitLong(), etc do not imply a fill. There is not a correct sequence if orders are not submitted, not filled, or cancelled.

                            You could try adding a check for the value of T to your conditions for entries. This would allow you to better follow this variable and not submit orders if T is not what you expect.
                            Ryan M.NinjaTrader Customer Service

                            Comment


                              #15
                              T is always what I expect, it is the input variable! It is calculated in the first line of OnBarUpdate().

                              The initial issue is not that fills do not happen. The issue is, what is the correct sequence of EnterLong, ExitLong etc..., assuming that all orders get filled, which will avoid ignored orders?

                              In my attempts, I first check what is the current position Position.Quantity and Position.Side and compared these to T in order to try to work out what orders I need to place such that if they were all filled (assumption) then the position would become equal to (i.e. track), T.

                              There is no problem if orders do not get filled because in each call to OnBarUpdate(), T is recalculated and can be compared with Position.Quantity and Position.Side to determine what orders to place.

                              Those are only changed due to filled orders. Unfilled orders will lead to a slight "tracking error". If you go in too far outside of bid/ask then your orders will not be filled and you will have a huge tracking error, if you are generous and always take the book, then you will have minimal tracking error. But regardless of that, there is a correct sequence of ExitLong, EnterLong etc... that should in principle obtain tracking. Do you agree?

                              The thing is, the hypothetical "changePositionTo" function is not some complicated, esoteric, wacky idea... it is one of the most fundamental functions that a systematic trader needs in order to trade his strategy.

                              It is the function that takes care of the orders to make sure that the position is as close as possible (notwithstanding tracking errors) to the value that his idea wants the position to be. That is why I cannot understand why this function is not already in NT. It's abscence leads me to wonder about the types of strategies that people use NT to trade, because they cannot be of the type which outputs an "optimal position", f(t) based on analysis of historical prices p(t-1), p(t-2)... since there is no way to make the positions track f(t).

                              Thanks,
                              Matthew.

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by fx.practic, 10-15-2013, 12:53 AM
                              5 responses
                              5,404 views
                              0 likes
                              Last Post Bidder
                              by Bidder
                               
                              Started by Shai Samuel, 07-02-2022, 02:46 PM
                              4 responses
                              95 views
                              0 likes
                              Last Post Bidder
                              by Bidder
                               
                              Started by DJ888, Yesterday, 10:57 PM
                              0 responses
                              8 views
                              0 likes
                              Last Post DJ888
                              by DJ888
                               
                              Started by MacDad, 02-25-2024, 11:48 PM
                              7 responses
                              159 views
                              0 likes
                              Last Post loganjarosz123  
                              Started by Belfortbucks, Yesterday, 09:29 PM
                              0 responses
                              8 views
                              0 likes
                              Last Post Belfortbucks  
                              Working...
                              X