قانون طلایی معاملات

قانون طلایی معاملات

مقدمه

وظیفه‌ی اصلی یک تریدر فقط پیدا کردن زمان دُرست برای ورود به بازار نیست. پیدا کردن زمان درست برای خروج از بازار هم لازم است. قانون طلایی معامله کردن می‌گوید: “همیشه ضرر را کم کنید و اجازه دهید سود ادامه داشته باشد”.

اگر بخواهیم بر اساس انتظارات ریاضی بالا، کسب سود داشته باشیم، باید سه اصل ابتدایی خوب معامله کردن را بفهمیم.

  1. ریسک خود را هنگام ورود به بازار بشناسید (که یعنی مقدار اولیه حد ضرر)؛
  2. کم‌کم از سود خود بردارید و اجازه دهید سود ادامه داشته باشد (قبل از اینکه استراتژی شما به شما بگوید، پوزیشن را نبندید)؛
  3. انتظارات ریاضی سیستم معاملاتی خود را بشناسید – و مرتباً آن را تست و تنظیم کنید.

روشِ تریلینگ مرحله به مرحلۀ پوزیشن‌ها به شما اجازه می‌دهد سود، دائم در جریان باشد

بسیاری فکر می‌کنند کسب سود غیرممکن است زیرا نمی‌دانیم بازار به کدام سمت می‌رود. اما آیا واقعاً برای ترید کردن باید این را بدانیم؟ ترید موفق بیشتر بر اساس یک سیستم خوب‌-طراحی‌شده، با درنظر گرفتن زمان‌های مناسب برای ورود به بازار، تعریف می‌شود. با استفاده از قدرت انتظار و قوانین تریلینگ مرحله به مرحله‌ی پوزیشن‌ها، که اجازه می‌دهند سود تا بالاترین حد ممکن در جریان باشد، چنین ملاحظاتی را در سیستم معاملاتی لحاظ می‌کنیم.

لحظه‌ی ورود به بازار را با روش‌های مختلف می‌توان پیدا کرد، برای مثال، با استفاده از مدل‌ کندل‌ها، مدل امواج، و غیره. در همین لحظه، عامل سود را نیز باید درنظر گرفت (نسبت سود/ضرر).

این روش بر اساس این نیاز است: هنگام باز کردن یک پوزیشن، تریدر، کمترین مقدار ممکنِ Stop Loss را انتخاب می‌کند. این مقدار را می‌توان با روش‌های مختلفی تعیین کرد، برای مثال، ممکن آن را برابر با ۱.۵ درصد سرمایۀ اولیه‌تان درنظر بگیرید. وقتی بازار به سودی برابر با مقدار Stop Loss می‌‌رسد، نیمی از لاتیج انتخاب‌شده (برای معامله)، بسته می‌شود، اما Stop Loss تغییر نمی‌کند!

بنابراین، برای شرایطی که بازار برعکس پیش می‌رود، به‌نوعی یک شبکه‌ی ایمن ایجاد کرده‌ایم؛ به‌عبارت دیگر، ریسک خود را با تثبیت حداقل ضرر، کاهش داده‌ایم. اگر هم بازار در جهت مطلوب پیش برود تا بعداً بازگشت داشته باشد، Stop Loss فعال خواهد شد (شکل‌های ۱-۳).

قانون طلایی معاملات

شکل ۱. باز کردن یک پوزیشن

قانون طلایی معاملات

شکل ۲. تنظیم Stop Loss

اگر بازار برگشت داشت:

قانون طلایی معاملات

شکل ۳. اگر بازار برگشت داشت، شما در سطح صفر-صفر هستید (نه سود، نه ضرر)

کد برنامه‌ی پوزیشن تریلینگ

به شما کد برنامه‌ای را ارائه می‌کنیم که تریلینگ پوزیشن‌های باز، و تحقق اصل طلایی دوم را برعهده دارد، و اجازه می‌دهد سود به بالاترین حد ممکن برسد.

اگر بازار کماکان در جهت مطلوب حرکت می‌کند و به بعضی از مقادیر از پیش‌ تعیین‌شده می‌رسد، برای مثال، ۱۰۰ پیپ (pips)، Stop Loss مجدد تنظیم شده و به خط صفر-صفر[۱] می‌آید. وقتی بازار، در فواصل از پیش تعیین‌شده، برای مثال ۵۰ پیپ (pips)، به سود می‌رسد، تنظیمات بیشتر را انجام می‌دهیم. می‌توانیم Stop Loss را با هر کندل بعدی، حرکت دهیم اما بروکرها از زیاد تغییر دادن خوششان نمی‌‌آید، به‌خصوص وقتی معامله در تایم‌فریم‌های پایین‌تر انجام می‌شود. فایل خطای (stdlib.mq4) از پوشه‌ی کتابخانه‌ها، حتی خطای                   #‌۸ error=”too frequent requests”، که دقیقاً برای چنین شرایطی است را، در خود دارد.

روشی که با آن خط Stop Loss بعدی را تعیین کنیم، بر اساس جایگاه قیمت در زمان جمع‌آوری سود بسته به خطوط فیبوناچی، انتخاب می‌شود. خطوط به‌کاررفته در فیبوناچی در اینجا بر اساس روش تونل وگاس[۲] ساخته شده‌اند.

محاسبه‌ی خطوط فیبوناچی، توسط تابع تولید خطوط LevelFibo()، انجام می‌شود:

//+------------------------------------------------------------------+
   void LevelFibo()
   {
   double Fb1,Fb2,Fb3,Fb4,Fb5,Fb6,Fb7,Fb8,Fb9,Fb10,Fb11,Fb12,Fb13;
   // "Vegas" channel
   double Ma144_1 = iMA(NULL,0,144,0,MODE_EMA,PRICE_CLOSE,1);
   double Ma169_1 = iMA(NULL,0,169,0,MODE_EMA,PRICE_CLOSE,1);
   // "Vegas" channel median
   double MedVegas=NormalizeDouble((Ma144_1+Ma169_1)/2,Digits); 
   // calculate Fibo levels values using "Vegas" method
   Fb1=MedVegas-377*Point;     Fb12=MedVegas+377*Point;
   Fb2=MedVegas-233*Point;     Fb11=MedVegas+233*Point;
   Fb3=MedVegas-144*Point;     Fb10=MedVegas+144*Point;
   Fb4=MedVegas-89*Point;      Fb9=MedVegas+89*Point;
   Fb5=MedVegas-55*Point;      Fb8=MedVegas+55*Point;
   Fb6=MedVegas-34*Point;      Fb7=MedVegas+34*Point;
   }
//+------------------------------------------------------------------+

وقتی داریم Stop Loss را برای پوزیشن‌های BUY محاسبه می‌کنیم، سود، تفاوت بین قیمتِMax  اولین کندل High[1] و خط بازشدن پوزیشن OrderOpenPrice()، است. خط Stop Loss به‌عنوان “نزدیک‌ترین” خط فیبوناچی نسبت به مقدارِ Min اولین کندل Low[1] تعریف می‌شود (شکل ۴).

قانون طلایی معاملات

شکل ۴. محاسبه‌ی Stop Loss برای پوزیشن BUY

هنگام محاسبه‌ی Stop Loss برای پوزیشن‌های SELL، سود، تفاوت بین خط بازشدن پوزیشن OrderOpenPrice()، و قیمتِ Max اولین کندل High[1] است (شکل ۵).

قانون طلایی معاملات

شکل ۵. محاسبه‌ی Stop Loss برای پوزیشن SELL

برای پوزیشن‌های Buy، مقادیر Stop Loss بر اساس خطوط فیبوناچی هستند. و بسته به کمترین مقدار اولین کندل‌اِستیک، [این موضوع] به‌عنوان یک تابع جداگانه ارائه می‌گردد.

کد تابع را در اینجا داریم:

//+---------------------------------------------------------------------+
//| Function (table) for specifying Stop Loss values for BUY position   |
//| by Fibo levels according to the lowest value of the first candle    |
//+---------------------------------------------------------------------+
 void StopLevelFiboBuy()
   {
   if(Low[1]>Fb12)                                newSL_B=Fb12-100*Point;
   if(Low[1]<=Fb12 && Low[1]>(Fb12+Fb11)/2)       newSL_B=(Fb12+Fb11)/2;
   if(Low[1]<=(Fb12+Fb11)/2 && Low[1]>Fb11)       newSL_B=Fb11;
   if(Low[1]<=Fb11 && Low[1]>(Fb11+Fb10)/2)       newSL_B=(Fb11+Fb10)/2;
   if(Low[1]<=(Fb10+Fb11)/2 && Low[1]>Fb10)       newSL_B=Fb10;
   if(Low[1]<=Fb10 && Low[1]>(Fb10+Fb9)/2)        newSL_B=Fb9;
   if(Low[1]<=(Fb10+Fb9)/2 && Low[1]>Fb9)         newSL_B=Fb8;
   if(Low[1]<=Fb9  && Low[1]>Fb8)                 newSL_B=Fb7;
   if(Low[1]<=Fb8  && Low[1]>Fb7)                 newSL_B=(Fb7+MedVegas)/2;
   if(Low[1]<=Fb7  && Low[1]>MedVegas)            newSL_B=Fb6;
   if(Low[1]<=MedVegas && Low[1]>(MedVegas+Fb6)/2)newSL_B=Fb6;
   if(Low[1]<=(MedVegas+Fb6)/2 && Low[1]>Fb6)     newSL_B=Fb5;
   if(Low[1]<=Fb6  && Low[1]>Fb5)                 newSL_B=Fb4;
   if(Low[1]<=Fb5  && Low[1]>Fb4)                 newSL_B=(Fb3+Fb4)/2;
   if(Low[1]<=Fb4  && Low[1]>Fb3)                 newSL_B=Fb3;
   if(Low[1]<=Fb3  && Low[1]>(Fb3+Fb2)/2)         newSL_B=(Fb3+Fb2)/2;
   if(Low[1]<=(Fb3+Fb2)/2  && Low[1]>Fb2)         newSL_B=Fb2;
   if(Low[1]<=Fb2  && Low[1]>(Fb2+Fb1)/2)         newSL_B=(Fb1+Fb2)/2;
   if(Low[1]<=(Fb2+Fb1)/2 && Low[1]>Fb1)          newSL_B=Fb1;
   if(Low[1]<=Fb1)                                newSL_B=Fb1-100*Point;
   }
//+------------------------------------------------------------------+

جدول مقادیر Stop Loss توسط خطوط فیبوناچی وابسته به حداکثر مقدار اولین کندل‌اِستیک تابع StopLevelFiboSell() برای پوزیشن‌های Sell، توسط کد زیر، ارائه شده‌است:

//+----------------------------------------------------------------------+
//| Function (table) for specifying Stop Loss values for SELL position   |
//| by Fibo levels according to the highest value of the first candle    |
//+----------------------------------------------------------------------+
 void StopLevelFiboSell()
   {
   if(High[1]<=Fb12 && High[1]>(Fb12+Fb11)/2)        newSL_S=Fb12+100*Point;
   if(High[1]<=Fb12 && High[1]>Fb11)                 newSL_S=Fb12;
   if(High[1]<=Fb11 && High[1]>Fb11+Fb10)            newSL_S=Fb11;
   if(High[1]<=Fb10 && High[1]>(Fb10+Fb9)/2)         newSL_S=(Fb11+Fb10)/2;
   if(High[1]<=Fb9  && High[1]>Fb8)                  newSL_S=(Fb10+Fb9)/2;
   if(High[1]<=Fb8  && High[1]>Fb7)                  newSL_S=Fb9;
   if(High[1]<=Fb7  && High[1]>MedVegas)             newSL_S=Fb8;
   if(High[1]<=MedVegas && High[1]>MedVegas)         newSL_S=Fb7;
   if(High[1]<=(MedVegas+Fb6)/2 && High[1]>Fb6)      newSL_S=MedVegas;
   if(High[1]<=Fb6  && High[1]>Fb5)                  newSL_S=MedVegas;
   if(High[1]<=Fb5  && High[1]>Fb4)                  newSL_S=Fb6;
   if(High[1]<=Fb4  && High[1]>Fb3)                  newSL_S=Fb5;
   if(High[1]<=Fb3  && High[1]>Fb2)                  newSL_S=Fb4;
   if(High[1]<=Fb2  && High[1]>(Fb2+Fb1)/2)          newSL_S=(Fb2+Fb3)/2;
   if(High[1]<(Fb2+Fb1)/2   && High[1]>Fb1)          newSL_S=Fb2;
   if(High[1]<Fb1)                                   newSL_S=(Fb2+Fb1)/2;
   }
//+------------------------------------------------------------------+

بهتر این است که تابع محاسبه‌ی خطوط فیبوناچی LevelFibo را به هر یک از دو تابع وابستگی اشاره‌شده، اضافه کنیم. این کار در فایل‌های دِموی پیوست‌شده، انجام شده‌است.

اکنون، با درنظر گرفتن ترکیب دو تابع، و یا به‌جای آن فعال‌سازی تابع محاسبه‌ی خطوط LevelFibo() در تابع شناسایی خطوط Stop Loss که روی این خطوط متمرکز شده‌است، این تابع منطقی به‌نظر می‌رسد زیرا توابع با هم کار می‌کنند. بنابراین، تعداد فراخوانی توابع حین تریلینگ، کاهش می‌یابد – و به‌جای دوتا، فقط یکی باقی می‌ماند.

بعد از ترکیب شدن، چنین چیزی را خواهیم داشت:

//| Function (table) for specifying Stop Loss values for BUY position    |
//| by Fibo levels according to the lowest value of the first candle     |
//+----------------------------------------------------------------------+
   void StoplevelFiboBuy()
   {
   double Fb1,Fb2,Fb3,Fb4,Fb5,Fb6,Fb7,Fb8,Fb9,Fb10,Fb11,Fb12,Fb13;
   double Ma144_1 = iMA(NULL,0,144,0,MODE_EMA,PRICE_CLOSE,1);
   double Ma169_1 = iMA(NULL,0,169,0,MODE_EMA,PRICE_CLOSE,1);
   double MedVegas=NormalizeDouble((Ma144_1+Ma169_1)/2,Digits); 
   Fb1=MedVegas-377*Point;     Fb12=MedVegas+377*Point;
   Fb2=MedVegas-233*Point;     Fb11=MedVegas+233*Point;
   Fb3=MedVegas-144*Point;     Fb10=MedVegas+144*Point;
   Fb4=MedVegas-89*Point;      Fb9=MedVegas+89*Point;
   Fb5=MedVegas-55*Point;      Fb8=MedVegas+55*Point;
   Fb6=MedVegas-34*Point;      Fb7=MedVegas+34*Point;
   if(Low[1]>Fb12)                                newSL_B=Fb12-100*Point;
   if(Low[1]<=Fb12 && Low[1]>(Fb12+Fb11)/2)       newSL_B=(Fb12+Fb11)/2;
   if(Low[1]<=(Fb12+Fb11)/2 && Low[1]>Fb11)       newSL_B=Fb11;
   if(Low[1]<=Fb11 && Low[1]>(Fb11+Fb10)/2)       newSL_B=(Fb11+Fb10)/2;
   if(Low[1]<=(Fb10+Fb11)/2 && Low[1]>Fb10)       newSL_B=Fb10;
   if(Low[1]<=Fb10 && Low[1]>(Fb10+Fb9)/2)        newSL_B=Fb9;
   if(Low[1]<=(Fb10+Fb9)/2 && Low[1]>Fb9)         newSL_B=Fb8;
   if(Low[1]<=Fb9  && Low[1]>Fb8)                 newSL_B=Fb7;
   if(Low[1]<=Fb8  && Low[1]>Fb7)                 newSL_B=(Fb7+MedVegas)/2;
   if(Low[1]<=Fb7  && Low[1]>MedVegas)            newSL_B=Fb6;
   if(Low[1]<=MedVegas && Low[1]>(MedVegas+Fb6)/2)newSL_B=Fb6;
   if(Low[1]<=(MedVegas+Fb6)/2 && Low[1]>Fb6)     newSL_B=Fb5;
   if(Low[1]<=Fb6  && Low[1]>Fb5)                 newSL_B=Fb4;
   if(Low[1]<=Fb5  && Low[1]>Fb4)                 newSL_B=(Fb3+Fb4)/2;
   if(Low[1]<=Fb4  && Low[1]>Fb3)                 newSL_B=Fb3;
   if(Low[1]<=Fb3  && Low[1]>(Fb3+Fb2)/2)         newSL_B=(Fb3+Fb2)/2;
   if(Low[1]<=(Fb3+Fb2)/2  && Low[1]>Fb2)         newSL_B=Fb2;
   if(Low[1]<=Fb2  && Low[1]>(Fb2+Fb1)/2)         newSL_B=(Fb1+Fb2)/2;
   if(Low[1]<=(Fb2+Fb1)/2 && Low[1]>Fb1)          newSL_B=Fb1;
   if(Low[1]<=Fb1)                                newSL_B=Fb1-100*Point;
   }
// ----------------------------------------------------------------------+

کد دستور اصلی تریلینگ پوزیشن‌ها به‌عنوان یک قطعه اکسپرت همراه با توالی اقدامات برای اجرای توابعی که پیش‌تر به آن‌ها اشاره شد، مطابق با مقادیر قیمت کندل‌های کنونی، ارائه شده‌است. تریلینگ مرحله به مرحله بعد از انتخاب یک معامله‌ی باز مناسب، آغاز می‌شود.

قطعه‌ی کوچکی از کد تریلینگ در اینجا آورده شده‌است:

//+------------------------------------------------------------------+
//| TRAILING OPEN POSITIONS                                          |
//+------------------------------------------------------------------+
for(int i=OrdersTotal()-1; i>=0; i--)
  {
   if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {Print("Order selection error = ",GetLastError());}
   if(OrderSymbol()==Symbol())
     {
      if(OrderType()==OP_BUY)
        {
         if(OrderMagicNumber()==Magic)
           {
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=SL_B*Point && OrderLots()==0.2)Close_B_lot();
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())/Point>=100 && OrderLots()==0.1 && OrderStopLoss()<OrderOpenPrice())
              {
               Print(" 1 - StopLoss shift");
               if(!OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+2*Point,OrderTakeProfit(),0,Aqua))
                 {
                  Print(" at Modif.ord.# ",OrderTicket()," Error # ",GetLastError());
                 }
               return;
              }
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=120*Point && OrderOpenPrice()>Ma144_1-144*Point)
              {
               StoplevelFiboBuy();
               newSL_B=newSL_B+21*Point;
               if((Bid-newSL_B)/Point<StopLevel)newSL_B=Bid-StopLevel*Point;
               if(newSL_B>OrderStopLoss() && (Bid-newSL_B)/Point>StopLevel)
                 {
                  Print("2nd shift of StopLoss ");
                  Modyf_B_lot();
                 }
              }
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=200*Point && (High[1]-OrderOpenPrice())<=250*Point)
              {
               StoplevelFiboBuy();
               if((Bid-newSL_B)/Point<StopLevel)newSL_B=Bid-StopLevel*Point;
               if(newSL_B>OrderStopLoss() && (Bid-newSL_B)/Point>StopLevel)
                 {
                  Print(" 3rd shift by level order # ",OrderTicket());
                  Modyf_B_lot();
                 }
              }
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=250*Point && OrderOpenPrice()>Ma144_1-144*Point)
              {
               StoplevelFiboBuy();
               newSL_B=newSL_B+10*Point;
               if((Bid-newSL_B)/Point<StopLevel) newSL_B=Bid-StopLevel*Point;
               if(newSL_B>OrderStopLoss() && (Bid-newSL_B)/Point>StopLevel)
                 {
                  Print(" 4th shift by level order # ",OrderTicket());
                  Modyf_B_lot();
                 }
              }
            // ----------------------------------------------------------------------+
            if((High[1]-OrderOpenPrice())>=300*Point && (High[1]-OrderOpenPrice())<=350*Point)
              {
               StoplevelFiboBuy();
               newSL_B=newSL_B+20*Point;
               if((Bid-newSL_B)/Point<StopLevel) newSL_B=Bid-StopLevel*Point;
               if(newSL_B>OrderStopLoss() && (Bid-newSL_B)/Point>StopLevel)
                 {
                  Print(" 5th shift by level order # ",OrderTicket());
                  Modyf_B_lot();
                 }
              }
            // ----------------------------------------------------------------------+
            ...
           }
        }
     }
  }

دنباله‌ی تریلینگ مرحله به مرحله شامل ۸ مرحله است که در نسخه‌ی پیوست‌شده‌ی اکسپرت دِمو می‌توانید آن را مشاهده کنید.

در اینجا اِسکرین‌شاتی را داریم که مراحل عملکرد اکسپرت دمو را برای پوزیشن تریلینگ Buy نشان می‌دهد. پوزیشن به این دلیل باز شده‌است که مدل “جذب سه کندل”[۳] شکل گرفته است. علاوه بر این، کندل “inverted hammer” در میان کندل‌های جذب‌شده دیده می‌شود. این واقعیت استحکام سیگنال را برای باز کردن یک پوزیشن Buy، تقویت می‌کند.

قانون طلایی معاملات

شکل ۶. مثالی از پوزیشن تریلینگ Buy

برای دیدن خطوط فیبوناچی، بطوریکه انگار روی یک اِسکرین‌شات روشن هستند، باید از اندیکاتور “Vegas” استفاده کنیم. می‌توان این اندیکاتور را در وب‌سایت MQL4 مشاهده کرد: https://www.mql5.com/en/code/7148

همان اِسکرین‌شات کشیده‌شدۀ کوچک از صفحۀ “تاریک”:

قانون طلایی معاملات

شکل ۷. اِسکرین‌شات از صفحه‌ی مانیتور (نسخه‌ی دِمو برای Buy)

قانون طلایی معاملات

شکل ۸. مثالی از پوزیشن تریلینگ Sell

برای نمایش کارکرد اکسپرت‌های دِمو، همانطور که در شکل‌های ۹ و ۱۰ نشان داده شده‌است، بایستی پارامترهای تست موقت را راه‌اندازی کرد:

قانون طلایی معاملات

شکل ۹. پارامترهای تست اکسپرت Demo_trail_Buy.mql

قانون طلایی معاملات

شکل ۱۰. پارامترهای تست اکسپرت Demo_trail_Sell.mql

توجه: فایل‌ها همراه با اکسپرت‌های دِمو به این مقاله پیوست شده‌اند، و به‌عنوان ربات‌هایی برای تریلینگ پوزیشن‌های Buy و Sell به‌حساب می‌آیند. پوزیشن‌ها در اینجا با لاتیج دو برابر باز می‌شوند. اما وقتی Stop Loss به خط Break-even برده می‌شود، اطمینان خاطری نسبت به حرکتِ قیمت در آینده در جهت صحیح، پیدا می‌شود و اضافه کردن یک پوزیشن دیگر هم حتی ممکن می‌شود.

نتیجه‌گیری

مثال‌های داده‌شده از تریلینگ معاملات نشان می‌دهند روش جابه‌جایی دستور‌های Stop Loss که روی خطوط دینامیک فیبوناچی متمرکز است، احتمالاً نتایج مثبتی به ما خواهد داد. روش توصیف‌شده را می‌توانید در عمل برای ترید کردن استفاده کنید و این کار را توصیه می‌کنیم.

توابع شناسایی خطوط دینامیک فیبوناچی:

  • LevelFiboKgd.mq4
  • StopLevelFiboBuy.mq4
  • StopLevelFiboSell.mq4
  • فایل‌های دِمو:
  • Demo_trail_Buy_v1.mq4 – فایل دمو برای Buy
  •  Demo_trail_Sell_v1.mq4– فایل دمو برایSell

این مقاله دارای فایل پیوست است.

[۱]) Break-even level

[۲]) Vegas Tunnel method

[۳]) Absorption of three candles model

مقالات پیشنهادی :

M23admin

→ خواندن مطلب قبلی

تلفیق متاتریدر ۴ با مایکروسافت SQL سِرور

خواندن مطلب بعدی ←

یک اکسپرتِ غیرمعاملاتی برای تست اندیکاتورها

۳۵ مورد نظر

نوشتن نظر شما

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *