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

interested in collaboration with other users to refine some code.

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

  • NinjaTrader_ChelseaB
    replied
    Hello rtwave,

    I'm seeing in the output that the order pustlopuen01 may be getting ignored. (Ignored order TraceOrder messages appear after the first violation and tend not to show for subsequent violations)

    05/03/2021 17:00:00 Strategy 'onorderupdatetests001/-1': Entered internal SubmitOrderManaged() method at 05/03/2021 17:00:00: BarsInProgress=0 Action=Sell OrderType=StopMarket Quantity=1 LimitPrice=0 StopPrice=2196.9 SignalName='pustlopuen01' FromEntrySignal='lopuen01'
    05/03/2021 17:00:00 Strategy 'onorderupdatetests001/-1': Ignored SubmitOrderManaged() method at 05/03/2021 17:00:00: BarsInProgress=0 Action=Sell OrderType=StopMarket Quantity=1 LimitPrice=0 StopPrice=2196.9 SignalName='pustlopuen01' FromEntrySignal='lopuen01' Reason='Invalid order price, please see log tab'

    This order was ignored once, which implies that it is may be ignored many times, and may have been ignored at on 20-03-2020 at 14:00 as the order is never accepted and does not become working.

    20/03/2020 14:00:00 Strategy 'onorderupdatetests001/-1': Entered internal SubmitOrderManaged() method at 20/03/2020 14:00:00: BarsInProgress=0 Action=Sell OrderType=StopMarket Quantity=1 LimitPrice=0 StopPrice=1037.4 SignalName='pustlopuen01' FromEntrySignal='lopuen01'
    20/03/2020 17:00:00 Strategy 'onorderupdatetests001/-1: Cancelled pending exit order, since associated position is closed, orderId='NT-00049-25680' account='Backtest' name='pustlopuen01' orderState=Working instrument='M2K 09-21' orderAction=Sell orderType='Stop Market' limitPrice=0 stopPrice=1037.4 quantity=1 tif=Gtc oco='' filled=0 averageFillPrice=0 onBehalfOf='' id=-1 time='2020-03-20 14:00:00' gtd='2099-12-01' statementDate='2021-09-12'

    Is pustlopuen01 being submitted from OnExecution() when the entry lopuen01 fills, or is this being submitted in OnBarUpdate()?
    (It looks like the stop is being submitted one hour later, which would imply Calculate is OnBarClose and the order is being submitted from OnBarUpdate())

    Are you confirming that the sell stop price is at least 1 tick less than GetCurrentBid() at the time the stop is submitted?

    Leave a comment:


  • rtwave
    replied



    people with nt,



    the text files with the nt output are in the zip file i uploaded in the previous post as an attachment, and on this post as well.


    the pullback entry reported on 20-03-2020 at 14:02 ended up in a loss of $388 usd, when the stop loss order in the strategy should keep the maximum loss at $42 usd.


    and other entries end up in losses far larger than what the stop loss should keep them to. in this particular case there are only 7 trades with very large losses, but with other strategies i have there are a very high number of such losses above what the stop loss orders should keep them to.


    i'm trying to define a maximum risk for the initial entry, and if there is an attractive pullback, to add an additional contract, but always keeping the monetary value at risk the same. obviously, if the stop loss orders are not working, then this completely defeats this idea.






    Attached Files

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello rtwave,

    I am happy to take a look at the output text files. Please attach these with your next post.

    What is the date and time of the first order we will focus on?

    Leave a comment:


  • rtwave
    replied



    people with nt,



    i have made some changes to my experimental onorderexecutionupdate strategies.


    i have managed to add prints to the sections that are the most problematic.


    i have uploaded the nt output for two backtests. the seven trades below which lost more than $204 usd are the cases where the stop loss orders failed to work for the strategy with two entry orders. i used two contracts for the ordinary initial entry and only one contract for the pullback entry, this to make it easier to identify each of the entries in the strategy analyzer and output logs.




    Click image for larger version

Name:	20210912 stops not working 0001.JPG
Views:	182
Size:	361.0 KB
ID:	1171089


    i also include the same output for the same strategy with the same parameters but with the second entry disabled. in that case, the stop loss orders never failed. this is something i had observed and documented in the two threads i have created dealing with this issue.


    this is a malfunction of the nt platform as far as i can tell, hopefully nt support can finally take a look at this information and propose a solution to these failures.


    very well, regards.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello rtwave,

    It is recommended that when testing for a specific issue, reduce the amount of data. Reduce the iterations in an optimization to as few as possible that can still reproduce the behavior, or just run a single backtest. Reduce the amount of days in the backtest as much as possible while still being able to reproduce the behavior.

    If this is still too much output, see if the prints can be more focused in the code, such as printing within a datetime condition to filter out other days and focus on a specific event in question.


    Or write the information to a text file with StreamWriter.
    Citizens of the NinjaTrader Community, A common question we hear from clients is 'why are results from backtest different from real-time or from market replay?'. Live orders are filled on an exchange with a trading partner on an agreed upon price based on market dynamics. Backtest orders are not using these market dynamics.


    Below are links to the help guide that have code examples of overriding OnOrderUpdate() and OnExecutionUpdate().



    To print the order object:
    Code:
    protected override void OnOrderUpdate(Cbi.Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, Cbi.OrderState orderState, DateTime time,  bi.ErrorCode error, string comment)
    {
    [B]Print(order.ToString());[/B]
    }
    To print the execution object:
    Code:
    protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time)
    {
    [B]Print(execution.ToString());[/B]
    }

    Leave a comment:


  • rtwave
    replied



    people with nt,



    i just discovered nt ninjascript output windows. there's very interesting information there. when i run an optimization the window will be saturated with thousands of lines of traceorders information, ¿how can i share this with nt support?



    and i need an example of how to print the code inside onorderupdate. nt support has suggested multiple times in this thread that i:

    "Enable TraceOrders, print the order object in OnOrderUpdate(), and print the price supplied to the order along with the time of the bar."

    but it is obvious that anyone who is not an experienced ninjascript programmer would never have any idea of how to do this. ¿can nt provide an example of how to print all the objects inside onorderupdate and onexecutionupdate (specially the exit-stopmarket orders)? the only samples that exist all deal with printing the entry conditions for the same old and tired nt sample sma crossover strategy but that has nothing to do with more advanced methods that are not covered or discussed anywhere.


    very well, regards.

    Leave a comment:


  • NinjaTrader_BrandonH
    replied
    Hello rtwave,

    Thanks for your note.

    This is Brandon responding on behalf of Chelsea who is out of the office at this time.

    if nt has any videos for how to debug code and how to use traceorders, onorderupdate and onexecutionupdate

    Please see this debugging video created by my colleague Jim which demonstrates debugging using prints and TraceOrders: https://drive.google.com/file/d/1rOz...w?usp=drivesdk

    Prints are used to understand why the script is behaving as it is, such as placing orders or not placing orders when expected. Prints would be added to a script to print the values used for the logic of the script to understand how the script is evaluating. In the strategy, add prints (outside of any conditions) that print the values of every variable used in every condition that places an order along with the time of that bar. A simple example could be seen below. This print will tell you what the Close and Open values are and can tell you why the condition below has/has not become true.

    Code:
    Print("Close: " + Close[0] + " Open: " + Open[0]);
    if (Close[0] > Open[0])
    {
        ...
    }
    Debugging Tips: https://ninjatrader.com/support/help...script_cod.htm

    TraceOrders could be used to check for messages saying that orders are being ignored and not being submitted when the condition to place the orders is evaluating as true. This may happen when there is an issue where the strategy is hitting an internal rule that is not allowing you to re-enter. TraceOrders could be enabled in the strategy (set in State.SetDefaults) so it prints its order feedback, and you may also observe the log tab of the Control Center for additional hints.

    TraceOrders: https://ninjatrader.com/support/help...aceorders2.htm

    Please see the example script, SampleOnOrderUpdate, linked here which demonstrates using the OnOrderUpdate() and OnExecutionUpdate() methods: https://ninjatrader.com/support/help...and_onexec.htm

    The way this script work is an entry market order is submitted if we currently don't have an entry order open.

    In OnOrderUpdate() we check to see if the name of the order matches the signal name of the order and we assign the order to our order object. Then we check if the OrderState is canceled without any fill and reset the order object. This is done for both entry orders, MyEntry and MyEntry2

    In OnExecutionUpdate() we check if our order object is not null and if the order object matches the executed order. A condition is made to check if the OrderState is filled, part-filled, canceled, or filled and we sum up the quantities of each execution making up the entry order and assign it to sumFilled. Next, we check if there are partial fills and submit exit orders for those partial fills or if the orders are filled and the execution quantities match order quantities then we update our exit order quantities. We then reset the order object and the sumFilled counter to null after each order has been filled. This is done for both entry orders, My Entry and MyEntry2. At the end of OnExecutionUpdate() we reset our stop orders and target orders' order objects after the position is closed.

    OnOrderUpdate(): https://ninjatrader.com/support/help...rderupdate.htm
    OnExecutionUpdate(): https://ninjatrader.com/support/help...tionupdate.htm

    Let us know if we may assist further.

    Leave a comment:


  • rtwave
    replied


    people with nt,



    i haven't been able to hire a programmer to help with the functionality i have been working on. i wrote to 8 - 10 programmers but only received 2 replies and 1 single quote. i work directly on nt's samples and it typically takes me 10 minutes or so to create or modify strategies, surprisingly the programmers i wrote to said my strategy would take several hours to create.


    now, once i saw that i wasn't making much progress on that front, i have been studying the resources that nt makes available and there are some videos which are magnificent. i have watched 3 videos that are among the results when one searches for nt + print or nt + traceorders. these videos are great, i really wish i had started by watching them when i first started trying to code on nt as i have learned most of the information covered there by trial and error.


    if nt has any videos for how to debug code and how to use traceorders, onorderupdate and onexecutionupdate i will be very interested in studying them.


    in the case of the code that i can't make work, i understand that it is the exit - stop loss orders that stop working after the second entry is executed. ¿am i supposed to print everything that is inside the order and execution methods? ¿can nt provide examples of how to do this? same with traceorders, if i enable this functionality in my strategies, ¿how can access this data when running optimization processes in strategy analyzer windows?



    very well, regards.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello rtwave,

    Debugging and gaining understanding with Print() and TraceOrders is really the only way to move forward. Trying different things doesn't give you an understanding of what is going wrong with the existing code.

    If you are not wanting to debug the script using TraceOrders and Print() yourself with our guidance and resolve the issue, you can also contact a professional NinjaScript Consultant who would be eager to create or modify this script at your request or assist you with your script. The NinjaTrader Ecosystem has affiliate contacts who provide educational as well as consulting services. Please let me know if you would like our NinjaTrader Ecosystem team follow up with you with a list of affiliate consultants who would be happy to create this script or any others at your request or provide one on one educational services.

    That said, we can get to the bottom of this with TraceOrders and prints.

    May I have you start by enabling TraceOrders and providing the output from this?

    As a suggestion, when debugging it is important to reduce variables, and reduce the amount of data being tested over, to focus on a smaller amount of output from TraceOrders and Print() and only focus on one issue at a time. Try testing over a much smaller data set and focus on a specific order that is not being submitted when expected.

    Leave a comment:


  • rtwave
    replied



    people with nt,



    i do not have any trace logs or prints for these strategies i'm working on. the data i have been working on goes from 202001 to 202106 and there are barely 30 pullback entries that have the characteristic i'm interested in over all that time. it would be impossible to evaluate whether these strategies are functioning as intended on simulator as it could take weeks to observe just one pullback like the ones i have in my strategies, what i do have are backtests and optimizations.


    and from those optimizations i can conclude that set stops do work without problem but exit orders would be better because those could allow for more flexibility in the number of contracts for each entry and would make the calculations of the number of ticks for each stop much easier.


    i have created another version of my experimental strategy and i have found that two sets of entry and exit orders do work without problem, provided that the two entries happen at the same time:



    // Set 1
    if (Close[0] < EMA1[0])
    {
    Dtc = true;
    Utc = false;
    if (shorenor == null)
    {
    EnterShort(Convert.ToInt32(Ordinaryentrysize), @"shoren01");
    EnterShort(Convert.ToInt32(Pullbackentrysize), @"shpuen01");
    }
    }


    // Set 2
    if (Close[0] > EMA1[0])
    {
    Utc = true;
    Dtc = false;
    if (loorenor == null)
    {
    EnterLong(Convert.ToInt32(Ordinaryentrysize), @"looren01");
    EnterLong(Convert.ToInt32(Pullbackentrysize), @"lopuen01");
    }
    }


    Click image for larger version

Name:	20210824 duplicate exit stops 0001.JPG
Views:	358
Size:	245.8 KB
ID:	1169003



    for all these trades, there is only one execution.Order.AverageFillPrice as entries happen at the same time. exit orders work without issue.




    however, when i first have ordinary short and long entries:



    // Set 1
    if (Close[0] < EMA1[0])
    {
    Dtc = true;
    Utc = false;
    if (shorenor == null)
    {
    EnterShort(Convert.ToInt32(Ordinaryentrysize), @"shoren01");
    }
    }


    // Set 2
    if (Close[0] > EMA1[0])
    {
    Utc = true;
    Dtc = false;
    if (loorenor == null)
    {
    EnterLong(Convert.ToInt32(Ordinaryentrysize), @"looren01");
    }
    }


    these result in some initial values for execution.Order.AverageFillPrice which are used to define exit orders for these ordinary entries.


    and then the pullback entries are added when these conditions are observed:



    if ( Dtc == true && High[0] > ( Position.AveragePrice + ( Punuti * TickSize ) ) )
    {
    EnterShort(Convert.ToInt32(Pullbackentrysize), @"shpuen01");
    }


    if ( Utc == true && Low[0] > ( Position.AveragePrice - ( Punuti * TickSize ) ) )
    {
    EnterLong(Convert.ToInt32(Pullbackentrysize), @"lopuen01");
    }



    these second entries will mean that there will be a new value for execution.Order.AverageFillPrice and it seems to me like the platform will then have problems with the stop orders as the averagefillprice has changed and the ordinary entry stops were defined for the initial value but the pullback entry stops will be referenced to the new value.


    if (shorenor != null && shorenor == execution.Order)

    shorenstor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Instlonuti * TickSize ), "orstshoren01", "shoren01");

    shorenstor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Instlonuti * TickSize ), "orstshoren01", "shoren01");


    if (shpuenor != null && shpuenor == execution.Order)

    shpuenstor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustshpuen01", "shpuen01");

    shpuenstor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustshpuen01", "shpuen01");



    i think this must be the issue here. shorenstor is correctly defined with the initial value for average price. however, when the second entry is added, there is now a new value for average price. after a pullback entry is added, what i want is for both exit orders to be set at the exact same level = execution.Order.AverageFillPrice + ( Costlonuti * TickSize ). ¿how could the shorenstor order be updated to the new level after the pullback entry has been added? ¿and how can the shpuenstor be correctly defined being that it is here that the stop orders seem to not work properly anymore? and eventually, if these entries are made to be nicely in profit, i would like to then move these stops to break even in parallel, i suppose it should also be possible to update shorenstor and shpuenstor once again to a new price level when the conditions are appropriate.



    as always, i have attached the latest version of this experimental strategy. i have tried everything i could think of, if i can now hire a proficient programmer perhaps this could be easy for them. i will definitely ask for quotes for this code i have not been able to make work.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello rtwave,

    We can take a look at the output from the TraceOrders and prints and help you along. The output will tell us what's going on so that we can direct you on what to change.

    There can be multiple entry orders that scale into a position and increase the positions quantity, and you can separate exit orders to scale of a position and reduce the position quantity.
    Below is a link to the help guide on Position.Quantity.


    OnExecutionUpdate() will be a method that runs when the execution of the entry fills and the position updates. This would be a good time to use exit order methods to submit a stop and target.

    You can choose to use SetStopLoss() instead of using exit orders, if SetStopLoss() suits your needs, but you cannot use both set methods and exit methods. You will have to choose one or the other. Set methods would be called before the entry is placed (and not in OnExecutionUpdate()).

    The pseudo logic you have suggested sounds possible, (though this is not very specific). When you say it is not working, what is the TraceOrders and prints specifically showing is not working?

    Leave a comment:


  • rtwave
    replied





    people with nt,



    i still haven't been able to get the stop loss orders to work when using the onorderupdate and onexecutionupdate methods.



    i have now taken a look at the directory of 3rd party programmers that nt maintains. in order for it to be worth the trouble of hiring a programmer, i first want to make sure that the functionalities i have in mind are perfectly clear and also that the nt methods that i have been trying to make work are adequate for the intended objectives.




    i have now made changes to all my strategies to make sure that i use a similar terminology to to the one that the nt platform uses. where i previously used the word position, i now use the word entry. this is inconsequential but it means that my strategies now have an ordinary and a pullback entry.



    i'm interested in having the people with nt evaluate whether the onorderupdate and onexecutionupdate methods are really appropriate to achieve the following objectives. the structure i have in mind for my strategies is the following:






    if downtrend

    ordinary short entry at market ( 2 contracts )

    create stop loss order for ordinary short entry at +800 ticks from initial average entry price ( ordinary short entry )


    if time is between 9:30 and 16:00 and pullback

    pullback short entry at market ( 1 contract )

    create stop loss order for ordinary short entry at +600 ticks from combined average entry price ( average of ordinary and pullback short entries )

    create stop loss order for pullback short entry at +600 ticks from combined average entry price ( average of ordinary and pullback short entries )


    if downtrend ends


    liquidate all short entries

    cancel all stop orders



    i have been trying to use the onorderupdate and onexecutionupdate methods as nt support have stated that these are necessary to be able to create an initial stop loss order defined in ticks from the ordinary entry and then parallel stop loss orders defined in ticks from the new average price once the second entry has been executed for both the ordinary and pullback entries.



    ¿is this formulation clearer? ¿are the onorderupdate and onexecutionupdate methods the most appropriate to achieve these functionalities?



    oks, very well, regards.

    Leave a comment:


  • NinjaTrader_ChelseaB
    replied
    Hello rtwave,

    Where you have claimed 'these onrderupdate and onexecutionupdate methods are really unpredictable.' what exactly are you finding that is inconsistent and changes each time the script is run?


    A strategy cannot have two positions on the same instrument so an example of this cannot be provided because this is not possible.

    It is possible to scale into a single position with multiple contracts.

    If you want to scale and scale out, have each quantity be a separate entry with a unique signal name, then have a single exit order attached to the fromEntrySignal of that entry. As each exit fills, it will only exit the quantity of that entry from the position.


    Previously, I have provided a script showing that using SetStopLoss() with two entries is possible, in response to the message of your post #9.
    Attached, is an example script that scales in and out using exit methods instead of set methods.
    ​​​​​​​
    Attached Files

    Leave a comment:


  • rtwave
    replied



    NinjaTrader_Jim, people with nt,




    these onrderupdate and onexecutionupdate methods are really unpredictable.



    i have now created 4 sumfilled variables as i have 4 different orders (ordinary and pullback, both short and long). i have indeed noticed some improvement once i made this change.



    and i want to emphasize, it is not like i created some very extensive and complicated innovative code and i was asking nt to debug it. it is the complete opposite, all i have is the most elementary ema crossover strategy and i'm trying to work on the very samples nt makes available. everything compiles without issue, the entries work as expected, but the stop loss orders seem to be invalidated once the second entry is triggered.



    in the first thread i created about this development i asked nt for a working sample of a strategy with 2 positions and this is the strategy that was provided:


    if (entryOrder != null && entryOrder == execution.Order)
    {
    if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
    {
    // We sum the quantities of each execution making up the entry order
    sumFilled += execution.Quantity;
    Print("MyEntry1 Position and Quantity: " + marketPosition + " " + quantity);

    // Submit exit orders for partial fills
    if (execution.Order.OrderState == OrderState.PartFilled)
    {
    stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
    targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
    }
    // Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
    else if (execution.Order.OrderState == OrderState.Filled && sumFilled == execution.Order.Filled)
    {
    // Stop-Loss order for OrderState.Filled
    stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 4 * TickSize, "MyStop", "MyEntry");
    targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 8 * TickSize, "MyTarget", "MyEntry");
    Print("MyEntry exit orders submitted");
    }

    // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
    if (execution.Order.OrderState != OrderState.PartFilled && sumFilled == execution.Order.Filled)
    {
    entryOrder = null;
    sumFilled = 0;
    }
    }
    }
    if (entryOrder2 != null && entryOrder2 == execution.Order)
    {
    if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
    {
    //We sum the quantities of each execution making up the entry order
    sumFilled2 += execution.Quantity;
    Print("MyEntry2 Position and Quantity: " + marketPosition + " " + quantity);

    //Submit exit orders for partial fills
    if (execution.Order.OrderState == OrderState.PartFilled)
    {
    stopOrder2 = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 8 * TickSize, "MyStop2", "MyEntry2");
    targetOrder2 = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 16 * TickSize, "MyTarget2", "MyEntry2");
    //Print("MyEntry2 exit orders submitted");
    }
    //Update our exit order quantities once orderstate turns to filled and we have seen execution quantities match order quantities
    else if (execution.Order.OrderState == OrderState.Filled && sumFilled2 == execution.Order.Filled)
    {
    //Stop-Loss order for OrderState.Filled
    Print("MyEntry2 exit orders submitted");
    stopOrder2 = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - 8 * TickSize, "MyStop2", "MyEntry2");
    targetOrder2 = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + 16 * TickSize, "MyTarget2", "MyEntry2");
    }

    // Resets the entryOrder object and the sumFilled counter to null / 0 after the order has been filled
    if (execution.Order.OrderState != OrderState.PartFilled && sumFilled2 == execution.Order.Filled)
    {
    entryOrder2 = null;
    sumFilled2 = 0;
    }
    }
    }




    i do notice that each one of those segments only references their own order, stop and target and they operate completely separately of one another. in contrast, in the strategy i have been trying to make work below, in the segment for the second order i try to reference its own stop and also the stop for the first position. it is possible that this is the cause of all the problems, ¿can the nt platform do this and adjust a stop loss that had been defined previously in reference to a new value for average fill price? that's the exact objective of this entire development, a strategy that can add a secondary position on a pullback but always keeping the maximum possible loss capped for the larger combined position.




    if (pushpoor != null && pushpoor == execution.Order)
    {
    if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))
    {
    pushpoorsufi += execution.Quantity;

    if (execution.Order.OrderState == OrderState.PartFilled && marketPosition == MarketPosition.Short)
    {
    pushpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustpusp01", "pusp01");
    orshpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustorsp01", "orsp01");
    }

    else if (execution.Order.OrderState == OrderState.Filled && pushpoorsufi == execution.Order.Filled && marketPosition == MarketPosition.Short)
    {
    pushpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustpusp01", "pusp01");
    orshpostor = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + ( Costlonuti * TickSize ), "pustorsp01", "orsp01");
    }

    if (execution.Order.OrderState != OrderState.PartFilled && pushpoorsufi == execution.Order.Filled)
    {
    pushpoor = null;
    pushpoorsufi = 0;
    }
    }
    }




    from everything i have seen, i'm now not even sure that an external programmer could be of much help.


    ¿can nt provide a working sample of their onorderupdate strategy such that it includes two positions, where the the second position is dependent on the profit - loss for the first and the stop loss orders are calculated and defined in relation to the average price for the aggregate position?
    Last edited by rtwave; 08-08-2021, 12:54 PM.

    Leave a comment:


  • NinjaTrader_Jim
    replied
    Hello rtwave,

    This is Jim responding on behalf of Chelsea who is out of the office at this time.

    the combined - coordinated stop loss orders will not work anymore.
    This would need to be investigated with prints and seeing how far the logic gets, and when some of the logic is not reached, print out the values used in each condition (above the condition) to see how they evaluate. This will point out why a piece of code is not being reached. If the code is reached but no order is submitted, test again with TraceOrders enabled to see why the order submission was ignored.

    You may have a better time testing this in Playback using Market Replay data and focusing on a specific time when the issue arises.

    it seems to me that the only things that could be causing these malfunctions would be conflicting values for execution.Order.Filled, execution.Order.AverageFillPrice and sumFilled between the first and second positions. if i want to create three variables to hold the values for execution.Order.Filled, execution.Order.AverageFillPrice and sumFilled for the ordinary position and three other variables to hold these values for the pullback position, ¿how could i do this? and i think all these variables would need to be reset every time these positions are liquidated, ¿how could i achieve this?
    execution.Order.Filled, execution.Order.AverageFillPrice, anything from the passed execution object in OnExecutionUpdate, will be local to the specific update of OnExecutionUpdate. sumFilled is a class level variable. You should make sure that each entry has its own class level sumFilled variable, and to treat each own as it is demonstrated in SampleOnOrderUpdate.

    Everything taking the SampleOnOrderUpdate approach is outlined in the example, for multiple entries you would just have to make sure that EntryHandling and EntriesPerDirection allow multiple entries, and the order handling logic (including stop/target submission logic) is unique for each entry. As you are developing, use debugging prints to see how far the code gets and why it is not reaching those sections to check your work.

    Let us know if there is anything else we can do to help.

    Leave a comment:

Latest Posts

Collapse

Topics Statistics Last Post
Started by Max238, Today, 01:28 AM
2 responses
26 views
0 likes
Last Post NinjaTrader_ChristopherJ  
Started by Shansen, 08-30-2019, 10:18 PM
25 responses
949 views
0 likes
Last Post NinjaTrader_BrandonH  
Started by JonesJoker, 04-22-2024, 12:23 PM
8 responses
41 views
0 likes
Last Post JonesJoker  
Started by timko, Today, 06:45 AM
0 responses
5 views
0 likes
Last Post timko
by timko
 
Started by Waxavi, 04-19-2024, 02:10 AM
2 responses
40 views
0 likes
Last Post poeds
by poeds
 
Working...
X