Is this possible, any best practices. I prefer to do a strategy I understand an addon may be needed. I was able to do this with tradestation.
Announcement
Collapse
No announcement yet.
Partner 728x90
Collapse
NinjaTrader
Use a strategy to exit separate from entry
Collapse
X
-
Use a strategy to exit separate from entry
I have minor changes in my stop code from strategy to strategy but I would prefer to just add a SL/TP strategy.
Is this possible, any best practices. I prefer to do a strategy I understand an addon may be needed. I was able to do this with tradestation.Tags: None
-
Hi Bart, thanks for posting. One way to do this would be a strategy with IsAdoptAccountPositionAware = true and setting the start behavior to AdoptAccountPosition. Skip the historical data with:
if(State == State.Historical)
return;
The strategy would then have exit logic for the position it adopts. You would enable the strategy after opening the position.
-
Chris, thanks that does not work the way I would like. I want to subscribe to events and see there is an position change. The idea is to fully automate
I would place my OnExecutionUpdate() in one strategy that is subscribed to events for this account and this symbol
Comment
-
Data provider is Rithmic paper trading
I believe it has to do with OCOID which I am not yet using or with cleanup on subscriptions
Code:#region Using declarations using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using NinjaTrader.Gui.SuperDom; using NinjaTrader.Gui.Tools; using NinjaTrader.Data; using NinjaTrader.NinjaScript; using NinjaTrader.Core.FloatingPoint; using NinjaTrader.NinjaScript.Indicators; using NinjaTrader.NinjaScript.DrawingTools; #endregion //This namespace holds Strategies in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.Strategies { public class ManageExitsStrat : Strategy { private Account myAccount; private Order myEntryOrder; private Order profitTarget; private Order stopLoss; } }///State == State.SetDefaults }///OnStateChange private void OnOrderUpdate(object sender, OrderEventArgs e) { // Submit stop/target bracket orders Print("OnOrderUpdate "+ PositionAccount.MarketPosition); if (myEntryOrder != null && myEntryOrder == e.Order) { if (e.OrderState == OrderState.Filled) { string oco = Guid.NewGuid().ToString("N"); profitTarget = myAccount.CreateOrder( e.Order.Instrument, OrderAction.Sell, OrderType.Limit, OrderEntry.Manual, TimeInForce.Day, e.Quantity, e.AverageFillPrice + 10 * e.Order.Instrument.MasterInstrument.TickSize, 0, oco, "Profit Target", Core.Globals.MaxDate, null); stopLoss = myAccount.CreateOrder( e.Order.Instrument, OrderAction.Sell, OrderType.StopMarket, OrderEntry.Manual, TimeInForce.Day, e.Quantity, 0, e.AverageFillPrice - 10 * e.Order.Instrument.MasterInstrument.TickSize, oco, "Stop Loss", Core.Globals.MaxDate, null); myAccount.Submit(new[] { profitTarget, stopLoss }); } } } private void OnExecutionUpdate(object sender, ExecutionEventArgs e) { // Output the execution Print("OnExecutionUpdate "+ PositionAccount.MarketPosition); //NinjaTrader.Code.Output.Process("__OnExecutionUpda te "+ PositionAccount.MarketPosition), PrintTo.OutputTab1"); NinjaTrader.Code.Output.Process(string.Format("Ins trument: {0} Quantity: {1} Price: {2}", e.Execution.Instrument.FullName, e.Quantity, e.Price), PrintTo.OutputTab1); Print("OnExecutionUpdate "+ PositionAccount.MarketPosition); } private void ManageStop(){ } protected override void OnBarUpdate() { if (BarsInProgress != 0) return; if (PositionAccount.MarketPosition != MarketPosition.Flat) Print("Open PnL Ticks/Dollars: " + PositionAccount.GetUnrealizedProfitLoss(Performanc eUnit.Ticks, Close[0]) +"/"+ PositionAccount.GetUnrealizedProfitLoss(Performanc eUnit.Ticks, Close[0]) ); // if (PositionAccount.MarketPosition != MarketPosition.Flat) Print("Open PnL Dollars: " + PositionAccount.GetUnrealizedProfitLoss(Performanc eUnit.Currency, Close[0])); } // public override void Cleanup() // { // // Make sure to unsubscribe to the execution subscription // if (myAccount != null) // myAccount.ExecutionUpdate -= OnExecutionUpdate; // } } } /* TODO: Cleanup outside of Addon */Last edited by BartMan; 06-10-2022, 03:17 PM.
Comment
-
Hi Bart, Im sorry, I should have tested earlier but the manual orders that you make from ChartTrader or any order entry window will not have a SignalName at all. You will need to add a button through your script that will create a custom entry order. I attached an example here.
Kind regards,
-ChrisLAttached Files
Comment
-
Chris, I have manual button based trading (it does name orders) as well as indicator based entries and exits. I keep updating my stop strategy and would like to manage it as a separate item.
I placed trades all day from the chart right click buy/sell and also with chart trader.
I am now using Playback connection or Live account and can no longer place an order I think it has to do with account subscriptions which I addressed.
I have completely removed the strategy and am about to reboot, I have rebooted but that did not fix it
Code:#region Using declarations using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using NinjaTrader.Gui.SuperDom; using NinjaTrader.Gui.Tools; using NinjaTrader.Data; using NinjaTrader.NinjaScript; using NinjaTrader.Core.FloatingPoint; using NinjaTrader.NinjaScript.Indicators; using NinjaTrader.NinjaScript.DrawingTools; #endregion //This namespace holds Strategies in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.Strategies { public class ManageExitsStrat : Strategy { private Account myAccount; private Order myEntryOrder; private Order profitTarget; private Order stopLoss; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Strategy here."; Name = "ManageExitsStrat"; Calculate = Calculate.OnPriceChange; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 99; IsFillLimitOnTouch = false; MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix; OrderFillResolution = OrderFillResolution.Standard; Slippage = 0; StartBehavior = StartBehavior.WaitUntilFlat; TimeInForce = TimeInForce.Gtc; TraceOrders = true; RealtimeErrorHandling = RealtimeErrorHandling.IgnoreAllErrors;///TODO: BE VERY CAREFUL StopTargetHandling = StopTargetHandling.PerEntryExecution; BarsRequiredToTrade = 20; IsInstantiatedOnEachOptimizationIteration = true; // lock (Account.All) myAccount = Account.All.FirstOrDefault(a => a.Name == "Sim101"); lock (Account.All) myAccount = Account.All.FirstOrDefault(a => a.Name == "Playback101"); //myAccount = "Sim101"; } else if (State == State.Configure) { } else if (State == State.DataLoaded) { Subscribe(); lock (myAccount.Positions) { Print("Positions in State.DataLoaded:"); foreach (Position position in myAccount.Positions) { Print(String.Format("Position: {0} at {1}", position.MarketPosition, position.AveragePrice)); } } /* if (myAccount != null) { myAccount.ExecutionUpdate += OnExecutionUpdate; myAccount.OrderUpdate += OnOrderUpdate; } */ foreach (Account sampleAccount in Account.All) Print(String.Format("The account {0} has a {1} unit FX lotsize set", sampleAccount.Name, sampleAccount.ForexLotSize)); Print("Selected Account="+myAccount); } else if (State == State.Terminated) { // Unsubscribe to events myAccount.ExecutionUpdate -= OnExecutionUpdate; myAccount.OrderUpdate -= OnOrderUpdate; }///State == State.SetDefaults }///OnStateChange private void Subscribe() { if (myAccount != null) { // Unsubscribe to any prior account subscriptions // myAccount.AccountItemUpdate -= OnAccountItemUpdate; myAccount.ExecutionUpdate -= OnExecutionUpdate; myAccount.OrderUpdate -= OnOrderUpdate; // myAccount.PositionUpdate -= OnPositionUpdate; // Subscribe to new account subscriptions // myAccount.AccountItemUpdate += OnAccountItemUpdate; myAccount.ExecutionUpdate += OnExecutionUpdate; myAccount.OrderUpdate += OnOrderUpdate; // myAccount.PositionUpdate += OnPositionUpdate; } } private void OnOrderUpdate(object sender, OrderEventArgs e) { // Submit stop/target bracket orders Print("OnOrderUpdate "+ PositionAccount.MarketPosition); /* if (myEntryOrder != null && myEntryOrder == e.Order) { if (e.OrderState == OrderState.Filled) { string oco = Guid.NewGuid().ToString("N"); profitTarget = myAccount.CreateOrder( e.Order.Instrument, OrderAction.Sell, OrderType.Limit, OrderEntry.Manual, TimeInForce.Day, e.Quantity, e.AverageFillPrice + 10 * e.Order.Instrument.MasterInstrument.TickSize, 0, oco, "Profit Target", Core.Globals.MaxDate, null); stopLoss = myAccount.CreateOrder( e.Order.Instrument, OrderAction.Sell, OrderType.StopMarket, OrderEntry.Manual, TimeInForce.Day, e.Quantity, 0, e.AverageFillPrice - 10 * e.Order.Instrument.MasterInstrument.TickSize, oco, "Stop Loss", Core.Globals.MaxDate, null); myAccount.Submit(new[] { profitTarget, stopLoss }); } } */ } private void OnExecutionUpdate(object sender, ExecutionEventArgs e) { // Output the execution Print("OnExecutionUpdate "+ PositionAccount.MarketPosition); //NinjaTrader.Code.Output.Process("__OnExecutionUpda te "+ PositionAccount.MarketPosition), PrintTo.OutputTab1"); NinjaTrader.Code.Output.Process(string.Format("Ins trument: {0} Quantity: {1} Price: {2}", e.Execution.Instrument.FullName, e.Quantity, e.Price), PrintTo.OutputTab1); Print("OnExecutionUpdate "+ PositionAccount.MarketPosition); } private void ManageStop(){ } protected override void OnBarUpdate() { if (BarsInProgress != 0) return; if (PositionAccount.MarketPosition != MarketPosition.Flat) Print("Open PnL Ticks/Dollars: " + PositionAccount.GetUnrealizedProfitLoss(Performanc eUnit.Ticks, Close[0]) +"/"+ PositionAccount.GetUnrealizedProfitLoss(Performanc eUnit.Currency, Close[0]) + " MarketPosition="); //+MarketPosition.ToString());+position.MarketPositi on // if (PositionAccount.MarketPosition != MarketPosition.Flat) Print("Open PnL Dollars: " + PositionAccount.GetUnrealizedProfitLoss(Performanc eUnit.Currency, Close[0])); switch ( Position.MarketPosition ) { case MarketPosition.Flat: return; case MarketPosition.Long: Print ("Long"); break; case MarketPosition.Short: Print ("Short"); break; } } } }
Comment
Latest Posts
Collapse
| Topics | Statistics | Last Post | ||
|---|---|---|---|---|
|
Started by NullPointStrategies, Yesterday, 05:17 AM
|
0 responses
62 views
0 likes
|
Last Post
|
||
|
Started by argusthome, 03-08-2026, 10:06 AM
|
0 responses
134 views
0 likes
|
Last Post
by argusthome
03-08-2026, 10:06 AM
|
||
|
Started by NabilKhattabi, 03-06-2026, 11:18 AM
|
0 responses
75 views
0 likes
|
Last Post
|
||
|
Started by Deep42, 03-06-2026, 12:28 AM
|
0 responses
45 views
0 likes
|
Last Post
by Deep42
03-06-2026, 12:28 AM
|
||
|
Started by TheRealMorford, 03-05-2026, 06:15 PM
|
0 responses
50 views
0 likes
|
Last Post
|

Comment