Ontem, Eu escrevi um pouco sobre como o backtester simula carrapatos. Quando NinjaTrader encontra um bar, onde a parada e tomar queda de lucro dentro do alcance do bar, ele sempre pressupõe que a parada foi atingido primeiro.
Eu tinha esse problema chegar para um cliente que queria vender sua estratégia para um cliente institucional. A instituição queria a capacidade de backtest, a fim de compreender como a estratégia se apresenta em condições de mercado mais amplas. Os resultados ao vivo só cobria 9 meses, o que tornava difícil para o investidor a tomar uma decisão informada. A confiança, backtest precisas permitiria que meu cliente para facilitar a venda.
Quando programada a primeira estratégia, parecia um fracasso abismal. Os resultados mostraram uma 45 mergulho equidade grau de cada comércio. Ele colocou suas paradas em 1/3 de ATR, tão naturalmente, NinjaTrader assumido que eles foram atingidos o tempo todo.
A solução que foi desenvolvida por ele utilizada a alta prazo gráfico que a estratégia realmente usado, mas, em seguida, modificou o código para que incluem o que chama a NinjaTrader intrabar granularidade. Basicamente, somarmos gráficos de carrapatos no backend para forçar a estratégia para atualizar em um carrapato por carrapato base.
É realmente muito simples de programa. Na função Initialize, você precisa adicionar oferta e pedir cartas de carrapatos.
Protected override void Initialize()
{
Adicionar(cadeia instrumentName, PeriodType.Tick, 1, MarketDataType.Bid);
Adicionar(cadeia instrumentName, PeriodType.Tick, 1, MarketDataType.Ask);
}
Em Seguida, no OnBarUpdate() função, você deixar o código inalterada. Tudo que você precisa fazer é colocá-lo dentro de um statment então se-simples
protected override OnBarUpdate vazio()
{
se for( BarsInProgress = = 0 )
{
// Fazer coisas
}
}
Os resultados backtest veio dentro $5 dos resultados comerciais reais ao longo de um período de 9 meses! Embora backtesting freqüentemente leva a resultados imprecisos, Ficamos felizes em reproduzir o resultado com um erro tão pequeno.
A principal desvantagem deste método é que você deve digitar manualmente o nome do instrumento dentro do código-fonte, em seguida, compilá-lo, toda vez que você quiser executar um backtest sobre um novo instrumento. Não é uma grande solução, mas NT7 infelizmente não suporta programaticamente chamando o InstrumentName de dentro Inicializar().
GD diz
Olá – Vou testar este obrigado. Eu estava usando apenas
Protected override void Initialize()
{
Adicionar(PeriodType.Tick, 1);
}
e então a mesma coisa que com
protected override OnBarUpdate vazio()
{
se for( BarsInProgress = = 0 )
{
// Fazer coisas
}
…….Mas agora eu estou querendo saber como adicionar o nome do instrumento? É o guia de ajuda? Se não, Você poderia postar um exemplo de um dos contratos atuais?
Obrigado!
Shaun Overton diz
Oi, Gav.,
Obrigado pelo seu comentário. Você deve adicionar manualmente o nome de instrumento já que não é acessível por meio de programação em Initialize().
Adicionar(cadeia instrumentName, PeriodType periodType, período de int)
http://www.ninjatrader.com/support/helpGuides/nt7/add3.htm
GD diz
Oi Shaun,
Obrigado fez em cima uma strat ontem à noite e usado o seguinte.
Adicionar(“TF 09-11”, PeriodType.Tick, 1, MarketDataType.Ask);
Adicionar(“TF 09-11”, PeriodType.Tick, 1, MarketDataType.Bid);
Adicionar(“TF 09-11”, PeriodType.Tick, 1, MarketDataType.Last);
Por isso pergunto, Lance e por último nas barras adicionais em andamento também. Então, eu tinha o dataseries principal (BIP 0) como um maior período de tempo e, em seguida, os adicionais como acima. O backtest parecia muito melhor, Obrigado por postar suas descobertas. Posteriormente me deparei código semelhante nos fóruns do NT, mas vi no seu primeiro.
Obrigado,
GAMES.
Shaun Overton diz
Fico feliz que você achou útil. Os fóruns são, por vezes, difícil de navegar. Demora algum tempo para saber onde encontrar as informações que você precisa.
Marty diz
Obrigado pela ajuda. Só o que eu estava procurando! 🙂
Shaun Overton diz
De nada. Fico feliz que você achou o post útil.
Seb diz
Olá, Shaun.,
Você menciona que você precisa para codificar o nome do instrumento cada vez que você quer tentar um outro instrumento. Eu tive um problema recentemente onde meu estoque não estava disponível para curto e eu tive que modificar minhas estratégias para que eu ainda posso usar o sinal de meu instrumento principal, mas criou uma variável de entrada para outro estoque de comércio, se necessário, sem ter que recompilar.
É bastante simples, Aqui está o código:
público classe ABC : Estratégia
{
#região variáveis
private string stockToTrade = @”ESPIÃO”; // Vamos assumir que você geralmente comércio espião.
(…)
#endregion
Protected override void Initialize()
{
(…)
Adicionar(stockToTrade, PeriodType.Minute, 5);
}
protected override OnBarUpdate vazio()
{
(…)
}
#região Propriedades
[Descrição(“”)]
[GridCategory(“Parâmetros”)]
seqüência pública StockToTrade
{
Obter { retornar stockToTrade; }
conjunto { stockToTrade = valor; } // Você será capaz de selecionar um outro instrumento, se você quer
}
#endregion
}
Espero que seja útil.
daszilagyi diz
Oi
e se você chama o prazo multi assim?
Adicionar(isto. Instrument.MasterInstrument.Name, PeriodType.Tick, 1, MarketDataType.Bid);
Adicionar(isto. Instrument.MasterInstrument.Name, PeriodType.Tick, 1, MarketDataType.Ask);
Acho que desta forma que você não precisa digitar os nomes manualmente.
Shaun Overton diz
Isso funciona, muito!
Aaron Soderstrom diz
Isso ainda funciona.? I rebanho ninjatrader agora forças backtest para fechar.
Cheers,
Aaron Soderstrom
Shaun Overton diz
Sim, ainda funciona.
Marca diz
Como você inserir ordens neste exemplo? EnterLong e SetStopLoss? Eu era incapaz de reproduzir os resultados que você descreveu com essas funções.
O exemplo de Ninja envia a ordem para o secundário bar série. É isso que você está fazendo?(http://www.ninjatrader.com/support/forum/showthread.php?t=6652)
Shaun Overton diz
O método usado para incorporar o comércio não irá afectar a execução. Você precisa enviar a ordem da série secundário (isto é., Não no fluxo de carrapato).
Marca diz
Obrigado por uma resposta tão rápida. Eu sou ainda um pouco obscuro.
Você mencionou no artigo que você deixou o código no OnBarUpdate() inalterado. Se o código em execução em um gráfico diário foi o seguinte:
se for (Perto[0] > EMA(20))
{
Digite Longo(); SetStopLoss(); SetProfitTarget();
}
Fez tudo o que foi adicionar a série ask e oferta de carrapato (Coloque o código dentro da lógica se (BarsInProgress = = 0))?
Shaun Overton diz
Exatamente.
Marca diz
Acho que eu estou faltando alguma coisa. Isso não muda os resultados que recebo. Lendo sobre o fórum de ninja, eles mencionam que SetStopLoss irá se referir a série de tempo principal. Eu tentei enviar uma ordem de saída usando ExitLongStop e ExitLongLimit para o BarsInProgress = 1 (Série de escala de oferta) para sair. Isto mudou os resultados.
Não sei se o que a diferença seria mas obrigado pelas suas respostas.
Shaun Overton diz
Os dois problemas óbvios seria:
1) Você baixou dados carrapato em NinjaTrader?
2) Mudou o tipo de preço da última nas configurações backtest?
Marca diz
Sim eu tenho dados de carrapato, Lance e perguntar. A série primária é 1 Dados de oferta do dia.
Darren diz
Quando eu fizer isso fico uma “Você deve usar a sobrecarga que tem um ' bares em andamento’ parâmetro ao chamar o BarsSinceEntry() método no contexto de uma estratégia de frame e instrumento multi tempo. Alguém alguma idéia como resolver isso?
Shaun Overton diz
Você está usando BarsInProgress em tudo?