Snippets e How-to Snippets para Ordens e Administração de Trade Estimated reading: 10 minutes 410 views Esta seção visa apresentar trechos de códigos com exemplos de envio de ordens e administração de trade utilizando técnicas de stoploss (fixo, móvel, breakeven) e take profit. Você pode acessar os Snippets diretamente pelo menu lateral direito, ou fazendo CRL+F (CTRL+L) para localizar algum texto específico na página, uma vez que o conteúdo tende a crescer ao longo do tempo, dificultando a navegação pelo menu. Caso tenham sugestões de código para acrescentar à lista, gentileza deixar o código nos comentários com o link para seu perfil em rede social (para devido crédito de autoria). Snippets Como rotear ordens de maneira fácil (Modo gerenciado)? A NinjaTrader possui em seu NinjaScript uma camada de abstração para envio e gestão de ordens. Este modo é chamado de modo gerenciado e seu funcionamento torna bem simples a implementação de estratégias para iniciantes e até mesmo pessoas com conhecimento intermediário.No modo gerenciado, as ordens são válidas apenas até o próximo candle/barra, o que simplifica a gestão de ordens abertas e cancelamentos. E também há diversos controles que reduzem a chance de problemas na administração da posição da estratégia.Veja abaixo um exemplo do envio de ordens em NinjaScript utilizando o modo gerenciado. #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 TestingOrdersStrategy : Strategy { private TimeSpan tsOpen; private TimeSpan tsClose; private Order myOrder; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Strategy here."; Name = "TestingOrdersStrategy"; Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 30; IsFillLimitOnTouch = false; MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix; OrderFillResolution = OrderFillResolution.Standard; Slippage = 0; StartBehavior = StartBehavior.WaitUntilFlat; TimeInForce = TimeInForce.Gtc; TraceOrders = false; RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose; StopTargetHandling = StopTargetHandling.PerEntryExecution; BarsRequiredToTrade = 20; // Disable this property for performance gains in Strategy Analyzer optimizations // See the Help Guide for additional information IsInstantiatedOnEachOptimizationIteration = true; PositionOpeningTime = DateTime.Parse("10:30", System.Globalization.CultureInfo.InvariantCulture); PositionClosingTime = DateTime.Parse("10:36", System.Globalization.CultureInfo.InvariantCulture); } else if (State == State.Configure) { tsOpen = new TimeSpan(PositionOpeningTime.Hour, PositionOpeningTime.Minute, 0); tsClose = new TimeSpan(PositionClosingTime.Hour, PositionClosingTime.Minute, 0); } } protected override void OnBarUpdate() { //Match real-time order object based on a historical order object (run just once) if (myOrder != null && myOrder.IsBacktestOrder && State == State.Realtime) myOrder = GetRealtimeOrder(myOrder); //Open position at specified time (tsOpen) if ((Time[0].TimeOfDay == tsOpen) && (Position.MarketPosition == MarketPosition.Flat)) { myOrder = EnterLong("openingSignal"); //myOrder = EnterLongLimit(4451.25, "openingSignal"); //myOrder = EnterLongStopMarket(4454.50, "openingSignal"); //This will not open position, since the price reach that price a few bars after the order was submitted (Managed orders) //myOrder = EnterLongLimit(4450, "openingSignal"); //This will not open position, since the price reach that price only 2 bars after the order was submitted (Managed orders) //myOrder = EnterLongStopMarket(4455, "openingSignal"); } //Close position at specified time (tsClose) if (Time[0].TimeOfDay == tsClose) { if (Position.MarketPosition == MarketPosition.Long) { ExitLong("openingSignal"); } if (Position.MarketPosition == MarketPosition.Short) { ExitShort("openingSignal"); } } } #region Properties [NinjaScriptProperty] [PropertyEditor("NinjaTrader.Gui.Tools.TimeEditorKey")] [Display(Name="OpeningTIime", Order=1, GroupName="Parameters")] public DateTime PositionOpeningTime { get; set; } [NinjaScriptProperty] [PropertyEditor("NinjaTrader.Gui.Tools.TimeEditorKey")] [Display(Name="ClosingTime", Order=2, GroupName="Parameters")] public DateTime PositionClosingTime { get; set; } #endregion } } Como fazer Gestão de Risco das operações de maneira simples (Stoploss/TakeProfit)? No âmbito da camada de abstração do NinjaScript, existem algumas funções que facilitam bastante a adoção de práticas de gestão de risco para operações no código fonte. Veja abaixo duas formas de definir o stoploss e alvo (take profit) das operações de maneira estática, ou seja, fixa durante toda a execução da estratégia, ou de maneira dinâmica, ajustando o risco de acordo com as condições do mercado. Gestão de risco estática Nesta situação, os parâmetros para o stoploss e alvo das operações são definidos na transição para o estado Configure da estratégia, podendo inclusive, serem utilizados parâmetros de entrada para fins de otimização futura. #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 TestingOpRiskManagement : Strategy { private TimeSpan tsOpen; private TimeSpan tsClose; private Order myOrder; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Strategy here."; Name = "TestingOpRiskManagement"; Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 30; IsFillLimitOnTouch = false; MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix; OrderFillResolution = OrderFillResolution.Standard; Slippage = 0; StartBehavior = StartBehavior.WaitUntilFlat; TimeInForce = TimeInForce.Gtc; TraceOrders = false; RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose; StopTargetHandling = StopTargetHandling.PerEntryExecution; BarsRequiredToTrade = 20; // Disable this property for performance gains in Strategy Analyzer optimizations // See the Help Guide for additional information IsInstantiatedOnEachOptimizationIteration = true; PositionOpeningTime = DateTime.Parse("10:30", System.Globalization.CultureInfo.InvariantCulture); PositionClosingTime = DateTime.Parse("16:00", System.Globalization.CultureInfo.InvariantCulture); } else if (State == State.Configure) { tsOpen = new TimeSpan(PositionOpeningTime.Hour, PositionOpeningTime.Minute, 0); tsClose = new TimeSpan(PositionClosingTime.Hour, PositionClosingTime.Minute, 0); // Static risk management. Stoploss and Target are defined and maintained fixed through the strategy lifetime SetStopLoss(CalculationMode.Ticks, 20); //SetTrailStop(CalculationMode.Ticks, 24); SetProfitTarget(CalculationMode.Ticks, 60); } } protected override void OnBarUpdate() { if (myOrder != null && myOrder.IsBacktestOrder && State == State.Realtime) myOrder = GetRealtimeOrder(myOrder); //Open position at specified time (tsOpen) if ((Time[0].TimeOfDay == tsOpen) && (Position.MarketPosition == MarketPosition.Flat)) { Random rnd = new Random(); if (rnd.Next(0,2) == 0) myOrder = EnterLong("openingSignal"); else myOrder = EnterShort("openingSignal"); } //Close position at specified time (tsClose) if (Time[0].TimeOfDay == tsClose) { if (Position.MarketPosition == MarketPosition.Long) { ExitLong("openingSignal"); } if (Position.MarketPosition == MarketPosition.Short) { ExitShort("openingSignal"); } } } #region Properties [NinjaScriptProperty] [PropertyEditor("NinjaTrader.Gui.Tools.TimeEditorKey")] [Display(Name="OpeningTIime", Order=1, GroupName="Parameters")] public DateTime PositionOpeningTime { get; set; } [NinjaScriptProperty] [PropertyEditor("NinjaTrader.Gui.Tools.TimeEditorKey")] [Display(Name="ClosingTime", Order=2, GroupName="Parameters")] public DateTime PositionClosingTime { get; set; } #endregion } } Gestão de risco dinâmica Nesta situação, os parâmetros para o stoploss e alvo das operações são definidos no método onBarUpdate e a frequencia de atualização dependerá da propriedade da estratégia relacionada a frequência de cálculo. Neste modo, o trader pode utilizar qualquer lógica que desejar, podendo inclusive utilizar indicadores técnicos, a exemplo do ATR (Average True Range). #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 TestingOpRiskManagement : Strategy { private TimeSpan tsOpen; private TimeSpan tsClose; private Order myOrder; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Strategy here."; Name = "TestingOpRiskManagement"; Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 30; IsFillLimitOnTouch = false; MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix; OrderFillResolution = OrderFillResolution.Standard; Slippage = 0; StartBehavior = StartBehavior.WaitUntilFlat; TimeInForce = TimeInForce.Gtc; TraceOrders = false; RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose; StopTargetHandling = StopTargetHandling.PerEntryExecution; BarsRequiredToTrade = 20; // Disable this property for performance gains in Strategy Analyzer optimizations // See the Help Guide for additional information IsInstantiatedOnEachOptimizationIteration = true; PositionOpeningTime = DateTime.Parse("10:30", System.Globalization.CultureInfo.InvariantCulture); PositionClosingTime = DateTime.Parse("16:00", System.Globalization.CultureInfo.InvariantCulture); } else if (State == State.Configure) { tsOpen = new TimeSpan(PositionOpeningTime.Hour, PositionOpeningTime.Minute, 0); tsClose = new TimeSpan(PositionClosingTime.Hour, PositionClosingTime.Minute, 0); // Static risk management. Stoploss and Target are defined and maintained fixed through the strategy lifetime //SetStopLoss(CalculationMode.Ticks, 20); //SetTrailStop(CalculationMode.Ticks, 24); //SetProfitTarget(CalculationMode.Ticks, 60); } } protected override void OnBarUpdate() { if (myOrder != null && myOrder.IsBacktestOrder && State == State.Realtime) myOrder = GetRealtimeOrder(myOrder); //Open position at specified time (tsOpen) if ((Time[0].TimeOfDay == tsOpen) && (Position.MarketPosition == MarketPosition.Flat)) { Random rnd = new Random(); double volatility = Math.Ceiling(ATR(500)[0]/TickSize); double stoplossTicks = 5*volatility; double takeProfitTicks = 3*stoplossTicks; // Dynamic risk management. Stoploss and Target are adapted to market conditions SetTrailStop(CalculationMode.Ticks, stoplossTicks); SetProfitTarget(CalculationMode.Ticks, takeProfitTicks); Print("CurrentBar: " + CurrentBar.ToString() + " - Stoploss: " + stoplossTicks.ToString() + " ticks | Target: " + takeProfitTicks.ToString() + " ticks"); if (rnd.Next(0,2) == 0) myOrder = EnterLong("openingSignal"); else myOrder = EnterShort("openingSignal"); } //Close position at specified time (tsClose) if (Time[0].TimeOfDay == tsClose) { if (Position.MarketPosition == MarketPosition.Long) { ExitLong("openingSignal"); } if (Position.MarketPosition == MarketPosition.Short) { ExitShort("openingSignal"); } } } #region Properties [NinjaScriptProperty] [PropertyEditor("NinjaTrader.Gui.Tools.TimeEditorKey")] [Display(Name="OpeningTIime", Order=1, GroupName="Parameters")] public DateTime PositionOpeningTime { get; set; } [NinjaScriptProperty] [PropertyEditor("NinjaTrader.Gui.Tools.TimeEditorKey")] [Display(Name="ClosingTime", Order=2, GroupName="Parameters")] public DateTime PositionClosingTime { get; set; } #endregion } }