آموزش ساخت یک سیستم معاملاتی

image

در این مقاله، من قصد دارم با استفاده از ریاضی و برنامه­ نویسی در این استراتژی­ ها تحقیق کرده و سودآوری آن­ها را ارزیابی کنم. این مقاله دارای بخش های ریاضی و عملی است. در بخش ریاضیات، معادلاتی را برای محاسبه بازده مورد انتظار از استراتژی­ ها و سایر پارامترهای مهم ارائه می­کنم که توسط بسیاری از معامله ­گران در نظر گرفته نشده است. در بخش عملی، من یک سیستم معاملاتی grid  و martingale ساده ایجاد می­کنم و معادلات را با واقعیت، مقایسه میکنم. این مقاله به ویژه برای مبتدیان بسیار مفید است زیرا این راهکارها معمولاً اولین راهکارهایی هستند که با آن روبه­ رو می­شوند. اعتقاد کورکورانه به آن­ها ممکن است منجر به ناامیدی و اتلاف وقت شود، همان­طور که در آن زمان برای من اتفاق افتاد. اگر من ریاضیات را نمی­دانستم، شاید هنوز هم به آن­ها اعتقاد داشتم. اما هنوز هم اگر به درستی به این استراتژی­ ها نگاه کنید منطقی هستند. این همان چیزی است که من میخواهم ثابت کنم.

سیستم معاملاتی این دو استراتژی چه چیزهای مشترکی دارند؟

برای درک محبوبیت این دو استراتژی، باید نگاهی به آن­چه همه معامله­ گران تازه کار فارکس می­خواهند، داشته باشیم. بیش­تر معامله­ گران تازه­ کار، ریاضیدانان و رویاپردازانی هستند که فکر می­کنند عقل آن­ها می­تواند به آن­ها کمک کند تا به سرعت و به راحتی ثروتمند شوند. من هم روزی چنین رویاپردازی بودم. هر دوی این استراتژی­ ها به شکل نمودارهای سودآوری که به طور مداوم در استراتژی تستر افزایش می­یابند، نمایان می­شوند. در بسیاری از بخش­ های اعلام قیمت سهام، تستر ممکن است حتی بدون فیلتر هم نتایج مشابه Grail را نشان دهد. در هر زمینه فعالیتی و در هر کسب و کاری این خطر وجود دارد که افراد آگاه­تر بتوانند با هزینه شما خود را غنی کنند. معامله فارکس نیز از این قاعده مستثنی نیست. فارکس، به مقدار زیادی از این قبیل اقدامات فریبنده برخوردار است و این دو استراتژی، بارزترین و مشهورترین اثبات این موضوع است. اولین باری که از این استراتژی­ ها استفاده میکنید، می­بینید که آن­ها روی همه جفت ارزها با فاکتورهای سود باورنکردنی و بازده مورد انتظار کار می­کنند و حتی می­توانند با هرگونه spread  کنار بیایند، بنابراین به نظر می­رسد که این الگوریتم فراتر از بازار است. دلیل این امر آن است که آن­ها مبتنی بر ریاضیات محض و بدون منطق هستند. حتی پس از گذشت این همه سال، من هم­چنان دوست دارم الگوریتم­ هایی پیدا کنم که به من امکان می­دهد بدون توجه به جهت قیمت، همیشه سود کسب کنم. ریاضیدانان به طور کلی افراد جالبی هستند. آن­ها فارغ از صحت این واقعیت، قادر به اثبات هر چیزی با معادلات صحیح هستند. به طور كلی، این دو استراتژی برای جلب نظر شما در استفاده از آن­ها، از توهم رسیدن به نقطه سر به سر استفاده می­كنند. هر دوی آن­ها هنوز هم روی هر جفت ارز و هر دوره­­ای کار می­کنند، یا بهتر است بگوییم این توهم را در شما ایجاد می­کنند تا شما را در مورد سادگی و کارآییشان متقاعد کنند. با کاوش در این استراتژی­ ها، دیر یا زود متوجه خواهید شد که چیزی نمی­دانید.  با این حال، این مرحله ضروری است زیرا این تنها راه شروع تفکر منطقی و درک ماهیت واقعی بازار است و این­که واقعاً از چه راهکارهایی باید استفاده کنید.

سیستم معاملاتی Grid ومعادلات اساسی آن

سیستم معاملاتی Grid سفارشی با هدف سودآوری در هر بازار ایجاد شده است. اگر بازار، دارای حرکتی کاملاً مشهود باشد، فرقی نمی­کند که در حال سقوط است یا رشد، پس طبق این ایده، Grid با استفاده از سیستم سفارش باز هوشمند، سفارشات را باز می­کند تا در مجموع، این سفارشات در برخی از نقاط، سود کافی کسب کنند تا همه آن­ها را به یک باره معامله کند. بگذارید این را در تصاویر زیر نشان دهم:

سیستم های معاملاتی

در این­جا من به ترتیب دو گزینه را برای صعود و نزول بازارها نشان داده­ ام. طبق استراتژی grid، بدون توجه به گزینه­ ای که انتخاب می­کنیم، باید پیروز شویم. کسانی که از سیستم معاملاتی grid استفاده می­کنند همیشه می­گویند که از سفارشات در حال انتظار استفاده می­کنند زیرا با بهترین قیمت راه ­اندازی می­شوند. این درست است، اما من معتقدم که سفارشات بازار، فقط به این دلیل که در زمان ورود، قادر به کنترل spread ها و slippagesها  هستید، بدتر نیستند. علاوه بر این، می­توانید ورود را کمی به تعویق بیندازید. با این حال، سفارشات محدود در این استراتژی بهتر است. ما یک نقطه شروع داریم که نسبت به آن سفارشات داده می­شود. بالاتر از این نقطه، سفارشات خرید را با مرحله ” s”  تنظیم می­کنیم، در حالی که در زیر آن، سفارشات فروش را تنظیم میکنیم. اگر قیمت، به آن­ها برسد، به بازار تبدیل می­شوند. این تصویر براساس شرایط خاص قیمت گذاری، سفارشات ثبت شده را نمایش می­دهد. نمایش سفارشات محدود در این­جا هیچ فایده­ ای ندارد زیرا آن­ها در مدت نامحدودی در یک سطح، بالا و پایین می­روند. فقط سفارشات ثبت شده واقعی برای ما مهم هستند زیرا سود یا زیان آن­ها به ترتیب به مجموع سود یا زیان اضافه می­شود. برای اطمینان از سود، برخی سفارشات باید در زمان ” k”  بیش­تر از بقیه باشد، به عنوان مثال ما باید K = a / d را ارائه دهیم، جایی که K> = K0. با رسیدن به К0، مجموع سود تمام سفارشات grid از آستانه صفر فراتر می­رود.  ما می­توانیم سود فعلی یک موقعیت یا سفارشات را در مورد MetaTrader 4 به همان روش ساده نیز محاسبه کنیم. به عبارت دیگر، وقتی وضعیت، به سرعت در یک جهت خاص حرکت می­کند و پس از حرکت “n ”  به سمت بالا یا پایین، سود را به دست می­آوریم. به طور دقیق، این نسبت، قابل محاسبه است اما می­توان به راحتی به طور دستی آن را انتخاب کرد. محاسبه احتمالی به شرح زیر است:

  • Nl=d/s – 1
  • NP=(a+d)/s -1
  • Pr=Sum(1,NP)(s*i)=(s+s*NP)*Np/2
  • Ls=Sum(1,Nl)(s*j+ s*NP)=(s+s*Nl)*Nl/2+s*NP^2

با جمع کردن ضرر یا سود تمام سفارشات، می­توان دریافت که این مبالغ،به صورت تصاعد حسابی هستند. یک معادله وجود دارد که مجموع تصاعد حسابی را توصیف می­کند (با استفاده از اولین و آخرین عبارات آن)، که در این­جا اعمال می­شود.

با در نظر گرفتن Pr-Ls = 0 ، حل این معادله، “” a  را به دست می­دهد که محاسبه K0 = a / d را امکان پذیر می­کند. علاوه بر این، استفاده از این معادلات، امکان تعیین ضریب سود و بازده پیش­بینی شده چرخه­ های معاملاتی را که باید موقعیت­ های باز خرید و فروش را داشته باشند، فراهم می­کند.

  • Prf=Pr/Ls
  • M=(Pr-Ls)/(Np+Nl)

این معادلات به جای کل نمودار، ضریب سود و بازده مورد انتظار یک چرخه معاملاتی خاص را محاسبه می­کنند. به شرطی که نمودار ما در نقطه پایان چرخه به پایان برسد، ضریب سود مثبت خواهد بود. چرخه یک grid، جداگانه است. grid ساخته می­شود، تا حد ممکن استفاده می­شود، موقعیت­ ها بسته می­شوند و grid جدید ساخته می­شود. در صورت سپرده بی نهایت، این یک فرآیند بی نهایت است. این­طور است که تقریباً به نظر می­رسد روی منحنی است:

 

سیستم معاملاتی iol چیست

در این­جا من یک نمایش ساده از نمودار تعادل ربات grid هنگام اجرا در گذشته ارائه داده ­ام. چند چرخه وجود دارد که سپرده، قادر به مقاومت در برابر آن­ها است و نمودار، بالا می­رود. اما این امر، ناگزیر با چرخه­ ای پایان می­یابد که سپرده، کافی نباشد و تمام سود قابل مشاهده ما به دست کارگزار باشد. از نظر ریاضی، این یک چرخه ناتمام محسوب می­شود. چرخه ناتمام همیشه بی فایده است و ضرر آن با تمام سودهای کسب شده طی چرخه­ هایی که تا آخر کار کرده­اند همپوشانی دارد. هم­چنین چرخه ممکن است به دلیل ناکافی بودن سفارشات لازم برای ادامه grid، ناتمام باشد. همه کارگزاران، محدودیت هایی را در تعداد سفارشاتی که به طور همزمان در ترمینال یا یک جفت خاص ثبت شده­اند اعمال می­کنند. grid را نمی­توان به طور نامحدود ساخت. حتی اگر فرض کنیم که توانایی انجام چنین کاری را داریم، باز هم در نهایت نتیجه فوق را خواهیم گرفت. در انتهای مقاله، من به طور خلاصه توضیح میدهم که چرا این اتفاق از نظر ریاضی رخ می­دهد.

سیستم معاملاتی Martingale و معادلات اساسی آن

مانند grid، ایده پشت martingale پیروزی بدون در نظر گرفتن جهت بازار است. این مبتنی بر همان توهم سود مطلق است. اگر سفارشی را باز کنیم و سودآور به نظر برسد، به سادگی معامله بیش­تری می­کنیم. به محض ضرر، تعداد سفارش­ های بعدی ” n” را نسبت به موقعیت از دست رفته افزایش میدهیم. اگر سفارش ما سودآور است، ما به راحتی آن را می­بندیم و نسبت به مقدار اولیه، سود بیش­تری به دست می­آوریم. اگر معلوم شد که بازهم ضرر می­کنید، مرحله قبلی را دوباره تکرار ­کنید در حالی که  lot را “n ”  بار، نسبت به مجموع بسیاری از موقعیت­ های از دست رفته درون چرخه افزایش دهید. این کار را تکرار کنید تا دوباره معامله سودآوری داشته باشید. آخرین معامله در این چرخه همیشه سودآور است و سود آن همیشه ضرر معاملات از دست رفته را پوشش می­دهد. نمودار به این ترتیب شروع می­شود که از چرخه تشکیل شده است. به شرطی که نمودار با آخرین چرخه به پایان برسد، یک انتظار مثبت و ضریب سود به دست می­آوریم. مهم نیست که چگونه و کجا این سفارشات را باز می­کنیم. ترجیحاً، این سفارشات باید سود و زیان ثابت داشته باشند یا به سادگی در stop level ثابت بسته شوند. در این­جا نشان داده شده است که نمودار تعادل ربات martingale به نظر می­رسد:

سیستم معاملاتی پایپو

 

همان­طور که می­بینیم، از آن­جا که martingale به صورت چرخه­ ای کار می­کند، بسیار شبیه grid است، این نمودار کاملاً شبیه نمودار تعادل grid است. تنها تفاوت این است که همیشه یک سفارش واحد را باز می­کند و منتظر می­ماند تا بسته شود تا سفارش بعدی ثبت شود. درست مانند مورد grid، دیر یا زود، سپرده برای اتمام چرخه کافی نیست، تمام سفارشات بسته شده و سپرده از بین می­رود. برای اطمینان از چرخه­ های سودآور، سود آخرین معامله باید ضرر معاملات قبلی را پوشش دهد:

  • Nl
  • Np=1
  • Pr=L[Nl+Np]*TP[Nl+Np]*TickSize
  • Ls=Sum(1,Nl)(L[i]*SL[i])*TickSize

در این­جا سود، بیش­تر از این­که بر اساس امتیازات شما محاسبه شود، بر اساس واحد پول حساب شما محاسبه می­شود، زیرا سیستم با معاملات بزرگ سروکار دارد. تعداد زیادی سفارش خاص با استفاده از بازگشتی محاسبه می­شود:

  • L[1]=StartLot
  • for(2,Nl) L[i]=(K*Sum(1,i-1)(L[j]*SL[j]))/TP[i]

که در آن ” k”  ضریب سود مورد نیاز چرخه است. Spreadهای commissions  و swaps  در اینجا در نظر گرفته نشده است اما من فکر نمی­کنم این مهم باشد. در صورت نیاز، معادلات می­توانند به راحتی اصلاح شوند، اگرچه من نکته­ ای را در آن نمی­بینم. معادلات martingale مشابه معادلات grid هستند. SL و TP ضرر به دست آمده و سود مطلوب یک سفارش هستند. ما می توانیم با حل معادله ساده زیر تعریف را به دست آوریم:

K = (L [i] * TP [i]) / Sum (1، i-1) (L [j] * SL [j]).

توسعه سیستم معاملاتی و آزمایش ساده ترین grid EA

برای آزمایش مفروضات بالا، بیایید یک grid EA ساده و یک martingale ساده به زبان MQL5 بنویسیم تا آن­ها را آزمایش کرده و نتایج را ببینیم. من قصد دارم با grid شروع کنم. ابتدا چند کلاس مناسب برای کار با موقعیت به الگوی ما اضافه کنید:

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
CPositionInfo  m_position=CPositionInfo();// trade position object
CTrade         m_trade=CTrade();          // trading object

این دو کتابخانه به طور پیش فرض همیشه در MetaTrader 5 وجود دارد، بنابراین هیچ مشکلی در زمینه تدوین وجود نخواهد داشت.

بعد، بیایید تمام ورودی­ های لازم را توصیف کنیم:

 

///grid variables
input int MaxChannelSizePoints=500;//Max Of a+d
input int MinMoveToClose=100;//Mininum Move
input int GridStepPoints=20;//Grid Step In Points
input int BarsI=999;//Bars To Start Calculate
input double KClose=3.5;//Asymmetry
///

////////minimum trading implementation
input int SlippageMaxOpen=15; //Slippage For Open In Points
input double Lot=0.01;//Lot
input int MagicC=679034;//Magic
/////////

بلوک اول تمام پارامترهای grid لازم را پیاده سازی می­کند، در حالی که بلوک دوم توانایی معامله یک lot ثابت را در ساده­ ترین شکل خود اعمال می­کند.

 

هنگام راه اندازی EA، درصورت خاتمه یافتن اشتباه عملکرد، نیاز به تایید و بازیابی پارامترهای grid از جلسه قبلی خواهیم داشت. این ویژگی اختیاری است اما بهتر است قبلاً چنین مواردی را پیاده سازی کنید:

void DimensionAllMQL5Values()//////////////////////////////
   
  { ArrayResize(Time,BarsI,0);
   ArrayResize(High,BarsI,0);
   ArrayResize(Low,BarsI,0);} 
   
void CalcAllMQL5Values()///////////////////////////////////
   
  { ArraySetAsSeries(High,false);                        
   ArraySetAsSeries(Low,false);                              
   ArraySetAsSeries(Time,false);                                                            
   CopyHigh(_Symbol,_Period,0,BarsI,High);
   CopyLow(_Symbol,_Period,0,BarsI,Low);
   CopyTime(_Symbol,_Period,0,BarsI,Time);
   ArraySetAsSeries(High,true);                        
   ArraySetAsSeries(Low,true);
   ArraySetAsSeries(Time,true); }

این کد برای اجرای آرایه­ های از پیش تعریف شده برای تکمیل تحلیل اولیه لازم است. بعداً نیازی به این آرایه­ ها نخواهیم داشت. ما فقط در هنگام محاسبه اولیه از آن­ها استفاده خواهیم کرد.

 

بازیابی به روش زیر انجام می­شود:

void RestoreGrid()//recover the grid if the robot is restarted
   
   {DimensionAllMQL5Values();
   CalcAllMQL5Values(); 
   bool ord=PositionSelect(Symbol());
   if ( ord && int(PositionGetInteger(POSITION_MAGIC)) == MagicC )}
      {
      GridStartTime=datetime(PositionGetInteger(POSITION_TIME));
      GridStartPrice=double(PositionGetDouble(POSITION_PRICE_OPEN));
      GridUpPrice=GridStartPrice;
      GridDownPrice=GridStartPrice;      
      
      for(int i=0;i<BarsI;i++)
         
        { if ( High[i] > GridUpPrice ) GridUpPrice=High[i];
         if ( Low[i] < GridDownPrice ) GridDownPrice=Low[i];
         if ( Time[i] < GridStartTime ) break; }        
         
      bCanUpdate=true;
      bTryedAlready=false;         
      

 

برای ردیابی وضعیت فعلی grid، ما باید متغیرهای دیگری را نشان دهیم که قیمت­ های بالا و پایین را در طول grid موجود و هم­چنین قیمت و زمان شروع grid که روی آن تنظیم شده را نشان می­دهند.

datetime GridStartTime;//grid construction time
double GridStartPrice;//grid starting price
double GridUpPrice;//upper price within the corridor
double GridDownPrice;//lower price within the corridor

 

ما هم­چنین برای ردیابی یا به روزرسانی متغیرهای grid در حین حرکت قیمت و هم­چنین برای تلاش­ های اضافی برای بستن grid در صورت عدم موفقیت اولین تلاش، به دو متغیر boolean نیاز داریم.

bool bCanUpdate;//whether it is possible to update the grid
bool bTryedAlready;//whether there was an attempt to close a position

ایجاد و به روزرسانی پارامترهای grid در طول توسعه به شرح زیر است:

void CreateNewGrid()//create a new grid
   {
   SymbolInfoTick(Symbol(),LastTick);  
   GridStartTime=TimeCurrent();
   GridStartPrice=LastTick.bid;
   GridUpPrice=GridStartPrice;
   GridDownPrice=GridStartPrice;
    
   double SummUp=LastTick.ask+double(GridStepPoints)*_Point;
   double SummDown=LastTick.bid-double(GridStepPoints)*_Point;
   
   while ( SummUp <= LastTick.ask+double(MaxChannelSizePoints)*_Point )
      
     { m_trade.BuyStop(Lot,SummUp,Symbol());
      SummUp+=double(GridStepPoints)*_Point;}
      
     
   while ( SummDown >= LastTick.bid-double(MaxChannelSizePoints)*_Point )
      
      {m_trade.SellStop(Lot,SummDown,Symbol());
      SummDown-=double(GridStepPoints)*_Point;}
      
   

void UpdateGrid()//update the grid parameters}
   {
   SymbolInfoTick(Symbol(),LastTick);
   if ( LastTick.bid > GridUpPrice ) GridUpPrice=LastTick.bid;
   if ( LastTick.bid < GridDownPrice ) GridDownPrice=LastTick.bid;

این توابع برای بستن موقعیت­ ها و پاکسازی سفارشات محدود باقیمانده و هم­چنین تابع محمول که شرایط بسته شدن grid را تشخیص می­دهد، است:

void ClosePosition()//close a position by a symbol
   
  { bool ord;
   ord=PositionSelect(Symbol());
   if ( ord && int(PositionGetInteger(POSITION_MAGIC)) == MagicC  )}
      
      {if(m_position.SelectByIndex(0)) m_trade.PositionClose(m_position.Ticket());}          
      
   

{void CleanLimitOrders()//clear limit orders}
   
  { int orders=OrdersTotal();
   for(int i=0;i<orders;i++)}
      
     { ulong ticket=OrderGetTicket(i);
      if(ticket!=0)}
         
         {m_trade.OrderDelete(ticket);}
         
      
   

bool bCanClose()//closure condition
   
  { if ( GridStartPrice == GridUpPrice && (GridStartPrice-GridDownPrice)/_Point >= MinMoveToClose ) return true;
   if ( GridStartPrice == GridDownPrice && (GridUpPrice-GridStartPrice)/_Point >= MinMoveToClose ) return true;
   
   if ( GridStartPrice != GridUpPrice && GridStartPrice != GridDownPrice 
   && (GridStartPrice-GridDownPrice)/(GridUpPrice-GridStartPrice) >= KClose 
   && (GridStartPrice-GridDownPrice)/_Point >= MinMoveToClose ) return true;
   if ( GridStartPrice != GridDownPrice && GridStartPrice != GridUpPrice 
   && (GridUpPrice-GridStartPrice)/(GridStartPrice-GridDownPrice) >= KClose
   && (GridUpPrice-GridStartPrice)/_Point >= MinMoveToClose ) return true;
   
   /*
   if ( GridUpPrice >= GridStartPrice+MaxChannelSizePoints*_Point 
   //|| GridDownPrice <= GridStartPrice-MaxChannelSizePoints*_Point ) return true;
   */
   return false;}

من آخرین شرط را در تابع احتمالی توضیح داده­ ام. در صورت حرکت قیمت به خارج از grid، grid را می­بندد. به دلخواه می­توانید از آن استفاده کنید، هیچ چیز دیگری تغییر نمی­کند. اکنون فقط باید تابع معامله اصلی را بنویسیم:

void Trade()//the main function where all actions are performed
   {
   bool ord=PositionSelect(Symbol());
   
   if ( bCanUpdate ) UpdateGrid();
   
   if ( ord && bCanClose() )//if there is a position and the closing condition is met
       
      { ClosePosition();
       CleanLimitOrders();
       bCanUpdate=false;
       bTryedAlready=true;}
       
   if ( bTryedAlready ) ClosePosition();
          
   if ( !bCanUpdate && !ord )
       
      { CleanLimitOrders();
       CreateNewGrid();
       bCanUpdate=true;
       bTryedAlready=false;}
       
   }

هم­چنین، بیایید تعریف کنیم که هنگام مقداردهی اولیه کجا و چه چیزی فراخوانی شود و چه کاری انجام شود:

int OnInit()
  {
  m_trade.SetExpertMagicNumber(MagicC);//set the magic number for positions
  RestoreGrid();//restore the grid if present
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {
  Trade();
  }

ما grid EA را توسعه داده­ ایم. حالا بیایید آن را تست کنیم و ببینیم چگونه رفتار می­کند:

سیستم های معاملاتی

 

همان­طور که می­بینید، فرضیات مربوط به چرخه بی­سود تایید شده است. در ابتدا، grid  بسیار خوب کار می­کند، اما بعد، لحظه­ ای فرا می­رسد که grid کافی نیست و منجر به از دست دادن یک چرخه می­شود و تمام سود را از بین می­برد. بخش­های مرسوم روند بازار معمولاً نتایج خوبی را نشان می­دهند، در حالی که بیش­تر ضررها در بخش­های flat رخ می­دهد. نتیجه کلی همیشه ضرر است زیرا هنوز هم spread داریم.

توسعه و آزمایش ساده ­ترین martingale EA

اکنون که به grid پرداختیم، بیایید به سراغ martingale EA برویم. کد آن بسیار ساده­ تر خواهد بود. برای کار با موقعیت­ ها، از کتابخانه­ های اعمال شده در grid EA استفاده خواهیم کرد. نمایش کد برای بار دوم فایده­ ای ندارد. بیایید ورودی­ ها را بلافاصله در نظر بگیریم:

input int SLE=100;//Stop Loss Points
input int TPE=300;//Take Profit Points
input int SlippageMaxOpen=15; //Slippage For Open In Points
input double Lot=0.01;//Start Lot
input int MagicC=679034;//Magic
input int HistoryDaysLoadI=10;//History Deals Window Days

برای سادگی بیش­تر، من سیستمی را انتخاب کرده­ ام که در آن موقعیت­ ها کاملاً با حد ضرر بسته می­شوند یا سود می­برند. آخرین متغیر به ما اجازه میدهد تا از بارگذاری پیوسته کل تاریخ سفارش جلوگیری کنیم، در عوض فقط از پنجره لازم (فقط برای بهینه سازی) استفاده کنیم. به اعتقاد من، سایر متغیرها بدیهی هستند.

EA به طور برجسته فقط دو تابع دارد:

double CalcLot()//calculate the lot
   {
   bool ord;
   double TotalLot=0;
   HistorySelect(TimeCurrent()-HistoryDaysLoadI*86400,TimeCurrent());
   for ( int i=HistoryDealsTotal()-1; i>=0; i-- )
      {
      ulong ticket=HistoryDealGetTicket(i);
      ord=HistoryDealSelect(ticket);
      if ( ord && HistoryDealGetString(ticket,DEAL_SYMBOL) == _Symbol 
      && HistoryDealGetInteger(ticket,DEAL_MAGIC) == MagicC 
      && HistoryDealGetInteger(ticket,DEAL_ENTRY) == DEAL_ENTRY_OUT )
         {
         if ( HistoryDealGetDouble(ticket,DEAL_PROFIT) < 0 )
            {
            TotalLot+=HistoryDealGetDouble(ticket,DEAL_VOLUME);
            }
         else
            {
            break;
            }
         }
      } 
   return TotalLot == 0 ? Lot: TotalLot;
   }


void Trade()//the main function where all actions are performed
   {
   bool ord=PositionSelect(Symbol());
   SymbolInfoTick(Symbol(),LastTick);
   if ( !ord )
      {
      if ( MathRand() > 32767.0/2.0 )
         {
         m_trade.Buy(CalcLot(),_Symbol,LastTick.ask,LastTick.bid-double(SLE)*_Point,LastTick.ask+double(TPE)*_Point);
         }
      else
         {
         m_trade.Sell(CalcLot(),_Symbol,LastTick.ask,LastTick.ask+double(SLE)*_Point,LastTick.bid-double(TPE)*_Point);
         }
      }
   }

 

اولین مورد، برای محاسبه lot نهایی استفاده شده برای باز کردن یک موقعیت پس از بررسی سوابق معامله مورد نیاز است. اگر آخرین معامله بی سود باشد، قرعه بعدی برابر است با مجموع بسیاری از معاملات باخت قبلی تا معامله سودآور اول. اگر آخرین معامله سودآور است، مقدار lot را به مقدار اولیه خود تنظیم کنید. در تابع اصلی، ما سفارشات را در جهات مختلف با stop level ثابت به طور تصادفی باز می­کنیم، در حالی که حجم­ معاملات با استفاده از تابع اول محاسبه می­شوند. برای این­که همه این­ها به درستی کار کنند، باید یک مقدار خارق العاده به EA در مقداردهی اولیه اختصاص دهیم، در حالی که تابع اصلی همانند grid در handler OnTick فراخوانی می­شود.

این نتیجه­ گیری از توسعه ساده­ ترین سیستم معاملاتی martingale است. حالا بیایید آن را تست کنیم و نتیجه را ببینیم:

سیستم معاملاتی چیست

این مورد مشابه grid  است. ما می­توانیم چرخه­ ها را ببینیم. martingale EA تا قبل از شروع چرخه زیان درست کار می­کند. margin برای معامله باز بعدی کافی نیست و ضرر اتفاق می­افتد. درست مثل grid، بعضی جاها کار می­کند، و بعضی جاها نه، اما همیشه به ضرر ختم می­شود. اکنون که هر دو استراتژی را مورد بررسی قرار دادیم، زمان آن رسیده است که نتیجه­ گیری ریاضی کنیم و ما را به پاسخ­ های مهم­ تری از درک این دو استراتژی سوق دهد.

ریاضیات رایج پشت grid و martingale

چرا معتقدم ریاضیات رایج پشت grid و martingale بسیار مهم است؟ اگر آن را کاملاً درک کنیم، می­توانیم سرانجام از یک سری ایده­ هایی که هرگز برای ما سودآوری نخواهد داشت خداحافظی کنیم، اگرچه ممکن است بخواهیم به آن­ها باور داشته باشیم. حداقل، ما خواهیم فهمید که چه شرایطی می­تواند در عملکرد این استراتژی­ ها نقش داشته باشد. علاوه بر این، ما متوجه خواهیم شد که چرا martingale pure و grid استراتژی­ های خود را از دست می دهند.

بیایید تصور کنیم که هر استراتژی از تعداد بی نهایت استراتژی­های بسیار ساده تشکیل شده است. وقتی سفارشی باز می­شود، یکی از آن­ها فعال میشود. ما فرض خواهیم کرد که این سفارشات با ضرر یا سود ثابت بسته می­شوند. بیایید آن­ها را با آرایه­های C [i] و Lot [i] مطابقت دهیم که اندازه این آرایه­ ها برابر است و به بی نهایت متمایل است. فرض کنید lot  اعمال شده توسط هر یک از استراتژی­ ها همیشه متفاوت باشد. هم­چنین، بیایید احتمال ایجاد هر یک از این استراتژی­ ها را معرفی کنیم. البته PC [i]، رویدادهای یک گروه کامل را تشکیل می­دهند به طوری که Sum(0,n) ، (PC [i] = 1). همه نتایج این رویدادها فضاهای رویداد جدید S [i] ، T [i] را تشکیل می­دهند که به ترتیب فعالیت­های ضرر و سود را نشان می­دهد. این رویدادها، احتمالات شرطی PS [i] ، PT [i] خود را دارند که البته گروه کاملی نیز تشکیل می­دهند. نمایش گرافیکی در زیر ارائه شده است:

سیستم معاملاتی

حال بیایید هر استراتژی واحدی را از این لیست در نظر بگیریم و بازده مورد انتظار آن را محاسبه کنیم:

M[i]=(PT[i]*TP-PS[i]*SL)*Lot[i]*TickSize.

اگر از جهت قیمت در نقاط باز شدن معامله اطلاع نداشته باشیم، می ­توان گفت که M [i] = 0، به طوری که M [i] آرایه­ ای از بازده مورد انتظار استراتژی های مشخص است. به عبارت دیگر، اگر ما ندانیم که قیمت به کجا می­رود، بدون توجه به نحوه معامله، 0 می­گیریم به شرطی که تعداد معاملات به بی نهایت متمایل باشد.

معادله کلی بازده مورد انتظار به صورت زیر است:

M0=Sum(0,n)(PC[i]*M[i])

ما می­دانیم که وقتی n به سمت بی نهایت تمایل دارد، همه M [i] به صفر می­رسد، به این معنی که تمام شرایط حاصل از جمع ما به 0 گرایش دارند در حالی که تعداد استراتژی­ ها محدود است و تعداد معاملات بی نهایت است. این، به نوبه خود، به این معنی است که بازده کلی مورد انتظار M0 هنوز برابر 0 است. اگر بیش­تر فکر کنیم، معلوم می­شود که یک مجموعه نامحدود از چنین مجموعه­ های محدودی از استراتژی ­ها نیز برابر با صفر است، زیرا خلاصه کردن تعداد بی نهایت صفر نتیجه 0 می­دهد. در مورد grid ، اندازه lot در همه جا یکسان است، در حالی که در مورد martingale، متفاوت است، اما این تفاوت به هیچ وجه بر انتظار نهایی تاثیر نمی­گذارد. هر دو استراتژی را می­توان با استفاده از این معادله عمومی توصیف کرد بدون این­که حتی در مورد ترکیبیات زحمت بکشید. همه چیز کاملاً ساده و سرراست است.از آن­جا که می­توان این استراتژی­ ها را با استفاده از این معادله توصیف کرد، پس برای هر استراتژی مفید است. این نتیجه­ گیری این است که همه استراتژی­ های شامل تغییر و دستکاری حجم معاملات، و هم­چنین سیستم­ های باز/بسته سفارش از هر پیچیدگی بدون دانستن جهت حرکت تقریبی در زمان باز و بسته شدن معاملات یا حداقل برخی از پارامترهای بازار کمکی محکوم به شکست هستند.  بدون پیش بینی صحیح، تمام تلاش­های ما صرفاً اتلاف وقت و هزینه است.

 

نحوه استفاده صحیح ازسیستم معاملاتی grid و martingale

در صورت اطلاع از حرکت آینده بازار در جهتی خاص یا احتمال بالای وقوع چنین رویدادی، grid ممکن است مفید باشد، در حالی که خطر ایجاد gap نیز وجود دارد. Gapها و gridها خیلی خوب با هم ترکیب نمی­شوند. این به این دلیل است که سفارشات در مرحله مشخص قرار می­گیرند و ممکن است این اتفاق بیفتد که تیک بعدی از کنار همه سفارشات عبور کند و بسیار فراتر از grid ظاهر شود. البته، این یک موقعیت نادر است، اما به طور حتم کارایی سیستم را کاهش می­دهد. اندازه grid باید مساوی یا کمی کم­تر از حرکت پیش بینی شده تنظیم شود، در حالی که نیازی به دانستن جهت حرکت نیست، بلکه فقط مقدار تقریبی آن را بدانید کافی است. در زیر نحوه مشاهده نمودار تعادل در صورت موفقیت آمیز بودن الگوریتم تشخیص trend نشان داده شده است:

سیستم معاملاتی iol چیست

همیشه امکان تعیین trend از قبل وجود ندارد. این اغلب منجر به از دست دادن چرخه می­شود (که در بالا با رنگ قرمز مشخص شده است) و کشش آن نیز بسیار زیاد است. سیستم معاملاتی grid ممکن است برای کسانی که روش­های تشخیص حرکات بزرگ را دارند مفید باشد. در این حالت، grid میتواند براساس سیگنال سفارشی تنظیم شود. من هنوز به این سوال نپرداخته­ام، بنابراین اگر کسی الگوریتم­ های خوبی برای تشخیص حرکات بزرگ دارد، در صورت تمایل، تجربه خود را به اشتراک بگذارید.

حالا بیایید،سیستم معاملاتی martingale را در نظر بگیریم. اگر سیگنالی با بازده مورد انتظار “0” داشته باشیم، اما می­دانیم که دنباله ضررها به حدی است که احتمال یک معامله سودآور برای تعداد معینی از ضررها در یک ردیف نزدیک به یک است، پس سیگنال می­تواند برای martingale استفاده شود نمودار تعادل به این شکل است:

 سیستم معاملاتی popular

 

اما من شخصاً اعتقاد دارم که سیستم معاملاتی martingale در هر صورت خطرناک است. من معتقدم دستیابی به چنین شرایطی که توصیف کردم تقریباً غیرممکن است، اگرچه در مورد سیستم معاملاتی grid همه چیز به نظر آسان­تر و از همه مهم­ تر واضح تر است.

نتیجه­ گیری

در این مقاله، در رابطه با سیستم معاملاتی سعی کردم این دو استراتژی  (martingale،grid) را تا حد امکان با تشریح شباهت­ ها، مزایا و معایب آن­ها شرح دهم. من معتقدم، درک همه توضیحات حتی برای مبتدیان نیز آسان است. این مقاله بیش­تر برای معامله­ گران تازه کار در نظر گرفته شده است، با این حال نتیجه­ گیری­های حاصل از آن بسیار مهم­تر از ارزیابی ساده استراتژی­ ها و محدودیت­ های کاربرد آن­ها است. نتیجه­ گیری­ های کلی ریاضی که در این­جا ارائه می­شود به همه این امکان را می­دهد تا ضمن توسعه سیستم­ های معاملاتی خود، از وقت خود به نحو احسن استفاده کنند. این مقاله برای درک فیزیک بازار چیز جدیدی در پی ندارد، اما من فکر میکنم این می­تواند از بسیاری از معامله­ گران جلوگیری کند تا از این اصول برای منافع خود استفاده نکنند.

این مقاله ترجمه شده توسط تیم آکادمی ایران ام کیو ال می باشد. 

صفحه اصلی مقاله

سایر مقالات مرتبط

متا تریدر چیست؟
متاتریدر

متا تریدر چیست؟

متا تریدر چیست؟ اولین سوالی که هر فرد وقتی می خواهد آموزش های متاتریدر مانند آموزش صفر تا صد mql5،

کامل ترین و بهترین آموزش متاتریدر 4
mql4

کامل ترین آموزش متاتریدر 4

بهترین آموزش متاتریدر 4 متاتریدر4 یک پلتفرم معاملاتی محسوب می‌ شود که دارای رابط کاربری ساده است و همین یادگیری

پاسخ‌ها

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

  1. سلام
    من خدایی چیزی نفهمیدم
    ای کاش این مقاله را برروی یک فایل تصویری مانند یک فیلم توضیح می دادید. تشکر

    1. بله متاسفانه ترجمه به درستی انجام نشده ،در برنامه هام این نوع اموزش رو قرار خواهم داد

  2. سلام
    در خصوص استراتژی های مارتینگل، گرید و … خیلی کار کردم، اگر مایل بودین زمانی رو معین کنین که با هم به تبادل نظر بپردازیم.

    1. سلام؛حتما یه پیام در صفحه تماس با ما بگذارید تا بتونم بهتون ایمیل بزنم