English Русский 中文 Español Deutsch 日本語 Italiano
A matemática do mercado: lucro, prejuízo e custos

A matemática do mercado: lucro, prejuízo e custos

MetaTrader 5Exemplos | 24 novembro 2022, 08:59
674 0
Evgeniy Ilin
Evgeniy Ilin

Conteúdo

Introdução

Ao desenvolver Expert Advisors, eu não prestei atenção para o significado de certos valores ao calcular os lucros ou prejuízos. Para a criação de EAs não é necessário se aprofundar nesta questão. Na verdade, por que eu devo entender todos esses valores, considerando que a MQL5 e até mesmo a MQL4 contêm todas as funcionalidades necessárias para realizar cálculos?

No entanto, após um certo tempo e uma certa quantidade de experiência, as perguntas inevitavelmente começam a surgir. Eventualmente, nós começamos a perceber tais detalhes que antes nos pareciam insignificantes. Depois de pensar um pouco sobre isso, você percebe que o EA é obscuro. Todos os dados sobre o assunto que consegui encontrar na Internet revelaram-se escassos e desestruturados. Então eu decidi estruturá-lo sozinho. Depois de ler este artigo, você receberá um modelo matemático completo e funcional, além de aprender a entender e calcular corretamente tudo relacionado as ordens.

Equações para calcular os lucros ou prejuízos das ordens

Para desenvolver um sistema de negociação eficiente, em primeiro lugar, é necessário entender como o lucro ou prejuízo de cada ordem é calculado. Todos nós somos capazes de calcular os nossos lucros e prejuízos de alguma forma para manter o nosso sistema de gerenciamento de dinheiro. Alguém faz isso intuitivamente, alguém faz estimativas aproximadas, mas quase todo EA tem os cálculos necessários de todas as quantidades necessárias. Desenvolver EAs dá disciplina aos seus pensamentos e faz você entender o que é e como ele é calculado, o que não tem preço. Agora vamos ao que interessa. Vale a pena começar com a ideia mais simples de como é calculado o lucro de uma ordem. Pessoalmente, eu sempre soube que o cálculo do lucro é bastante complexo em sua essência, mas se baseia em algumas considerações simples. Para simplificar o entendimento, vamos supor que não existam spread, swap e comissão. Eu acho que muitas pessoas nem levam em conta esses valores no começo. É claro que a linguagem MQL5 fornece funções integradas, como OrderCalcProfit e possivelmente outras, mas neste artigo quero abordar o básico para que todos entendam o que é calculado e como. Tal meticulosidade pode ser desconcertante, mas não prestar atenção a parâmetros como spread, comissão e swap é um erro fatal que muitos traders cometem. Cada um desses valores afeta o lucro ou prejuízo à sua maneira. Em meus cálculos, eu levarei tudo em consideração e mostrarei como essas pequenas coisas podem ajudar. Lucros e prejuízos de ordens excluindo spreads, comissões e swaps:

  • PrBuy = Lot * TickValue * [ ( PE - PS )/Point ] — lucro para uma ordem de compra
  • PrSell = Lot * TickValue * [ ( PS - PE )/Point ] — lucro para uma ordem de venda
  • Point — alteração mínima possível do preço em um símbolo selecionado
  • TickValue — valor do lucro para uma posição lucrativa quando o preço se move em “1” Ponto
  • PE — preço de fechamento da negociação (Bid)
  • PS — preço de abertura do negócio (Bid)

Esses valores como Point e TickValue na MQL5 são definidos no nível de variáveis predefinidas ou estão disponíveis na funcionalidade integrada na forma do valor de retorno das funções do tipo SymbolInfoDouble. Eu abordarei regularmente o tópico em MQL5 em meus artigos de uma forma ou de outra, porque muitas vezes é possível chegar ao fundo de muitos assuntos apenas analisando como a MQL5 ou sua determinada funcionalidade é construída.

Agora vamos expandir um pouco o entendimento dessa equação. Uma ordem de compra é aberta em Ask, enquanto uma ordem de venda é aberta em Bid. Assim, uma ordem de compra é fechada em Bid, enquanto uma ordem de venda é fechada em Ask. Vamos reescrever as equações tendo em conta as novas alterações:

  • PrBuy = Lot * TickValue * [ ( Bid2 – Ask1 )/Point ] — lucro para uma ordem de compra
  • PrSell = Lot * TickValue * [ ( Bid1 – Ask2 )/Point ] — lucro para uma ordem de venda
  • Bid1 — Preço de abertura da negociação de venda
  • Ask1 — Preço de abertura da negociação de compra
  • Bid2 — preço de fechamento da negociação de compra
  • Ask2 — preço de fechamento da negociação de venda

O fragmento da especificação abaixo contém a maioria dos dados que nós precisaremos posteriormente:

dados necessários

Isso é apenas parte dos dados que serão necessários para o cálculo. O restante dos dados pode ser obtido usando várias funções integradas em MQL5. Vamos pegar o USDJPY como exemplo. Na verdade, nós não precisamos de uma especificação para escrever um código, mas entender onde esses dados são exibidos pode ser muito útil.

Vamos considerar a comissão desta vez. A comissão por ordem pode ser calculada de várias maneiras, mas todos os métodos principais se resumem a uma porcentagem dos lotes que negociamos. Existem outras formas de cobrar uma comissão de negociação, mas não as considerarei aqui, pois não precisaremos delas. Vou considerar dois cenários possíveis para calcular a comissão. Acredito que sejam suficientes. Se tomarmos como base o swap, então os exemplos de swap podem sugerir outro método de cálculo comum que pode ser aplicado à comissão — cálculo em pontos.

Como resultado, nós temos dois métodos aparentemente diferentes. No entanto, como nós veremos, esses métodos são apenas uma forma conveniente de perceber o mesmo método de “tributação”, incluindo o spread. Abaixo estão duas equações para calcular a comissão:

  1. Comission = Lot * TickValue * ComissionPoints
  2. Comission = Lot * ContractSize * BidAlpha * ComissionPercent/100

Aqui nós vemos o novo valor “ContractSize”, que também possui uma implementação em MQL5 no nível de uma funcionalidade integrada que recebe informações do servidor de negociação. Este valor é um dos mais importantes e está presente em absolutamente todos os cálculos de lucros e prejuízos, embora de forma implícita, a fim de simplificar os cálculos para os programadores. Eu vejo a validade de tais simplificações do ponto de vista do programador. Mas o nosso objetivo atual é entender tudo. Você verá por que isso é necessário no final do artigo. Além disso, eu introduzi uma variável BidAlpha adicional. Eu também revelarei o seu significado abaixo. Os seguintes valores especificados na especificação do símbolo também aparecem:

  • ComissionPoints – comissão em pontos
  • ComissionPercent – comissão como uma porcentagem do tamanho do contrato
O multiplicador BidAlpha é necessário para converter um swap em unidades da moeda base em um swap em unidades de nosso saldo. Existem quatro cenários aqui:
  1. BidAlpha = 1 (se a moeda base for a mesma moeda de depósito)
  2. BidAlpha = Bid (do símbolo selecionado)
  3. BidAlpha = Bid (da taxa correspondente, onde a moeda base do símbolo selecionado é a mesma moeda base do símbolo de transição, e a segunda moeda é a mesma moeda do depósito)
  4. BidAlpha = 1/Ask (da taxa correspondente, onde a moeda base do símbolo selecionado é a mesma que a segunda moeda do símbolo de transição, e a moeda base é a mesma que a moeda de depósito)

De fato, se o tamanho do contrato for aplicado ao par USDCHF, fica claro que a moeda base do par selecionado é USD. Suponha que tenhamos um depósito em USD, então a moeda de transição se torna USDUSD e, portanto, sua taxa é sempre igual a um. O segundo caso é ainda mais simples. Suponha que nós temos um par EURUSD, que também é a taxa de conversão, então o Bid é o valor necessário. O terceiro caso pode ser assim. Suponha que nossa moeda seja o EURNZD. Então descobrimos que temos que encontrar a taxa de conversão de EUR e USD. A taxa EURUSD e o Bid desta taxa são o que nós precisamos. No quarto caso, as coisas são um pouco mais complicadas. Suponha que selecionamos CHFJPY. É claro que o par de transição é USDCHF, pois não existe taxa de câmbio CHFUSD no Forex. Claro, nós podemos criar nosso próprio símbolo sintético e trabalhar com CHFUSD. Neste caso, podemos usar o caso anterior. Mas, na verdade, só precisamos virar este símbolo, então sua taxa se tornará igual a "1/Ask" da taxa "inconveniente" atual. Na verdade, criamos um símbolo sintético sem focar nele. As mesmas coisas são verdadeiras para os swaps. Existem algumas outras questões também. Por exemplo, qual taxa deve ser usada na moeda de transição - Bid, Ask ou Mid? Esta questão não pode ser resolvida dentro da abordagem atual. Gradualmente, nós encontraremos a abordagem certa ao longo do caminho. E agora vamos definir a estrutura para melhoria, pelo menos de forma aproximada. Para fazer isso, nós devemos escrever pelo menos a primeira versão aproximada da equação geral de lucros e prejuízos, levando em consideração todas as opções de “tributação”, como spread, swap e comissão.

Para calcular os swaps, nós obtemos as equações semelhantes:

  1. Swap = Lot * TickValue * SwapPoints * SwapCount(StartTime,EndTime)
  2. Swap = Lot * ContractSize * BidAlpha * SwapPercent/100 * SwapCount(StartTime,EndTime)

As equações são realmente muito semelhantes. A única diferença é que o multiplicador certo apareceu aqui na forma da função SwapCount. Espero que você me permita alguma liberdade de terminologia. Eu chamo isso de "função", porque os swaps não são cobrados imediatamente, enquanto seu tamanho depende dos tempos de abertura e fechamento da ordem. Em uma aproximação grosseira, nós podemos, é claro, dispensar o multiplicador e escrever o seguinte:

  • SimpleCount = MathFloor( (EndTime -StartTime) / ( 24 * 60 * 60 ) )

Se assumirmos que EndTime e StartTime são do tipo 'datetime', então a sua diferença é igual ao número de segundos entre os pontos de abertura e fechamento da ordem. O swap é cobrado uma vez ao dia, então basta dividir esse valor pela quantidade de segundos em um dia. Desta forma, nós podemos ter uma primeira ideia de como as posições de swap podem ser avaliadas. Claro, esta equação está longe de ser perfeita, mas dá a resposta para a pergunta que tipo de função é e o que ela retorna. Além disso, ela pode sugerir como (pelo menos aproximadamente) o swap é calculado. Ela retorna o número de swaps acumulados durante a vida útil da posição. Da mesma forma, a comissão na especificação será um dos dois valores possíveis para o swap com a indicação obrigatória do método de cálculo:

  • SwapPoints – swap por uma rolagem de posição única em pontos
  • SwapPercent – swap para uma rolagem de uma única posição em % do tamanho do contrato

Se no caso da comissão as equações são mais simples e não requerem esclarecimentos, no caso do swap tudo é muito mais complicado, mas nós trataremos das sutilezas e nuances dessas simplificações mais adiante. Primeiro, vamos trazer as equações de lucros e prejuízos, excluindo as comissões e swaps, para uma forma mais consistente:

  • PrBuy = Lot * TickValue * [ ( Bid2 – (Bid1+S1*Point) )/Point ] — lucro para uma ordem de compra
  • PrSell = Lot * TickValue * [ ( Bid1 – (Bid2+S2*Point) )/Point ] — lucro para uma ordem de venda
  • S1 — spread ao abrir uma ordem de compra
  • S2 — spread ao fechar uma ordem de venda

É claro que Ask inclui o spread e Bid. Vamos separar o lucro ou prejuízo da ordem resultante do spread, tornando-o um somatório separado:

  • PrBuy = Lot * TickValue * [ ( Bid2 – Bid1)/Point ] + ( - Lot * TickValue * S1 ) — lucro para uma ordem de compra
  • PrSell = Lot * TickValue * [ ( Bid1 – Bid2)/Point ] + ( - Lot * TickValue * S2 ) — lucro para uma ordem de venda

Percebe-se que em ambas as equações foi separado um determinado montante, que é a parte cobrada pela corretora. Claro, esse não é o valor total, mas pelo menos agora você pode ver com mais clareza o que nós recebemos e o que o corretor leva. Observe que, no primeiro caso, nosso “imposto” sobre o spread depende apenas do valor do spread ao abrir uma posição “Compra” e, no segundo caso, ao fechar uma posição “Venda”. Acontece que nós damos ao corretor parte do nosso lucro na forma de um spread exatamente no momento da compra em todos os momentos. De fato, se nos aprofundarmos na negociação Forex, fica claro que abrir uma posição de compra e fechar uma posição de venda é uma ação equivalente confirmada por nossas equações. Nesse caso:

  • S1 — spread em pontos ao abrir qualquer posição
  • S2 — spread em pontos ao fechar qualquer posição

Esses valores são exatamente os que você pode ver na janela do Observador de Mercado se quiser exibir o spread. A função integrada SymbolInfoInteger correspondente com as entradas correspondentes e retorna exatamente os mesmos valores. Você pode encontrar as entradas na seção de Ajuda da MQL5. Minha tarefa neste caso é criar um modelo de cálculo matemático conveniente vinculado à linguagem MQL5 para que essas equações possam ser imediatamente codificadas em qualquer EA ou qualquer outro código útil em MQL5. Aqui está a nossa parcela, que agora é semelhante ao swap e à comissão:

  • SpreadBuy = - Lot * TickValue * S1
  • SpreadSell = - Lot * TickValue * S2

Spread na abertura e no fechamento

Convencionalmente, o spread é calculado no ponto de compra, mas agora eu vou mostrar porque isso está incorreto. Fiz muitas pesquisas de mercado e o ponto mais previsível de movimentação de preços acabou sendo o ponto “0:00”. Este é o ponto de transição de um dia para o outro. Se você observar cuidadosamente este ponto, você verá aproximadamente a mesma coisa em todos os pares de moedas — um salto em direção ao movimento de queda da taxa. Isso acontece devido a um aumento do spread neste momento. O salto é seguido por uma reversão de mesma magnitude. O que é o spread? Spread é uma diferença entre Bid e Ask. Convencionalmente, acredita-se que essa diferença seja consequência da profundidade do mercado. Se a profundidade do mercado estiver saturada de ordens limitadas, o spread tende a zero e, se os "players" deixarem o mercado, o spread aumenta. Nós podemos chamar isso de desintegração da profundidade do mercado. Mesmo à primeira vista, nós podemos dizer que o Bid não é o principal aqui. Acontece que Ask e Bid são fundamentalmente iguais. Isso é fácil de entender se imaginarmos que, por exemplo, é possível construir um instrumento espelho USDEUR a partir de “EURUSD”, e então Bid se torna Ask e, vice-versa, Ask se torna Bid. Simplificando, nós apenas invertemos a profundidade do mercado.

A linha Ask geralmente não é exibida no gráfico, embora isso seja útil:

bid & ask

Como nós podemos ver, Ask e Bid começam a se fundir junto com um aumento no período do gráfico. Talvez, devido a essas considerações, nenhuma plataforma exibe as duas linhas, embora eu pessoalmente ache que essa é uma opção necessária. No entanto, saber sobre a presença desses valores e suas diferenças não é tão importante, porque você ainda pode usar essas coisas em um EA. Eu não desenhei Mid aqui, mas acho que todos entendem que essa linha está exatamente no meio entre Bid e Ask. Claramente, para períodos maiores, a diferença entre esses valores praticamente não desempenha um papel, e parece que você nem precisa levar em conta a presença de Ask, mas na verdade é necessário. Esses detalhes são muito importantes.

Com isso em mente, nós podemos dizer com absoluta certeza que o meio da profundidade do mercado é uma invariante durante tais transformações. Este valor pode ser calculado da seguinte forma:

  • Mid = (Ask + Bid) / 2

Considerando tal representação e usando a última equação, nós podemos ver que:

  • Bid = Mid * 2 – Ask
  • Ask = Mid * 2 - Bid

Próximo:

  • Bid = Mid * 2 – (Bid + S*Point) = Mid – (S*Point)/2
  • Ask = Mid * 2 – (Ask - S*Point) = Mid + (S*Point)/2

Essas expressões agora podem ser substituídas nas equações originais para calcular o lucro ou prejuízo das ordens. Foi importante obter exatamente essas expressões, porque eu quero mostrar algo que você não entendia antes. Acontece que o valor cobrado pela corretora na verdade não depende apenas do ponto de compra, mas dos pontos de entrada e saída, bem como de qualquer posição. Vamos ver no que nossas equações se transformarão quando nós inserirmos novas definições estendidas lá. Nós podemos ver o seguinte:

  • PrBuy = Lot * TickValue * [ ( (Mid2 – (S2*Point)/2) – (Mid1 + (S1*Point)/2) ) )/Point ]
  • PrSell = Lot * TickValue * [ ( (Mid1 – (S1*Point)/2) – (Mid2 + (S2*Point)/2) ) )/Point ]

Após as transformações apropriadas, nós podemos ver o seguinte:

  • PrBuy = Lot * TickValue * [ (Mid2 – Mid1)/Point ] - Lot * TickValue * (  S1/2 + S2/2  )
  • PrSell = Lot * TickValue * [ (Mid1 – Mid2)/Point ] - Lot * TickValue * (  S1/2 + S2/2  )

Considerando que:

  • Bid1 = Mid1 – (S1*Point)/2
  • Bid2 = Mid2 – (S2*Point)/2
  • Ask1 = Mid1 + (S1*Point)/2
  • Ask2 = Mid2 + (S2*Point)/2

E lembrando que:

  • Mid1 — meio da profundidade do mercado ao abrir qualquer posição
  • Mid2 — meio da profundidade do mercado ao fechar qualquer posição

Por conveniência, nós denotamos o montante negativo definindo o prejuízo dos spreads da seguinte forma:

  • Spread = -Lot * TickValue * (  (S1*Point)/2 + (S2*Point)/2  )

E, consequentemente, o montante indicando lucro ou prejuízo excluindo o spread, comissão e swap, por exemplo:

  • ProfitIdealBuy = Lot * TickValue * [ (Mid2 – Mid1)/Point ]
  • ProfitIdealSell = Lot * TickValue * [ (Mid1 – Mid2)/Point ]

Agora nós podemos escrever as equações convenientes considerando todas os prejuízos de spread, comissão e swaps. Vamos começar com o protótipo da expressão. Vamos tomar como base as últimas equações de lucros e prejuízos da ordem, sendo o spread a única coisa considerada aqui:

  • TotalProfitBuy = ProfitIdealBuy + (Spread + Comission + Swap)
  • TotalProfitSell= ProfitIdealSell + (Spread + Comission + Swap)

Talvez eu devesse ter escrito essa equação logo no início, mas acho que ela é mais apropriada aqui. Podemos ver que o obscuro TickValue está presente em quase todos os lugares. A questão principal é como ele é calculado e como um e o mesmo valor pode ser usado para o cálculo em diferentes momentos. Pontos de tempo significam entradas e saídas de posições. Eu acho que você entende que esse valor é de natureza dinâmica e, além disso, ele é diferente para cada símbolo de negociação. Sem decompor esse valor em componentes, nós obteremos erros que serão maiores quanto mais distantes forem esses "alvos". Em outras palavras, as equações obtidas são apenas uma aproximação. Existe uma equação absolutamente exata desprovida dessas deficiências. As razões obtidas acima servem como o seu limite. Os próprios limites podem ser expressos da seguinte forma:

  • Lim[ dP -> 0 ] ( PrBuy(Mid1, Mid1+dP… ) ) = TotalProfitBuy(Mid1, Mid1+dP…)
  • Lim[ dP -> 0 ] ( PrSell(Mid1, Mid1+dP… ) ) = TotalProfitSEll(Mid1, Mid1+dP…)
  • Mid1+dP = Mid2 — o novo preço é obtido do anterior mais o delta tendendo a zero
  • TotalProfitBuy = TotalProfitBuy(P1,P2… ) — como foi determinado, o lucro ou prejuízo é uma função dos valores Mid e muitos outros
  • TotalProfitSell = TotalProfitSell(P1,P2… ) — similar

Em geral, os limites equivalentes para uma compreensão geral da situação podem ser desenhados de várias maneiras. Não há necessidade de multiplicá-los. No nosso caso, um é suficiente para maior clareza.

Embora tenhamos recebido algumas equações e elas até funcionem, os limites de aplicabilidade são muito condicionais. Em seguida, nós estaremos empenhados em obter as equações iniciais que envolvem tais equações aproximadas. Sem conhecer os blocos de construção de um lucro ou prejuízo, nós nunca obteremos essas equações. Por sua vez, essas equações nos ajudarão não apenas a encontrar as proporções mais precisas para calcular os lucros e prejuízos, mas também a encontrar o desequilíbrio dos processos de mercado, que posteriormente podem gerar lucro.

Método mais preciso para calcular o lucro e prejuízo das ordens

Para entender como construir essas equações, nós precisamos voltar ao básico, ou seja, o que é Comprar e Vender. Mas antes, eu acho importante lembrar que comprar na verdade significa trocar o seu dinheiro por um produto. Outra moeda pode ser vista como uma mercadoria, pois ela simboliza a capacidade de possuir certos bens. Então fica claro que a venda é o processo inverso de trocar a segunda moeda pela primeira. Mas se nós omitirmos todas as convenções, veremos que comprar e vender são ações equivalentes. Uma moeda é trocada por outra e a única diferença é qual moeda damos e qual recebemos em troca.

Ao procurar informações sobre esses cálculos, eu encontrei convenções estranhas que pessoalmente não consegui entender por muito tempo, porque não têm base. Como eu sou um "techie" com bastante experiência no estudo de vários materiais técnicos, eu determinei duas verdades muito simples. Se o material não estiver claro para você e levantar dúvidas, então:

  • Os próprios autores não entendem completamente, então eles fazem o possível para convencê-lo do contrário por todos os meios (isso geralmente é feito usando declarações antilógicas)
  • Os detalhes são omitidos deliberadamente para ocultar informações desnecessárias de você.

A imagem abaixo desenvolve a ideia, tornando-a mais fácil de entender. Ele mostra a abertura e o fechamento de dois tipos de ordens à mercado:

buy & sell

Agora, eu acho que a seção de spreads e a seção atual ficarão mais claras. Em geral, esta imagem é relevante para todo o artigo, mas ela é mais útil neste bloco.

Claro, eu tenho certeza de que existem cálculos corretos na literatura especializada, mas é óbvio que encontrar essas informações é mais difícil do que adivinhar o que está faltando por conta própria. A convenção afirma que quando compramos, por exemplo, EURUSD, nós compramos EUR e vendemos USD. Vamos escrever isso:

  • EUR = Lot * ContractSize
  • USD = - Ask1 * Lot * ContractSize = - (Bid1 + S1*Point) * Lot * ContractSize

Nesse caso, ao comprar, nós obtemos um valor positivo da moeda base e um valor negativo da segunda moeda. Acredito que eu não sou o único que pensa que isso é um absurdo completo. Depois de pensar um pouco, eu cheguei à conclusão de que as proporções estão corretas, mas são apresentadas de maneira pouco intuitiva. Vamos alterar da seguinte forma… Para comprar EUR, precisamos de outra moeda, USD, que devemos retirar do nosso balanço, pegar emprestado de uma corretora ou usar os dois métodos. Em outras palavras, nós pegamos primeiro o USD emprestado de algum armazenamento compartilhado. Ele se parece com isso:

  • USD1 = Ask1 * Lot * ContractSize = (Bid1 + S1*Point) * Lot * ContractSize — isso é o que nós pegamos emprestado
  • EUR1 = Lot * ContractSize — é o que nós compramos com os fundos emprestados à taxa de câmbio Ask no momento da compra

O valor negativo aparecerá mais tarde. Na verdade, ele não pode estar aqui no momento. O valor negativo aparece quando nós fechamos nossa posição. Portanto, se a posição estiver aberta, ela deve ser fechada. Acontece que nós precisamos realizar a ação Sell usando o mesmo lote. Se nós aderirmos às considerações padrão:

  • EUR2 =  Lot * ContractSize
  • USD2 = Bid2 * Lot * ContractSize

Acontece que nós já vendemos EUR e compramos USD. Em relação às nossas transformações, nós descobrimos que pegamos os euros pelos quais trocamos fundos emprestados e os mudamos de volta para a moeda emprestada. Um lucro ou um prejuízo será obtido subtraindo os fundos emprestados dos fundos recebidos:

  • Profit_EUR = EUR1 – EUR2 = 0
  • Profit_USD = USD2 – USD1 = Bid2 * Lot * ContractSize - (Bid1 + S1*Point) * Lot * ContractSize = Lot * ContractSize * ( Bid2 – Bid1 – S1*Point)

Acontece que o EUR desaparece e apenas o USD permanece. Se o nosso depósito for em USD, nós não precisamos converter a moeda resultante na moeda do depósito, pois elas são iguais. A equação é muito parecida com a que tomamos como base logo no início, a única diferença é que comissão e swap não são considerados aqui porque elas são consideradas separadamente. Vamos agora reescrever um pouco esta expressão:

  • Profit_USD = Lot * (ContractSize*Point) * [ ( Bid2 – Bid1 – S1*Point) / Point ]

Aqui nós simplesmente dividimos e multiplicamos o lado direito por Point e obtemos nossa equação original. A mesma equação pode ser obtida se nós usarmos o sistema original de convenções afirmando que nós vendemos e compramos ao mesmo tempo, independentemente da direção da negociação. Nesse caso, tudo o que foi emprestado tem um sinal de menos, simbolizando que nós devemos, enquanto o valor comprado fica com um sinal de mais. Em tal sistema de convenções, nós não precisamos considerar o que estamos mudando para o quê e de onde. Vamos fazer o mesmo usando esta abordagem:

  • EUR1 = Lot * ContractSize
  • USD1 = - Ask1 * Lot * ContractSize = - (Bid1 + S1*Point) * Lot * ContractSize

Isso é uma compra. Ação um.

  • EUR2 = - Lot * ContractSize
  • USD2 = Bid1 * Lot * ContractSize

Isso é uma venda. Ação dois.

Mais adiante, tudo se simplifica, pois não precisamos pensar no que subtrair do que e como. Simplesmente nós precisamos somar todos os euros e todos os dólares separadamente. A moeda base desaparece de qualquer maneira, deixando apenas a segunda moeda. Vamos somar e garantir que as equações sejam idênticas às anteriores:

  • Profit_EUR = EUR1 + EUR2 = 0
  • Profit_USD = USD1 + USD2 = - (Bid1 + S1*Point) * Lot * ContractSize + Bid2 * Lot * ContractSize = Lot * ContractSize * ( Bid2 – Bid1 – S1*Point)

Acontece que o lucro de qualquer símbolo é considerado exclusivamente na segunda moeda (não na base), e a moeda base sempre desaparece durante o ciclo completo de abertura e fechamento. Naturalmente, tudo é espelhado para vender. Vamos escrever tudo isso para completar os nossos cálculos. Agora nós vendemos EURUSD e depois fechamos esta posição fazendo uma "Compra":

  • EUR1 =  - Lot * ContractSize
  • USD1 = Bid1 * Lot * ContractSize

Isso é uma venda. Ação um.

  • EUR2 = Lot * ContractSize
  • USD2 = - (Bid2 + S2*Point) * Lot * ContractSize

Esta é uma compra, ação dois.

Agora vamos somar todos os valores da mesma forma:

  • Profit_EUR = EUR1 + EUR2 = 0
  • Profit_USD = USD1 + USD2 = Bid1 * Lot * ContractSize - (Bid2 + S2*Point) * Lot * ContractSize = Lot * ContractSize * ( Bid1 – Bid2 – S2*Point)

Como você pode ver, a equação difere apenas porque Bid1 e Bid2 são trocados. E claro, o spread é cobrado no ponto de fechamento da posição, pois o ponto de fechamento é o ponto de compra. Até agora, tudo está em estrita conformidade com as equações originais. Também é importante notar que agora sabemos o que é oTickValue, pelo menos se a segunda moeda (não a base) do nosso símbolo corresponder à moeda do nosso depósito. Vamos escrever a equação desse valor:

  • TickValue = ContractSize * Point

No entanto, esse valor é novamente adequado apenas para os símbolos, nos quais a moeda do lucro é igual à moeda do nosso depósito. Mas e se nós usarmos, digamos, uma taxa cruzada, como AUDNZD? O principal aqui não é o símbolo em si, mas o fato desse valor ser sempre calculado em relação à moeda do nosso depósito, e nós o recebemos do servidor de negociação. Mas se nós usarmos essa equação em relação à taxa cruzada, descobrimos que ela claramente funciona, mas ela responderá a nós não em nossa moeda de depósito, mas na segunda moeda do símbolo. Para converter isso na moeda de depósito, é necessário multiplicar esse valor por uma determinada razão, que, na verdade, é a taxa de conversão que nós consideramos no bloco anterior.

  • TickValueCross = ContractSize * Point * BidAlphaCross

O cálculo da taxa de conversão é bem simples:

  1. Veja a segunda moeda em nosso símbolo (não a base)
  2. Procure um símbolo que contenha esta moeda e a moeda do nosso depósito
  3. Faça uma troca na taxa apropriada
  4. Se necessário, convertemos o símbolo (câmbio inverso)

Por exemplo, se nós negociarmos EURCHF e tivermos um depósito em USD, o lucro inicial será em CHF, portanto, nós podemos usar o instrumento USDCHF e sua taxa. Então, nós precisamos trocar o CHF por USD, então descobrimos que precisamos comprar USD por CHF. Mas como CHF = PBid * USD, então USD = (1/PAsk) * CHF e, portanto:

  • BidAlphaCross = 1/PAsk

Vamos usar outro símbolo para o segundo exemplo. Por exemplo, nós negociamos AUDNZD e obtemos lucro em NZD, então nós podemos pegar a taxa NZDUSD e, como USD = PBid * NZD, neste caso:

  • BidAlphaCross = PBid

Vamos descobrir. A conversão de CHF para USD significa “+USD ; -CHF”. Em outras palavras, nós perdemos uma moeda e ganhamos outra. Isso significa comprar USD, vender à taxa USDCHF, ao preço de PAsk, o que na verdade significa apenas o seguinte: “USD = (1/PAsk) * CHF”. É mais fácil perceber da seguinte forma: ao comprar, nós devemos receber um pouco menos de USD do que receberíamos se a corretora não levasse nada da nossa operação de câmbio. Isso significa que se nós dividirmos por um PAsk maior, nós obtemos um valor menor que 1/P.

No segundo caso, a situação se inverte. A conversão de NZD para USD significa “+USD ; -NZD”, o que significa vender ao preço PBid usando a taxa NZDUSD. Vamos definir uma proporção semelhante para “USD = PBid * NZD”. O câmbio é feito novamente a uma taxa um pouco pior, que é “PBid”. Tudo combina. Tudo é transparente e fácil de entender. Lembre-se de que a taxa perfeita primária é "PMid", que eu considerei acima. Diante disso, fica fácil entender que o spread nada mais é do que o percentual que a corretora cobra na forma de câmbio da moeda. Portanto, cada negociação, seja abrindo ou fechando uma posição, é acompanhada por uma taxa da corretora sobre o câmbio chamado de spread. O restante desse imposto está contido em comissão e swap.

A taxa de conversão não é necessária e a proporção é igual a um apenas se a moeda do lucro corresponder à moeda do nosso depósito, portanto, a proporção desaparece no caso dos principais pares de moedas e torna o tamanho do tick fixo para todos esses pares. Como no caso anterior, nosso símbolo de negociação pode ser uma taxa de transição, portanto nós não precisamos procurá-lo entre outros símbolos.

Considerando a presença do novo valor BidAlphaCross, reescrevemos as equações de lucro e prejuízo da ordem sem comissão e swap:

  • BuyProfit = BidAlphaCross * Lot * ContractSize * ( Bid2 – Bid1 – S1*Point)
  • SellProfit = BidAlphaCross * Lot * ContractSize * ( Bid1 – Bid2 – S2*Point)

Tendo em conta que:

  • Bid1 = Mid1 – (S1*Point)/2
  • Bid2 = Mid2 – (S2*Point)/2

Vamos reescrever as equações de uma forma mais visual, substituindo as razões por Mid:

  • BuyProfit = BidAlphaCross * Lot * ContractSize * ( Mid2 – (S2*Point)/2 – Mid1 + (S1*Point)/2 – S1*Point)
  • SellProfit = BidAlphaCross * Lot * ContractSize * ( Mid1 – (S1*Point)/2 – Mid2 + (S2*Point)/2 – S2*Point)

Vamos simplificar tudo isso:

  • BuyProfit = Lot * BidAlphaCross * ContractSize * Point * [ ( Mid2 – Mid1 )/ Point  - ( S1/2 + S2/2 ) ]
  • SellProfit = Lot * BidAlphaCross * ContractSize * Point * [ ( Mid1 – Mid2 )/ Point  - ( S1/2 + S2/2 ) ]

Ainda mais simplificação:

  • BuyProfit = Lot * TickValueCross * [ ( Mid2 – Mid1 )/ Point ] - Lot * TickValueCross * ( S1/2 + S2/2 )
  • SellProfit = Lot * TickValueCross * [ ( Mid1 – Mid2 )/ Point ] - Lot * TickValueCross * ( S1/2 + S2/2 )

Agora, penso eu, ficou mais fácil e claro. Eu retirei deliberadamente o montante associado ao spread, para que possamos ver que este é exatamente o valor cobrado, independentemente de quanto tempo nossa posição ou ordem permaneça ativa.

Função para o cálculo exato do Swap

Agora resta esclarecer as equações de swap. Vamos relembrar as equações que nós recebemos no início do artigo:

  • Swap = Lot * TickValue * SwapPoints * SwapCount(StartTime,EndTime)
  • Swap = Lot * ContractSize * BidAlpha * SwapPercent/100 * SwapCount(StartTime,EndTime)

No último bloco, nós descobrimos que TickValue não é um valor de um dígito e ele é calculado de forma diferente para os diferentes pares de moedas. Foi determinado que:

  • TickValue = ContractSize * Point

Mas isso só funciona para os pares em que a moeda de lucro corresponde à moeda de depósito. Em casos mais complexos, nós usamos o seguinte valor:

  • TickValueCross = ContractSize * Point * BidAlphaCross

onde BidAlphaCross também é um valor diferente, que depende da moeda de depósito e do símbolo selecionado. Tudo isso nós definimos acima. Com base nisso, nós precisamos reescrever a primeira versão da equação substituindo a constante padrão:

  • Swap = Lot * TickValueCross * SwapPoints * SwapCount(StartTime,EndTime)

Mas essa equação ainda está longe de ser perfeita. Isso ocorre porque, ao contrário de uma comissão ou spread, um swap pode ser creditado um número arbitrariamente grande de vezes enquanto sua posição permanecer aberta. Acontece que, no caso de taxas cruzadas, um valor de TickValueCross não é suficiente para descrever todo o swap total, porque acontece que a cada ponto de acumulação do swap esse valor é ligeiramente diferente porque o valor de BidAlphaCross muda. Vamos escrever as equações completas para calcular os swaps para as duas opções de "tributação":

  1. Swap = SUMM(1 … D) { Lot * (SwapPoints * K[i]) * TickValueCross[i] } — soma de todos os swaps acumulados em pontos, para cada ponto cruzado 0:00
  2. Swap = SUMM(1 … D) { Lot * ContractSize * BidAlpha[i] * (SwapPercent/100 * K[i]) * } — in %

Arrays para somar:

  • K[i] = 1 ou 3 — se o índice for “3”, significa que foi o dia do acúmulo do swap triplo
  • TickValueCross[i] — array de tamanhos de ticks nos pontos de swap
  • BidAlpha[i] — array de taxas de ajuste nos pontos de cobrança do swap

Vejamos um exemplo de cálculo do swap para uma ordem arbitrária. Para fazer isso, eu introduzirei as seguintes notações:

  • TickValueCross[i] = T[i]
  • BidAlpha[i] = B[i]
  • K[i] = K[i]

Agora vamos representar graficamente como nós somaremos os swaps:

cálculo do swap


Analisamos todos os exemplos possíveis de cálculo dos lucros e prejuízos da ordem.

Parte prática

Nesta seção, nós testaremos o nosso modelo matemático. Em particular, eu daria atenção especial às questões de cálculo do lucro ou prejuízo sem levar em consideração as comissões e swaps. Se você se lembra, eu queria saber em que momento eu devo calcular o valor TickValueCross se calcularmos o lucro na taxa cruzada? Este momento é a única incerteza em todo o modelo que eu vou testar. Para fazer isso, vamos primeiro implementar todas as funcionalidades necessárias para calcular o lucro ou prejuízo de qualquer ordem usando o nosso modelo matemático, testá-lo no testador de estratégia e, depois de tudo isso, comparar os nossos cálculos com os dados de ordens reais do histórico de negociação. O objetivo final é testar o nosso modelo matemático e compará-lo com a função de referência MQL5, como OrderCalcProfit ao mesmo tempo.

Para avaliar tudo isso, é necessário introduzir quatro quantidades:

  1. Real — lucro da ordem a partir do histórico
  2. BasicCalculated — o mesmo lucro calculado ao abrir uma ordem usando a função OrderCalcProfit
  3. CalculatedStart — lucro calculado no momento da abertura da ordem usando o nosso modelo matemático
  4. CalculatedEnd — lucro calculado no momento do fechamento da ordem usando o nosso modelo matemático

Isso implica três tipos de desvio médio do valor do lucro:

  1. AverageDeviationCalculatedMQL = Summ(0..n-1) [ 100 * MathAbs(BasicCalculated - Real)/MathAbs(Real) ]  / n : desvio do lucro relativo pelo código MQL5
  2. AverageDeviationCalculatedStart = Summ(0.. n-1 ) [  100 * MathAbs(CalculatedStartReal)/MathAbs(Real) ] / n : desvio do lucro relativo pelo nosso código ao abrir uma ordem
  3. AverageDeviationCalculatedEnd =  Summ(0.. n-1 ) [  100 * MathAbs(CalculatedEnd Real)/MathAbs(Real) ] / n : desvio do lucro relativo pelo código ao fechar uma ordem

Da mesma forma, você pode inserir três tipos de desvio máximo:

  1. MaxDeviationCalculatedMQL = Max(0.. n-1 ) [ (100 * MathAbs(BasicCalculated - Real)/MathAbs(Real))  ] - desvio do lucro relativo pelo código MQL5
  2. MaxDeviationCalculatedStart =  Max(0.. n-1 ) [  (100 * MathAbs(CalculatedStart Real)/MathAbs(Real)) ]  - desvio de lucro relativo pelo nosso código ao abrir uma ordem
  3. MaxDeviationCalculatedEnd =  Max(0.. n-1 ) [  (100 * MathAbs(CalculatedEnd Real)/MathAbs(Real)) ]  - desvio relativo do lucro pelo nosso código ao fechar uma ordem

onde:

  • Summ(0..n-1) — soma de todos os desvios relativos de todas as "n" ordens
  • Max(0..n-1) — desvio relativo máximo de todos as "n" ordens

Nós podemos testar o nosso modelo matemático implementando esses cálculos no código de um EA arbitrário. Vamos começar implementando a nossa equação de lucro. Eu fiz isso da seguinte maneira:

double CalculateProfitTheoretical(string symbol, double lot,double OpenPrice,double ClosePrice,bool bDirection)
   {
   //PrBuy = Lot * TickValueCross * [ ( Bid2 - Ask1 )/Point ]
   //PrSell = Lot * TickValueCross * [ ( Bid1 - Ask2 )/Point ]
   if ( bDirection )
      {
      return lot * TickValueCross(symbol) * ( (ClosePrice-OpenPrice)/SymbolInfoDouble(symbol,SYMBOL_POINT) );
      }
   else
      {
      return lot * TickValueCross(symbol) * ( (OpenPrice-ClosePrice)/SymbolInfoDouble(symbol,SYMBOL_POINT) );
      }   
   }

Aqui nós temos duas equações em uma: para comprar e para vender. O marcador "bDirection" é responsável por isso. A função adicional calculando o tamanho do tick é destacado em verde. Eu implementei da seguinte forma:

double TickValueCross(string symbol,int prefixcount=0)
   {
   if ( SymbolValue(symbol) == SymbolBasic() )
      {
      return TickValue(symbol);
      }
   else
      {
      MqlTick last_tick;
      int total=SymbolsTotal(false);//symbols in Market Watch
      for(int i=0;i<total;i++) Symbols[i]=SymbolName(i,false);
      string crossinstrument=FindCrossInstrument(symbol);
      if ( crossinstrument != "" )
         {
         SymbolInfoTick(crossinstrument,last_tick);
         string firstVAL=StringSubstr(crossinstrument,prefixcount,3);
         string secondVAL=StringSubstr(crossinstrument,prefixcount+3,3);
         if ( secondVAL==SymbolBasic() && firstVAL == SymbolValue(symbol) )
            {
             return TickValue(symbol) * last_tick.bid;
            }
         if ( firstVAL==SymbolBasic() && secondVAL == SymbolValue(symbol) )
            {
            return TickValue(symbol) * 1.0/last_tick.ask;
            }         
         }
      else return TickValue(symbol);  
      }
   return 0.0;   
   }

Há também duas implementações internas para os seguintes casos:

  1. A moeda de lucro do símbolo é a mesma moeda do nosso depósito
  2. Todos os outros casos (procurando uma taxa de transição)

O segundo cenário também se divide em dois casos:

  • A moeda do depósito está no topo da taxa de conversão
  • A moeda do depósito está na parte inferior da taxa de conversão

Tudo está em estrita conformidade com o modelo matemático. Para implementar as últimas divisões, primeiro nós precisamos encontrar a ferramenta certa para calcular a taxa de conversão:

string FindCrossInstrument(string symbol,int prefixcount=0)
   {
   string firstVAL;
   string secondVAL;
   for(int i=0;i<ArraySize(Symbols);i++)
      {
      firstVAL=StringSubstr(Symbols[i],prefixcount,3);
      secondVAL=StringSubstr(Symbols[i],prefixcount+3,3);
      if ( secondVAL==SymbolBasic() && firstVAL == SymbolValue(symbol) )
         {
         return Symbols[i];
         }
      if ( firstVAL==SymbolBasic() && secondVAL == SymbolValue(symbol) )
         {
         return Symbols[i];
         }      
      }
   return "";
   }

Para fazer isso, nós precisamos saber como "tirar" a moeda base de um nome do símbolo:

string SymbolValue(string symbol,int prefixcount=0)
   {
   return StringSubstr(symbol,prefixcount+3,3);
   }

E pegar a moeda de lucro usando a função MQL5 integrada:

string SymbolBasic()
   {
   return AccountInfoString(ACCOUNT_CURRENCY);
   }

Comparar tudo isso com moedas em todos os símbolos do Observador de Mercado antes da primeira correspondência. Agora podemos utilizar esta funcionalidade na hora de abrir e fechar as ordens. Se desejar, você pode ver o restante do código no arquivo anexado abaixo. Eu adicionei o cálculo dos desvios após o término do backtest. Eles são gravados no log da plataforma. Eu testei todos os vinte e oito principais pares de moedas e taxas cruzadas e coloquei o resultado em uma tabela para que nós possamos avaliar o desempenho de nosso modelo matemático e compará-lo com a implementação da MQL5. Os resultados foram divididos em três blocos condicionais. Os dois primeiros têm a seguinte aparência:

1 & 2 blocks

Como você pode ver, para os primeiros quatro pares de moedas, tanto a MQL5 quanto nossa implementação funcionam perfeitamente porque a moeda de lucro é a mesma que a de depósito. Em seguida, vem um bloco de três pares de moedas, no qual a moeda base é a mesma moeda de lucro. Nesse caso, a implementação da MQL5 funciona melhor, mas, no entanto, já está claro que o erro de cálculo ao abrir uma ordem é muito maior do que o mesmo erro ao fechar. Isso mostra indiretamente que o cálculo realmente deve ser feito no momento do fechamento da ordem. Vamos dar uma olhada em outros pares de moedas:

block 3

Aqui a minha funcionalidade não é inferior à do MQL5 básica. Além disso, é claro que os cálculos realizados ao fechar uma posição são muito mais precisos em todos os momentos. A única coisa que eu não consigo explicar é a presença de zeros na primeira linha do segundo bloco. Pode haver muitos motivos, mas me parece que não estão relacionados ao meu modelo, embora eu possa estar errado. Quanto à verificação das equações de comissões e swaps, eu não acho necessário. Estou confiante nessas equações, pois não há nada particularmente complicado nelas.

Conclusão

Neste artigo, eu criei um modelo matemático criado do zero e guiado apenas por fragmentos de informações. O modelo contém tudo o que você precisa para calcular as ordens para os principais pares de moedas e taxas cruzadas. O modelo foi testado no testador de estratégia e está pronto para uso imediato em qualquer EA, indicador ou script útil. Na verdade, a aplicabilidade desse modelo é muito mais ampla do que apenas calcular lucros, prejuízos ou custos, mas isso é assunto para outro artigo. Você pode encontrar todas as funcionalidades necessárias e exemplos de seu uso no EA da pesquisa que eu usei para compilar a tabela. O EA está anexado ao artigo. Você mesmo pode executá-lo e comparar os resultados com a tabela. Mais importante ainda, eu acredito que consegui criar um "manual" simples e lógico.



Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/10211

Arquivos anexados |
Ciência de Dados e Aprendizado de Máquina — Redes Neurais (Parte 02): Arquitetura das Redes Neurais Feed Forward Ciência de Dados e Aprendizado de Máquina — Redes Neurais (Parte 02): Arquitetura das Redes Neurais Feed Forward
Há detalhes a serem abordadas na rede neural feed-forward antes de finalizarmos este assunto, a arquitetura é uma delas. Vamos ver como nós podemos construir e desenvolver uma rede neural flexível para as nossas entradas, o número de camadas ocultas e os nós para cada rede.
Aprendendo a construindo um EA que opera de forma automática (Parte 07): Tipos de Contas (II) Aprendendo a construindo um EA que opera de forma automática (Parte 07): Tipos de Contas (II)
Aprenda como criar um EA que opera de forma automática, isto de forma simples e o mais seguro possível. É preciso sempre ficar atento, ao que um EA automatizado, esta fazendo, e se ele sair da linha, removê-lo o mais rápido possível do gráfico, encerrando o que ele estava fazendo, a fim de evitar que as coisas fugam do controle.
Crie o seu próprio Indicador técnico Crie o seu próprio Indicador técnico
Neste artigo, eu abordarei os algoritmos que permitem que você crie o seu próprio indicador técnico. Você aprenderá como obter resultados bem complexos e interessantes com suposições iniciais muito simples.
DoEasy. Controles (Parte 16): Objeto WinForms TabControl - múltiplas fileiras de cabeçalhos de guias, modo esticamento de cabeçalhos consoante o tamanho do contêiner DoEasy. Controles (Parte 16): Objeto WinForms TabControl - múltiplas fileiras de cabeçalhos de guias, modo esticamento de cabeçalhos consoante o tamanho do contêiner
Neste artigo vamos continuar o desenvolvimento do controle TabControl, e trataremos da localização dos cabeçalhos das guias nos quatro lados do controle para todos os modos de tamanho de cabeçalho: "Normal", "Fixed" e "Fill To Right".