Boa @Guirinco, algumas observações,
Primeiro, o cálculo não está arredondando para o tamanho de lote mínimo da ação, por exemplo:
Se meu Capital for de R$10.000,00 e o preço da ação estiver R$35, o resultado da sua fórmula retorna 300 ações (3 lotes), quando o correto seria retornar 200 ações (2 lotes),
Nós temos que arredondar para baixo, já que esse capital permite operar apenas 285 ações, e como nós temos que trabalhar com lotes cheios, eu precisaria de mais R$500 para poder operar 300 ações (3 lotes cheios).
Segundo, você está fechando a posição também com o tamanho da posição baseada no cálculo, isso causa um problema, já que, (usando o nosso exemplo) você teria aberto essa posição com 2 lotes cheios (200 ações) porém no decorrer do tempo, o preço pode ser movimentar, por exemplo para R$25, e agora o cálculo vai retornar 400 ações e o algoritmo vai tentar fechar a posição com 4 lotes cheios, mas obviamente você não tem essa posição aberta,
O ideal seria fechar posição com o tamanho da posição aberta, pra isso você poderia usar as funções BuyPosition
ou SellPosition
que retornam o tamanho da posição de compra ou venda que estão abertas naquele momento (tem aula no curso sobre essa função no módulo de funções de Backtesting).
Terceiro, existe uma função que faz esse cálculo pra você, e já arredonda para o lote mínimo, chamada NumUnits
(tem aula no curso sobre essa função no módulo de funções Matemáticas)
Uma última observação, que não tem muita relação com o algoritmo em si, mas algo que já notei problemas anteriores mas nunca encontrei o motivo (e pode ser que até já tenha sido resolvido pela Nelógica), mas para evitar eu sempre prefiro usar uma forma diferente, na linha:
Se (HasPosition = false) entao
Eu prefiro usar
Se Not(HasPosition) entao
O resultado é (deveria) ser o mesmo, e a sua forma está correta, mas já vi problemas no passado em usar teste condicional = false
, novamente não sei por que, e é difícil dizer se foi 100% resolvido, a Nelógica não da detalhes das correções que aplica (infelizmente), mas pra evitar eu sempre prefiro usar o operador NOT
que simplesmente nega a condição. (também tem aula sobre o operador no módulo de lógica de programação).
E agora sim, por último, segue um exemplo (super simplificado) de uma execução, seguindo esse modelo, tente fazer essas alterações e nos diga os resultados,
Espero que ajude,
Parametro
Capital(10000);
var
mm : real;
tamanhoPosicao : inteiro;
b: inteiro;
Inicio
tamanhoPosicao := NumUnits(Capital, Lote);
mm := Media(9, Fechamento);
Se Not(HasPosition) e (fechamento > mm) entao
BuyAtMarket(tamanhoPosicao);
Se (IsBought) e (fechamento < mm) entao
SellToCoverAtMarket(BuyPosition * Lote);
Fim;