Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Testing risk management strategy using historical data

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

    Testing risk management strategy using historical data

    Hi

    I need to test the risk management logic within a strategy which calculates the size of a position as a percentage of the account's cash value.
    This seems to be a fairly straight forward process when using real time data, however, back testing using historical data is proving troublesome.
    I need to be able to access the current account's Cash Value. I am aware that the Cash Value in back testing remains constant to what ever the Sim101 account value was initially set to. I am trying to code an alternative method which can be used during back testing only to determine the effectiveness of the risk management logic by getting the strategy go keep track of the cash value of the account as the back test is running.
    There are various methods of achieving this. Eg. Accessing the open positions profit and loss value, entry/exit price, etc and adding it to a custom series created in the logic.
    In my attempts, I have found that Position.AveragePrice and Position.GetUnrealizedProfitLoss() only ever yield a value of 0.
    Using Account.Get() with the various account items available to retrieve has not been working either with back testing.
    Is there any other way that I can retrieve this kind of data during historical back testing?

    #2
    Hello JulieV,

    You can get the current real-time value of the account using <account>.Get().


    You could then assign that to a variable and add or remove the pnl from that starting value.
    Hello, I've updated the DailyLossLimit and DailyLosLimitMultiTrade examples that were posted on the forum for NinjaTrader 7 for NinjaTrader 8. These are often requested and I felt they are good examples to have for NT8. DailyLossLimitExample_NT7 - http://ninjatrader.com/support/forum...241#post451241 (http://ninjatrader
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      Thanks, Chelsea.
      I created the below method to add the pnl of a position to a series called totalPnL. The method runs, just before the logic that closes the position.

      private double AddNewPnL()
      {
      Print("Position's pnl = " + Position.GetUnrealizedProfitLoss(PerformanceUnit.C urrency, Close[0]));
      return totalPnL[0] = totalPnL[1] + Position.GetUnrealizedProfitLoss(PerformanceUnit.C urrency, Close[0]);
      }

      From the above method's Print statement, I can see that the position's PnL value is accessed but when I do a print statement straight after this method runs in the OnBarUpDate(), it returns a value of 0 for the totalPnL[0].

      Any suggestions what I am doing wrong here?
      Many thanks

      Comment


        #4
        Hello JulieV,

        OnBarUpdate and other data driven methods are asynchronous with order methods and events. It takes some time for an order to be submitted, accepted, working, filled, and then takes some time for the order to be updated and then for the position to be changed. So you may need to wait a few ticks or a bar in OnBarUpdate for that all to happen.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Hi ChelseaB
          I worked out where my initial error was and things are working out a lot better.
          The only thing I am still stuck on is when a position is closed when it hits the stop loss set in State.Configure.

          else if (State == State.Configure)
          {
          SetStopLoss(CalculationMode.Percent, 0.07);
          }

          The logic used to keep a running total of the total PnL of all the positions sits in the OnBarUpdate() and obviously doesn't execute when a stop loss is hit resulting in the PnL total not updating for that position causing an incorrect total PnL.
          Can you suggest a work around please?

          Comment


            #6
            Hello JulieV,

            When a stop loss fills this will change the position. On the next update of OnBarUpdate after the position has changed you will be able to see the change with the Position.MarketPosition object.

            If you want to trigger an action at the moment the positions changes put that code in OnPositionUpdate(). If you want to trigger an action when the stop loss fills, put that logic in OnOrderUpdate() / OnExecution().

            SetStopLoss() cannot be unset. When this is set in State.Configure the order is not actually being submitted. Instead this is setup to be ready for an entry order to fill. When the entry order fills, the stop loss is immediately submitted using whatever it was last set to. (This is why its important to call SetStopLoss() before placing an order and not after when dynmically changing the price of a stop loss. When a new entry fills, the stop loss will still be using whatever it was last called with)

            But once the entry is filled the stop loss is immediately submitted and will be working. When the stop loss fills, this triggers the Position to change and all of the order driven methods to trigger just like any other order.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Hi ChelseaB
              Would it be better practice to rather put the stop loss logic in the OnExecutionUpdate() rather than fix it in the State.Configure section?

              I am also interested in looking at scaling into and out of positions. Would this logic be best to add also in the OnExecutionUpdate() rather than OnBarUpdate()?

              Comment


                #8
                Hello JulieV,

                Elaborating on Chelsea's response in post #6, Set methods will prep NinjaTrader so the next tied entry that fills will then have NinjaTrader submit the stop loss to that level. Set methods should only be used in State.Configure/State.DataLoaded for static stop levels or used in OnBarUpdate for dynamic levels.

                You can submit Exit methods in OnExecutionUpdate to submit your stop loss and this will give you more direct control over submitting the stop loss. Generally I would recommend using these methods instead of the Set methods if you are comfortable using the Advanced Order Handling methods.

                Scaling in and out of positions would also be out of preference for how you want to scale in and out. If you want to update/submit new orders upon the fill of an order, OnExecutionUpdate can be used. If you want to update orders after a data update, OnBarUpdate would be used.

                I have included a link to our SampleOnOrderUpdate strategy which can further demonstrate using OnOrderUpdate/OnExecutionUpdate for managing Profit Target and Stop Loss orders.

                SampleOnOrderUpdate - https://ninjatrader.com/support/help...and_onexec.htm

                Please let us know if we can be of further assistance.
                JimNinjaTrader Customer Service

                Comment


                  #9
                  Thanks, Jim.
                  I would like to just make sure my understanding of a few things are correct.
                  1. If I use the Set methods in OnBarUpdate(), these methods will run once per bar. If, eg. the %loss condition is met in the middle of the bar, nothing will happen until the OnBarUpdate() runs.
                  2. If the Set methods are set in the State.Configure/State.DataLoaded, as soon as the %loss condition is met, the position will be closed. However, no other conditions can be added or changed, ie not dynamic.
                  3. All other types of Exit methods is best used in OnExecutionUpdate() as this is the best method to deal with advanced order handling. This is especially important when eg. a second position is added to the first for scaling in or if a portion of a position is sold to scale out of a position.

                  Comment


                    #10
                    I forgot to add in point 3. My understanding is that OnExecutionUpdate() runs when ever something in an open position changes. OnOrderUpdate() runs when ever something changes in a submitted order or open position.

                    Comment


                      #11
                      Hello JulieV,

                      With point 1, calling a Set method in OnBarUpdate when you are in a position will update the target/stop on each bar/tick/price change. Calling it when flat in OnBarUpdate will prep the next entry to have targets and stops submitted at an appropriate level once that entry fills.

                      The %loss condition would be factored into the order submission, and the order would be filled be either the simulation engine or an exchange.

                      The simulation engine is external to the strategy and does not run OnBarUpdate, but does use the OHLC data from that data series to simulate order fills for historical processing. Realtime order simulations will use current bid/ask data. I've included two documentation pages that go further into depth on order fill simulations and how you can expect them to work.

                      Discrepancies between realtime and backtest - https://ninjatrader.com/support/help...ime_vs_bac.htm

                      Understanding Historical Fill Processing - https://ninjatrader.com/support/help...ical_fill_.htm

                      To elaborate and address point 2, calling the Set method in State.Configure/State/DataLoaded will have this method called once before the script starts processing OnBarUpdate. The Target and Stop orders will then be submitted when associated entries fill. If these methods are not called again, they will not change dynamically. When/how the order fills depending on if you are using historical data, simulating with realtime data, or using the exchange to fill the order under their rules.

                      To address point 3, using the Advanced Order Handling methods is good as they give you more direct control of the strategy, but I may not necessarily say these would be especially important when scaling in/out since you can create new EntrySignals/FromEntrySignals when creating new positions with the Set methods. The Advanced Order Handling methods simply give you more direct control of when to do things.

                      OnExecutionUpdate and OnOrderUpdate will update on Execution events and OrderUpdate events which are when a position changes and when an order state updates or that order gets submitted/changed/updated/filled/cancelled. I may suggest testing a strategy with prints added to the OnOrderUpdate and OnExecutionUpdate method to see what goes through and better learn how they can be used.

                      Code:
                      protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity,
                          Cbi.MarketPosition marketPosition, string orderId, DateTime time)
                      {
                          Print(execution.ToString());
                      }
                      
                      protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice,
                          int quantity, int filled, double averageFillPrice,
                          Cbi.OrderState orderState, DateTime time, Cbi.ErrorCode error, string comment)
                      {
                          Print(order.ToString());
                      }
                      Please let us know if you have any questions.
                      JimNinjaTrader Customer Service

                      Comment


                        #12
                        Hi Jim
                        Thanks for the detailed response. Much appreciated.

                        Comment

                        Latest Posts

                        Collapse

                        Topics Statistics Last Post
                        Started by KenneGaray, Today, 03:48 AM
                        0 responses
                        3 views
                        0 likes
                        Last Post KenneGaray  
                        Started by thanajo, 05-04-2021, 02:11 AM
                        4 responses
                        470 views
                        0 likes
                        Last Post tradingnasdaqprueba  
                        Started by aa731, Today, 02:54 AM
                        0 responses
                        4 views
                        0 likes
                        Last Post aa731
                        by aa731
                         
                        Started by Christopher_R, Today, 12:29 AM
                        0 responses
                        10 views
                        0 likes
                        Last Post Christopher_R  
                        Started by sidlercom80, 10-28-2023, 08:49 AM
                        166 responses
                        2,237 views
                        0 likes
                        Last Post sidlercom80  
                        Working...
                        X