lines 473-85
unknown
csharp
2 years ago
35 kB
18
Indexable
Never
using System.Windows.Controls; // For TextBox //using System.Collections.ObjectModel; // For Flatten() multiple instrument using System.Runtime.InteropServices; using System.Windows.Interop; using NinjaTrader.Gui.NinjaScript; using NinjaTrader.NinjaScript.Indicators; #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.DrawingTools; #endregion //This namespace holds Indicators in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.Indicators { #region ChildControls Class / Hotkeys Snippets public class ChildControls { private List<object> lstChildren; public List<object> GetChildren(Visual p_vParent, int p_nLevel) { if (p_vParent == null) { throw new ArgumentNullException("Element {0} is null!", p_vParent.ToString()); } this.lstChildren = new List<object>(); this.GetChildControls(p_vParent, p_nLevel); return this.lstChildren; } private void GetChildControls(Visual p_vParent, int p_nLevel) { int nChildCount = VisualTreeHelper.GetChildrenCount(p_vParent); for (int i = 0; i <= nChildCount - 1; i++) { Visual v = (Visual)VisualTreeHelper.GetChild(p_vParent, i); lstChildren.Add((object)v); if (VisualTreeHelper.GetChildrenCount(v) > 0) { GetChildControls(v, p_nLevel + 1); } } } } #endregion public class ProfitSnipers : Indicator { #region Class Level Variables private Position accountPosition; private List<Order> submitTargetsOrdersList, submitStopLossesOrdersList, multiOrders; private double currentPTPrice, currentSLPrice; private Order entryBuyMarketOrder, entrySellMarketOrder, profitTargetOrder, stopLossOrder; private Account myAccount; #region QuantitySelector // QS Define a Chart object to refer to the chart on which the indicator resides private Chart chartWindow; NinjaTrader.Gui.Tools.QuantityUpDown quantitySelector; // QS private bool Is_ToolBar_Controls_Added; // QS https://stackoverflow.com/a/9301272/10789707 private int qs; private TextBox quantitySelectorTextBox; #endregion #endregion #region OnStateChange protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Orders Hotkeys Manager."; Name = "ProfitSnipers"; Calculate = Calculate.OnEachTick; IsOverlay = true; DisplayInDataBox = false; PrintDetails = false; ProfitTargetDistance = 10; StopLossDistance = 10; UseProfitTarget = true; UseStopLoss = true; ProfitTargetMove = 1; StopLossMove = 1; AccountName = "Sim101"; } else if (State == State.Configure) { } else if (State == State.Historical) { //Call the custom addButtonToToolbar method in State.Historical to ensure it is only done when applied to a chart // -- not when loaded in the Indicators window if (!Is_ToolBar_Controls_Added) Add_Controls_To_Toolbar(); } else if (State == State.DataLoaded) { // Find our account lock (Account.All) myAccount = Account.All.FirstOrDefault(a => a.Name == AccountName); if (myAccount != null) myAccount.OrderUpdate += Account_OrderUpdate; if (ChartControl != null) { ChartControl.Dispatcher.InvokeAsync((Action)(() => { quantitySelector = (Window.GetWindow(ChartControl.Parent).FindFirst("ChartTraderControlQuantitySelector") as NinjaTrader.Gui.Tools.QuantityUpDown); })); ChartControl.PreviewKeyDown += OnPreviewKeyDown; ChartControl.PreviewKeyDown += ChartControl_PreviewKeyDown; } multiOrders = new List<Order>(); submitTargetsOrdersList = new List<Order>(); submitStopLossesOrdersList = new List<Order>(); } else if (State == State.Terminated) { if (myAccount != null) myAccount.OrderUpdate -= Account_OrderUpdate; if (ChartControl != null) { quantitySelector.PreviewKeyDown -= DeleteBackspace_quantitySelector_PreviewKeyDown; quantitySelector.PreviewKeyDown -= NumbersInput_quantitySelector_PreviewKeyDown; ChartControl.PreviewKeyDown -= OnPreviewKeyDown; quantitySelector.PreviewKeyDown -= OnPreviewKeyDown; ChartControl.PreviewKeyDown -= ChartControl_PreviewKeyDown; } //Call a custom method to dispose of any leftover objects in State.Terminated DisposeCleanUp(); } } #endregion #region Add Controls To Toolbar / QuantitySelector & PreviewKeyDown private void Add_Controls_To_Toolbar() { // Use this.Dispatcher to ensure code is executed on the proper thread ChartControl.Dispatcher.InvokeAsync((Action)(() => { //Obtain the Chart on which the indicator is configured chartWindow = Window.GetWindow(this.ChartControl.Parent) as Chart; if (chartWindow == null) { Print("chartWindow == null"); return; } quantitySelector = new NinjaTrader.Gui.Tools.QuantityUpDown(); //quantitySelector.ValueChanged += On_quantitySelector_ValueChanged; quantitySelector.PreviewKeyDown += DeleteBackspace_quantitySelector_PreviewKeyDown; quantitySelector.PreviewKeyDown += NumbersInput_quantitySelector_PreviewKeyDown; quantitySelector.PreviewKeyDown += OnPreviewKeyDown; chartWindow.MainMenu.Add(quantitySelector); Is_ToolBar_Controls_Added = true; quantitySelector.Value = 1; })); } #endregion #region QuantitySelector Delete / Backspace & Numbers Keys Snippets #region Delete / Backspace - Delete in ToolBar's Quantity Selector private void DeleteBackspace_quantitySelector_PreviewKeyDown(object sender, KeyEventArgs p) { NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; if (p.Key == Key.Delete || p.Key == Key.Back) { p.Handled = true; quantitySelector.Value = 0; } } #endregion #region Numbers (Main Keyboard OR Numeric Pad Keys) for Input in ToolBar's Quantity Selector private void NumbersInput_quantitySelector_PreviewKeyDown(object sender, KeyEventArgs p) { NinjaTrader.Gui.Tools.QuantityUpDown qs = sender as NinjaTrader.Gui.Tools.QuantityUpDown; if ((p.Key >= Key.D0 && p.Key <= Key.D9 || (p.Key >= Key.NumPad0 && p.Key <= Key.NumPad9))) { p.Handled = true; string number = p.Key.ToString(); string newnumber = qs.Value.ToString(); number = number.Replace("NumPad", ""); number = number.Replace("D", ""); int num = int.Parse(newnumber + number); if (qs != null) qs.Value = num; } } #endregion #endregion #region OnPreviewKeyDown / FocusOut & EnterBuyMarketOrder Order OR EnterShortMarketOrder private async void OnPreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs p) { if (p.Key == Key.Add) { #region FOCUS on ToolsBar's QuantitySelector TextBox ChildControls ccChildren = new ChildControls(); foreach (object o in ccChildren.GetChildren(quantitySelector, 0)) { if (o.GetType() == typeof(TextBox)) { TextBox quantitySelectorBoxFocusIn = (TextBox)o; quantitySelectorBoxFocusIn.Focus(); System.Windows.Forms.SendKeys.SendWait("{DELETE}"); } } #endregion } await ChartControl.Dispatcher.InvokeAsync((Action) (() => { if (p.Key == Key.Multiply) { #region FocusOut of QS TextBox Keyboard.Focus(sender as ChartControl); #endregion #region Enter BuyMarketOrder // LONG Orders TriggerCustomEvent(BuyMarketOrderVar => { // multiOrders = new List<Order>(); for (int index = 0; index < quantitySelector.Value; index++) { entryBuyMarketOrder = myAccount.CreateOrder( Instrument, OrderAction.Buy, OrderType.Market, OrderEntry.Manual, TimeInForce.Day, 1, 0, 0, string.Empty, "Entry", Core.Globals.MaxDate, null); multiOrders.Add(entryBuyMarketOrder); } myAccount.Submit(multiOrders); }, null); TriggerCustomEvent(k => { Print("Buy"); }, null); #endregion } else if (p.Key == Key.Subtract) { #region FocusOut of QS TextBox Keyboard.Focus(sender as ChartControl); #endregion #region Enter SellMarketOrder // SHORT Orders TriggerCustomEvent(SellMarketOrderVar => { // multiOrders = new List<Order>(); for (int index = 0; index < quantitySelector.Value; index++) { entrySellMarketOrder = myAccount.CreateOrder( Instrument, OrderAction.Sell, OrderType.Market, OrderEntry.Manual, TimeInForce.Day, 1, 0, 0, string.Empty, "Entry", Core.Globals.MaxDate, null); multiOrders.Add(entrySellMarketOrder); } myAccount.Submit(multiOrders); }, null); TriggerCustomEvent(k => { Print("Sell"); }, null); #endregion } })); p.Handled = true; } #endregion #region Hotkeys Snippets / ChildControls Class protected void ChartControl_PreviewKeyDown(object sender, KeyEventArgs e) { #region FLATTEN All Current Instrument Positions TriggerCustomEvent(FlattenVar => { if (Keyboard.IsKeyDown(Key.Pause)) { myAccount = Account.All.FirstOrDefault(a => a.Name == AccountName); myAccount.Flatten(new [] { Instrument }); } }, null); e.Handled = true; #endregion #region CANCEL All Current Instrument Positions TriggerCustomEvent(CancelAllVar => { if (Keyboard.IsKeyDown(Key.Scroll)) { myAccount = Account.All.FirstOrDefault(a => a.Name == AccountName); myAccount.CancelAllOrders(Instrument); } }, null); e.Handled = true; #endregion #region MOVE UP Target OCO Orders for BuyMarket OR SellMarket Orders TriggerCustomEvent(BuyMarketORSellMarket_OrderMoveTargetUpOCOVar => { if (entryBuyMarketOrder != null) { if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { currentPTPrice = profitTargetOrder.LimitPrice + (ProfitTargetMove * TickSize); for (int index = 0; index < ((submitTargetsOrdersList.Count > 0) ? submitTargetsOrdersList.Count : quantitySelector.Value); index++) { submitTargetsOrdersList[index].LimitPriceChanged = currentPTPrice; } myAccount.Change(submitTargetsOrdersList); } } else if (entrySellMarketOrder != null) { if (Keyboard.IsKeyDown(Key.NumPad7) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { currentPTPrice = profitTargetOrder.LimitPrice - (ProfitTargetMove * TickSize); for (int index = 0; index < ((submitTargetsOrdersList.Count > 0) ? submitTargetsOrdersList.Count : quantitySelector.Value); index++) { submitTargetsOrdersList[index].LimitPriceChanged = currentPTPrice; } myAccount.Change(submitTargetsOrdersList); } } }, null); e.Handled = true; #endregion #region MOVE DOWN Target OCO Orders for BuyMarket OR SellMarket Orders TriggerCustomEvent(BuyMarketORSellMarket_OrderMoveTargetDownOCOVar => { if (entryBuyMarketOrder != null) { if (Keyboard.IsKeyDown(Key.NumPad7) && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { currentPTPrice = profitTargetOrder.LimitPrice - (ProfitTargetMove * TickSize); for (int index = 0; index < ((submitTargetsOrdersList.Count > 0) ? submitTargetsOrdersList.Count : quantitySelector.Value); index++) { submitTargetsOrdersList[index].LimitPriceChanged = currentPTPrice; } myAccount.Change(submitTargetsOrdersList); } } else if (entrySellMarketOrder != null) { if (Keyboard.IsKeyDown(Key.NumPad7) && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { currentPTPrice = profitTargetOrder.LimitPrice + (ProfitTargetMove * TickSize); for (int index = 0; index < ((submitTargetsOrdersList.Count > 0) ? submitTargetsOrdersList.Count : quantitySelector.Value); index++) { submitTargetsOrdersList[index].LimitPriceChanged = currentPTPrice; } myAccount.Change(submitTargetsOrdersList); } } }, null); e.Handled = true; #endregion #region MOVE UP StopLoss OCO Orders for BuyMarket OR SellMarket Orders TriggerCustomEvent(BuyMarketORSellMarket_OrderMoveStopLossUpOCOVar => { double stopLossMoveUpRejectionPrevented = 0; if (entryBuyMarketOrder != null) { double rejectionGapSize = (Instrument.MasterInstrument.RoundToTickSize(GetCurrentBid() - stopLossOrder.StopPrice) ); double stopLossMoveSize = (StopLossMove * Instrument.MasterInstrument.RoundToTickSize(TickSize)); double oneTickSize = (1 * Instrument.MasterInstrument.RoundToTickSize(TickSize)); if (Keyboard.IsKeyDown(Key.NumPad4)) stopLossMoveUpRejectionPrevented = ((stopLossMoveSize > rejectionGapSize) ? (rejectionGapSize - oneTickSize) : stopLossMoveSize); if (Keyboard.IsKeyDown(Key.NumPad4) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { currentSLPrice = stopLossOrder.StopPrice + (stopLossMoveUpRejectionPrevented); for (int index = 0; index < ((submitTargetsOrdersList.Count > 0) ? submitTargetsOrdersList.Count : quantitySelector.Value); index++) { submitStopLossesOrdersList[index].StopPriceChanged = currentSLPrice; } myAccount.Change(submitStopLossesOrdersList); } } else if (entrySellMarketOrder != null) { if (Keyboard.IsKeyDown(Key.NumPad4) && !(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { currentSLPrice = stopLossOrder.StopPrice + (StopLossMove * TickSize); for (int index = 0; index < ((submitTargetsOrdersList.Count > 0) ? submitTargetsOrdersList.Count : quantitySelector.Value); index++) { submitStopLossesOrdersList[index].StopPriceChanged = currentSLPrice; } myAccount.Change(submitStopLossesOrdersList); } } }, null); e.Handled = true; #endregion #region MOVE DOWN StopLoss OCO Orders for BuyMarket OR SellMarket Orders TriggerCustomEvent(BuyMarketORSellMarket_OrderMoveStopLossDownOCOVar => { double stopLossMoveDownRejectionPrevented = 0; if (entryBuyMarketOrder != null) { if (Keyboard.IsKeyDown(Key.NumPad4) && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { currentSLPrice = stopLossOrder.StopPrice - (StopLossMove * TickSize); for (int index = 0; index < ((submitTargetsOrdersList.Count > 0) ? submitTargetsOrdersList.Count : quantitySelector.Value); index++) { submitStopLossesOrdersList[index].StopPriceChanged = currentSLPrice; } myAccount.Change(submitStopLossesOrdersList); } } else if (entrySellMarketOrder != null) { double rejectionGapSize = (Instrument.MasterInstrument.RoundToTickSize(stopLossOrder.StopPrice - GetCurrentAsk()) ); double stopLossMoveSize = (StopLossMove * Instrument.MasterInstrument.RoundToTickSize(TickSize)); double oneTickSize = (1 * Instrument.MasterInstrument.RoundToTickSize(TickSize)); if (Keyboard.IsKeyDown(Key.NumPad4)) stopLossMoveDownRejectionPrevented = ((stopLossMoveSize > rejectionGapSize) ? (rejectionGapSize - oneTickSize) : stopLossMoveSize); if (Keyboard.IsKeyDown(Key.NumPad4) && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))) { currentSLPrice = stopLossOrder.StopPrice - (stopLossMoveDownRejectionPrevented); for (int index = 0; index < ((submitTargetsOrdersList.Count > 0) ? submitTargetsOrdersList.Count : quantitySelector.Value); index++) { submitStopLossesOrdersList[index].StopPriceChanged = currentSLPrice; } myAccount.Change(submitStopLossesOrdersList); } } }, null); e.Handled = true; #endregion #region */* LONG AND SHORT ENTRY FROM CHART (WITHOUT QS FOCUS OUT) /* #region Entry LONG : BuyMarketOrderFocusOnChartVar TriggerCustomEvent(BuyMarketOrderFocusOnChartVar => { if (Keyboard.IsKeyDown(Key.NumPad1)) { multiOrders = new List<Order>(); for (int index = 0; index < quantitySelector.Value; index++) { entryBuyMarketOrder = myAccount.CreateOrder( Instrument, OrderAction.Buy, OrderType.Market, OrderEntry.Manual, TimeInForce.Day, 1, 0, 0, string.Empty, "Entry", Core.Globals.MaxDate, null); multiOrders.Add(entryBuyMarketOrder); } } myAccount.Submit(new[] { entryBuyMarketOrder }); myAccount.Submit(multiOrders); }, null); e.Handled = true; #endregion #region Entry SHORT : SellMarketOrderFocusOnChartVar TriggerCustomEvent(SellMarketOrderFocusOnChartVar => { if (Keyboard.IsKeyDown(Key.NumPad2)) { multiOrders = new List<Order>(); for (int index = 0; index < quantitySelector.Value; index++) { entrySellMarketOrder = myAccount.CreateOrder( Instrument, OrderAction.Sell, OrderType.Market, OrderEntry.Manual, TimeInForce.Day, 1, 0, 0, string.Empty, "Entry", Core.Globals.MaxDate, null); multiOrders.Add(entrySellMarketOrder); } } myAccount.Submit(new[] { entrySellMarketOrder }); myAccount.Submit(multiOrders); }, null); e.Handled = true; #endregion */ #endregion } #endregion #region Initial Target & StopLoss Snippets private async void Account_OrderUpdate(object sender, OrderEventArgs orderUpdateArgs) { // Print(string.Format("{0} | Account_OrderUpdate | order.ToString(): {1}", orderUpdateArgs.Time, orderUpdateArgs.Order.ToString())); #region LONG Order Target and StopLoss OCO orders if (entryBuyMarketOrder != null && entryBuyMarketOrder == orderUpdateArgs.Order && orderUpdateArgs.Order.OrderState == OrderState.Filled) { string oco = Guid.NewGuid().ToString("N"); // submitTargetsOrdersList = new List<Order>(); // submitStopLossesOrdersList = new List<Order>(); await ChartControl.Dispatcher.InvokeAsync((Action) (() => { if (UseProfitTarget) { currentPTPrice = orderUpdateArgs.AverageFillPrice + ProfitTargetDistance * TickSize; for (int index = 0; index < quantitySelector.Value; index++) { profitTargetOrder = myAccount.CreateOrder( orderUpdateArgs.Order.Instrument, OrderAction.Sell, OrderType.Limit, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, currentPTPrice, 0, oco+index, "Profit Target", Core.Globals.MaxDate, null); submitTargetsOrdersList.Add(profitTargetOrder); // Print("Account_OrderUpdate SNIPPETS"); // Print("submitTargetsOrdersList.Count : " + submitTargetsOrdersList.Count); // Print("profitTargetOrder.OrderState == OrderState.Filled : " + (profitTargetOrder.OrderState == OrderState.Filled)); // Print("profitTargetOrder.OrderState == OrderState.Cancelled: " + (profitTargetOrder.OrderState == OrderState.Cancelled)); // Print("profitTargetOrder.OrderState == OrderState.Rejected: " + (profitTargetOrder.OrderState == OrderState.Rejected)); // Print(" "); } } if (UseStopLoss) { currentSLPrice = orderUpdateArgs.AverageFillPrice - StopLossDistance * TickSize; for (int index = 0; index < quantitySelector.Value; index++) { stopLossOrder = myAccount.CreateOrder( orderUpdateArgs.Order.Instrument, OrderAction.Sell, OrderType.StopMarket, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, 0, currentSLPrice, oco+index, "Stop Loss", Core.Globals.MaxDate, null); submitStopLossesOrdersList.Add(stopLossOrder); } } myAccount.Submit(submitTargetsOrdersList); myAccount.Submit(submitStopLossesOrdersList); })); } #endregion #region SHORT Order Target and StopLoss OCO orders if (entrySellMarketOrder != null && entrySellMarketOrder == orderUpdateArgs.Order && orderUpdateArgs.Order.OrderState == OrderState.Filled) { string oco = Guid.NewGuid().ToString("N"); // submitTargetsOrdersList = new List<Order>(); // submitStopLossesOrdersList = new List<Order>(); await ChartControl.Dispatcher.InvokeAsync((Action) (() => { if (UseProfitTarget) { currentPTPrice = orderUpdateArgs.AverageFillPrice - ProfitTargetDistance * TickSize; for (int index = 0; index < quantitySelector.Value; index++) { profitTargetOrder = myAccount.CreateOrder( orderUpdateArgs.Order.Instrument, OrderAction.Buy, OrderType.Limit, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, currentPTPrice, 0, oco+index, "Profit Target", Core.Globals.MaxDate, null); submitTargetsOrdersList.Add(profitTargetOrder); } } if (UseStopLoss) { currentSLPrice = orderUpdateArgs.AverageFillPrice + StopLossDistance * TickSize; for (int index = 0; index < quantitySelector.Value; index++) { stopLossOrder = myAccount.CreateOrder( orderUpdateArgs.Order.Instrument, OrderAction.Buy, OrderType.StopMarket, OrderEntry.Automated, TimeInForce.Day, orderUpdateArgs.Quantity, 0, currentSLPrice, oco+index, "Stop Loss", Core.Globals.MaxDate, null); submitStopLossesOrdersList.Add(stopLossOrder); } } myAccount.Submit(submitTargetsOrdersList); myAccount.Submit(submitStopLossesOrdersList); })); } #endregion // once the exit orders are closed, reset for a new entry. else if ((profitTargetOrder != null && (profitTargetOrder.OrderState == OrderState.Filled || profitTargetOrder.OrderState == OrderState.Rejected || profitTargetOrder.OrderState == OrderState.Cancelled)) || (stopLossOrder != null && (stopLossOrder.OrderState == OrderState.Filled || stopLossOrder.OrderState == OrderState.Rejected || stopLossOrder.OrderState == OrderState.Cancelled))) { } } #endregion #region OnBarUpdate Prints Snippets protected override void OnBarUpdate() { if (myAccount != null && myAccount.Positions.Where(o => o.Instrument == Instrument).Count() > 0) accountPosition = myAccount.Positions.Where(o => o.Instrument == Instrument).Last(); else accountPosition = null; if (accountPosition == null) { entryBuyMarketOrder = null; entrySellMarketOrder = null; profitTargetOrder = null; stopLossOrder = null; multiOrders.Clear(); submitTargetsOrdersList.Clear(); submitStopLossesOrdersList.Clear(); } else { } } #endregion #region DisposeCleanUp Snippet private void DisposeCleanUp() { //ChartWindow Null Check if (chartWindow != null) { //Dispatcher used to Assure Executed on UI Thread ChartControl.Dispatcher.InvokeAsync((Action)(() => { if( quantitySelector != null ) chartWindow.MainMenu.Remove(quantitySelector); })); } } #endregion #region Properties [TypeConverter(typeof(NinjaTrader.NinjaScript.AccountNameConverter))] [Display(Name = "Account Name", Description = "Selects The Account (from Ones Available)", Order = 1, GroupName = "#1 Account Selector")] public string AccountName { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Profit Target Distance", Description = "Sets The ProfitTarget OCO Order Distance (in ticks)", Order = 2, GroupName = "#2 Indicator's Input Setings")] public int ProfitTargetDistance { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Stop Loss Distance", Description = "Sets The StopLoss OCO Order Distance (in ticks)", Order = 3, GroupName = "#2 Indicator's Input Setings")] public int StopLossDistance { get; set; } [NinjaScriptProperty] [Display(Name = "Use Profit Target", Description = "Enables ProfitTarget OCO Order", Order = 4, GroupName = "#2 Indicator's Input Setings")] public bool UseProfitTarget { get; set; } [NinjaScriptProperty] [Display(Name = "Use Stop Loss", Description = "Enables StopLoss OCO Order", Order = 5, GroupName = "#2 Indicator's Input Setings")] public bool UseStopLoss { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Profit Target Move (<= Profit Target Distance)", Description = "Sets The ProfitTarget OCO Order move (in ticks)", Order = 6, GroupName = "#2 Indicator's Input Setings")] public int ProfitTargetMove { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Stop Loss Move (<= Stop Loss Distance)", Description = "Sets The StopLoss OCO Order move (in ticks)", Order = 7, GroupName = "#2 Indicator's Input Setings")] public int StopLossMove { get; set; } [NinjaScriptProperty] [Display(Name = "Print Details", Description = "Prints In Output Window (Debugging)", Order = 8, GroupName = "#3 Debug Mode")] public bool PrintDetails { get; set; } #endregion } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private ProfitSnipers[] cacheProfitSnipers; public ProfitSnipers ProfitSnipers(int profitTargetDistance, int stopLossDistance, bool useProfitTarget, bool useStopLoss, int profitTargetMove, int stopLossMove, bool printDetails) { return ProfitSnipers(Input, profitTargetDistance, stopLossDistance, useProfitTarget, useStopLoss, profitTargetMove, stopLossMove, printDetails); } public ProfitSnipers ProfitSnipers(ISeries<double> input, int profitTargetDistance, int stopLossDistance, bool useProfitTarget, bool useStopLoss, int profitTargetMove, int stopLossMove, bool printDetails) { if (cacheProfitSnipers != null) for (int idx = 0; idx < cacheProfitSnipers.Length; idx++) if (cacheProfitSnipers[idx] != null && cacheProfitSnipers[idx].ProfitTargetDistance == profitTargetDistance && cacheProfitSnipers[idx].StopLossDistance == stopLossDistance && cacheProfitSnipers[idx].UseProfitTarget == useProfitTarget && cacheProfitSnipers[idx].UseStopLoss == useStopLoss && cacheProfitSnipers[idx].ProfitTargetMove == profitTargetMove && cacheProfitSnipers[idx].StopLossMove == stopLossMove && cacheProfitSnipers[idx].PrintDetails == printDetails && cacheProfitSnipers[idx].EqualsInput(input)) return cacheProfitSnipers[idx]; return CacheIndicator<ProfitSnipers>(new ProfitSnipers(){ ProfitTargetDistance = profitTargetDistance, StopLossDistance = stopLossDistance, UseProfitTarget = useProfitTarget, UseStopLoss = useStopLoss, ProfitTargetMove = profitTargetMove, StopLossMove = stopLossMove, PrintDetails = printDetails }, input, ref cacheProfitSnipers); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.ProfitSnipers ProfitSnipers(int profitTargetDistance, int stopLossDistance, bool useProfitTarget, bool useStopLoss, int profitTargetMove, int stopLossMove, bool printDetails) { return indicator.ProfitSnipers(Input, profitTargetDistance, stopLossDistance, useProfitTarget, useStopLoss, profitTargetMove, stopLossMove, printDetails); } public Indicators.ProfitSnipers ProfitSnipers(ISeries<double> input , int profitTargetDistance, int stopLossDistance, bool useProfitTarget, bool useStopLoss, int profitTargetMove, int stopLossMove, bool printDetails) { return indicator.ProfitSnipers(input, profitTargetDistance, stopLossDistance, useProfitTarget, useStopLoss, profitTargetMove, stopLossMove, printDetails); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.ProfitSnipers ProfitSnipers(int profitTargetDistance, int stopLossDistance, bool useProfitTarget, bool useStopLoss, int profitTargetMove, int stopLossMove, bool printDetails) { return indicator.ProfitSnipers(Input, profitTargetDistance, stopLossDistance, useProfitTarget, useStopLoss, profitTargetMove, stopLossMove, printDetails); } public Indicators.ProfitSnipers ProfitSnipers(ISeries<double> input , int profitTargetDistance, int stopLossDistance, bool useProfitTarget, bool useStopLoss, int profitTargetMove, int stopLossMove, bool printDetails) { return indicator.ProfitSnipers(input, profitTargetDistance, stopLossDistance, useProfitTarget, useStopLoss, profitTargetMove, stopLossMove, printDetails); } } } #endregion