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

Tutoriais sobre Estrutura do código

Leitura estimada: 14 minutos 82 views

Introdução

Esta seção visa apresentar trechos de códigos com funcionalidades relativas à estrutura do código de indicadores e estratégias. Por exemplo, como criar parâmetros de entrada.

Você pode acessar os Snippets/Tutoriais diretamente pelo menu lateral direito, ou fazendo CTRL+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/Tutoriais

Como criar parâmetros no meu indicador/estratégia?

Os parâmetros de uma estratégia ou indicador são declarados como atributos da classe.

O que diferencia esses atributos dos demais atributos são as anotações (em C# chama-se Annotations e são contidas entre [ ]) que realizamos imediatamente antes da definição dos atributos. Vamos ver abaixo como criar diferentes tipos de parâmetros, como definir seu valor padrão, qual texto será exibido na interface de configuração da estratégia/indicador e pré-validações.

A primeira anotação que realizamos é invocar a função InputParameter. Esta função recebe 3 parâmetros: Tipo do parâmetro da estratégia, Texto a ser exibido na interface de configuração e a ordem de apresentação.

Os tipos de parâmetros possíveis em EvoCode são: Combobox, Checkbox, Numeric ,Color, Instrument, Account, String, DateTime e TimeSpan. Sendo Numeric e ComboBox os mais utilizados. O texto a ser exibido consiste em uma string de sua livre escolha e a ordem deve ser um inteiro iniciando em zero o qual irá ordenar a exibição dos parâmetros na janela de configuração da estratégia.

Existe também uma sobrecarga da função InputParameter, na qual não é necessário informar o parâmetro de ordem. Ao utilizar essa função, os parâmetros da estratégia terão exatamente a ordem na qual são criados no código-fonte.

A segunda anotação que pode ser utilizada é um validador. O usuário pode ver no dicionário EvoCode que existem uma função de validação para parâmetros numéricos chamada SimpleNumericAttribute. Este método é sobrecarregado, ou seja, possui diferentes combinações de parâmetros que realizam diferentes validações. Nos exemplos abaixo, ficará claro o uso desse método.

A terceira anotação possível é utilizada no caso de parâmetros exibidos no formato de ComboBox, ou seja, caixa de seleção. Nesse caso, podem ser inseridas quantas anotações forem necessárias para cada opção do ComboBox, invocando a função ComboBoxItem e passando como parâmetro a chave e o valor. Entenda chave como a string que será apresentada no combobox e valor como a representação da opção selecionada, que pode ser um número inteiro ou um enum.

Veja a seguir alguns exemplos de definição de parâmetros para estratégia:

Parâmetro Inteiro (Exemplo: Qtde de períodos de uma média móvel)

No código abaixo a tela de configuração da estratégia/indicador apresentará como primeiro parâmetro a ser definido a “Média rápida – Qtde de periodos” que é do tipo numérico e inteiro, variando entre 1 e 9999. Dentro do código esse parâmetro é reconhecido pelo nome fastestPeriod e a caixa de texto da tela de configuração já irá exibir o valor padrão igual a 5, conforme definido no código.

				
					[InputParameter(InputType.Numeric, "Média rápida - Qtde de periodos", 0)]
		[SimpleNumeric(1D,9999D)]
		public int fastestPeriod = 5;
				
			
Parâmetro ComboBox (Exemplo: Tipo da média móvel)

No código abaixo a tela de configuração da estratégia/indicador apresentará como segundo parâmetro a ser definido a “Média rápida – Tipo da média”, que apresentará em um comboBox as seguintes opções: SMA, EMA, SMMA, LWMA. O valor padrão desse parâmetro será a média aritmética. Observe que dentro do código, esse parâmetro de tipo de média utiliza um eNum pré-definido do EvoCode chamado MAMode.

Caso haja até 3 opções de seleção, a renderização desse componente na interface gráfica da plataforma será no formato de RadioBox ou invés de ComboBox (Caixa de seleção).

				
							[InputParameterAttribute(InputType.Combobox, "Média rápida - Tipo da média", 1)]
		[ComboboxItem("Aritmética (SMA)", MAMode.SMA)]
		[ComboboxItem("Exponencial (EMA)", MAMode.EMA)]
		[ComboboxItem("Amortecida (SMMA)", MAMode.SMMA)]		
		[ComboboxItem("Ponderada Linear (LWMA)", MAMode.LWMA)]		
		public MAMode fastestAvgType = MAMode.SMA;
				
			
Parâmetro Percentual

No código abaixo a tela de configuração da estratégia/indicador apresentará como primeiro parâmetro a ser definido a “bandPct”, que apresentará em uma caixa de texto com valor padrão igual a 2. É um parâmetro do tipo double e observe a anotação de validação possui 4 parâmetros, o que validará: valor mínimo (0.0), valor máximo (9999) precisão numérica (1 casa decimal) e incremento mínimo (0.1).

				
					        [InputParameter(InputType.Numeric, "bandPct", 0)]
        [SimpleNumeric(0.0D, 9999D, 1, 0.1)]
        public double bandPct = 2;
				
			
Código de um indicador com TODOS os tipos de parâmetros em EvoCode

No código abaixo você encontrará um exemplo de um indicador com todos os tipos de parâmetros possíveis em EvoCode.

				
					using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Runtime.Script;
using TradeApi;
using TradeApi.History;
using TradeApi.Indicators;
using TradeApi.Instruments;
using TradeApi.ToolBelt;
using TradeApi.Trading;


namespace NeoTraderBot
{
    /// <summary>
    /// Indicator
    /// 
    /// </summary>
    public class TestingParameters : IndicatorBuilder 
    {
    	//Exemplo de parâmetro numérico inteiro
		[InputParameter(InputType.Numeric, "Periods", 0)]
		[SimpleNumeric(1D,9999D)]
		public int periods = 5;

		//Exemplo de parâmetro numérico percentual		
		[InputParameter(InputType.Numeric, "Percentage band (%)", 1)]
		[SimpleNumeric(0.0D, 9999D, 1, 0.1)]
		public double bandPct = 2.3;		

		//Exemplo de parâmetro ComboBox		
		[InputParameterAttribute(InputType.Combobox, "Average type", 2)]
		[ComboboxItem("Aritmética (SMA)", MAMode.SMA)]
		[ComboboxItem("Exponencial (EMA)", MAMode.EMA)]
		[ComboboxItem("Amortecida (SMMA)", MAMode.SMMA)]
		[ComboboxItem("Ponderada Linear (LWMA)", MAMode.LWMA)]
		public MAMode avgType = MAMode.SMA;
		
		[InputParameterAttribute(InputType.Checkbox, "Daytrade mode", 3)]
		public Boolean dayTradeMode;
		
		[InputParameterAttribute(InputType.String, "Input message", 4)]
		public string msg = "Hello EvoCode!";
		
		[InputParameterAttribute(InputType.Color, "Color", 5)]
		public Color someColor = Color.Orange;
		
		[InputParameterAttribute(InputType.Instrument, "Symbol", 6)]
		public Instrument instrument;		
		
		[InputParameterAttribute(InputType.DateTime, "Trading start on:", 7)]
		public DateTime startDateTime = DateTime.Now.AddDays(-3);
		
		[InputParameterAttribute(InputType.TimeSpan, "Open position after:", 8)]
		public TimeSpan openPosAfter = DateTime.Now.TimeOfDay;
    	
        public TestingParameters()
            : base()
        {
			#region Initialization
            Credentials.Author = "";
            Credentials.Company = "";
            Credentials.Copyrights = "";
            Credentials.DateOfCreation = new DateTime(2023, 7, 21);
            Credentials.ExpirationDate = DateTime.MinValue;
            Credentials.Version = "";
            Credentials.Password = "66b4a6416f59370e942d353f08a9ae36";
            Credentials.ProjectName = "TestingParameters";
            #endregion 
            
            Lines.Set("indicator");
			Lines["indicator"].Color = Color.Blue;

            SeparateWindow = false;
        }
        
        /// <summary>
        /// This function will be called after creating
        /// </summary>
		public override void Init()
		{
			string param = "Parâmetros:\n";
			param += "Periods: " + periods.ToString() + "\n";
			param += "Percentage band (%): " + bandPct.ToString() + "\n";
			param += "Average type: " + avgType.ToString() + "\n";
			param += "Daytrade mode: " + dayTradeMode.ToString() + "\n";
			param += "Input message: " + msg + "\n";
			param += "Color: " + someColor.Name + "\n";
			param += "Symbol: " + instrument.Symbol.ToString() + "\n";
			param += "Trading start on: " + startDateTime.ToLongDateString() + "\n";
			param += "Open position after: " + openPosAfter.ToString() + "\n";
		
			Notification.Comment(param);
			
		}        
 
        /// <summary>
        /// Entry point. This function is called when new quote comes or new bar created
        /// </summary>
        public override void Update(TickStatus args)
        {
			Lines["indicator"].SetValue(HistoryDataSeries.GetValue(PriceType.Close));
        }
        
        /// <summary>
        /// This function will be called before removing
        /// </summary>
		public override void Complete()
		{
			
		} 
     }
}

				
			

O que são as credenciais do meu código?

As credenciais servem para identificar a sua estratégia com os atributos de Autor, Empresa, Direitos Autorais (se for o caso), Data de criação do código, Data de Expiração, Versão do código, Senha e Nome do Projeto (este é o nome que irá aparecer nas listagens dentro da plataforma). 

A utilização de #region não tem nenhum impacto sobre o código, sendo apenas uma funcionalidade .NET para poder expandir ou colapsar blocos de código na IDE (ambiente de desenvolvimento).

OBS: É importante ressaltar que se você configurar a data de expiração para um valor diferente de “DateTime.MinValue”, compilar o seu código e compartilhar ele com alguém, o código executará apenas até a data de expiração.

				
					#region Initialization
Credentials.Author = "Johnathas Carvalho";
Credentials.Company = "Comunidade NeoTraderBot";
Credentials.Copyrights = "";
Credentials.DateOfCreation = new DateTime(2023, 5, 16);
Credentials.ExpirationDate = DateTime.MinValue;
Credentials.Version = "1.0";
Credentials.Password = "66b4a6416f59370e942d353f08a9ae36";
Credentials.ProjectName = "NTB_TripleCrossoverIndicator";
Credentials.Description = "Descrição";
#endregion 
				
			

Como definir texto a ser apresentado no cabeçalho do gráfico o indicador?

A definição do texto a ser apresentado no cabeçalho do gráfico, quando seu indicador for aplicado deve ser realizada no método Init. Conforme exemplo abaixo.

É importante dizer que ScriptShortName é um atributo da Classe IndicatorBuilder e o que estamos fazendo é simplesmente atribuir valor a essa variável com uma string. Utilizou-se também a função de formatação de string que permite colocar placeholders (reserva de espaço) dentro da string e definir seus valores nos próximos parâmetros da função string.Format. A sequencia {0} é um placeholder que irá ser substituída pelo primeiro parâmetro, no caso, fastestAvgType.

 

				
					public override void Init()
{

ScriptShortName = (string.Format("NTB Crossover: {0}({1}) | {2}({3}) | {4}({5})",
                              fastestAvgType, fastestPeriod, fastAvgType, fastPeriod, slowAvgType, slowPeriod));

}  
				
			

Quais são os principais eventos que serão tratados pelo método Update?

As classes de indicador e estratégia (IndicatorBuilder e StrategyBuilder) podem lidar com diferentes tipos de eventos. Não obstante, existem 3 eventos que são comuns nessas duas classes e que exigem a implementação de 3 métodos, a saber: Init, Update e Complete.

O Método Init será executado sempre que um indicador/estratégia for inicializado dentro da plataforma TraderEvolution. Ou seja, quando o indicador for incluído em um gráfico um uma estratégia iniciar sua execução.

De maneira análoga, o método Complete é chamado ao final da execução do indicador ou estratégia.

Assim, resta falar do método Update que podemos dizer se tratar do coração do indicador/estratégia. Todos eventos durante a execução do seu código devem ser tratados no método Update, o qual recebe como parâmetro um objeto do tipo TickStatus chamado args).

O valor de args pode ser um dos três valores possíveis do eNum TickStatus: IsBar, IsQuote e IsHistory. Vamos explicar cada um desses eventos abaixo:

      • isBar: quando uma barra é encerrada, gera-se uma chamada ao método Update com o valor de args igual a isBar. Assim, o programador pode definir o que fazer no fechamento das barras no código dentro de Update. Sempre após um evento isBar, o método Update é chamado com um evento isQuote.
      • isQuote: este evento é sempre disparado para cada negociação recebida pela sua plataforma cliente (seu programa TraderEvolution). Assim, o programador pode definir o que fazer no tick. Nos dados históricos, isQuote é disparado 4 vezes para cada barra.
      • isHistory: este evento é disparado para cada barra enquanto seu código processa os dados históricos. Uma vez em tempo real, esse evento não é mais disparado.

Quais são as informações que consigo obter da conta do usuário logado pelo código?

Todas as estratégias/indicador tem acesso às informações da conta logada por meio da classe AccountManager, a qual pode retornar a conta atual e seus detalhes. O código abaixo demonstra como obter o e-mail do usuário que está executando o código.

Posição do DicionárioPropriedade
[0]Conta
[1]Saldo
[2]Saldo bloqueado
[3]L/P líquido aberto
[4]L/P bruto aberto
[5]Saldo projetado
[6]Nº de ordens
[7]Nº de posições
[8]Margem Inicial
[9]Nível de risco
[10]Nível de alerta de margem
[11]Nível “Stop Out”
[12]Fundos disponíveis
[13]Alerta de margem
[14]Manutenção de Margem
[15]Disponível para Retirada
[16]ID do usuário
[17]Login do usuário
[18]Cliente
[19]E-mail
[20]Bruto de hoje
[21]Taxas de hoje
[22]Líquido de hoje
[23]Volume de hoje
[24]Nº de negociações de hoje
[25]Valor da Ação
[26]Saldo em dinheiro
[27]Número do telefone
[28]Margem inicial
[29]Saldo + Risco total
[30]Situação da negociação
[31]Limite diário de perda
[32]Contagem máxima de ordens por dia
[33]Nº máximo de posições
[34]Nº máximo de ordens pendentes
[35]Capital de ordem máximo
[36]Margem disponível
[37]Valor de crédito
[38]Modo da conta
[39]Ativo
[40]Descrição do Ativo
[41]Tipo de conta
[42]Tipo de Ativo
[43]Taxa de juros
[44]Descontos de hoje
[45]Bloqueado para ‘Ações’
[46]Ganho incerto
[47]Modificar nivel de rebaixamento
[48]Quantidade máxima da posição
[49]Limite de perda semanal
[50]Perda diária
[51]Perda semanal
[52]Ordens de ações
[53]Valor da Opção
[54]Liquidez de Ações
[55]Perda não realizada
[56]Limite de perda não realizado
[57]Objetivo de lucro diário
[58]Limite de volume de ações
[59]Limite de volume futuro
[60]Limite de volume de opções
[61]Procuração
[62]Valor da ordem máximo
[63]Req. de prêmio de opção
[64]Rebaixamento Máximo
[65]Margem isenta
[66]Warn. margin req.
[67]Warn. margin req.%
[68]Margin before warning
Obtendo e-mail do usuário
				
					Dictionary<string, string> detalhesConta = AccountManager.Current.GetAccountDetails();
string email = "";
if (detalhesConta.TryGetValue("E-mail", out email))
{
    Notification.Print(email);
}
				
			

Como identificar se o código está rodando em conta real ou conta demo?

				
					string tipoConta = "";
Boolean contaReal = false;

Dictionary<string, string> detalhesConta = AccountManager.Current.GetAccountDetails();
if (detalhesConta.TryGetValue("Conta", out tipoConta))
{
    if (!tipoConta.Contains("demo"))
    {
        contaReal = true;
    }
}
				
			

2 Comments

  • ZynTech Tecnologia em Envestimentos

    Agosto 28, 2023

    É sempre muito bom poder contar com a documentação apresentada neste site, pois é comum termos pequenas dúvidas durante o desenvolvimentos de estratégias. Parabéns pela iniciativa!

    Reply
    • Johnathas

      Agosto 28, 2023

      Obrigado, ZynTech! TMJ!

      Reply

Leave a Comment

CONTENTS