I have attached sample code.
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!
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
NinjaTrader
Managed Stop Loss Per Unique Entry
Collapse
X
-
Managed Stop Loss Per Unique Entry
I would like to implement into my strategy a way to have individual stop losses per unique order entry. When backtesting or using live replay, setting entries per direction >1 fires the same logic with the same entry "LONG" or "SHORT" and enters into OnOrderUpdate() and OnExecutionUpdate(). From there initial targets and stops are placed and OnBarUpdate() manages trailing based on ATR once conditions are met. This works great for one contract, but n>1 causes only one stop/target bracket while the rest of the orders are on their own.
I have attached sample code.Tags: None
-
Hello rdavido,
Thank you for your note.
So I can best answer your question, the issue is that new entries are not having a stop and profit target associated with them? If so, have you tried updating the quantity of the PT and SL upon a new fill?
I have attached a strategy which enters a long position with 3 entry calls, then submits a separate profit target and stop loss for each entry, without using order objects. You could use this as a template as well.
I look forward to your reply.Attached FilesAlan P.NinjaTrader Customer Service
-
Yes, this is essentially what I'm looking for, however, am I able to make it more dynamic; i.e. based on the market conditions a new order will be placed on each bar, each having its own stop and profit target handled by OnExecutionUpdate versus specifically entering 3 trades at a time?
How could I adjust my stop and profit quantity upon each order entry? In the code I have attached, OnBarUpdate utilizes a trailing stop method, but as it is, only processes one contract, when additional contracts are added, it still utilizes P/S orders for one contract and as soon as that order is fulfilled, I am left with remaining open orders with no stop/profit targets.. probably due to the reset coded within OnExecution; is there a way to make each S/P limit independent of eachother?
Perhaps adding unique identifiers to each "LONG" or "SHORT" order such as + Time[0] and then processing it so it will have the same target and stop, but I'm not sure how to code this.Last edited by rdavido; 01-21-2018, 03:07 PM.
Comment
-
Hello rdavido,
I put together a script which I suggest you connect to the simulated data feed, and apply the strategy to a 2 second chart, with the orders tab open.
When applied the strategy will EnterLong, 3 bars later a SL will be submitted, 7 bars later a bool will be reset to allow a new entry to be made on the next bar, which will have a SL submitted 7 bars after that, etc. You will see in the orders tab a new SL is submitted covering this entry.
To tie a stop loss to a particular entry, you must pass the stop the entries entry name. In this sample I amended the entry name with the current bar ("entry1"), as well as named the stops signal name with the CB ("stopentry1").
Please let us know if you need further assistance.Alan P.NinjaTrader Customer Service
Comment
-
Thanks for the samples, however, I am trying to tie in stop losses within my own strategy and not sure if your latest sample is what I'm looking for.
I do not want to have a predefined set of Long orders (such as three in your example), I'd like to stick with just one Long condition that is dynamically scalable and processed through OnOrderUpdate with initial bracket handled with OnExecutionUpdate with final trailing handled OnBarUpdate; see my sample code
Comment
-
Hello rdavido,
The script I provided demonstrates how you could have multiple entries using the same entry logic, with unique PT and SL tied to each entry. You could use the logic as a framework for building what you're looking to do, however in the support department at NinjaTrader we do not create, debug, or modify code for our clients. This is so that we can maintain a high level of service for all of our clients.
You can also contact a professional NinjaScript Consultants who would be eager to create or modify this script at your request or assist you with your script. Please let me know if you would like our business development follow up with you with a list of professional NinjaScript Consultants who would be happy to create this script or any others at your request.
Please let us know if you need further assistance.Alan P.NinjaTrader Customer Service
Comment
-
Thanks for the sample, with your method, am I able to tie it to use within OnExecution and OnOrder update? It seems that your example only has OnBarUpdate. Also, I don't want to wait three bars to have stop losses kick in. Please refer to my original sample.
As it is:
Code: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 nativeError) { // Handle entry orders here. The entryOrder object allows us to identify that the order that is calling the OnOrderUpdate() method is the entry order. // Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected. // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not gauranteed to be complete if it is referenced immediately after submitting if (order.Name == "LONG") { entryOrder = order; // Reset the entryOrder object to null if order was cancelled without any fill if (order.OrderState == OrderState.Cancelled && order.Filled == 0) entryOrder = null; } if (order.Name == "SHORT") { entryOrder = order; if (order.OrderState == OrderState.Cancelled && order.Filled == 0) entryOrder = null; } } protected override void OnExecutionUpdate(Cbi.Execution execution, string executionId, double price, int quantity, Cbi.MarketPosition marketPosition, string orderId, DateTime time) { // /* We advise monitoring OnExecution to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate() // which ensures your strategy has received the execution which is used for internal signal tracking. */ if (entryOrder != null && entryOrder == execution.Order) { Print(execution.Order.Name.ToString()); if (execution.Order.Name == "LONG" && (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))) { targetOrder = ExitLongLimit(1, true,entryOrder.Quantity, execution.Order.AverageFillPrice + (profitTargetTicks * TickSize), "T1", "LONG"); stopOrder = ExitLongStopMarket(1, true, entryOrder.Quantity, execution.Order.AverageFillPrice - (stopLossTicks * TickSize), "S1", "LONG"); } if (execution.Order.Name == "SHORT" && (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled || (execution.Order.OrderState == OrderState.Cancelled && execution.Order.Filled > 0))) { targetOrder = ExitShortLimit(1, true, entryOrder.Quantity, execution.Order.AverageFillPrice - (profitTargetTicks * TickSize), "T1", "SHORT"); stopOrder = ExitShortStopMarket(1, true, entryOrder.Quantity, execution.Order.AverageFillPrice + (stopLossTicks * TickSize), "S1", "SHORT"); } if (execution.Order.OrderState != OrderState.PartFilled) entryOrder = null; } // Reset our stop order and target orders' Order objects after our position is closed. if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order)) { if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled) { stopOrder = null; targetOrder = null; } } }
Last edited by rdavido; 01-24-2018, 05:35 PM.
Comment
-
Hello rdavido,
The code sample I provided demonstrates how you could uniquely define your entry signal name,
Code:Entry1=”Entry”+CurrentBar.ToString()
Code:Stopentry1=”stop”+CurrentBar.ToString(),
Within OnExecutionUpdate, you could filter fills for the entry with,
Code:if (execution.Order.Name == Entry1 && execution.Order.OrderState == OrderState.Filled)
Alan P.NinjaTrader Customer Service
Comment
-
This makes more sense. However, when running the following in MarketReplay, orders are not filling
Code:protected override void OnOrderUpdate(Order order, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, OrderState orderState, DateTime time, ErrorCode error, string nativeError) { // Handle entry orders here. The entryOrder object allows us to identify that the order that is calling the OnOrderUpdate() method is the entry order. // Assign entryOrder in OnOrderUpdate() to ensure the assignment occurs when expected. // This is more reliable than assigning Order objects in OnBarUpdate, as the assignment is not gauranteed to be complete if it is referenced immediately after submitting if (order.Name == entryLong || order.Name == entryShort || order.Name == profitTarget || order.Name == stopLoss) { entryOrder = order; // Reset the entryOrder object to null if order was cancelled without any fill if (order.OrderState == OrderState.Cancelled && order.Filled == 0) entryOrder = null; } } protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition, string orderId, DateTime time) { // /* We advise monitoring OnExecution to trigger submission of stop/target orders instead of OnOrderUpdate() since OnExecution() is called after OnOrderUpdate() // which ensures your strategy has received the execution which is used for internal signal tracking. */ if (execution.Order.OrderState == OrderState.Filled && entryOrder != null) { if (Position.MarketPosition == MarketPosition.Long) { targetOrder = ExitLongLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + (profitTargetTicks * TickSize), "T1", entryLong); stopOrder = ExitLongStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - (stopLossTicks * TickSize), "S1", entryLong); if (execution.Order.OrderState != OrderState.PartFilled) entryOrder = null; } if (Position.MarketPosition == MarketPosition.Short) { targetOrder = ExitShortLimit(0, true, execution.Order.Filled, execution.Order.AverageFillPrice - (profitTargetTicks * TickSize), "T1", entryShort); stopOrder = ExitShortStopMarket(0, true, execution.Order.Filled, execution.Order.AverageFillPrice + (stopLossTicks * TickSize), "S1", entryShort); if (execution.Order.OrderState != OrderState.PartFilled) entryOrder = null; } } // Reset our stop order and target orders' Order objects after our position is closed. if ((stopOrder != null && stopOrder == execution.Order) || (targetOrder != null && targetOrder == execution.Order)) { if (execution.Order.OrderState == OrderState.Filled || execution.Order.OrderState == OrderState.PartFilled) { stopOrder = null; targetOrder = null; stopLoss = string.Empty; profitTarget = string.Empty; } } }
Code:Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Cancelled' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error='' Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Cancel submitted' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error='' Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Working' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error='' Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Accepted' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error='' Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Change submitted' Instrument='ES 03-18' Action='Buy' Limit price=2808.25 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error='' Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Working' Instrument='ES 03-18' Action='Buy' Limit price=2808.5 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error='' Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Accepted' Instrument='ES 03-18' Action='Buy' Limit price=2808.5 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error='' Order='53fdfe99113441f198f6b2063e516849/Playback101' Name='LONG229' New state='Submitted' Instrument='ES 03-18' Action='Buy' Limit price=2808.5 Stop price=0 Quantity=1 Type='Limit' Time in force=GTC Oco='' Filled=0 Fill price=0 Error='No error' Native error='' NinjaScript strategy 'ThreeLine/128380886' submitting order
Comment
-
Hello rdavido,
It does not look like you have logic to prevent the resubmission of the orders. I would suggest using a bool,
Code:private doOnce=false; if(doOnce==false) <do something>
Please let us know if you need further assistance.Alan P.NinjaTrader Customer Service
Comment
-
Hello rdavido,
In the support department at NinjaTrader we do not create, debug, or modify code for our clients. This is so that we can maintain a high level of service for all of our clients.
If you wanted to upload a copy of the script, stripped down to the bare minimum to reproduce, I could take a look and see if anything jumps out.
You can also contact a professional NinjaScript Consultants who would be eager to create or modify this script at your request or assist you with your script. Please let me know if you would like our business development follow up with you with a list of professional NinjaScript Consultants who would be happy to create this script or any others at your request.
Please let us know if you need further assistance.Alan P.NinjaTrader Customer Service
Comment
Latest Posts
Collapse
Topics | Statistics | Last Post | ||
---|---|---|---|---|
Started by bortz, 11-06-2023, 08:04 AM
|
47 responses
1,602 views
0 likes
|
Last Post
by aligator
Today, 07:22 PM
|
||
Started by jaybedreamin, Today, 05:56 PM
|
0 responses
8 views
0 likes
|
Last Post
by jaybedreamin
Today, 05:56 PM
|
||
Started by DJ888, 04-16-2024, 06:09 PM
|
6 responses
18 views
0 likes
|
Last Post
by DJ888
Today, 05:12 PM
|
||
Started by Jon17, Today, 04:33 PM
|
0 responses
4 views
0 likes
|
Last Post
by Jon17
Today, 04:33 PM
|
||
Started by Javierw.ok, Today, 04:12 PM
|
0 responses
12 views
0 likes
|
Last Post
by Javierw.ok
Today, 04:12 PM
|
Comment