English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Alım Satım Robotlarının Hikayeleri: Daha Az mı Daha Fazla mı?

Alım Satım Robotlarının Hikayeleri: Daha Az mı Daha Fazla mı?

MetaTrader 5Ticaret | 14 Ocak 2022, 10:52
198 0
Roman Zamozhnyy
Roman Zamozhnyy

Bir sorunu çözebilmem için önce onu kendime açıklamalıyım. Çözümü bulduğumu düşündüğümde haklı olduğumu kanıtlamalıyım.

Bunu kanıtlamanın tek bir yolunu kendi paramla kanıtlamaktır.

Jesse Livermore


Önsöz

Son Haçlı Seferi içinde piyasa bilgilerini görüntülemek için oldukça ilginç ancak şu anda yaygın olarak kullanılmayan bir yöntem olan nokta ve şekil grafiklerini inceledik. Sunulan script dosyası bir grafik çizebilir. Ancak alım satım otomasyonu önermedi. Şimdi, analiz için ve alım satım işleminin yönü ve hacmine karar vermek için nokta ve şekil grafiğini kullanarak alım satım işlemi sürecini otomatikleştirmeye çalışabiliriz.

Burada temel çizim ilkelerini yazmayacağım; sadece tipik bir grafiğe göz atın:

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

Bu grafikte alım satım fırsatlarının açıkça görüldüğünü iddia etmeyeceğim. Sadece iki alım satım hipotezini kontrol etmenizi öneriyorum:

Birincil trendle işlem yapın — boğa piyasasında satın alın ve ayı piyasasında satın.

Piyasaya girmeden önce tanımlanmış zarar durdur işlevini kullanın.

  • önceki X sütununun en yükseğinin üzerinde bir durdur talimatı kullanarak destek seviyesinin üzerinde satın alın, önceki O sütununun en düşük seviyesinin altında bir satmayı durdur talimatı kullanarak direnç çizgisinin altından satış yapın; pivot seviyesinde bir izleyen durdurma kullanın;

Karınızın artmasına izin verin.

Zarar veren anlaşmaları kapatın (iyi anlaşmalar genellikle hemen kar gösterir).

  • direnç çizgisini aştığında satın alın, destek çizgisini aştığında satın; pivot seviyesinde zarar durdur işlevini ayarlayın, trend çizgisinde takip eden durdur işlevini ayarlayın.


Hacim Seçme

Bir hisse senedi spekülasyon ustasının yukarıdaki alıntılarına dikkat edin: durdur talimatını kullanın. Piyasaya belirli bir hacimle girmeyi tercih ederim, böylece Zarar Durdur talimatı tetiklendiğinde, bakiye kaybı kabul edebileceğim bakiyenin yüzdesinden fazla olmaz (Ralph Vince'in The Mathematics of Money Management kitabında optimal F dediği şey budur). Anlaşma başına kayıp riski iyi optimize edilebilir bir değişkendir (aşağıdaki kodda opt_f).

Böylece, işlem başına kabul edilebilir riske bağlı olan hacim hesaplama mekanizması ile alım/satım talimatı veren bir işlevimiz var:

//+------------------------------------------------------------------+
//| 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;
  };


Hangi Optimizasyon Kriteri Kullanılmalı?

Aslında sadece iki optimizasyon kriteri vardır: belirli bir getiri seviyesinde en düşük düzeye indirme ya da düşüş veya belirli bir düşüş seviyesi için bakiyenin en yüksek düzeye getirme. İkinci kritere göre optimize etmeyi tercih ederim:

//+------------------------------------------------------------------+
//| 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)));
  };

Risk, stratejinin benim için kabul edilemez olduğu düşüş seviyesidir. Bu aynı zamanda optimize edilecek değişkenlerden biridir.


Ne Zaman Yeniden Optimize Edilmeli?

Birisi stratejileri zaman aralıklarında (örneğin haftada bir, ayda bir), biri anlaşma aralıklarında (50, 100 anlaşmadan sonra), biri pazar değiştiğinde yeni optimizasyona başlar. Aslında, yeniden optimizasyon ihtiyacı, yalnızca önceki paragrafta seçilen optimizasyon kriterine bağlıdır. Düşüş, izin verilen maksimum risk parametresinin altına düşerse stratejiyi yeniden optimize ederiz; her şey yolundaysa olduğu gibi çalışmasına izin verin. %10'dan fazla düşüş benim için kabul edilemez. Böylece, sistem çalışma sırasında daha fazla düşüş yaşarsa onu yeniden optimize ederim.


Her Şeyi Tek Seferde Optimize Edebilir Miyim?

Ne yazık ki, strateji test cihazında "Piyasa İzlemede seçilen tüm semboller" modu için harici değişkenleri optimize edemezsiniz. Bu nedenle, piyasa enstrümanlarını diğer optimize edilebilir harici değişkenlerle birlikte aşağıdaki gibi seçelim:

//+------------------------------------------------------------------+
//| 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;
     };
  };

Gerekirse sembol seçim fonksiyonuna ve numaralandırmaya gerekli araçları ekleyebilirsiniz (fonksiyon OnInit() içinde çağrılır).


Hangi Robotu Yarattık?

Onay İşareti Tanıtıcı:

//+------------------------------------------------------------------+
//| 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();
        }

     };
  };

Strateji 1 için: "Önceki X sütununun en yükseğinin üzerinde bir durdur talimatı kullanarak destek seviyesinin üzerinde satın alın, önceki O sütununun en düşük seviyesinin altında bir satmayı durdur talimatı kullanarak direnç çizgisinin altından satış yapın; pivot seviyesinde bir izleyen durdurma kullanın|":

//+------------------------------------------------------------------+
//| 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();
  };

Strateji 2 için "Direnç çizgisini aştığında satın alın, destek çizgisini aştığında satın; pivot seviyesinde zarar durdur işlevini ayarlayın, trend çizgisinde takip eden durdur işlevini ayarlayın":

//+------------------------------------------------------------------+
//| 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();
  };

Sevgili okuyucu, lütfen birkaç şeye dikkat edin.

  • Piyasa enstrümanlarının fiyatları, sentlerden onbinlere kadar oldukça geniş bir aralıkta değişmektedir (örnek - Japon borsalarındaki hisse senetleri ve CFD'ler). Bu nedenle, kutu boyutu için bir ila on binlerce piplik değerler ayarlamaktan kaçınmak için nokta ve şekil grafiğinde fiyat logaritmasını kullanıyorum.
  • Nokta ve şekil grafiği dizisinin indekslenmesi sıfırdan başlar, bu nedenle son sütunun indeksi, eksi bir sütun sayısına eşittir.
  • Destek hattının değeri, kullanılıyorsa -10.0'dan daha büyüktür, ancak fiyatın fiyat logaritmasından daha küçüktür. Destek (veya direnç) çizgisi kullanılmazsa grafik dizisindeki değeri -10.0'dır. Bu nedenle, destek/direnç çizgilerini aşma koşulları, yukarıdaki Strateji 2 kodundaki ile aynı biçimde yazılmıştır.

Aşağıdaki eklerdeki yardımcı işlevlerin koduna bakın. Grafiğin kodu çok büyük o yüzden yazıda yazmıyorum; aşağıdaki eklerde yorumlarla birlikte görün.


EA Alım Satım Sonuçları

Optimizasyon için symbol_list_1.mhq ve symbol_list_2.mhq dosyalarında iki set piyasa sembolü hazırladım; Dow endeksinden döviz çiftlerini ve hisse senedi CFD'lerini içerir.

Kurulum Penceresi:

Test seçenekleri

İlk durumda, strateji test cihazındaki kurulum penceresi aşağıdaki gibi görünür:

Optimizasyon parametreleri

Test Başlatma satırına dikkat edin. Robot, analiz ve karar verme için en az birkaç tablo sütununa ihtiyaç duyar ve kutu boyutunu 50 pip veya daha fazlasına ayarladığınızda, bir sütun için bile bir yıllık geçmiş çoğu zaman yeterli olmaz. Bu nedenle, kutu boyutu 50 pip veya daha fazla olan çizelgeler için robot çalışmasının başlangıcından itibaren yaklaşık üç yıl veya daha fazla olan aralığı kullanın, Kurulum Penceresindeki Test Başlatma parametresinde robot çalışmasının başlangıcını ayarlayın. Örneğimizde 01.01.2012'den bu yana 100 pip'lik kutu boyutuyla test yapmak için Ayarlar sekmesinde 01.01.2009'dan itibaren aralığı belirtin; Parametreler sekmesinde 01.01.2012 tarihinden itibaren aralığı ayarlayın.

"Alım satım minimum lot?" parametresinin yanlış değeri lot boyutunun bakiyeye ve "İşlem Başına Risk, %" değişkenine bağlı olduğunu belirtir (bu durumda alım satım işlemi başına %1, ancak optimize edilebilir). "Maks. Düşüş, %", OnTester() işlevindeki optimizasyon kriteridir. Bu yazıda optimizasyon için sadece iki değişken kullanıyorum: Pip cinsinden Sembol ve Kutu boyutu.

Optimizasyon süresi: 2012-2013. EA, EURUSD grafiğinde en iyi sonucu verir, çünkü sembol en iyi onay işareti kapsamını sağlar. Aşağıdaki tablo, ilk stratejiye dayalı olarak kutu boyutu 10 olan çeşitli döviz çiftleri üzerinde test etmek için tam bir rapor içermektedir:

Geçiş Sonuç Kar Beklenen Ödeme Kar Faktörü Kurtarma Faktörü Sharpe Oranı Özel Öz sermaye GG % Alım satım işlemleri seçili_sembol kutu
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

İşte çeşitli semboller ve kutu boyutu değerleri için bir özet tablo:

Strateji Semboller Kutu boyutu Alım satım işlemleri Öz sermaye GG % Kar Sonuç Beklenen Bakiye
1 Para birimleri 10 1 659 Eylül -10 214 2 030 2 030
1 Para birimleri 20 400 5 1 638 2 484 2 484
1 Hisse senetleri 50 350 60 7 599 7 599 15 199
1 Hisse senetleri 100 81 2 4 415 4 415 17 659
2 Para birimleri 10 338 20 -4 055 138 138
2 Para birimleri 20 116 8 4 687 3 986 3 986
2 Hisse senetleri 50 65 6 6 770 9 244 9 244
2 Hisse senetleri 100 12 1 -332 -332 -5 315

Ne görüyoruz?

Her zaman yanlış yapan aptallar vardır.

Ve her zaman alım satım yapmanız gerektiğine inanan Wall Street aptalları var.

Dünyada hisse senedi almak veya satmak için gerekli tüm bilgilere her zaman sahip olan ve bunu oldukça makul bir şekilde yapan kimse yoktur.

Sonuç size garip gelebilir: Depozitonuzun daha az alım satım işlemiyle daha yüksek olması daha olasıdır. İki yıl önce EA hisse senetlerimizi 100 kutu büyüklüğünde ve alım satım başına riski %1 olan alım satıma bıraksaydık, EA o zamandan beri sadece 81 anlaşma yapacaktı (yılda sembol başına ortalama 1.25 anlaşma) mevduatımız %44 büyüyecekti, ortalama özkaynak düşüşü %2'nin biraz üzerinde olacaktı. %10'luk olası bir çekilişi kabul edersek anlaşma başına %4 risk alabiliriz ve mevduatımız iki yıl boyunca %177, yani ABD doları cinsinden yılda %90 oranında büyüyecekti!


Sonsöz

Fiyat, satın almaya başlamak için asla çok yüksek değildir ve satışa başlamak için asla çok düşük değildir.

Büyük parayı getiren düşünmek değildir. Oturmaktır.

Yukarıda açıklanan stratejiler değiştirilebilir ve %10'dan fazla olmayan düşüşle daha da büyük bir getiri gösterebilir. Çok sık alim satim yapmaya çalışmayın, sadece iki düzine döviz çifti ve üç düzine hisse senedinden oluşan "standart bir sembol seti" değil, en az üç veya dört yüz sembol (hisse senetleri, vadeli işlemler) sağlayan bir komisyoncu bulmanızı öneriyoruz. Büyük olasılıkla, semboller ilişkilendirilmeyecek ve para yatırma işleminiz daha güvenli olacaktır. Bir açıklama daha; hisse senetleri döviz çiftlerinden daha iyi sonuçlar gösteriyor.


Not (reklam notu)

PnF Chartist script dosyası Piyasa'da mevcut. MT4, MT5 veya Yahoo finans tarafından sağlanan alıntıları kullanarak metin dosyalarında nokta ve şekil grafikleri çizer. Beyninizden daha iyi bir test edici/iyileştirici olmadığı için, fiyat formasyonlarını görsel olarak aramak üzere kullanın. Kalıpları bulur bulmaz, fikirlerinizin kanıtını bulmak için bu makaledeki EA şablonlarını kullanın.

MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/910

Ekli dosyalar |
licence.txt (1.05 KB)
strategy_one.mq5 (37.87 KB)
strategy_two.mq5 (37.39 KB)
symbol_list_1.mqh (2.43 KB)
symbol_list_2.mqh (2.17 KB)
Bir Sosyal Teknoloji Girişimi Kurmak, Bölüm I: MetaTrader 5 Sinyallerinizi Tweetleyin Bir Sosyal Teknoloji Girişimi Kurmak, Bölüm I: MetaTrader 5 Sinyallerinizi Tweetleyin
Bugün, EA'larınızın alım satım sinyallerini tweetleyebilmeniz için bir MetaTrader 5 terminalini Twitter ile nasıl bağlayacağınızı öğreneceğiz. PHP'de RESTful web servisine dayalı bir Sosyal Karar Destek Sistemi geliştiriyoruz. Bu fikir, bilgisayar destekli alım satım adı verilen belirli bir otomatik alım satım anlayışından gelmektedir. İnsan yatırımcılarının bilişsel yeteneklerinin, aksi takdirde Expert Advisor'lar tarafından otomatik olarak piyasaya sürülecek olan alım satım sinyallerini filtrelemesini istiyoruz.
Üç Satır Kesme Grafiği Oluşturma Göstergesi Üç Satır Kesme Grafiği Oluşturma Göstergesi
Bu makale Steve Nison'ın "Candlesticks Ötesinde" adlı kitabında önerilen Üç Satır Arası tablosuna ayrılmıştır. Bu grafiğin en büyük avantajı, bir önceki harekete göre bir fiyattaki küçük dalgalanmaları filtrelemeye izin vermesidir. Grafik oluşturma ilkesini, gösterge kodunu ve buna dayalı bazı alım satım stratejileri örneklerini tartışacağız.
MQL5'ten (MQL4) MySQL Veritabanına Nasıl Erişilir MQL5'ten (MQL4) MySQL Veritabanına Nasıl Erişilir
Makale, MQL ve MySQL veritabanı arasında bir arayüzün geliştirilmesini açıklar. Mevcut pratik çözümleri tartışır ve veritabanlarıyla çalışmak için bir kitaplık uygulamanın daha uygun bir yolunu sunar. Makale, MySQL ile çalışmanın işlevleri, arayüz yapısı, örnekleri ve bazı belirli özelliklerinin ayrıntılı bir açıklamasını içerir. Yazılım çözümlerine gelince, makale ekleri, MQL4 ve MQL5 dilleri için dinamik kitaplıkların dosyalarını, dokümantasyonu ve script dosyası örneklerini içerir.
SQL ve MQL5: SQLite Veritabanı ile Çalışmak SQL ve MQL5: SQLite Veritabanı ile Çalışmak
Bu makale, projelerinde SQL kullanmak isteyen geliştiricilere yöneliktir. SQLite'ın işlevselliğini ve avantajlarını açıklar. Makale, SQLite işlevleri hakkında özel bilgi gerektirmez, ancak SQL'in minimum düzeyde anlaşılması faydalı olacaktır.