Récits de Robots de Trading : Est-ce moins plus que ca ?
Avant de pouvoir résoudre un problème, je dois me l’exprimer. Quand je pense avoir trouvé la solution, je dois prouver que j’ai raison.
Je ne connais qu’une seule façon de le prouver; et c’est-à-dire avec mon propre argent.
Jesse Livermore
Prologue
Dans La dernière croisade, nous avons passé en revue une méthode intéressante mais actuellement peu utilisée pour afficher des informations sur le marché - des graphiques de points et de figures. Le script proposé pourrait tracer un graphique. Cependant, il ne suggérait pas l’automatisation du trading. Maintenant, nous pouvons essayer d’automatiser le processus de trading en utilisant le graphique de points et de chiffres pour l’analyse et pour prendre des décisions sur la direction et le volume des échanges.
Je n’écrirai pas ici les principes de base du dessin; il suffit de regarder un graphique type :
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
Je ne soutiendrai pas que les opportunités de trading sont clairement visibles dans ce graphique; Je vous suggère seulement de vérifier deux hypothèses de trading :
Trader avec la tendance principale - acheter dans un marché haussier et vendez dans un marché baissier.
Utiliser des stop loss, définis avant d’entrer sur le marché.
- acheter au-dessus du niveau de support en utilisant un ordre stop au-dessus du sommet de la colonne X précédente, vendre en dessous de la ligne de résistance en utilisant un ordre stop de vente inférieur au bas de la colonne O précédente; utiliser un arrêt de fin au niveau du pivot;
Laissez vos profits croître.
Concluez des transactions à perte (les bonnes affaires montrent généralement immédiatement les bénéfices).
- acheter quand il franchit la ligne de résistance, vendre quand il franchit la ligne de support; définissez stop loss au niveau du pivot, définissez l’arrêt de fin sur la ligne de tendance.
Comment choisir le volume
Faites attention aux cotations ci-dessus d’un maître de spéculation boursière: utilisez des ordres stop. Je préfère entrer sur le marché avec un certain volume de sorte que lorsque l’ordre Stop Loss se déclenche, la perte d’équilibre ne soit pas supérieure à un pourcentage du solde que je peux accepter (ce que Ralph Vince appelle le F optimal dans ses Mathématiques de la gestion de l’argent). Le risque de perte par transaction est une variable bien optimisable (opt_f dans le code ci-dessous).
Ainsi, nous avons une fonction qui place un ordre d’achat / vente avec le mécanisme de calcul du volume qui dépend du risque acceptable par transaction :
//+------------------------------------------------------------------+ //| 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; };
Quel critère d’optimisation utiliser ?
En fait, il n’y a que deux critères d’optimisation : la minimisation ou le prélèvement à un niveau de rendement donné, ou la maximisation de l’équilibre pour un niveau de prélèvement donné. Je préfère optimiser par le deuxième critère :
//+------------------------------------------------------------------+ //| 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))); };
où le risque est le niveau de retrait au-dessus duquel la stratégie est inacceptable pour moi. C’est aussi l’une des variables à optimiser.
Quand ré-optimiser ?
Quelqu’un ré-optimise les stratégies à des intervalles de temps (par exemple, une fois par semaine, un mois), quelqu’un à des intervalles de transaction (après 50 100 transactions), quelqu’un commence une nouvelle optimisation lorsque le marché change. En fait, la nécessité d’une ré-optimisation ne dépend que du critère d’optimisation sélectionné dans le paragraphe précédent. Si le prélèvement tombe en dessous du paramètre de risque maximal autorisé, nous ré-optimisons la stratégie; si tout fonctionne bien, laissez-le fonctionner tel qu’il est. Un prélèvement supérieur à 10 % est inacceptable pour moi. Ainsi, si le système obtient un plus grand retrait pendant le fonctionnement, je le ré-optimise.
Puis-je tout optimiser en même temps ?
Malheureusement, dans le testeur de stratégie, vous ne pouvez pas optimiser les variables externes pour le mode « Tous les symboles sélectionnés dans la surveillance des marchés ». Par conséquent, choisissons les instruments de marché ainsi que d’autres variables externes optimisable comme suit :
//+------------------------------------------------------------------+ //| 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; }; };
Si nécessaire, vous pouvez ajouter les instruments requis dans la fonction de sélection de symbole et l’énumération (la fonction est appelée dans OnInit()).
Quel robot avons-nous créé ?
Gestionnaire de tics :
//+------------------------------------------------------------------+ //| 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(); } }; };
Pour la stratégie 1 : « acheter au-dessus du niveau de support en utilisant un ordre stop au-dessus du sommet de la colonne X précédente, vendre en dessous de la ligne de résistance en utilisant un ordre stop de vente inférieur au bas de la colonne O précédente; utiliser un arrêt de fin au niveau du pivot| »:
//+------------------------------------------------------------------+ //| 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(); };
Pour la stratégie 2 « acheter à la percée de la ligne de résistance, vendre à la percée de la ligne de support ; définir le stop loss au niveau du pivot, définir l’arrêt de fin à la ligne de tendance »:
//+------------------------------------------------------------------+ //| 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(); };
Cher lecteur, veuillez noter quelques points.
- Les prix des instruments de marché varient dans une fourchette assez large, allant de cents à des dizaines de milliers (exemple - actions et CFD sur les bourses japonaises). Par conséquent, j’utilise le logarithme de prix pour le graphique en points et en chiffres afin d’éviter de définir des valeurs de un à des dizaines de milliers de pips pour la taille de la boîte.
- L’indexation du tableau du graphique en points et en figures commence à zéro, de sorte que l’index de la dernière colonne est égal au nombre de colonnes moins une.
- La valeur de la ligne de support, si elle est utilisée, est supérieure à -10,0, mais inférieure au logarithme du prix. Si aucune ligne de support (ou de résistance) n’est utilisée, sa valeur dans le tableau de graphiques est -10.0. Par conséquent, les conditions de rupture des lignes de support/résistance sont écrites sous la même forme que dans le code de la stratégie 2 ci-dessus.
Voir le code des fonctions auxiliaires dans les pièces jointes ci-dessous. Le code du graphique est trop grand, donc je ne l’écris pas dans l’article; voyez-le avec des commentaires dans les pièces jointes ci-dessous.
Résultats d’EA Trading
J’ai préparé deux ensembles de symboles de marché dans des fichiers symbol_list_1.mhq et symbol_list_2.mhq pour l’optimisation; ils comprennent les paires de devises et les CFD sur actions de l’indice Dow.
Fenêtre d’installation :
Dans le premier cas, la fenêtre d’installation du testeur de stratégie se présente comme suit :
Notez la ligne de démarrage du test. Le robot nécessite au moins quelques colonnes de graphique pour l’analyse et la prise de décision; et lorsque vous définissez une taille de boîte égale à 50 pips ou plus, un historique d’un an n’est souvent pas suffisant, même pour une colonne. Par conséquent, pour les graphiques avec une taille de boîte de 50 pips ou plus, utilisez l’intervalle d’environ trois ans ou plus à partir du début de l’opération du robot, définissez le démarrage de l’opération du robot dans le paramètre Démarrage du test dans la fenêtre de configuration. Dans notre exemple, pour les tests avec la taille de boîte de 100 pips depuis le 01.01.2012, spécifiez l’intervalle depuis le 01.01.2009 dans l’onglet Paramètres; définir l’intervalle depuis le 01.01.2012 dans l’onglet Paramètres.
La fausse valeur du paramètre « Lot minimum de Trade ? » indique que la taille du lot dépend du solde et de la variable « Risque par Trade, % » (dans ce cas 1% par trade, mais il peut également être optimisé). « Max Drawdown, % » est le critère d’optimisation de la fonction OnTester() . Dans cet article, je n’utilise que deux variables pour l’optimisation : Symbole et taille de la boîte en pips.
Période d’optimisation : 2012-2013. L’EA fonctionne mieux sur le graphique EURUSD, car le symbole fournit la meilleure couverture de tics. Le tableau ci-dessous contient un rapport complet pour les tests sur différentes paires de devises avec une taille de boîte 10 basée sur la première stratégie :
Passer | Résultat | Bénéfice | Gain attendu | Facteur de profit | Facteur de récupération | Ratio de Sharpe | Personnalisé | Capitaux propres DD % | Trades | selected_symbol | boîte |
---|---|---|---|---|---|---|---|---|---|---|---|
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 |
Voici un tableau récapitulatif pour divers symboles et valeurs de taille de boîte :
Stratégie | Symboles | x_size+=1; | Trades | Capitaux propres DD % | Bénéfice | Résultat | Solde attendu |
---|---|---|---|---|---|---|---|
1 | Devises | 10 | 1 659 | Septembre, | -10 214 | 2 030 | 2 030 |
1 | Devises | 20 | 400 | 5 | 1 638 | 2 484 | 2 484 |
1 | Actions | 50 | 350 | 60 | 7 599 | 7 599 | 15 199 |
1 | Actions | 100 | 81 | 2 | 4 415 | 4 415 | 17 659 |
2 | Devises | 10 | 338 | 20 | -4 055 | 138 | 138 |
2 | Devises | 20 | 116 | 8 | 4 687 | 3 986 | 3 986 |
2 | Actions | 50 | 65 | 6 | 6 770 | 9 244 | 9 244 |
2 | Actions | 100 | 12 | 1 | -332 | -332 | -5 315 |
Que voyons-nous ?
Il y a des imbéciles, qui font toujours le mal.
Et il y a les imbéciles de WallStreet qui croient que vous devriez toujours trader.
Il n’y a personne au monde qui a toujours toutes les informations nécessaires pour acheter ou vendre des actions et le faire de manière tout à fait raisonnable.
La conclusion peut vous sembler étrange: votre dépôt est plus susceptible d’être plus élevé avec moins de transactions. S’il y a deux ans, nous avions laissé nos actions EA négocier des actions avec une taille de boîte de 100 et un risque par transaction de 1%, l’EA n’effectuerait que 81 transactions depuis lors (une moyenne de 1,25 transaction par symbole et par an), notre dépôt aurait augmenté de 44%, tandis que le retrait moyen des actions aurait été légèrement supérieur à 2%. En acceptant un éventuel tirage de 10%, nous pourrions risquer 4% par transaction, et notre dépôt aurait augmenté de 177% pendant deux ans, soit 90% par an en dollars américains!
Epilogue
Le prix n’est jamais trop élevé pour commencer à acheter, et n’est jamais trop bas pour commencer à vendre.
Ce n’est pas la pensée qui fait beaucoup d’argent. C’est un siège.
Les stratégies décrites ci-dessus peuvent être modifiées et peuvent afficher un rendement encore plus élevé avec un prélèvement ne dépassant pas 10%. N’essayez pas de trader trop souvent, mieux vaut trouver un broker qui fournit non seulement un « ensemble standard » de symboles de deux douzaines de paires de devises et trois douzaines d’actions, mais au moins trois ou quatre cents symboles (actions, contrats à terme). Plus probablement, les symboles ne seront pas corrélés et votre dépôt sera plus sécurisé. Une remarque de plus - les actions montrent de meilleurs résultats que les paires de devises.
P.S. (une remarque publicitaire)
Mon Chartist »PnF Chartist script est disponible sur le marché. Il dessine des graphiques de points et de figures dans des fichiers texte en utilisant des citations fournies par MT4, MT5 ou Yahoo finance. Utilisez-le pour la recherche visuelle des modèles de prix, car il n’y a pas de meilleur testeur / optimiseur que votre cerveau. Dès que vous trouvez des modèles, utilisez les modèles EA de cet article pour trouver des preuves de vos idées.
Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/910
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation