Neo traderBot

Neo traderBot

Você sabia?

Um backtesting adequado deve buscar simular situações práticas do mercado (slippage, custo de operação, etc...)

Snippets e How-to

Snippets para Ordens e Administração de Trade

Leitura estimada: 10 minutos 132 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)?

Reproduzir vídeo

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)?

Reproduzir vídeo

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

	}
}
				
			

Leave a Comment

CONTENTS