Datenum amibroker forex


Amibroker forex feed de dados de MT4 em tempo real Registrado em Ago 2017 Status: Member 42 Posts Hello there. Eu encontrei Amibroker maneira melhor do que o MetaTrader, por exemplo, por causa de seu suporte multi-timeframe. Mas não há um corretor usando Amibroker, portanto, o feed de dados forex em tempo real é difícil de alcançar. Cavando a rede eu descobri alguns exemplos de código. E aqui está a minha solução: Você pode atualizar em tempo real quantos pares você quiser 1. Primeiro, execute o CurrencyLoader EA no MT4, ele tem que ser executado em cada par que você deseja atualizar. Você pode definir intervalos de tempo para atualizar e atrasar (entre cada atualização). Este EA está criando arquivos. csv com aspas e atualizá-los com freqüência. (MT4folderdirectory-gtexperts-gtfiles-gtexporthistory) 2. Agora você tem que colocar esses dados em Amibroker, e fazê-lo com freqüência. Então eu criei arquivos. bat and. js. No arquivo. js (abra-o via Bloco de Notas ou Geany) defina o caminho para sua atualização. csvs. No final do loop você pode definir atraso entre atualizações em Amibroker (em msec.) Em. bat defina caminho para o seu script. js. Está feito. Agora, quando você abre o Metatrader, os dados serão carregados para. csv. Quando você executar (clique duplo).bat arquivo, este docs será salvo no banco de dados Amibroker automaticamente (Ami deve ser aberto também). Para facilitar, você pode adicionar atalhos no menu do Amibroker. Basta ir para tools-gtcustomize-gttools - gt adicionar novo item (caminho para o arquivo. bat). Quando você quiser fazer upload de muitos pares (como eu) é melhor definir (Em EA) um pequeno número de barras carregadas para. csv assim que carregar dados para Amibroker será feito agradável. E de vez em quando é bom deletar. csv que eles não vão crescer muito grande. EDIT: // Ahh Esqueci-me de uma coisa. Ami usa seus próprios quotformatsquot, arquivos que definem qual coulumn no. csv é para. Quando você deseja atualizar seu banco de dados, você deve especificá-lo primeiro. Nesse caso, o arquivo. format especial também é necessário. Você pode criá-lo por conta própria (para MT4.csvs) ou downlad e colocar na pasta amibroker-gtformats. EDIT2: // Também fonte pode ser útil: amibroker / newsletter / 02-2001.html Registrado Out 2008 Estado: Junior Member 1 Post Ei, obrigado por Piotr JUst o que eu estava tentando alcançar. Os scripts js e bat são especialmente úteis. Agradável ouvir que estou carregando 13 pares, número de barras é definido para 500. Portanto, é um número bastante grande, mas o processo está fazendo muito bem em segundo plano, sem congelamento. Depois de 1 semana arquivos crescem muito, então eu excluí-los para evitar o carregamento pesado csvs (cos após 8-9 dias e seria congelamento). Eu adicionei arquivo. bat que rapidamente excluí-los para ferramentas Ami Poucas semanas atrás eu descobri por que Ami é muito melhor do que MT4 - gt Im carregando barras m5 e criando barras 4h. Em Ami eu posso definir qualquer fuso horário que eu quero, então eu não tenho que escolher outro corretor MT4 quando h4 barras arent bom para mim Seu muito mais fácil com Ami. Membro Comercial Registrado em Sep 2017 22 Posts Obrigado pelo seu post. Eu não sou capaz de seguir suas instruções. Gentil explação claro. Eu carrego carregador de moeda, eu tenho o arquivo de exportação no formato. csv. Como carregar mais para amibroker. Faz o seu método ajudar a trabalhar em forex com gráfico amibroker Juntado May 2017 Status: Member 7 Posts Oi Piotr2, Se você ainda está por aí, o que você precisa de dois arquivos para em MT4 Ther é um mq4 e ex4. Por favor, me ajude. Registrado May 2017 Status: Membro 7 Posts Got passado esse obstáculo. Mas eu simplesmente não consigo descobrir como adicionar o caminho do arquivo no. js Parece apenas palavras confusas para mim. SOrry não um techie. Por favor me ajude Juntado Jun 2017 Status: Junior Member 1 Post Eu tento fazer siga suas instruções, mas não é tão fácil comigo. Você poderia por favor ajudar quem se importa com sua idéia. Você pode até o vídeo no youtube como pode configurar os dados para Amibroker. Postagem mais recente Postagem mais antiga Postagem mais antiga Postagem mais antiga Postagem mais antiga Postagenas Eu sei que você é uma pessoa inteligente sabendo todos os ins e outs outs de AB - e escrevendo código afl mais rápido do que eu poderia comprar uma bebida: Você pode ser tão gentil para nos dar qualquer idéia Logged Para conectar o AB à API do Oanda e a alguns feed de dados MT4 Os membros devem ter pelo menos 0 vouchers para postar neste tópico. 0 traders visualizando agora Forex Factoryreg é uma marca registada. Connect Sobre Produtos WebsiteThis afl desenha gráfico de preços com suporte e linhas de resistência em Amibroker. Salve este afl na pasta personalizada e insira-o. Isso é muito útil afl. (HaClose, HaOpen) HaOpen AMA (Ref (HaClose, -1), 0,5) HaHigh Max (H, Max (HaClose, HaOpen)) HaLow Min (L, ) Temp (Máximo, HaOpen) Temp Min (Baixo, HaOpen) supresParamToggle (SupRes, NoYes, 1) se (supres) Prd1Param (ResPeriod1,2,0,200,1) teste TEMA (High Prd1) (PK, haHigh, 0) // PeakValue0 PKV1 ValorWhen (PK, haHigh, 1) // PeakValue1 PKV2 ValorQuando (PK, haHigh, 2) // PeakValue2 MPK PKV2 lt PKV1 E PKV1 gt PKV0 // MajorPeak MPKV ValorQuando (Ref (MPK, -1) 0 e MPK 1, PKV1,1) // MajorPeakValue MPKD ValorQuando (Ref (MPK, -1) 0 AND MPK 1 , DateNum (), 1) // MajorPeakDate SD IIf (DateNum () lt LastValue (MPKD, lastmode True), Null, LastValue (MPKV, Lastmode True)) // SelectedDate Plot (SD, Resist1, colorGreen, ParamStyle (ResStyle1, (MK, MP), MPKV2 ValueWhen (Ref (MPK, -1) 0 e MPK 1, PKV1,2) // MajorPeakValue MPKD2 ValorWhen (Ref (MPK, -1) 0 e MPK 1, DateNum () (MPKD2, LastMode True)) // SelectedDate Plot (SD2, Resist2, colorGreen, ParamStyle (ResStyle2, styleLinestyleNoTitle, maskAll)) MPKV3 ValueWhen (Ref (MPK, -1) 0 e MPK 1, PKV1,3) // MajorPeakValue MPKD3 ValorWhen (Ref (MPK, -1) 0 e MPK 1, DateNum (), 3) // MajorPeakDate SD3 IIf (DateNum () lt LastValue (MPKD3, lastmode True), Null, LastValue (MPKV3, Lastmode True)) // SelectedDate Trama (SD3, Resist3, colorGreen, ParamStyle (ResStyle3, styleLinestyleNoTitle, maskAll)) MPKV4 ValueWhen 1, PKV1,4) // MajorPeakValue MPKD4 ValorWhen (Ref (MPK, -1) 0 e MPK 1, DateNum (), 4) // MajorPeakDate SD4 IIf (DateNum () lt LastValue (MPKD4, lastmode True) Última Valor (MPKV4, Lastmode True)) // SelectedDate Traçar (SD4, Resist4, colorGreen, ParamStyle (ResStyle4, styleLinestyleNoTitle, maskAll)) MPKV5 ValueWhen (Ref (MPK, -1) 0 / MPK 1, PKV1,5) // MajorPeakValue MPKD5 ValueWhen (Ref (MPK, -1) 0 e MPK 1, DateNum (), 5) // MajorPeakDate SD5 IIf (DateNum () lt LastValue (MPKD5, lastmode True), Null, LastValue (MPKV5, Lastmode True) MPKV6 ValueWhen (Ref (MPK, -1) 0 e MPK 1, PKV1,6) // MajorPeakValue MPKD6 ValueWhen (Ref (MPK, - l)) / SelectedDate trama (SD5, Resist5, colorGreen, ParamStyle (ResStyle5, styleLinestyleNoTitle, ) 0 / MPK 1, DateNum (), 6) // MajorPeakDate SD6 IIf (DateNum () lt LastValue (MPKD6, lastmode True), Null, LastValue (MPKV6, Lastmode True)) // SelectedDate Plot (SD6, Resist6, colorGreen , ParamStyle (ResStyle6, styleLinestyleNoTitle, maskAll)) SEÇÃO 2 (HaClose, -1), 0,5) HaHigh Max (H, Max (HaClose, HaOpen)) HaLow (L, 1) E Ref (L, 1) lt L / L (L, Mín. / Peak Prd2Param (SupPeriod1,2,0,200,1) test2 TEMA (Low. (SP, haLow, 0) // PeakValue0 SPV1 ValorWhen (SP, haLow, 1) // PeakValue1 SPV2 ValueWhen (SP, haLow, 0) SP Ref (test2,1) gt Baixo E test2 lt Ref (test2, -1) (SP, haLow, 2) // PeakValue2 // PKV5 ValorWhen (PK, haHigh, 5) // PeakValue5 // PKV6 ValorWhen (PK, haHigh, 6) // PeakValue6 MSP SPV2 gt SPV1 E SPV1 lt SPV0 // MajorPeak MSPV ValueWhen (Ref (MSP, -1) 0 MSPD ValueWhen (Ref (MSP, -1) 0 E MSP 1, DateNum (), 1) SD IIf (DateNum () lt LastValue (MSPD, MSPV2 ValueWhen (Ref (MSP, -1) 0 e MSP 1, SPV1, 2) MSPV2 ValueWhen (Ref (MSP, -1) MSPD2 ValueWhen (Ref (MSP, -1) 0 e MSP 1, DateNum (), 2) SD2 IIf (DateNum () lt LastValue (MSPD2, lastmode True), Null, LastValue (MSPV2, Lastmode True) MSPV3 ValueWhen (Ref (MSP, -1) 0 e MSP 1, SPV1,3) MSPD3 ValueWhen (Ref (MSP, -1) 0 e MSP 1, DateNum () Voltar ao topo A informação contida neste artigo aplica-se a: , 3) SD3 IIf (DateNum () lt LastValue (MSPD3, lastmode True), Null, LastValue (MSPV3, Lastmode True)) Plot (SD3, Support3, colorBrown, ParamStyle (SupportLine3, styleLinestyleNoTitle, Maskall)) MSPV4 ValueWhen (Ref ( MSPD4 ValueWhen (Ref (MSP, -1) 0 E MSP 1, DateNum (), 4) SD4 IIf (DateNum () lt LastValue (MSPD4, lastmode True) MSPV5 ValueWhen (Ref (MSP, -1) 0 e MSP 1, SPV1,5) MSPD5 ValueWhen (Ref (MSP, -1) MSPV5 ValueWhen (Ref (MSP, -1) (MSP, -1) 0 e MSP 1, DateNum (), 5) SD5 IIf (DateNum () lt LastValue (MSPD5, lastmode True), Null, LastValue (MSPV5, Lastmode True) ParamStyle (SupportLine5, styleLinestyleNoTitle, maskAll)) MSPV6 ValueWhen (Ref (MSP, -1) 0 e MSP 1, SPV1,6) MSPD6 ValueWhen (Ref (MSP, -1) 0 e MSP 1, DateNum () IIF (DateNum () lt LastValue (MSPD6, lastmode True), null, LastValue (MSPV6, Lastmode True)) plotagem (sd6, Support6, colorBrown, ParamStyle (SupportLine6, styleLinestylehiddenstyleNoTitle, Maskall)) SECTIONBEGIN (Price) SetChartOptions (0, chartShowArrowschartShowDates ) N) () () () () () () () () () () Color, colorBlack), styleNoTitle ParamStyle (Style) GetPriceStyle ()) Este afl irá traçar o sistema de negociação icmoku kinko hoya no seu Amibroke. AFL para várias médias móveis e diferentes parâmetros para o teste do sistema SetChartBkColor (ColorHSB (42, 42, 62)) SetChartOptions (0, chartShowArrowschartShowDates) Função (C, Close, 47. styleNoTitle styleCandle) função T3 (preço, períodos) s 0,84 e1EMA os preços, os períodos) e2EMA (e1, períodos) e3EMA (e2, períodos) e4EMA (e3, períodos) e5EMA (E4, períodos) e6EMA (E5, períodos) c1-sss c23ss3sss c3-6ss-3s-3sss c413ssss3ss Ti3c1e6c2e5c3e4c4e3 retorno TI3 Type1 (Tipo 1 Simples) m MA (C, Prd) if (Tipo1 Simples) (C1, Prd) if (Tipo1 Extendencial) m EMA (C, Prd) if (Tipo1 Exponencial Duplo) m DEMA (C, Prd) if (Tipo1 Tripple Exponencial) (Tipo1 T3) m T3 (C, Prd) Tipo2 ParamList (Tipo 2, Simples, Exponencial, Exponencial Duplo, Tripple Exponencial, Wilders, Ponderado, 5) m1 0 prd1Param (períodos tipo2 Se (Tipo2 Simples) m1 MA (C, Prd1) se (Tipo2 Exponencial) m1 EMA (C, Prd1) se (Tipo2 Dupla exponencial) m1 DEMA (C, Prd1) M1 TEMA (C, Prd1) se (Tipo 2 Wilders) m1 Wilders (C, Prd1) se (Tipo2 Ponderado) m1 WMA (C, Prd1) Plot (m,, colorSkyblue, , -1), 5,4), 4) BuysetupCross (m, m1) ShortsetupCross (m1, m) BuysetupvalidFlip (Buysetup, Shortsetup) ShortsetupvalidFlip (Shortsetup, Buysetup) BuyCover Buysetupvalid SellShort Shortsetupvalid BuyExRem (Compra, Venda) SellExRem (Sell, Comprar) ShortExRem (Curto, Capa) CoverExRem (Capa, Curto) ComprarPreçoPreçoPesquisadoPortuárioPreçoC GraphXSpace 5 dist 1.5ATR (10) para (i 0 i lt BarCount i) if (Shorti) PlotText (Shortn ShortPrice i, i, H i disti, colorRed) (Coveri) PlotText (covern CoverPrice i, i, L i - disti, colorLime) se (Selli) PlotText (Selln SellPrice i, i, H i disti, colorOrange) PlotShapes (IIf (Sell, shapeHollowSmallDownTriangle, 0, L, - 15) PlotShapes (IIf (Cover, shapeHollowSmallUpTriangle, shapeNone), colorGreen, 0, L, - 15) PlotShapes (IIf (Buy, shapeUpArrow, shapeNone), colorBrightGreen, (Short, shapeDownArrow, shapeNone), colorRed, 0, H, - 25) FilterBuy OU Venda OU Curta OU Cover AddColumn (IIf (Buy, BuyPrice, Null), Buy / cover, 6.2.1, colorGreen) AddColumn , SellPrice, Null), venda / short, 6.2.1, colorOrange) AddColumn (IIf (Curto, ShortPrice, Null), short Price, 6.2,1, colorRed) 6.2.1, colorLime) Título - -. WriteEd (m1, (type2 - prd1) WriteVal (m1) ,,) nEncodeColor (7) WriteIf (m1, (tipo2 - prd1) WriteVal (m) NEncodeColor (colorPink) WriteIf (CM, disance de type1 ma WriteVal (CM) ,,) // Plot (V,, colorPaleBlue, 2styleOwnScale) SECTIONBEGIN (Texto de fundo) GfxSetOverlayMode (1) GfxSelectFont (Tahoma, Status pxheight) GfxSetTextAlign (6) // center alinhamento // GfxSetTextColor (ColorRGB (200, 200, 200)) GfxSetTextColor (ColorHSB (42, 42, 82)) GfxSetBkMode (0) // transparente GfxTextOut (Name (), Status (pxwidth) GfxSelectFont (Tahoma, Status (pxheight) / 12) GfxSelectFont (Tahoma, Status (pxheight) / 12) GfxTextOut (Multi MA cross system, Status (pxwidth) / 2, 36) GfxTextOut (Gráfico por Cas, Status (pxwidth) / 2, Status (pxheight) / 2) SECTIONEND () / Isso irá plotar gráficos mensais, semanais, daly, horários, 15 minutos, 5 minutos e 1 minuto em um gráfico, mas Diferentes painéis. Você pode aplicar esses gráficos como indicadores em painéis diferentes no Amibroker. / SetChartBkGradientFill (colorWhite, colorLightGrey, colorWhite) Período ParamList (Base, MonthlyWeeklyDailyHourly15Minute5Minute1Minute, 0) if (PeriodMonthly) TimeFrameSet (inMonthly) PlotOHLC (Open, High, Low, Close, Preço Mensal Gráfico, colorBlack, estilo styleCandle styleOwnScale) Plot (V, Volume, colorWhite, styleHistogram) if (PeriodWeekly) TimeFrameSet (inWeekly) PlotOHLC (Open, High, Low, Close, gráfico de preços semanais, colorBlack, estilo styleCandle styleOwnScale) Plot (V, Volume, colorWhite, styleHistogram) if (PeriodDaily) TimeFrameSet InDaily) PlotOHLC (Open, High, Low, Close, Tabela de preços diários, colorBlack, estilo styleCandle styleOwnScale) Plot (V, Volume, colorWhite, styleHistogram) if (PeriodHourly) TimeFrameSet (inHourly) horária preço Gráfico, colorBlack, estilo styleCandle styleOwnScale) Plot (V, Volume, colorWhite, styleHistogram) if (Period15Minute) TimeFrameSet (in15Minute) PlotOHLC (Open, High, Low, close, 15minute preço Gráfico, colorBlack, estilo styleCandle styleOwnScale) Plot ( V, Volume, colorWhite, styleHistogram) if (Period5Minute) TimeFrameSet (in5Minute) PlotOHLC (Open, High, Low, Close, 5Minute Gráfico de Preços, colorBlack, style styleCandle styleOwnScale) Plot (V, Volume, colorWhite, styleHistogram) if (Period1Minute) (V, Volume, colorWhite, styleHistogram) Use este afl para desenhar Murrey Math linhas de preços para o seu chart. Use-lo como Indicador em você carta de preço em Amibroker. SECTIONBEGIN (Murrey Math Preço Linhas) / // Arquivo: /AFL. root/AFL/YofaTrader/Custom/Murrey Math Preço Lines. afl. cs // Data: 08.03.29 22:57 // Modtime: 08.03.29 22: 52 // Revisão: 15 // Arquivo de Trabalho: Murrey Math Price Lines. afl. cs / ParamShowLevelParamList (Mostrar níveis harmônicos, 1/81/41/2, 1) ParamShowLabelParamStyle (Mostrar etiquetas harmônicas, styleNoLabel, styleNoLabel) if (Status ) 1) // indicador LastVisibleIndex LastValue (Status (lastvisiblebarindex)) se (LastVisibleIndex gt BarCount -1) // para evitar erros é caso do cursor está atrás da última barra LastVisibleIndex BarCount-1 TotalVisibleBars LastVisibleIndex - LastValue (Status (firstvisiblebarindex)) 1 pessoa LastVisibleIndex BarCount -1 TotalVisibleBars BarCount HHScreen HHV (High, TotalVisibleBars) LLScreen LLV (Baixo, TotalVisibleBars) PRScreen HHScreenLastVisibleIndex - gama LLScreenLastVisibleIndex // Preço PriceRangeVisible PRScreen 1.1 MiddleVisible (HHScreenLastVisibleIndex LLScreenLastVisibleIndex) / 2 HighestVisible MiddleVisible PriceRangeVisible / 2 LowestVisible MiddleVisible - PriceRangeVisible / Se (MaiorVisível gt 1.525) se (MaiorVisível gt 1.500) se (MaiorVisível gt 1.525) se (MaiorVisível gt 1.253) if ) ShowLevel 1 PriceStep SquareBase / 8 while (PriceRangeVisible / 4 PriceStep lt E ShowLevel lt 4) PriceStep PriceStep / 8 ShowLevel // mais baixo, maior valor harmónico para mostrar no chão painel LowerValue (LowestVisible / PriceStep) PriceStep HigherValue ceil (HighestVisible / PriceStep ) PriceStep Octave1PriceStep SquareBase / 8 Octave2PriceStep SquareBase / 64 Octave3PriceStep SquareBase / 512 Harmonic LowerValue // itera de baixo para valores altos enquanto (Harmonic lt HigherValue) estilo styleDashed // 1/8, 3/8, 5/8, 7/8 linhas De qualquer cor de nível ColorGreen // 1/8, 7/8 if ((Harmonic / PriceStep) 8 1 OR (Harmonic / PriceStep) 8 7) cor colorYellow // 3/8, 5/8 if (ParamShowLevel 1/8) StyleNoLine if ((Harmonic / PriceStep) 2 0) // 1/4, 3/4 linhas de qualquer estilo de nível styleDashed cor colorPink if (ParamShowLevel 1/2) estilo styleNoLine if ((Harmonic / PriceStep) 4 0) // 1/2 linha de qualquer estilo de estilo cor de estiloDashed colorBlue se ((Harmonic / PriceStep) 8 0) // 1/1 linha de cor de nível de bebê colorBlue estilo styleLine if ((Harmonic / Octave3PriceStep) 64 0) // 1/1 line De estilo de nível menor styleThick // 1/1 / Level Menor if (estilo styleNoLine) // se houver uma linha para plotar. (Evitar impressão de rótulos não utilizados) Estilo de estilo ParamShowLabel Plot Harmonic Harmonic PriceStep Disclosure e Disclaimer: Todas as informações e opiniões fornecidas aqui neste blog são de fontes acreditadas para reliable. Auther não garante a sua exatidão, integridade E correção. Este documento não é, e não deve ser interpretado como, uma oferta de venda ou solicitação para comprar qualquer ações / valores mobiliários. Eu e meus afiliados podem ter posições em qualquer ação mencionada neste documento e podem, de tempos em tempos, adicionar ou alienar tais ativos (ou investimentos). O uso dos dados e informações contidos neste relatório é por sua conta e risco. Sandeep Gupta. Modelo simples. Powered by Blogger. August 25, 2017 IMPORTANTE: Não use o indicador em um sistema de comércio real que olha para a frente no tempo e vai fazer você perder dinheiro. Destina-se somente à pesquisa: mostrar lucros potenciais e exibir setas em posições altamente lucrativas para facilitar a formulação de melhores regras comerciais. O indicador apresentado aqui é muito semelhante ao Indicador ZigZag, exceto que os pontos de viragem para este indicador são onde as Bandas Bollinger opostas são rompidas pela última vez antes do próximo sinal. A fórmula é escrita como um sistema comercial. Ele pode ser Backtested, eo período de BB e largura pode ser otimizado. Uma vez que esta é apenas uma fórmula experimental nenhuma tentativa foi feita para otimizar o código. A forma usual de reduzir o atraso de indicadores em fórmulas de média, como o MA (), EMA e Tilson T3 (), é tentar E sonhar uma fórmula completamente nova. Isso não é fácil. Muitas vezes é mais fácil remover a defasagem de um lote já alisado, do que melhorar a fórmula básica de suavização. Indicador Atraso é muitas vezes uma qualidade de indicador essencial e (imo) não é o mesmo que Lag indicador. A função de alisamento ideal é uma com atraso zero, isto é, uma que rastreia o preço com um lote perfeitamente liso. O atraso pode ser adicionado mais tarde como uma qualidade independente usando a função ref (). Algumas fórmulas de suavização já têm um ajuste de sensibilidade, estas não se comportarão necessariamente da mesma maneira que o fator LagReducing usado abaixo. Recomenda-se a optimização de todos os parâmetros para obter os melhores resultados. A fórmula de Lag-Redução apresentada aqui pode ser aplicada à maioria das fórmulas de média e aos indicadores baseados em médias (como Bandas). O parâmetro de redução de atraso (RLFactor) da função Reducelag () também pode ser usado para tornar as fórmulas adaptativas em relação a outro preço ou qualidade do Indicador. A imagem abaixo mostra como o atraso foi reduzido para a fórmula Tilson T3. Para ver como funciona esta fórmula Aplique o código mostrado abaixo para um novo painel indicador, abra a janela Parâmetro e tente configurações diferentes. Arquivado por Herman em 09:32 sob Indicadores Comments Off em Reduzindo Indicator-Lag 21 de fevereiro de 2009 o objetivo é traçar negócios no gráfico para que ele possa ser revisado periodicamente para aprender a negociar melhor. O objetivo é produzir um afl genérico que terá no símbolo, datas de comércio e preços e trama em um gráfico. Suportar diferentes prazos para que a plotagem ainda seja visível. Diária, semanal, intraday, 5 minutos / 15 minutos para suportar escalonamento de posição, uma vez que pode haver múltiplas entradas / saídas de negócios, esta afl precisa da entrada em termos de variáveis ​​estáticas da seguinte forma. Então você pode precisar de um adaptador que terá seus negócios e colocá-lo para afl. // define se é um estoque ou forex. StaticVarSetText (TradeType. Stocks) // StocksForex // define o símbolo forex StaticVarSetText (forexSymbol. SBUX) //EUR. USD-IDEALPRO-CASH // define o símbolo de ações StaticVarSetText (StockSymbol, SBUX) // YHOO // longo ou curto comércio. StaticVarSetText (ShortOrLong. Longa) // ShortLong // Preços de entrada StaticVarSetText (EntryPrice. 14.5,15.5) // preços saída StaticVarSetText (ExitPrice. 14.3) // data de entrada no número de data delimitados por vírgula StaticVarSetText (ENTRYDATE. 1080717,1080723) // Data de saída no número da data. delimitado por vírgula StaticVarSetText (ExitDate, 1.080.725) // tempo de entrada em número tempo delimitado por vírgula StaticVarSetText (EntryTime, 142500,120000) // tempo de saída em número tempo delimitado por vírgula StaticVarSetText (ExitTime. 110500) // ID de comércio. É uma chave interna para mim StaticVarSetText (Tradeid. 4) // estratégia comercial. StaticVarSetText (TradeStrategy. fsdfdsfds) // quaisquer comentários sobre o comércio StaticVarSetText (TradeComments. este é o comentário) / define nenhum de entradas para que o código loops ao imprimir o número de trdes. Se 1, então deve haver apenas 1 data / hora de entrada se houver mais de 1 entrada ou saídas, o número de entradas delimitadas por vírgulas deve ser igual à variável estática NoOfEntries e o mesmo se aplica para saídas / StaticVarSet (NoOfEntries. o mesmo que acima. StaticVarSet (NoOfExits. 1) SetChartOptions (0, chartShowArrows chartShowDates) N (Título StrFormat (8220 8211 Abrir g, Hi g, Lo g, Fechar g (.1f) 8221, O, H, L, C, SelectedValue , 1)))) Título Título 8220n8221 NumToStr (DateNum ()) Título Título 8220n8221 NumToStr (TimeNum ()) Plot (C, 8220Close8221, ParamColor (8220Color8221, colorBlack), styleNoTitle ParamStyle (8220Style8221) GetPriceStyle ()) // TRACE ( 8220ABTest: teste TRACE1 8220) // incluem 8220C: Programa FilesAmiBrokersharedLibraryDateTimeToNumber. afl8221 / include 8220C: Programa FilesAmiBrokersharedLibraryDateTimeToNumber. afl8221 StaticVarSetText (8220TradeType8221, 8221Stocks8221) // StocksForex StaticVarSetText (8220forexSymbol8221, 8221AAPL8221) //8221EUR. USD-IDEALPRO-CASH StaticVarSetText (8220StockSymbol8221 , 8221AAPL8221) // 8220YHOO8221 StaticVarSetText (8220ShortOrLong8221, 8221Short8221) // 8221ShortLong8221 StaticVarSet (8220EntryPrice8221, 163,52000) StaticVarSet (8220ExitPrice8221, 148,18000) StaticVarSet (8220EntryDate8221, DateToNum (8220200807218221)) StaticVarSet (8220ExitDate8221, DateToNum (8220200807218221)) StaticVarSet (8220EntryTime8221, TimeToNum (822017: 01: 478221)) StaticVarSet (8220ExitTime8221, TimeToNum (822017: 52: 178221)) StaticVarSetText (8220TradeType8221. 8220Stocks8221) // StocksForex StaticVarSetText (8220forexSymbol8221. 8220SBUX8221) //8221EUR. USD-IDEALPRO-CASH StaticVarSetText (8220StockSymbol8221, 8220SBUX8221) // 8220YHOO8221 StaticVarSetText (8220ShortOrLong8221. 8220Long8221) // 8221ShortLong8221 StaticVarSetText (8220EntryPrice8221. 822017.5,15.58221) StaticVarSetText (8220ExitPrice8221. 822.014,38221) StaticVarSetText (8220EntryDate8221. 82201880717,10807238221) StaticVarSetText (8220ExitDate8221, 822018807258221) StaticVarSetText (8220EntryTime8221, 8220172500,1200008221) StaticVarSetText (8220ExitTime8221. 82201705008221) StaticVarSetText (8220Tradeid8221. 822048221) StaticVarSetText (8220TradeStrategy8221. 8220fsdfdsfds8221) StaticVarSetText (8220TradeComments8221. 8220this é o comment8221 ) StaticVarSet (8220NoOfEntries8221. 2) StaticVarSet (8220NoOfExits8221. 1) função returnBarIndex (array) indx -1 para (i 1 i lt BarCounti) função returnShiftedArray (array, shift) para (i 1 i 0) ampamp ((shift i) lt BarCount)) newArrayshifti Verdadeiro newArrayi False se (strtoupper (Name ()) strtoupper (StaticVarGetText (8220forexSymbol8221)) OU (strtoupper (Name ()) strtoupper (StaticVarGetText (8220StockSymbol8221)))) // obter as variáveis ​​estáticas TradeType StaticVarGetText (8220TradeType8221) forexSymbol StaticVarGetText (8220forexSymbol8221) stockSymbol StaticVarGetText (8220StockSymbol8221) ShortOrLong StaticVarGetText (8220ShortOrLong8221) if (TradeType 8220Stocks8221) stockname stockSymbol SetOption (8220FuturesMode8221, False) else stockname forexSymbol SetOption (8220FuturesMode8221, True) para (i 0 i lt StaticVarGet (8220NoOfEntries8221) i) VARSET (8220EntryDate8221 (I), StrToNum (StrExtract (StaticVarGetText (8220EntryDate8221), (i)))) VARSET (8220EntryPrice8221 (I), StrToNum (StrExtract (StaticVarGetText (8220EntryPrice8221), (i)))) VARSET (8220EntryTime8221 (i), StrToNum (StrExtract (StaticVarGetText (8220EntryTime8221), (i)))) TRACE (8220ABTest: teste 182 8221 8220EntryDate8221 (i) NumToStr (VarGet (8220EntryDate8221 (i)))) TRACE (8220ABTest: teste 182 8221 8220EntryDate8221 (i) 8220string8221 StrExtract (StaticVarGetText (8220EntryDate8221), (i))) // tESTE Se as variáveis ​​existem para (i 0 i lt StaticVarGet (8220NoOfEntries8221) i) TRACE (8220ABTest: teste 182 TESTING8221 8220EntryDate8221 (i) NumToStr (VarGet (8220EntryDate8221 (i)) )) TRACE (8220ABTest: teste 182 tESTES timeframe8221 inWeekly) for (j 0 j lt StaticVarGet (8220NoOfExits8221) j) VARSET (8220ExitDate8221 (j), StrToNum (StrExtract (StaticVarGetText (8220ExitDate8221), (j)))) VARSET (8220ExitTime8221 ( j), StrToNum (StrExtract (StaticVarGetText (8220ExitTime8221), (j)))) VARSET (8220ExitPrice8221 (j), StrToNum (StrExtract (StaticVarGetText (8220ExitPrice8221), (j)))) // TRACE (8220ABTest: teste 182 8221 8220ExitDate8221 (J) 8220string8221 StrExtract (StaticVarGetText (8220ExitDate8221), (j))) // Comprar Vender Curto Cobertura entryPrices exitPrices False // se o símbolo corresponder ao que procuro dn DateNum () entryPrices exitPrices Comprar Vender Curto Cobertura FALSE gama H 8211 L (Intervalo ()) // COMEÇO DO INTERRUPTOR. Para (b 0b lt BarCountb) // INÍCIO DE DIARIAMENTE para (i 0 i dnb 8211 1) E (VarGet (8220EntryDate8221 i) lt dnb 1)) entryPricesb VarGet (8220EntryPrice8221 i) Buyb Shortb True // TRACE (8220ABTest: teste 182 preço correspondente 8221 NumToStr (VarGet (8220EntryPrice8221 i))) plotText (StaticVarGetText (8220ShortOrLong8221) 8221 8221 entrada i 8221 8221 8220:.. 8221 entryPricesb b, rangeb Highb, colorBlue) // plotText (8220entry8221 VarGet (8220EntryPrice8221 i) b, EntryPrice0 , ColorBlue) // TRACE (8220ABTest: teste 182 COMBINADO 8221 NumToStr (VarGet (8220EntryDate8221 i)) NumToStr (dnb)) para (j 0 j dnb 8211 1) E (VarGet (8220ExitDate8221 j) lt dnb 1)) exitPricesb VarGet 8220ExitPrice8221 j) Sellb Coverb Verdadeiro plotText (StaticVarGetText (8220ShortOrLong8221) 8221 Exit 8221 j 8220: 8221 VarGet (8220ExitPrice8221 j) b, Lowb 8211 rangeb, Colorred) // TRACE (8220ABTest:. teste de 182 MATCHED 8221 NumToStr (VarGet (8220ExitPrice8221 j) ) NumToStr (dnb) NumToStr (VarGet (8220ExitDate8221 j))) para (b 1b lt BarCount 8211 1b) // START OF semanalmente para (i 0 i 0) AnteriorBarb-1 NextBarb if (b dnb) AND (VarGet (8220EntryDate8221 i ) lt dnb1)) entryPricesb VarGet (8220EntryPrice8221 i) Buyb Shortb Verdadeiro TRACE (8220ABTest: teste de 182 entrada de preço correspondente 8221 NumToStr (VarGet (8220EntryPrice8221 i))) plotText (StaticVarGetText (8220ShortOrLong8221) 8221 entry8221 i 8221 8221 8220: 8221 entryPricesb. b, Highb rangeb, colorBlue) // plotText (8220entry8221 VarGet (8220EntryPrice8221 i) b, EntryPrice0, colorBlue) // //. (8220ABTest: teste 182 MATCHED 8221 NumToStr (VarGet (8220EntryDate8221 i)) NumToStr (dnb)) para ( j 0 j dnb-1) e (VarGet (8220EntryDate8221 i) dnb) E (VarGet (8220ExitDate8221 j) lt dnb1)) exitPricesb VarGet (8220ExitPrice8221 j) Sellb Coverb Verdadeiro plotText (StaticVarGetText (8220ShortOrLong8221) 8221 Exit8221 j 8220: 8221 VarGet ( (8220ExitPrice8221 j)) NumToStr (dnb) NumToStr (VarGet (8220ExitDate8221 j))) // COMEÇO DE semanal // TRACE (8220ABTest: teste 182 8221 8221getting para break8221) para (b 1b lt BarCount 8211 1b) // Início do intraday para (i 0 i TNB) E (VarGet (8220EntryTime8221 i) lt tnb1)) entryPricesb VarGet (8220EntryPrice8221 i) Buyb Shortb True TRACE (8220ABTest: teste 182 entrada de preço correspondente 8221 NumToStr (VarGet (8220EntryPrice8221 i))) PlotText (StaticVarGetText (8220ShortOrLong8221) 8221 entrada 8221 8221 8221 8220: 8221 entryPricesb. b, Highb rangeb, colorBlue) // plotText (8220entry8221 VarGet (8220EntryPrice8221 i) b, EntryPrice0, colorBlue) // //. (8220ABTest: teste 182 MATCHED 8221 NumToStr (VarGet (8220EntryDate8221 i)) NumToStr (dnb)) para ( j 0 j dnb-1) e (VarGet (8220EntryDate8221 i) TNB) E (VarGet (8220ExitTime8221 j) lt tnb1)) exitPricesb VarGet (8220ExitPrice8221 j) Sellb Coverb Verdadeiro plotText (StaticVarGetText (8220ShortOrLong8221) 8221 Exit8221 j 8220: 8221 VarGet ( (8220ExitPrice8221 j)) NumToStr (dnb) NumToStr (VarGet (8220ExitDate8221 j))) // fim de intraday // TRACE (8220ABTest: testar 182 8221 8221correndo a break8221) PlotShapes (IIf (Buy OU Short, shapeSmallCircle, shapeNone), colorBrightGreen, 0, EntryPrices, 0) PlotShapes (IIf (Sell OU Cover, shapeSmallCircle, shapeNone), colorRed, 0. ExitPrices , 0) Estado Miny (8220axisminy8221) Estado Maxy (8220axismaxy8221) pxheight Status (8220pxheight8221) y (GetCursorYPosition () 8211 Miny) / (Maxi 8211 Miny) y (1 8211 y) pxheight GfxSelectPen (colorRed, 1) // GfxRectangle , Y-100, 270, y) GfxSelectFont (8220Tahoma8221, 8, 700) GfxTextOut (Nome () 8221 Tradeid 8221 StaticVarGetText (8220Tradeid8221). X, y) GfxTextOut (8221 Estratégia 8221 StaticVarGetText (8220TradeStrategy8221) x, y 10) GfxTextOut (8221 Comentários 8221 StaticVarGetText (8220TradeComments8221) x / y 20) // // se o símbolo corresponde ao que eu estou procurando Arquivado por suresh at 7:57 pm under AmiBroker Tools and Features, Uncategorized Comments Off on Plotting trades on chart March 16, 2008 From version 4.67.0, AmiBroker provides a custom backtester interface to allow customising the operation of the backtester8217s second phase which processes the trading signals . This allows a range of special situations to be achieved that aren8217t natively supported by the backtester. AmiBroker tends to refer to this as the Advanced Portfolio Backtester Interface, but as it seems to be more widely referred to as the Custom Backtester Interface, I will use this latter terminology. Due to the object model used by the backtester interface, a higher level of programming knowledge is required than for simple AFL or looping. This document starts by discussing that model, so is aimed at AFL programmers who are already proficient and comfortable with basic AFL use, array indexing, and looping. If you don8217t understanding looping, then you almost certainly won8217t understand the custom backtester interface. The modern programming paradigm is called object-oriented programming, with the system being developed modelled as a set of objects that interact. The custom backtester interface follows that model. An object can be thought of as a self-contained black-box that has certain properties and can perform certain functions. Internally it8217s a combination of code and variables, where both can be made either private to the internals of the object only or accessible from outside for the benefit of users of the object. The private code and variables are totally hidden from the outside world and are of no interest to users of the object. Only developers working on the object itself care about them. Users of the object are only interested in the code and variables made accessible for their use. Any variable made accessible to an object8217s user is called a property of the object. For example, the Backtester object has a property (variable) called 8220Equity8221, which is the current value of the portfolio equity during a backtest. Properties can be read and written much the same as any other variable, just by using them in expressions and assigning values to them (although some properties may be read-only). However, the syntax is a little different due to the fact they8217re properties of an object, not ordinary variables. An object8217s code is made accessible to its users by providing a set of functions that can be called in relation to the object. These functions are called methods of the object. They are essentially identical to ordinary functions, but perform operations that are relevant to the purpose of the object. For example, the Backtester object has methods (functions) that perform operations related to backtesting. Methods are called in much the same way as other functions, but again the syntax is a little different due to them being methods of an object rather than ordinary functions. The aim of the object model is to view the application as a set of self-contained and reusable objects that can manage their own functionality and provide interfaces for other objects and code to use. Imagine it as being similar to a home entertainment system, where you buy a number of components (objects) like a TV, DVD player, surround-sound system, and karaoke unit (if you8217re that way inclined). Each of those components manages its own functionality and provides you with a set of connectors and cables to join them all together to create the final application: the home entertainment system. The beauty of that arrangement is that each component provides a standard interface (if you8217re lucky) that will allow any brands of the other components to be connected, without those components having to know the details of how all the other components work internally, and considerable choice in the structure of the final entertainment system constructed. Similarly, software objects have standard interfaces in the form of methods and properties that allow them to be used and reused in any software. Accessing Oject Properties And Methods To access the properties and methods of an object, you need to know not only the name of the property or method, but also the name of the object. In AmiBroker AFL, you cannot define or create your own objects, only use objects already provided by AmiBroker. AmiBroker help details all its objects, methods, and properties in the section 8220Advanced portfolio backtester interface8221. To use real AFL examples, the first object detailed in the help is the Backtester object. AmiBroker provides a single Backtester object to perform backtests. To use the Backtester object, you first have to get a copy of it and assign that to your own variable: The variable 8220bo8221 is your own variable, and you can call it whatever you like within the naming rules of AFL. However, to avoid a lot of verbose statements, it8217s good to keep it nice and short. Previously you8217ve only dealt with variables that are either single numbers, arrays of numbers, or strings. The variable 8220bo8221 is none of those, instead being a new type of variable called an object variable. In this case it holds the Backtester object (or really a reference to the Backtester object, but I don8217t want to get into the complicated topic of references here). Now that you have the Backtester object in your own variable, you can access its properties and methods. The syntax for referencing an object8217s property is objectName. objectProperty. for example bo. InitialEquity. That can then be used the same as any other variable (assuming it8217s not a read-only property, which InitialEquity is not): From this you can see the advantage of keeping object variable names short. If you called the variable 8220myBacktesterObject8221, then for the last example above you8217d end up with: Here I8217ve had to reduce the font size just to fit it all on a single line. If a property is read-only, then you cannot perform any operation that would change its value. So, using the Equity property which is read-only: The same syntax is used to access the methods of an object. The method name is preceded by the object name with a decimal point: objectName. objectMethod(). Any parameters are passed to the method in the same manner as to ordinary functions: For example, to call the Backtester object8217s AddCustomMetric method and pass the two compulsory parameters Title and Value, a statement like this would be used: AmiBroker help indicates that this method returns a value of type 8220bool8221, which means boolean and thus can only take the values True and False. However, it doesn8217t detail what this return value means. A good guess would be that it returns True if the custom metric was successfully added and False if for some reason it failed to be added. However, that8217s only a guess, but a common reason for returning boolean values. For some of the other methods that return values of type 8220long8221, it8217s more difficult to guess what they might contain. Another example with a return parameter: Here the variable 8220sig8221 is another object variable, but this time of type Signal rather than Backtester. In other words, it holds a Signal object rather than a Backtester object. Unlike the single Backtester object, AmiBroker can have many different Signal objects created at the same time (one for each trading signal). As a Signal object holds the signal data for a particular symbol at a particular bar, the method needs to know the bar number, which would typically be specified using a loop index variable (8216i8217 above) inside a loop: Once a Signal object has been obtained, its properties and methods can be referenced: Note that the property sig. PosScore is a single number, not an array. While the AFL variable PositionScore is an array, the 8220sig8221 object only holds data for a single bar, so the property sig. PosScore is the position score value for that bar only, thus a single number. Also note that AmiBroker help is not very clear on some topics. For example, the Signal object only has a few methods that indicate whether the current bar contains an entry, exit, long, or short signal, or has a scale in or out signal. However, it doesn8217t indicate how you combine these to get the exact details. For example, how do you tell the difference between a scale-in and a scale-out Is scaling in to a long position a combination of IsScale, IsEntry, and IsLong, or perhaps just IsScale and IsLong, or neither of those In some cases you need to use trial and error and see what actually works (learn how to use the DebugView program with TRACE statements: see Appendix B). Fortunately for this specific example, the Signal object also has a property called Type that indicates exactly what type the signal is. Using The Custom Backtester Interface To use your own custom backtest procedure, you first need to tell AmiBroker that you will be doing so. There are a few ways of doing this: By setting a path to the file holding the procedure in the Automatic Analysis Settings Portfolio page. This procedure will then be used with all backtests, if the 8220Enable custom backtest procedure8221 checkbox is checked. By specifying these same two settings in your AFL code using the functions SetOption(8220UseCustomBacktestProc8221, True) and SetCustomBacktestProc(8220 8220). Note that path separators inside strings need to use two backslashes, for example 8220c:AmiBrokerFormulasCustomBacktestsMyProc. afl8221. Although why is not important here, it8217s because a single backslash is what8217s called an escape character, meaning the character(s) after it can have special meaning rather than just being printable characters, so to actually have a printable backslash, you have to put two in a row. By putting the procedure in the same file as the other AFL code and using the statement SetCustomBacktestProc(82208221). This tells AmiBroker that there is a custom backtest procedure but there8217s no path for it, because it8217s in the current file. This option will be used throughout the rest of this document. The next thing that8217s required in all backtest procedures is to ensure the procedure only runs during the second phase of the backtest. That8217s achieved with the following conditional statement: And finally, before anything else can be done, a copy of the Backtester object is needed: So all custom backtest procedures, where they8217re in the same file as the other AFL code, will have a template like this: If the backtests were using a procedure in the file: then the first line above in your system AFL code would be replaced with: and the rest of the procedure would be in the specified file. Or, if the same values were specified in the Automatic Analysis settings, the two lines above would not be needed in your AFL code at all, and the procedure would be in the specified file. Custom Backtester Levels The AmiBroker custom backtester interface provides three levels of user customisation, simply called high-level, mid-level, and low-level. The high-level approach requires the least programming knowledge, and the low-level approach the most. These levels are just a convenient way of grouping together methods that can and need to be called for a customisation to work, and conversely indicate which methods cannot be called in the same customisation because their functionality conflicts. Some methods can be called at all levels, others only at higher levels, and others only at lower levels. AmiBroker help details which levels each method can be used with. Naturally, the higher the level and the simpler the programming, the less flexibility that8217s available. This document will not detail every single method and property available, so the rest of this document should be read in conjunction with the AmiBroker help sections 8220Advanced portfolio backtester interface8221 and 8220Adding custom backtest metrics8221. The high-level interface doesn8217t allow any customising of the backtest procedure itself. It simply allows custom metrics to be defined for the backtester results display, and trade statistics and metrics to be calculated and examined. A single method call runs the whole backtest in one hit, the same as when the custom backtester interface isn8217t used at all. AmiBroker help has an example of using the high level interface to add a custom metric. See the section called 8220Adding custom backtest metrics8221. In essence, the steps are: Start with the custom backtest template above Run the backtest Get the performance statistics or trade details Calculate your new metric Add your new metric to the results display That would look something like this: As well as just using the built-in statistics and metrics, obtained from the Stats object after the backtest has been run, it8217s also possible to calculate your metric by examining all the trades using the Trade object. As some positions may still be open at the end of the backtest, you may need to iterate through both the closed trade and open position lists: In this example, 8220trade8221 is an object variable of type Trade, meaning it holds a Trade object. As with the Signal object, AmiBroker can have many Trade objects created at the same time, one for each closed or open trade. The first for loop iterates through the closed trade list, and the second through the open position trade list. The continuation condition 8220trade8221 theoretically means while the trade object is not zero, but in fact 8220trade8221 will be Null when the end of the list is reached. However, any conditional involving a null value is always false, so this will still work. The five Backtester object methods GetFirstTrade, GetNextTrade, GetFirstOpenPos, GetNextOpenPos, and FindOpenPos all return Null when the end of the list is reached or if no trade or open position is found. The for loops are a little different to normal for loops in that they don8217t have a standard loop index variable like 8216i8217 that gets incremented at the end of each pass. Instead they call a Backtester object method to get the initial value (the first Trade object) and then another member to get the next value (the next Trade object). So the for loop conditions here are just saying start from the first Trade object, at the end of each pass get the next Trade object, and keep doing that until there are no more Trade objects (ie. 8220trade8221 is Null). The loops are iterating through the list of trades, not the bars on a chart. Each Trade object holds the details for a single trade. Putting that code inside the custom backtest template looks like this: As an example, say we want to calculate the average number of calendar days that winning trades were held for (there8217s already a built-in Stats object value for number of bars, but we want number of calendar days). For that we8217ll need a function that can calculate the number of calendar days between two dates. Let8217s call it 8220DayCount8221, a function that takes two parameters: the entry date and the exit date, both in AmiBroker date/time format. Since this document is about the custom backtester interface, I don8217t want to go into how that function works right now. Let8217s just assume it does, but the code for such a function is given in Appendix A if you8217re interested. Then, for each trade we8217ll need to know: If it was a winning or losing trade The entry date The exit date And to calculate the average, we8217ll need a total figure for the number of winning trade days and another total figure for the number of trades. The average is the total number of days winning trades were held divided by the total number of winning trades. For the trade details, the Trade object has the following properties: EntryDateTime The entry date 038 time ExitDateTime The exit date 038 time and the following method: GetProfit() The profit for the trade Before trying this example, the first time we8217ve used this Trade object method, we make the assumption that the profit will be negative for losing trades and positive for winning trades, as AmiBroker help doesn8217t clarify that detail (it could be some undefined value for losing trades). If trial and error proves that not to be the case, then we could alternatively try using the Trade object properties EntryPrice, ExitPrice, and IsLong to determine if it was a winning or losing trade. As it turns out upon testing, GetProfit does in fact work as expected. Note that the Trade object also has a property called BarsInTrade, which looks like it could potentially be used instead of the dates, but that only gives the number of bars, not the number of calendar days. So, to get the number of calendar days spent in a trade, we call our DayCount function passing the entry and exit dates: DayCount(trade. EntryDateTime, trade. ExitDateTime) and to determine if it was a winning trade, where break-even doesn8217t count as winning: trade. GetProfit() 0 The whole procedure would then be: Note that we only need to consider closed trades in this example, as counting open positions would not accurately reflect the number of days trades were typically held for. Also, the 8220totalTrades8221 variable only counts winning trades, not all trades, since we8217re only averaging over winning trades. When a backtest is run with this custom interface and a report generated, our new metric 8220avgWinDays8221 will be printed at the bottom of the report: And if we run an optimisation (using a different backtest to above), it will have a column near the right-hand end of the results: Note that the reason the 8220W. Avg Bars Held8221 column doesn8217t seem to agree with the 8220AvgWinDays8221 column (ie. the former goes down while the latter goes up) is because the average bars figure includes open positions at the end of the backtest whereas we specifically excluded them. As well as overall metrics per backtest, it8217s also possible to include individual trade metrics in the backtester results. For this, the metric is added to each Trade object rather than the Backtester object and the trades are listed at the end of the procedure. For example, to display the entry position score value against each trade in the backtester results, the following code could be used: The first for loop iterates through the closed trade list and the second through the open position list to get the entry score value for every trade listed in the results. Note that the bo. BackTest call is passed the value 8220True8221 in this case to prevent the list of trades being generated automatically by the backtester. Instead, they8217re generated by the subsequent call to the bo. ListTrades method. As another example, say we want to list for each winning trade how far above or below the average winning profit it was as a percentage, and similarly for each losing trade, how far above or below the average loss it was as a percentage. For this we need the 8220WinnersAvgProfit8221 and 8220LosersAvgLoss8221 values from the Stats object, and the profit from the Trade objects for each closed trade (for this example we8217ll ignore open positions). Relative loss percentages are displayed as negative numbers. To be able to modify actual backtest behaviour, the mid-level or low-level interfaces must be used. New metrics can also be calculated at these levels, but since that8217s already covered above, this section will only look at what backtest behaviour can be modified at this level. Essentially this means using Signal objects as well as the Backtester object. With the mid-level interface, each trading signal at each bar can be examined and the properties of the signals changed, based on the value of other Signal or Backtester object properties, before any trades are executed for that bar. For example, one Backtester object property is 8220Equity8221, which gives the current portfolio equity, and one Signal object property is 8220PosSize8221, the position size specified in the main AFL code, so the mid-level interface can allow, for example, position size to be modified based on current portfolio equity. The custom backtester interface template for a mid-level approach, where all the signals at each bar need to be examined, is: In this example, the variable 8220sig8221 is an object variable of type Signal, meaning it holds a Signal object. As with the Trade object in the earlier example, the inner for loop iterates through the list of signals at each bar, not through all bars on a chart. The for loop conditions are effectively saying start from the first Signal object for the current bar, at the end of each pass get the next Signal object for the same bar, and keep doing that until there are no more Signal objects for the bar (ie. 8220sig8221 is Null). Each Signal object holds the details of one signal at the current bar (ie. a buy, sell, short, cover or scale indication for one symbol). The main differences between the mid-level and high-level approaches are: The Backtester object8217s Backtest method is not called. The Backtester object8217s ProcessTradeSignals method is called instead at each bar, after examining and possibly modifying some of the Signal object properties and/or closed or open Trade object properties. A loop is required to iterate through all bars of the chart. A nested loop is required inside that one to iterate through all the signals at each of those bars. If a trading decision needs to be based on some other property of a particular stock, like it8217s average daily trading volume for example, then the stock code symbol must be used to obtain that information. This is available in the Signal object8217s 8220Symbol8221 property. However, since the backtester at this level is not run in the context of a particular symbol, the data must be saved to a composite symbol in the main code (or perhaps a static variable) and referenced in the custom backtest procedure with the Foreign function. For example, in the main AFL code: Here the volume EMA array is saved to a separate composite symbol for each stock (ie. each composite consists of just a single stock). For this to work in backtests, the atcFlagEnableInBacktest flag must be used. Then in the custom backtest procedure: As a real example, to limit the number of shares purchased to a maximum of 10 of the 100 day EMA of the daily volume, and also ensure the position size is no less than 5,000 and no more than 50,000, the following mid-level procedure could be used: In this example, the statement psize (-psize/100) bo. Equity converts the percentage of equity value (which is negative) to its actual dollar value, using the Backtester object8217s Equity property. The term - psize/100 (which doesn8217t actually need to be inside brackets) converts the negative percentage to a positive fraction which is then multiplied by the current portfolio equity. The statement if (sig. IsEntry() 038038 sig. IsLong()) calls the two Signal object methods IsEntry and IsLong to determine if the current signal is an entry signal and a long signal (ie. a buy signal). Remember that the 038038 operator is equivalent to AND. An alternative would be to check if the Signal object8217s Type property was equal to one. The array variable 8220evol8221 contains the whole EMA array realigned to the number of bars used by the custom backtest procedure. Padded bars don8217t matter here as there won8217t be any signals for the stock at any of those bars, and we8217re only checking the volume on bars where there is a signal. As 8220evol8221 is an array, at each bar we8217re only interested in the value for the current bar, hence the references to evoli. Finally, as detailed in the AmiBroker help, the Signal object8217s Price property gives the price for the current signal, so there8217s no need to use BuyPrice, SellPrice, etc. and the PosSize property is the signal8217s position size value for the current bar. As this is not a read-only property, it can be both read and modified. Another example, to prevent scaling in a position that already has 50,000 or more in open position value: In this example, as each new scale-in signal is detected, the list of open positions is checked for an open position in the same stock as the new signal. If an open position exists, its current value is obtained, and if that value is 50,000 or more, the position size is set to zero to prevent the scale-in from happening. The example combines use of the Backtester object, Signal objects and Trade objects to determine whether or not scale-in of a position should be permitted. Note that the Trade object is returned Null if no open position is found. As any comparison with a null value is always false, provided the test is for the True condition then the IsNull function is not needed: ie. 8220if (trade)8221 gives the same result as 8220if (IsNull(trade))8221. However, if the test is for the negative condition, IsNull is required: ie. 8220if (trade)8221 won8217t work (when 8220trade8221 is Null it will be treated as False rather than the desired True) and 8220if (IsNull(trade))8221 becomes necessary. The low-level interface provides the most flexibility to control backtester operation. As well as allowing signal properties to be modified, it also allows the entering, exiting, and scaling of trades even if no signal exists. With the low-level interface, each trading signal at each bar can be examined, the properties of the signals changed, and trades entered, exited, and scaled. This could be used to implement special stop conditions not provided in the ApplyStop function, or to scale trades based on current portfolio equity or open position value and the like. The custom backtester interface template for a low-level approach is: Note that this template currently has no trades performed in it, as there are a number of options there depending on the system. Typically, inside the signal loop (or possibly the trades loop) there will be a number of tests for various conditions and then trades entered, exited, and scaled accordingly. The main differences between the low-level and mid-level approaches are: The Backtester object8217s ProcessTradeSignals method is not called. The Backtester object8217s EnterTrade, ExitTrade, and ScaleTrade methods are called instead at each bar, after examining and possibly modifying some of the signal properties and/or closed or open trade properties. The Backtester object8217s HandleStops method must be called once per bar to apply any stops programmed in the settings or by the ApplyStop function. The Backtester object8217s UpdateStats method must be called at least once for each bar to update values like equity, exposure, MAE/MFE, etc. The AmiBroker help is a little vague on how the TimeInsideBar parameter works (the values 821618217 038 821628217 in the sample above), but it must be called exactly once with that parameter set to two. It should also be called with it set to one to update the MAE/MFE statistics, but why it would be called with the value set to zero or more than once, I8217m not sure. As an example, let8217s create a custom backtest procedure that scales in a long position by 50 of its injected capital (ie. excluding profit) whenever its open position profit exceeds its total injected capital, which means it8217s sitting on 100 or more profit. The scale-in can be repeated whenever this condition occurs, as immediately after each scale-in, the injected capital will go up by 50. The system doesn8217t do any shorting and no other scaling occurs. The required conditions therefore are: The profit must be greater than the injected capital to scale in. The scale-in position size is equal to half the injected capital. No signal is required to perform the scale-in. The Signal object list is still needed to enter and exit all trades, as there8217s no other mechanism to do that, but just the Trade object list is needed for scaling open positions. At each bar, each open long position in the trade open position list must be tested for scaling in, and a scale-in performed if the conditions are met. The test for scale-in then looks like this: The scale-in position size is: And the scale-in method call, using the closing price for scaling, is: Putting it all into our template gives: Since we stated that the system doesn8217t do any shorting, the tests for sig. IsLong aren8217t really necessary. The signal for loop processes all entry and exit signals generated by our buy and sell conditions in the main AFL code. As mentioned above, this is necessary since we8217re not calling the ProcessTradeSignals method now, as that8217s a mid-level method. The trade open position for loop checks for and processes all scaling in. When an exit signal occurs, the whole position is closed. Extending this example now to include our custom avgWinDays metric from the high-level interface example: Note that stops are handled before scale-in checking occurs, as there8217s no point scaling in a trade if it8217s about to get stopped out on the same bar (although it would be unlikely to satisfy the scale-in condition anyway if it was about to get stopped out). Also note that the Trade object method GetEntryValue returns the total amount of injected capital, including all previous scale-in amounts. It8217s not possible to get just the amount used in the initial purchase. It would actually be nice here if the Trade object had a few user-defined properties, to allow the user to persist any values they wanted to throughout the life of a trade (although this could also be done with static variables). For example, as mentioned above, the initial purchase amount before any scaling could be remembered, or perhaps the number of times scaling has occurred (your system may want to limit scaling in to a maximum of say three times). Another similar example, but this time scaling out a position once it has doubled in value, removing the initial capital invested (approximately): In this example we only want to do the scale-out once, which introduces a new problem: how do we tell whether we8217ve already done it or not Trial and error shows that the entry value returned by the GetEntryValue method halves if you remove half of the value, so AmiBroker appears to treat a scale-out of half the value as being half profit and half original capital. As mentioned above, we really need a Trade object property here that we can write to with our own information. Since we8217re not using margin, we can use the MarginLoan property, which fortunately is not read-only. I tried to use the Score property first, but that turned out to be read-only, despite AmiBroker help not mentioning that fact. This example is mostly the same as the previous one, but instead of scaling in, we now scale out. Again, the trigger condition is the profit being greater than the entry value (injected capital), but we need to use a state variable to remember whether or not we8217ve already scaled out the position so that we only do it once. As mentioned above, we can8217t tell this from the entry value alone. While the MarginLoan property was available and writeable in this case, it would be much better, as already mentioned, if Trade objects had some user-definable properties. And once again as a reminder, since I use C and C syntax rather than the syntax defined in AmiBroker help. trade. MarginLoan is the same as NOT trade. MarginLoan and 038038 is equivalent to AND. The statement trade. MarginLoan just means if trade. MarginLoan equals zero. That pretty much covers the use of the custom backtester interface at all three levels. While there are a number of object properties and methods I haven8217t mentioned or used, this document is not intended to be a reference manual but rather an introduction to using the interface. There should be enough information here to allow you to figure out the rest for yourself with a bit of trial and error (as I8217ve had to use myself while writing this document). Computer programming in any language can be a rewarding, but at times extremely frustrating, experience. After many hours of trying to get your 8220simple8221 piece of code working properly, by which time you8217re ready to swear on your grandmother8217s grave that there has to be a problem with the language interpreter or compiler, almost invariably the problem is in your own code. It could be as simple as a missing semicolon, or as complex as a complete misunderstanding about how something is supposed to work. But as Eric Idle once said, always look on the bright side of life. The good thing about an extremely frustrating problem is that it feels SO good once you finally figure it out Appendix A 8211 DayCount Function The code for the DayCount function used to calculate the number of calendar days between two date/time values is below. This includes both entry and exit days in the count. It consists of two functions, the DayCount function itself, and a DayInYear function to calculate the current day number in a year for a particular date. Firstly, the DayInYear function: This gets called by the DayCount function for both the entry and exit days. Now the DayCount function: Appendix B 8211 Using DebugView This appendix discusses the use of the Microsoft SysInternals program DebugView for debugging AFL applications. DebugView can be obtained from the Microsoft website here: microsoft/technet/sysinternals/Miscellaneous/DebugView. mspx When you run the program, you will get a window like this: The display area is where your AFL application can write to using TRACE statements. Note though, as can be seen above, that your application may not be the only thing sending data to the viewer. DebugView captures all data sent to the viewer from all running applications. The main toolbar controls are: The Clear Display button is the one you8217ll likely use the most while debugging an application. And as with most applications, you can multi-select lines in the output display and use Edit-Copy (CtrlC) to copy them to the Clipboard for pasting into another application for further analysis. Using The AFL TRACE Statement To output messages to the viewer from your AFL code, including from custom backtest procedures, you use the TRACE statement: You can concatenate strings simply by 8220adding8221 them together: To include the value of parameters in the message, use the StrFormat function the same as for Plot statements: A sample trace while testing the first low-level example given in this document: That output was produced by the following code in the custom backtest procedure: Remember that as newlines are considered white space by the language, one statement can be spread over multiple lines for readability without affecting its operation. The only thing to be aware of is where a single string inside double quotes needs to span multiple lines. White space in a string is treated as exactly what it is, so if you put a line break in the middle of it, you will end up with a line break in your output (this is not true in all languages, but is with AFL as far as tracing goes). Instead, you can split it into two strings and concatenate them: In the end though, this is only for readability purposes. As far as the language goes, it doesn8217t matter if a single line is 1000 characters long and scrolls off the right-hand end of the screen. It just makes it more difficult to read the line when you8217re working on that part of the code. There8217s little else that can be said about using DebugView for debugging your AFL code. Debugging is something of an art, and knowing what sort of information to trace at which parts of the code is something you8217ll get better at the more you do it. Too little information and you can8217t tell what8217s happening. Too much and it can be like looking for the proverbial needle in a haystack. Appendix C 8211 Lichello AIM Algorithm The default parameters specified here are the AIM standard values, with 10K initial position, 10K cash, and 10 buy and sell safes. For vealies, the maximum cash balance for a stock defaults to 100K. To experiment with this algorithm in the manner it was intended, try it on individual stocks that have had significant swings but no overall trend. Strongly uptrending stocks will give the best results as the parameters approach buy and hold, with initial cash and buy safe of zero, and sell safe of 100. Note that the code uses trade. Sharestrade. GetPrice(i, 8220C8221) for the current value, not trade. GetPositionValue. That8217s because the latter function use8217s the previous bar8217s closing price to determine the current value, whereas we want the current bar8217s price (it8217s assumed that buy/sell tests are made after the close of trading). The actual prices then used are the next bar8217s prices, to mimic making the trade the next trading day. Trade delays are set to zero to avoid confusion and conflict. To run this code, copy everything in blue to an AFL file and then run it with the backtester. If you run it over a single stock, set the total cash value to be the sum of the initial position and initial cash values (the default setting), otherwise the backtest report won8217t give a realistic result for the percentage return (most of the cash would never have been invested so would have zero gain for that component unless an annual interest rate was set). If running it over a portfolio, set the total cash value to be some multiple of the two initial values to allow that many positions to be entered simultaneously. Running it over a large watchlist of stocks will only pick a few positions, depending on the total cash available, with new positions subsequently only being opened if others are stopped out (note that the maximum loss stop is not part of the AIM algorithm, it8217s my own addition). If the backtester results report the trade list, there will only be one entry for each position, no matter how many times it scaled in and out. However, if it got stopped out and the same stock subsequently purchased again, that would show as two trades in the list. To see all the scale in and out trades, run the backtest in Detailed Log mode. At the end of a backtest, the final quantity of shares, their value, the position control, and the cash balance figures are added to the Trade objects as custom metrics (one or two will be the same as existing metrics though). If the trade was closed, the quantity will be zero. The parameters include a percentage for Monte Carlo testing. This is the probability of ignoring any particular new buy signal. A value of zero means all buys will be taken, subject to cash availability, while a value of 100 means none will be. The value shouldn8217t be set too high otherwise the results might be unrealistic due to a sparsity of trades taken. I8217d suggest a value up to 50, with 25 being what I typically use myself. The less buy signals there are in the Buy array, the lower the value needs to be to avoid giving unrealistic results. To run a Monte Carlo test, set a percentage value and then run an optimisation. The random PositionScore array also helps with Monte Carlo testing. Finally a disclaimer: while I8217ve made every attempt to ensure this correctly implements the AIM algorithm as I have specified in the comments and accompanying text, I can8217t guarantee that there are no errors or omissions or that this does in fact implement the algorithm correctly. I have presented it here primarily as a more advanced example of a custom backtest procedure, and all use is at your own risk. However, if you do find any errors, please let me know. Filed by Herman at 11:52 am under Custom Backtester Comments Off on AmiBroker Custom Backtester Interface September 30, 2007 This indicator program was developed for the trader who wishes to plot opening gaps to aid his identification of where gaps occur in a price chart. The gaps are drawn as horizontal lines (green upper, red lower) extending a variable number of bars to the right of the gap. The code hasn8217t been optimized so that you can use the variables in subsequent code. While AFL has GapUp() and GapDown() functions the code below uses custom definitions to allow substitution of other criteria. Filed by Herman at 12:49 pm under Indicators Comments Off on Plotting Gap Prices Info Recent Posts Recent Comments Categories Archives Meta Copyright (C)2006 AmiBroker . This site uses WordPress Page generated in 0.617 seconds.

Comments

Popular posts from this blog

Binary option signal indicator xm

Bonus forex sem depósito

D3 forex