Implementação de estratégias
Introdução
Esta seção visa apresentar trechos de códigos com exemplos de tarefas comuns para implementação de estratégias.
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
Cruzamento simples entre 2 séries
O exemplo abaixo visa identificar quando há um cruzamento simples entre duas séries, considerando apenas o instante atual e anterior.
var
fMedia1, fMedia2: float;
iCruzamento: integer;
function NTB_ArredondarFloat(Value: float; nCasas: integer):float;
var
fValor: float;
fParteInteira: float;
fParteDecimal: float;
begin
fValor := Value;
fParteInteira := IntPortion(fValor);
fParteDecimal := Round((fValor - fParteInteira)*Power(10,nCasas));
Result := fParteInteira + fParteDecimal/Power(10,nCasas);
end;
begin
iCruzamento := 0;
fMedia1 := NTB_ArredondarFloat(Media(10,Close),2);
fMedia2 := NTB_ArredondarFloat(Media(20,Close),2);
if (fMedia1 > fMedia2)
and (fMedia1[1] <= fMedia2[1]) then
iCruzamento := 1;
if (fMedia1 < fMedia2)
and (fMedia1[1] >= fMedia2[1]) then
iCruzamento := -1;
if iCruzamento = 1 then
begin
// O que fazer quando houver cruzamento para cima?
PlotText("Cruzou acima", clGreen, -1,12);
end;
if iCruzamento = -1 then
begin
// O que fazer quando houver cruzamento para baixo?
PlotText("Cruzou abaixo", clRed, -1,12);
end;
//Plot apenas para visualizar graficamente o funcionamento
//do código
Plot(fMedia1);
Plot2(fMedia2);
SetPlotColor(1,clRed);
SetPlotWidth(1,2);
SetPlotColor(2,clWhite);
SetPlotStyle(2,psDash);
SetPlotWidth(2,2);
end;
Cruzamento simples entre 2 séries com percentual de cruzamento
O exemplo abaixo visa identificar quando há um cruzamento simples entre duas séries, considerando apenas o instante atual e anterior, e desde que o cruzamento seja superior a um determinado valor percentual.
const
//Constante fornecida em percentual. Ex: 0.1 significa 0.1%
fPercCruzamento = 0.1;
var
fMedia1, fMedia2: float;
iCruzamento: integer;
begin
iCruzamento := 0;
fMedia1 := Media(10,Close);
fMedia2 := Media(20,Close);
//Plot apenas para visualizar graficamente o funcionamento
//do código
Plot(fMedia1);
Plot2(fMedia2);
if (fMedia1 <> 0) and (fMedia2 <> 0) then
begin
if (fMedia1 > fMedia2)
and (fMedia1[1] <= fMedia2[1])
and (((fMedia1-fMedia2)/fMedia1*100) >= fPercCruzamento)
then iCruzamento := 1;
if (fMedia1 < fMedia2)
and (fMedia1[1] >= fMedia2[1])
and ((Abs((fMedia2-fMedia1)/fMedia1*100)) >= fPercCruzamento)
then iCruzamento := -1;
if iCruzamento = 1 then
begin
// O que fazer quando houver cruzamento para cima?
PlotText("Cruzou pra cima", clGreen, -1,12);
end;
if iCruzamento = -1 then
begin
// O que fazer quando houver cruzamento para baixo?
PlotText("Cruzou pra baixo", clRed, -1,12);
end;
end;
end;
Cruzamento entre 2 séries nos últimos N períodos
O exemplo abaixo visa identificar qual cruzamento houve entre duas séries nos últimos N períodos (constante cJanelaCruzamento).
const
cJanelaCruzamento = 5;
var
fMedia1,fMedia2 : float;
iCruzamento : integer;
iUltimoCruzamentoJanela : integer;
iPeriodo, iPeriodoJanela : integer;
begin
iCruzamento := 0;
fMedia1 := Media(10,Close);
fMedia2 := Media(20,Close);
//Plot apenas para visualizar graficamente o funcionamento
//do código
Plot(fMedia1);
Plot2(fMedia2);
if (fMedia1 > fMedia2) and (fMedia1[1] <= fMedia2[1]) then
iCruzamento := 1;
if (fMedia1 < fMedia2) and (fMedia1[1] >= fMedia2[1]) then
iCruzamento := - 1;
if iCruzamento = 1 then
begin
// O que fazer quando houver cruzamento para cima?
PlotText("Cruzou pra cima",clGreen, - 1,12);
end;
if iCruzamento = - 1 then
begin
// O que fazer quando houver cruzamento para baixo?
PlotText("Cruzou pra baixo",clRed, - 1,12);
end;
// Código para proteção do início da série em backtesting
if MaxBarsBack < cJanelaCruzamento then
iPeriodoJanela := MaxBarsBack
else iPeriodoJanela := cJanelaCruzamento;
// Identificação do último cruzamento
if iPeriodoJanela >= 1 then
begin
iUltimoCruzamentoJanela := iCruzamento;
iPeriodo := 1;
while iPeriodo <= iPeriodoJanela do
begin
if iCruzamento[iPeriodo] <> 0 then
begin
iUltimoCruzamentoJanela := iCruzamento[iPeriodo];
iPeriodo := iPeriodoJanela + 1;
end;
iPeriodo := iPeriodo + 1;
end;
// Escreve no gráfico qual cruzamento houve nos últimos
// cJanelaCruzamento periodos
if (iCruzamento = 0) and (iUltimoCruzamentoJanela <> 0) then
if iUltimoCruzamentoJanela = 1 then
PlotText("Cruz p/ cima",clWhite, - 1,8)
else
PlotText("Cruz p/ baixo",clWhite, - 1,8);
end;
end;
Toque na média utilizando percentual de proximidade
O exemplo abaixo visa identificar quando ocorre o toque do preço em uma média, utilizando como parâmetro o percentual de proximidade.
OBS: Neste exemplo foi introduzido também uma função customizada para arredondar um valor float de acordo com a quantidade de casas decimais desejada (NTB_ArredondarFloat)). Este tipo de função não tem de forma nativa no Profit (o que é uma pena!);
const
// Define o percentual que caracteriza o toque
// Se for igual a zero, a barra tem conter a média
// Ex: se cPercProximidade = 0.5, define como toque se
// preço chegar a 0.5% ou menos de distância da média
cPercProximidade = 0.0;
var
fMedia: float;
bTocouMedia: boolean;
function NTB_ArredondarFloat(Value: float; nCasas: integer):float;
var
fValor: float;
fParteInteira: float;
fParteDecimal: float;
begin
fValor := Value;
fParteInteira := IntPortion(fValor);
fParteDecimal := Round((fValor - fParteInteira)*Power(10,nCasas));
Result := fParteInteira + fParteDecimal/Power(10,nCasas);
end;
begin
bTocouMedia := false;
fMedia := NTB_ArredondarFloat(Media(20,Close),2);
//Plot apenas para visualizar graficamente o funcionamento
//do código
Plot(fMedia);
SetPlotColor(1,clRed);
SetPlotWidth(1,2);
if (cPercProximidade <> 0) then
begin
Plot2(NTB_ArredondarFloat(fMedia*(1 + cPercProximidade/100),2));
Plot3(NTB_ArredondarFloat(fMedia*(1 - cPercProximidade/100),2));
SetPlotColor(2, clGray);
SetPlotColor(3, clGray);
end;
//Proteção para os primeiros períodos de backtesting
//Quando pode ocorrer divisão por zero
if fMedia <> 0 then
begin
// Situação em que a media está no meio da barra
if (fMedia >= Low) and (fMedia <= High)
then bTocouMedia := True;
// Situação em que a media está abaixo do preço
// negociado e este chegou a cPercProximidade da
// média
if (fMedia < Low)
and (((Low - fMedia)/fMedia*100) <= cPercProximidade)
then
begin
bTocouMedia := True;
end;
// Situação em que a media está abaixo do preço
// negociado e este chegou a cPercProximidade da
// média
if (fMedia > High)
and (((fMedia - High)/High*100) <= cPercProximidade)
then
begin
bTocouMedia := True;
end;
if bTocouMedia then
PlotText("Tocou",clWhite, - 1,8);
end;
end;
Toque na média utilizando quantidade de ticks de proximidade
O exemplo abaixo visa identificar quando ocorre o toque do preço em uma média, utilizando como parâmetro a quantidade de ticks do ativo.
OBS: Neste exemplo foi introduzido também uma função customizada para arredondar um valor float de acordo com a quantidade de casas decimais desejada (NTB_ArredondarFloat)). Este tipo de função não tem de forma nativa no Profit (o que é uma pena!);
const
// Define o percentual que caracteriza o toque
// Se for igual a zero, a barra tem conter a média
// Ex: se cPercProximidade = 0.5, define como toque se
// preço chegar a 0.5% ou menos de distância da média
cTicksProximidade = 0;
var
fMedia: float;
bTocouMedia: boolean;
function NTB_ArredondarFloat(Value: float; nCasas: integer):float;
var
fValor: float;
fParteInteira: float;
fParteDecimal: float;
begin
fValor := Value;
fParteInteira := IntPortion(fValor);
fParteDecimal := Round((fValor - fParteInteira)*Power(10,nCasas));
Result := fParteInteira + fParteDecimal/Power(10,nCasas);
end;
begin
bTocouMedia := false;
fMedia := NTB_ArredondarFloat(Media(20,Close),2);
//Plot apenas para visualizar graficamente o funcionamento
//do código
Plot(fMedia);
SetPlotColor(1,clRed);
SetPlotWidth(1,2);
if (cTicksProximidade <> 0) then
begin
Plot2(fMedia + cTicksProximidade*MinPriceIncrement);
Plot3(fMedia - cTicksProximidade*MinPriceIncrement);
SetPlotColor(2,clGray);
SetPlotColor(3,clGray);
end;
//Proteção para os primeiros períodos de backtesting
//Quando pode ocorrer divisão por zero
if fMedia <> 0 then
begin
// Situação em que a media está no meio da barra
if (fMedia >= Low) and (fMedia <= High)
then bTocouMedia := True;
// Situação em que a media está abaixo do preço
// negociado e este chegou a cPercProximidade da
// média
if (fMedia < Low)
and (((Low - fMedia)/MinPriceIncrement) <= cTicksProximidade)
then
begin
bTocouMedia := True;
end;
// Situação em que a media está abaixo do preço
// negociado e este chegou a cPercProximidade da
// média
if (fMedia > High)
and (((fMedia - High)/MinPriceIncrement) <= cTicksProximidade)
then
begin
bTocouMedia := True;
end;
if bTocouMedia then
PlotText("Tocou",clWhite, - 1,8);
end;
end;
Como acessar o Book de Ofertas em NTSL por nível de preço
O exemplo abaixo demonstra como armazenar em um array os próximos N níveis de preço do book e obter as quantidades apregoadas para estes níveis no lado da compra e da venda.
OBS: Este código funciona apenas quando o mercado está aberto, não sendo possível fazer backtesting de estratégias baseadas em leitura de book. Isso é algo comum às demais plataformas de trading.
const
cQtdeNiveis = 4;
input
cAtivo("CASH3", feedBovespa);
var
i: integer;
fBookSell, fBookBuy: array[0..cQtdeNiveis] of float;
fBookSellSum, fBookBuySum: float;
begin
for i:= 0 to cQtdeNiveis do
begin
fBookSellSum := TotalSellQtd(cAtivo,i+1);
fBookBuySum := TotalBuyQtd(cAtivo,i+1);
if i <> 0 then
begin
fBookSell[i] := fBookSellSum - TotalSellQtd(cAtivo,i);
fBookBuy[i] := fBookBuySum - TotalBuyQtd(cAtivo,i);
end
else
begin
fBookSell[i] := fBookSellSum;
fBookBuy[i] := fBookBuySum;
end;
end;
{
// Comparando retorno das funções (Ask/Bid)Size com Total(Sell/Buy)Qtd
plot(fBookSell[0]);
plot2(fBookBuy[0]);
SetPlotColor(1,clRed);
SetPlotColor(2,clRed);
plot3(AskSize);
plot4(BidSize);
SetPlotColor(3,clYellow);
SetPlotColor(4,clYellow);
}
// Comparando os 5 primeiros níveis do lado da compra
plot(fBookBuy[0]);
plot2(fBookBuy[1]);
plot3(fBookBuy[2]);
plot4(fBookBuy[3]);
plot5(fBookBuy[4]);
SetPlotColor(1,clRed);
SetPlotColor(2,clRed);
SetPlotColor(3,clRed);
SetPlotColor(4,clRed);
SetPlotColor(5,clRed);
end
Boa noite professor,
não consegui criar o robo com os parametros de Toque na média utilizando quantidade de ticks de proximidade.Estou colocando ao final , dos parametros de compra e venda mas, não esta dando certo.
abraço.