Contos de Robôs de Negociação: É Mais ou Menos?
Antes que eu possa resolver um problema, devo provar que estou certo quando acho que encontrei a solução.
Conheço apenas uma maneira de provar isso, com o meu próprio dinheiro.
Jesse Livermore
Prólogo
Em A Última Cruzada analisamos bastante um método que ainda não é amplamente utilizado na atualidade e interessante para a exibição das informações de mercado - gráficos de ponto e figura. O script oferecido podia traçar um gráfico. No entanto não foi sugerido uma negociação automatizada. Agora podemos tentar automatizar o processo de negociação usando o gráfico ponto e figura para análise e tomada de decisão sobre a direção e o volume de negócios.
Não vou escrever aqui os princípios básicos do desenho; basta olhar para um gráfico típico:
Copyright (c) 2012-2014 Roman Rich Euro vs US Dollar, Box-20, Reverse-3 1.4588 | \.....\.................................................................... | 1.4588 1.4521 | X\....X\................................................................... | 1.4521 1.4454 | XO\.\.XO\.................................................................. | 1.4454 1.4388 | XOX\X\XO.\................................................................. | 1.4388 1.4322 | XOXOXOXO..\................................................................ | 1.4322 1.4256 | XOXOXOXO...\....\.......................................................... | 1.4256 1.4191 | XOXO/OXO....\...X\......................................................... | 1.4191 1.4125 | XOX/.O/O.....\..XO\........................................................ | 1.4125 1.4060 | XO/../.O......\.XO.\....................................................... | 1.4060 1.3996 | ./.....O.......\XO..\...................................................... | 1.3996 1.3932 | .......OX.......XO...\....................................................X | 1.3932 1.3868 | .......OXO..X.X.XOX...\.................................................X.X | 1.3868 1.3804 | .......OXO..XOXOXOXOX..\..............................................X.XOX | 1.3804 1.3740 | .......OXO..XOXOXOXOXO..\.................................\...........XOXOX | 1.3740 1.3677 | .......OXOX.XO.O.OXOXO...\................................X\..........XOXOX | 1.3677 1.3614 | .......OXOXOX....O.OXO....\...............................XO\.........XOXOX | 1.3614 1.3552 | .......O.OXOX...../OXO.....\..............................XO.\........XOXOX | 1.3552 1.3490 | .........OXOX..../.O.OX.....\.............................XO..\.......XOXO. | 1.3490 1.3428 | .........OXOX.../....OXO.....\X.\.........................XO...\\...X.XOX.. | 1.3428 1.3366 | .........O.OX../.....OXO......XOX\........................XO....X\..XOXOX.. | 1.3366 1.3305 | ...........OX./......OXO....X.XOXO\.....................X.XO....XO\.XOXO... | 1.3305 1.3243 | ...........OX/.......O.O....XOXOXOX\....................XOXO....XO.\XOX.../ | 1.3243 1.3183 | ...........O/..........OX...XOXOXOXO\...................XOXOX.X.XOX.XOX../. | 1.3183 1.3122 | .........../...........OXO..XOXOXOXO.\..........X...X.X.XOXOXOXOXOXOXO../.. | 1.3122 1.3062 | .......................OXOX.XOXO.OXO..\.........XOX.XOXOXOXOXOXOXOXOX../... | 1.3062 1.3002 | .......................O.OXOXO...O/O...\........XOXOXOXOXO.OXO.OXOXO../.... | 1.3002 1.2942 | .........................OXOX..../.O....\.......XOXOXOXOX..OX..OXOX../..... | 1.2942 1.2882 | .........................O.OX.../..O.....\......XOXO.OXO...OX..OXOX./...... | 1.2882 1.2823 | ...........................OX../...OX.....\.....XO...OX.../OX..O/OX/....... | 1.2823 1.2764 | ...........................OX./....OXO.....\....X....OX../.O.../.O/........ | 1.2764 1.2706 | ...........................OX/.....OXO..X...\...X....O../......../......... | 1.2706 1.2647 | ...........................O/......O.OX.XOX..\..X....../................... | 1.2647 1.2589 | .........................../.........OXOXOXO..\.X...../.................... | 1.2589 1.2531 | .....................................OXOXOXO...\X..../..................... | 1.2531 1.2474 | .....................................OXO.OXO....X.../...................... | 1.2474 1.2417 | .....................................OX..O.O..X.X../....................... | 1.2417 1.2359 | .....................................OX....OX.XOX./........................ | 1.2359 1.2303 | .....................................O.....OXOXOX/......................... | 1.2303 1.2246 | ...........................................OXOXO/.......................... | 1.2246 1.2190 | ...........................................OXO./........................... | 1.2190 1.2134 | ...........................................OX.............................. | 1.2134 1.2078 | ...........................................O............................... | 1.2078 1.2023 | ........................................................................... | 1.2023 222222222222222222222222222222222222222222222222222222222222222222222222222 000000000000000000000000000000000000000000000000000000000000000000000000000 111111111111111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111112222222222222222222222222222222333333333333333344 ........................................................................... 000000000001111111111111110000000000000000000000011111111000000000000011100 788888899990000001111112221122233445566666677888900001222123444567778901213 ........................................................................... 200011211220111220011231220101212121201112222001100010001002123110112020231 658801925683489071404504193396436668111288937260415979579417630739120547713 000100001012111111110111111100112010210001111101101101011111111101011101110 910501876933613095500253237788652909250001557626626824655375907538165785367 ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 550433251023230204310404232105354323532031240033315125241340044324523153453 000000000000000000000000000000000000000000000000000000000000000000000000000
Eu não vou argumentar que as oportunidades de negociação estão claramente visíveis nesta tabela; Eu apenas sugiro que você verifique duas hipóteses na negociação:
Negociação com tendência primária — comprar no mercado touro e vender no urso.
Usar stop losses, definidos antes de entrar no mercado.
- comprar acima do nível de suporte usando uma stop order (ordem pendente) acima do alto da coluna "X" anterior, vender abaixo da linha de resistência usando uma ordem sell stop abaixo coluna da "O" anterior; usar um trailing stop no nível do pivô;
Deixe os seus lucros crescerem.
Fechar operações com prejuízo (geralmente boas entradas mostram imediatamente o lucro).
- entrar com posição comprada quando a linha resistência é quebrada, entrar com posição vendida quando a linha suporte é quebrada; definir stop loss no nível pivô, definir trailing stop na linha de tendência.
Como Escolher o Volume
Preste atenção nas citações de um mestre da especulação em ações: usar stop orders (ordens pendentes). Eu prefiro entrar no mercado com um certo volume de modo que as ordens desencadeadas pelo Stop Loss não sejam um percentual maior do que eu possa aceitar (o que Ralph Vince chama ideal F em seu A Matemática da Gestão do Dinheiro). O risco de perda por operação é uma variável bem otimizável (opt_f no código abaixo).
Assim, temos uma função que coloca uma ordem de compra/venda com o mecanismo de cálculo do volume dependendo do risco aceitável por transação:
//+------------------------------------------------------------------+ //| The function places an order with a precalculated volume | //+------------------------------------------------------------------+ void PlaceOrder() { //--- Variables for calculating the lot uint digits_2_lot=(uint)SymbolInfoInteger(symbol,SYMBOL_DIGITS); double trade_risk=AccountInfoDouble(ACCOUNT_EQUITY)*opt_f; double one_tick_loss_min_lot=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE_LOSS)*SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP); //--- Fill out the main fields of the request trade_request.magic=magic; trade_request.symbol=symbol; trade_request.action=TRADE_ACTION_PENDING; trade_request.tp=NULL; trade_request.comment=NULL; trade_request.type_filling=NULL; trade_request.stoplimit=NULL; trade_request.type_time=NULL; trade_request.expiration=NULL; if(is_const_lot==true) { order_vol=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN); } else { order_vol=trade_risk/(MathAbs(trade_request.price-trade_request.sl)*MathPow(10,digits_2_lot)*one_tick_loss_min_lot)*SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP); order_vol=MathMax(order_vol,SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN)); if(SymbolInfoDouble(symbol,SYMBOL_VOLUME_LIMIT)!=0) order_vol=MathMin(order_vol,SymbolInfoDouble(symbol,SYMBOL_VOLUME_LIMIT)); order_vol=NormalizeDouble(order_vol,(int)MathAbs(MathLog10(SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP)))); } //--- Place an order while(order_vol>0) { trade_request.volume=MathMin(order_vol,SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX)); if(!OrderSend(trade_request,trade_result)) Print("Failed to send order #",trade_request.order); order_vol=order_vol-SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX); }; ticket=trade_result.order; };
Usar Qual Critério de Otimização?
Na verdade existem apenas dois critérios de otimização: minimização ou rebaixamento em determinado nível de retorno, ou então, maximização do balanço para um certo nível de rebaixamento. Eu prefiro otimizar pelo segundo critério:
//+------------------------------------------------------------------+ //| Result of strategy run in the testing mode | //+------------------------------------------------------------------+ double OnTester() { if(TesterStatistics(STAT_EQUITY_DDREL_PERCENT)>(risk*100)) return(0); else return(NormalizeDouble(TesterStatistics(STAT_PROFIT),(uint)SymbolInfoInteger(symbol,SYMBOL_DIGITS))); };
Onde o risco acima do nível de rebaixamento na estratégia é inaceitável para mim. Esta também é uma das variáveis a ser otimizada.
Quando Reotimizar?
Alguns reotimizam estratégias em intervalos de tempo (por exemplo, uma vez por semana, um mês), em intervalos de operações (após 50, 100 operações) ou quando o mercado muda. Na verdade a necessidade de reotimização depende apenas do critério de otimização selecionado no parágrafo anterior. Se o rebaixamento fica abaixo do parâmetro de risco máximo permitido, nós reotimizamos a estratégia; se tudo funciona ok, deixamos trabalhar como está. Rebaixamento superior a 10% é inaceitável para mim. Assim se o sistema tem um rebaixamento maior durante a operação eu reotimizo.
Posso Otimizar Tudo de Uma Vez?
Infelizmente no testador estratégia você não pode otimizar variáveis externas para o modo "Todos os ativos selecionados na Observação de Mercado". Então vamos escolher os instrumentos (ativos) do mercado juntamente com outras variáveis externas otimizáveis da seguinte forma:
//+------------------------------------------------------------------+ //| Enumeration of symbols | //+------------------------------------------------------------------+ enum SYMBOLS { AA=1, AIG, AXP, BA, C, CAT, DD, DIS, GE, HD, HON, HPQ, IBM, IP, INTC, JNJ, JPM, KO, MCD, MMM, MO, MRK, MSFT, PFE, PG, QQQ, T, SPY, UTX, VZ, WMT, XOM }; //+------------------------------------------------------------------+ //| Symbol selection function | //+------------------------------------------------------------------+ void SelectSymbol() { switch(selected_symbol) { case 1: symbol="#AA"; break; case 2: symbol="#AIG"; break; case 3: symbol="#AXP"; break; case 4: symbol="#BA"; break; case 5: symbol="#C"; break; case 6: symbol="#CAT"; break; case 7: symbol="#DD"; break; case 8: symbol="#DIS"; break; case 9: symbol="#GE"; break; case 10: symbol="#HD"; break; case 11: symbol="#HON"; break; case 12: symbol="#HPQ"; break; case 13: symbol="#IBM"; break; case 14: symbol="#IP"; break; case 15: symbol="#INTC"; break; case 16: symbol="#JNJ"; break; case 17: symbol="#JPM"; break; case 18: symbol="#KO"; break; case 19: symbol="#MCD"; break; case 20: symbol="#MMM"; break; case 21: symbol="#MO"; break; case 22: symbol="#MRK"; break; case 23: symbol="#MSFT"; break; case 24: symbol="#PFE"; break; case 25: symbol="#PG"; break; case 26: symbol="#QQQ"; break; case 27: symbol="#T"; break; case 28: symbol="#SPY"; break; case 29: symbol="#UTX"; break; case 30: symbol="#VZ"; break; case 31: symbol="#WMT"; break; case 32: symbol="#XOM"; break; default: symbol="#SPY"; break; }; };
Se necessário, você pode adicionar os instrumentos (ativos) na função para selecionar o símbolo e a enumeração (a função é chamada em OnInit()).
Qual Robô Nós Criamos?
Tick Handler:
//+------------------------------------------------------------------+ //| A typical ticks handler OnTick() | //| Draw the chart only based on complete bars but first | //| check if it is a new bar. | //| If the bar is new and there is a position, check | //| whether we need to move the stop loss, | //| if the bar is new and no position, check | //| if we have conditions for opening a deal. | //+------------------------------------------------------------------+ void OnTick() { //--- If the bar is new if(IsNewBar()==true) { RecalcIndicators(); //--- Tester/optimizer mode? if((MQLInfoInteger(MQL_TESTER)==true) || (MQLInfoInteger(MQL_OPTIMIZATION)==true)) { //--- Is it the testing period? if(cur_bar_time_dig[0]>begin_of_test) { //--- If there is an open position on the symbol if(PositionSelect(symbol)==true) //--- check if we need to move SL; if need, move it TrailCondition(); //--- If there are no positions else //--- check if we need to open a position; if we need, open it TradeCondition(); } } else { //--- if there is an oprn position on the symbol if(PositionSelect(symbol)==true) //--- check if we need to move SL; if need, move it TrailCondition(); //--- If there are no positions else //--- check if we need to open a position; if we need, open it TradeCondition(); } }; };
Para Estratégia 1: "comprar acima do nível de suporte usando uma stop order (ordem pendente) acima do alto da coluna "X" anterior, vender abaixo da linha de resistência usando uma ordem sell stop abaixo coluna da "O" anterior; usar um trailing stop no nível do pivô;":
//+------------------------------------------------------------------+ //| Function checks trade conditions for opening a deal | //+------------------------------------------------------------------+ void TradeCondition() { if(order_col_number!=column_count) //--- Are there any orders on the symbol? { if(OrdersTotal()>0) { //--- Delete them! for(int loc_count_1=0;loc_count_1<OrdersTotal();loc_count_1++) { ticket=OrderGetTicket(loc_count_1); if(!OrderSelect(ticket)) Print("Failed to select order #",ticket); if(OrderGetString(ORDER_SYMBOL)==symbol) { trade_request.order=ticket; trade_request.action=TRADE_ACTION_REMOVE; if(!OrderSend(trade_request,trade_result)) Print("Failed to send order #",trade_request.order); }; }; order_col_number=column_count; return; } else { order_col_number=column_count; return; } } else if((MathPow(10,pnf[column_count-1].resist_price)<SymbolInfoDouble(symbol,SYMBOL_ASK)) && (pnf[column_count-1].column_type=='X') && (pnf[column_count-1].max_column_price<=pnf[column_count-3].max_column_price)) { //--- Conditions for BUY met; let's see if there are any pending Buy orders for the symbol with the price we need? trade_request.price=NormalizeDouble(MathPow(10,pnf[column_count-3].max_column_price+double_box),digit_2_orders); trade_request.sl=NormalizeDouble(MathPow(10,pnf[column_count-3].max_column_price-(reverse-1)*double_box),digit_2_orders); trade_request.type=ORDER_TYPE_BUY_STOP; if(OrderSelect(ticket)==false) //--- No pending orders - place an order { PlaceOrder(); order_col_number=column_count; } else //--- If there is a pending order { //--- what is the type and price of the pending order? if((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP) || ((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP) && (OrderGetDouble(ORDER_PRICE_OPEN)!=trade_request.price))) { //--- The wrong type or the price differs - close the order trade_request.order=ticket; trade_request.action=TRADE_ACTION_REMOVE; if(!OrderSend(trade_request,trade_result)) Print("Failed to send order #",trade_request.order); //--- open with the desired price PlaceOrder(); order_col_number=column_count; }; }; return; } else if((MathPow(10,pnf[column_count-1].resist_price)>SymbolInfoDouble(symbol,SYMBOL_ASK)) && (pnf[column_count-1].column_type=='O') && (pnf[column_count-1].min_column_price>=pnf[column_count-3].min_column_price)) { //--- Conditions for SELL met; let's see if there are any pending Sell orders for the symbol with the price we need? trade_request.price=NormalizeDouble(MathPow(10,pnf[column_count-3].min_column_price-double_box),digit_2_orders); trade_request.sl=NormalizeDouble(MathPow(10,pnf[column_count-3].min_column_price+(reverse-1)*double_box),digit_2_orders); trade_request.type=ORDER_TYPE_SELL_STOP; if(OrderSelect(ticket)==false) //--- No pending orders, place an order { PlaceOrder(); order_col_number=column_count; } else //--- or there is a pending order { //--- what is the type and price of the pending order? if((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP) || ((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP) && (OrderGetDouble(ORDER_PRICE_OPEN)!=trade_request.price))) { //--- The wrong type or the price differs - close the order trade_request.order=ticket; trade_request.action=TRADE_ACTION_REMOVE; if(!OrderSend(trade_request,trade_result)) Print("Failed to send order #",trade_request.order); //--- and open with the desired price PlaceOrder(); order_col_number=column_count; }; }; return; } else return; }; //+------------------------------------------------------------------+ //| The function checks conditions for moving Stop Loss | //+------------------------------------------------------------------+ void TrailCondition() { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) trade_request.sl=NormalizeDouble(MathPow(10,pnf[column_count-1].max_column_price-reverse*double_box),digit_2_orders); else trade_request.sl=NormalizeDouble(MathPow(10,pnf[column_count-1].min_column_price+reverse*double_box),digit_2_orders); if(PositionGetDouble(POSITION_SL)!=trade_request.sl) PlaceTrailOrder(); };
Para Estratégia 2: "entrar com posição comprada quando a linha resistência é quebrada, entrar com posição vendida quando a linha suporte é quebrada; definir stop loss no nível pivô, definir trailing stop na linha de tendência.":
//+------------------------------------------------------------------+ //| The function checks trade conditions for opening a deal | //+------------------------------------------------------------------+ void TradeCondition() { if(order_col_number!=column_count) //--- Are there any orders for the symbol? { if(OrdersTotal()>0) { //--- Delete them! for(int loc_count_1=0;loc_count_1<OrdersTotal();loc_count_1++) { ticket=OrderGetTicket(loc_count_1); if(!OrderSelect(ticket)) Print("Failed to select order #",ticket); if(OrderGetString(ORDER_SYMBOL)==symbol) { trade_request.order=ticket; trade_request.action=TRADE_ACTION_REMOVE; if(!OrderSend(trade_request,trade_result)) Print("Failed to send order #",trade_request.order); }; }; order_col_number=column_count; return; } else { order_col_number=column_count; return; } } else if(MathPow(10,pnf[column_count-1].resist_price)>SymbolInfoDouble(symbol,SYMBOL_ASK)) { //--- Conditions for BUY met; let's see if there are any pending Buy orders for the symbol with the price we need? trade_request.price=NormalizeDouble(MathPow(10,pnf[column_count-1].resist_price),digit_2_orders); trade_request.sl=NormalizeDouble(MathPow(10,pnf[column_count-1].resist_price-(reverse-1)*double_box),digit_2_orders); trade_request.type=ORDER_TYPE_BUY_STOP; if(OrderSelect(ticket)==false) //--- No pending orders - place an order { PlaceOrder(); order_col_number=column_count; } else //--- or there is a pending order { //--- what is the type and price of the pending order? if((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP) || ((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP) && (OrderGetDouble(ORDER_PRICE_OPEN)!=trade_request.price))) { //--- The wrong type or the price differs - close the order trade_request.order=ticket; trade_request.action=TRADE_ACTION_REMOVE; if(!OrderSend(trade_request,trade_result)) Print("Failed to send order #",trade_request.order); //--- open with the desired price PlaceOrder(); order_col_number=column_count; }; }; return; } else if(MathPow(10,pnf[column_count-1].resist_price)<SymbolInfoDouble(symbol,SYMBOL_ASK)) { //--- Conditions for SELL met; let's see if there are any pending Sell orders for the symbol with the price we need? trade_request.price=NormalizeDouble(MathPow(10,pnf[column_count-1].supp_price),digit_2_orders); trade_request.sl=NormalizeDouble(MathPow(10,pnf[column_count-1].supp_price+(reverse-1)*double_box),digit_2_orders); trade_request.type=ORDER_TYPE_SELL_STOP; if(OrderSelect(ticket)==false) //--- No pending orders - place an order { PlaceOrder(); order_col_number=column_count; } else //--- If there is a pending order { //--- what is the type and price of the pending order? if((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP) || ((OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP) && (OrderGetDouble(ORDER_PRICE_OPEN)!=trade_request.price))) { //--- The wrong type or the price differs - close the order trade_request.order=ticket; trade_request.action=TRADE_ACTION_REMOVE; if(!OrderSend(trade_request,trade_result)) Print("Failed to send order #",trade_request.order); //--- open with the desired price PlaceOrder(); order_col_number=column_count; }; }; return; } else return; }; //+------------------------------------------------------------------+ //| The function checks conditions for moving Stop Loss | //+------------------------------------------------------------------+ void TrailCondition() { if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) trade_request.sl=NormalizeDouble(MathMax(SymbolInfoDouble(symbol,SYMBOL_ASK),MathPow(10,pnf[column_count-1].max_column_price-reverse*double_box)),digit_2_orders); else trade_request.sl=NormalizeDouble(MathMin(SymbolInfoDouble(symbol,SYMBOL_BID),MathPow(10,pnf[column_count-1].min_column_price+reverse*double_box)),digit_2_orders); if(PositionGetDouble(POSITION_SL)!=trade_request.sl) PlaceTrailOrder(); };
Caro leitor, por favor observe algumas coisas:
- Os preços dos ativos do mercado variam num alcance muito grande, a partir de centavos para dezenas de milhares (exemplo - ações e CFDs na Bolsa de Valores Japonesa). Portanto eu uso o algoritmo de preço para o gráfico ponto e figura para evitar definir valores de um a dezenas de milhares de pips para o tamanho da caixa.
- A indexação do array do gráfico ponto e figura começa do zero, de modo que o índice da última coluna seja igual ao número de colunas menos um.
- O valor da linha suporte, se for utilizado, é maior do que -10, mas menor do que o algoritmo de preço. Se nenhuma linha suporte (ou resistência) é usada, seu valor no array do gráfico é -10. Portanto as condições para rompimento das linhas suporte/resistência são escritas da mesma forma como no código de Estratégia 2 acima.
Veja o código das funções auxiliares nos anexos abaixo. O código do gráfico é muito grande, então eu não o escrevi no artigo, ver com comentários nos anexos abaixo.
Resultados da Negociação do EA
Eu preparei dois conjuntos de ativos do mercado nos arquivos symbol_list_1.mhq e symbol_list_2.mhq para otimização; eles incluem pares de moedas e CFDs de ações do índice Dow.
Janela de Configuração:
No primeiro caso, a janela de configuração do testador estratégia é a seguinte:
Observe a Linha Inicial do Teste. O robô requer pelo menos algumas colunas do gráfico para análise e tomada de decisão; e quando você define o tamanho da caixa igual a 50 pips ou mais, o histórico de um ano muitas vezes não é o suficiente até mesmo para uma coluna. Portanto para gráficos com tamanho da caixa de 50 pips ou mais, usar o intervalo de cerca de três anos ou mais a partir do início operacional do robô, definir o início da operação do robô no parâmetro "Testing Start" na janela de configuração. No nosso exemplo, para testar com uma tamanho da caixa de 100 pips desde 01.01.2012, especificar intervalo de 01.01.2009 na aba Configuração do Testador de Estratégia e definir o intervalo de 01.01.2012 na aba Parâmetros de Entrada.
O valor falso do parâmetro "Trade minimum lot?" indica que o tamanho do lote depende do balanço e da variável "Risk per Trade, %" (neste caso 1% por negociação, mas também pode ser otimizado). "Max Drawdown, %" é o critério de otimização na função OnTester(). Neste artigo, vou usar apenas duas variáveis para otimização: "Symbol" e "Box size in pips".
Período de otimização: 2012-2013. O EA trabalha melhor no gráfico EURUSD, já que o símbolo proporciona uma melhor cobertura de tick. A tabela abaixo contém um relatório completo para o teste com vários pares de moedas com caixa de tamanho base 10 (b_10) na primeira estratégia.
Passe | Resultado | Lucro | Resultado Esperado | Fator de Lucro | Fator de Recuperação | Índice Sharpe | Personalizado | Patrimônio DD % | Negociações | Símbolo | Caixa |
---|---|---|---|---|---|---|---|---|---|---|---|
0,00 | 0,00 | -1 002,12 | -18,91 | 0,54 | -0,79 | -0,24 | 0,00 | 12,67 | 53,00 | AUDCAD | 10,00 |
1,00 | 886,56 | 886,56 | 14,53 | 1,40 | 1,52 | 0,13 | 886,56 | 5,76 | 61,00 | AUDCHF | 10,00 |
2,00 | 0,00 | -1 451,63 | -10,60 | 0,77 | -0,70 | -0,09 | 0,00 | 19,92 | 137,00 | AUDJPY | 10,00 |
3,00 | -647,66 | -647,66 | -17,50 | 0,57 | -0,68 | -0,24 | -647,66 | 9,46 | 37,00 | AUDNZD | 10,00 |
4,00 | -269,22 | -269,22 | -3,17 | 0,92 | -0,26 | -0,03 | -269,22 | 9,78 | 85,00 | AUDUSD | 10,00 |
5,00 | 0,00 | -811,44 | -13,52 | 0,72 | -0,64 | -0,14 | 0,00 | 12,20 | 60,00 | CADCHF | 10,00 |
6,00 | 0,00 | 1 686,34 | 16,53 | 1,36 | 1,17 | 0,12 | 0,00 | 11,78 | 102,00 | CHFJPY | 10,00 |
7,00 | 356,68 | 356,68 | 5,66 | 1,13 | 0,40 | 0,06 | 356,68 | 8,04 | 63,00 | EURAUD | 10,00 |
8,00 | 0,00 | -1 437,91 | -25,68 | 0,53 | -0,92 | -0,25 | 0,00 | 15,47 | 56,00 | EURCAD | 10,00 |
9,00 | 0,00 | -886,66 | -46,67 | 0,34 | -0,74 | -0,46 | 0,00 | 11,56 | 19,00 | EURCHF | 10,00 |
10,00 | 0,00 | -789,59 | -21,93 | 0,54 | -0,75 | -0,26 | 0,00 | 10,34 | 36,00 | EURGBP | 10,00 |
11,00 | 0,00 | 3 074,86 | 28,47 | 1,62 | 1,72 | 0,20 | 0,00 | 12,67 | 108,00 | EURJPY | 10,00 |
12,00 | 0,00 | -1 621,85 | -19,78 | 0,55 | -0,97 | -0,25 | 0,00 | 16,75 | 82,00 | EURNZD | 10,00 |
13,00 | 152,73 | 152,73 | 2,88 | 1,07 | 0,21 | 0,03 | 152,73 | 6,90 | 53,00 | EURUSD | 10,00 |
14,00 | 0,00 | -1 058,85 | -14,50 | 0,65 | -0,66 | -0,16 | 0,00 | 15,87 | 73,00 | GBPAUD | 10,00 |
15,00 | 0,00 | -1 343,47 | -25,35 | 0,43 | -0,64 | -0,34 | 0,00 | 20,90 | 53,00 | GBPCAD | 10,00 |
16,00 | 0,00 | -2 607,22 | -44,19 | 0,27 | -0,95 | -0,59 | 0,00 | 27,15 | 59,00 | GBPCHF | 10,00 |
17,00 | 0,00 | 1 160,54 | 11,72 | 1,27 | 0,81 | 0,10 | 0,00 | 12,30 | 99,00 | GBPJPY | 10,00 |
18,00 | 0,00 | -1 249,91 | -14,70 | 0,69 | -0,85 | -0,15 | 0,00 | 14,41 | 85,00 | GBPNZD | 10,00 |
19,00 | 208,94 | 208,94 | 5,36 | 1,12 | 0,25 | 0,05 | 208,94 | 7,81 | 39,00 | GBPUSD | 10,00 |
20,00 | 0,00 | -2 137,68 | -21,17 | 0,53 | -0,79 | -0,24 | 0,00 | 25,62 | 101,00 | NZDUSD | 10,00 |
21,00 | 0,00 | -1 766,80 | -38,41 | 0,30 | -0,97 | -0,53 | 0,00 | 18,10 | 46,00 | USDCAD | 10,00 |
22,00 | -824,69 | -824,69 | -11,95 | 0,73 | -0,90 | -0,13 | -824,69 | 9,11 | 69,00 | USDCHF | 10,00 |
23,00 | 2 166,53 | 2 166,53 | 26,10 | 1,58 | 2,40 | 0,18 | 2 166,53 | 7,13 | 83,00 | USDJPY | 10,00 |
2 029,87 | -10 213,52 | 13,40 | 1 659,00 |
Aqui está uma tabela de resumo para vários símbolos e valores de tamanho de caixa:
Estratégia | Símbolos | Tamanho da Caixa | Negociações | Patrimônio DD % | Lucro | Resultado | Balanço Esperado |
---|---|---|---|---|---|---|---|
1 | Moedas | 10 | 1 659 | Setembro | -10 214 | 2 030 | 2 030 |
1 | Moedas | 20 | 400 | 5 | 1 638 | 2 484 | 2 484 |
1 | Ações | 50 | 350 | 60 | 7 599 | 7 599 | 15 199 |
1 | Ações | 100 | 81 | 2 | 4 415 | 4 415 | 17 659 |
2 | Moedas | 10 | 338 | 20 | -4 055 | 138 | 138 |
2 | Moedas | 20 | 116 | 8 | 4 687 | 3 986 | 3 986 |
2 | Ações | 50 | 65 | 6 | 6 770 | 9 244 | 9 244 |
2 | Ações | 100 | 12 | 1 | -332 | -332 | -5 315 |
O que vemos?
Existem tolos que sempre estão fazendo errado.
E existem tolos de Wall Street acreditando que você deve sempre negociar.
Não há ninguém no mundo tendo sempre todas as informações necessárias para comprar ou vender ações de maneira completamente coerente.
A conclusão pode parecer estranho para você: o seu depósito é provavelmente muito maior com menos negociações. Se há dois anos nós deixássemos nosso EA negociando ações com o tamanho da caixa igual a 100 e o risco por negociação igual a 1%, o EA faria apenas 81 operações (com média de 1,25 operações por símbolo a cada ano), o nosso depósito teria crescido 44 % e a média do rebaixamento patrimônio líquido teria sido um pouco acima de 2%. Aceitando possível rebaixamento de 10%, poderíamos arriscar 4% por operação, e nosso depósito teria crescido 177% em dois anos, ou seja, 90% ao ano em dólares norte-americanos! dólares!
Epílogo
O preço nunca é alto demais para começar a comprar e nunca é muito baixo para começar a vender.
Não é pensando que se faz o dinheiro grande, é sentado.
As estratégias acima descritas podem ser modificadas e podem mostrar um rendimento ainda maior com o rebaixamento não superior a 10%. Não tente negociar muitas vezes, é melhor encontrar uma corretora que não proporciona apenas um "conjunto padrão" de duas dezenas de pares de moedas e três dezenas de ações, mas pelo menos três ou quatro centenas de símbolos (ações, futuros). É mais provável que os símbolos não serão correlacionados e seu depósito estará mais seguro. Uma observação a mais - ações apresentam melhores resultados do que os pares de moedas.
P.S. (um comentário de publicidade)
Meu script PnF Chartist está disponível no Mercado. Ele desenha gráficos de ponto e figura em arquivos de texto usando cotações fornecidas pelo terminal MT4, MT5 ou Yahoo finanças. Use-o para a busca visual dos padrões de preços, uma vez que não existe melhor testador/otimizador do que seu cérebro. Assim que você encontrar padrões, usar os modelos de EA deste artigo para provar de suas idéias.
Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/910
- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso