English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5 Cookbook: ОСО Talimatları

MQL5 Cookbook: ОСО Talimatları

MetaTrader 5Örnekler | 14 Ocak 2022, 13:38
413 0
Denis Kirichenko
Denis Kirichenko

Giriş

Bu makale, OCO gibi bu tür bir talimat çifti ile ilgilenmeye odaklanmaktadır. Bu mekanizma, MetaTrader 5 ile rekabet eden bazı alım satım terminallerinde uygulanmaktadır. OCO talimatlarının işlenmesi için bir panele sahip bir EA oluşturma örneğinde iki amaç güdüyorum. Bir yandan Standart Kitaplığın özelliklerini açıklamak, diğer yandan bir yatırımcının araç setini genişletmek istiyorum.


1. OCO Talimatlarının Özü

OCO talimatları (biri diğer talimatı iptal eder) bekleyen iki talimatı temsil eder.

Karşılıklı iptal işleviyle bağlanırlar: ilki tetiklenirse ikincisi kaldırılmalıdır ve bunun tersi de geçerlidir.

Şek. 1 Çift OCO talimatı

Şek. 1 Çift OCO talimatı

Şekil 1, basit bir talimat karşılıklı bağımlılık şemasını göstermektedir. Temel bir tanımı yansıtır: Her iki talimat talimat var olduğu sürece bir çift vardır. Mantık açısından çiftin herhangi bir [bir] talimatı, çiftin varlığı için gerekli ancak yeterli olmayan bir koşuldur.

Bazı kaynaklar, çiftin bir limit talimatı ve bir durdur talimatı olması gerektiğini, ayrıca talimatların tek yönlü (al veya sat) olması gerektiğini söylüyor. Bana göre bu tür kısıtlamalar, esnek alım satım stratejilerinin oluşturulmasına yardımcı olamaz. Çiftte çeşitli OCO talimatlarının analiz edilmesini ve en önemlisi bu çifti programlamaya çalışmamızı öneriyorum.


2. Programlama Talimat Çifti

Benim düşünceme göre, ООP araç seti, OCO talimatları üstündeki kontrol ile bağlantılı programlama görevleri için mümkün olan en uygunudur.

Aşağıdaki bölümler amacımıza hizmet edecek yeni veri türlerine ayrılmıştır. CiOcoObject sınıfı önce gelir.


2.1. CiOcoObject Sınıfı

Bu nedenle, birbirine bağlı iki talimatın kontrolünden sorumlu bir yazılım nesnesi bulmamız gerekiyor.

Geleneksel olarak, CObject abstract sınıfı temelinde yeni bir nesne oluşturalım.

Bu yeni sınıf aşağıdaki gibi görünebilir:

//+------------------------------------------------------------------+
//| Class CiOcoObject                                                |
//| Purpose: a class for OCO orders                                  |            
//+------------------------------------------------------------------+
class CiOcoObject : public CObject
  {
   //--- === Data members === --- 
private:
   //--- tickets of pair
   ulong             m_order_tickets[2];
   //--- initialization flag
   bool              m_is_init;
   //--- id
   uint              m_id;

   //--- === Methods === --- 
public:
   //--- constructor/destructor
   void              CiOcoObject(void){m_is_init=false;};
   void             ~CiOcoObject(void){};
   //--- copy constructor
   void              CiOcoObject(const CiOcoObject &_src_oco);
   //--- assignment operator
   void              operator=(const CiOcoObject &_src_oco);

   //--- initialization/deinitialization
   bool              Init(const SOrderProperties &_orders[],const uint _bunch_cnt=1);
   bool              Deinit(void);
   //--- get id
   uint              Id(void) const {return m_id;};

private:
   //--- types of orders
   ENUM_ORDER_TYPE   BaseOrderType(const ENUM_ORDER_TYPE _ord_type);
   ENUM_BASE_PENDING_TYPE PendingType(const ENUM_PENDING_ORDER_TYPE _pend_type);
   //--- set id
   void              Id(const uint _id){m_id=_id;};
  };

Her bir OCO talimatının çiftinin kendi tanımlayıcısı olacaktır. Değeri, rastgele sayı üreteci aracılığıyla ayarlanır (CRandom sınıfı nesnesi).

Çift başlatma ve başlatmadan kaldırma yöntemleri, arayüz bağlamında endişe vericidir. İlki çifti yaratır (başlatır), ikincisi onu kaldırır (başlangıçtan çıkarır).

CiOcoObject::Init() yöntemi, argüman olarak SOrderProperties türündeki yapıların dizisini kabul eder. Bu tür yapı, çiftteki düzenin özelliklerini temsil eder, yani OCO talimatı.


2.2 SOrderProperties Yapısı

Yukarıda bahsedilen yapının alanlarını ele alalım.

//+------------------------------------------------------------------+
//| Order properties structure                                       |
//+------------------------------------------------------------------+
struct SOrderProperties
  {
   double                  volume;           // order volume   
   string                  symbol;           // symbol
   ENUM_PENDING_ORDER_TYPE order_type;       // order type   
   uint                    price_offset;     // offset for execution price, points
   uint                    limit_offset;     // offset for limit price, points
   uint                    sl;               // stop loss, points
   uint                    tp;               // take profit, points
   ENUM_ORDER_TYPE_TIME    type_time;        // expiration type
   datetime                expiration;       // expiration
   string                  comment;          // comment
  }

Bu nedenle, başlatma yönteminin çalışması için iki öğeden oluşan yapılar dizisini önceden doldurmalıyız. Basitçe ifade edersek programa hangi talimatları vereceğini açıklamamız gerekiyor.

Yapıda ENUM_PENDING_ORDER_TYPE türünün numaralandırması kullanılıyor:

//+------------------------------------------------------------------+
//| Pending order type                                               |
//+------------------------------------------------------------------+
enum ENUM_PENDING_ORDER_TYPE
  {
   PENDING_ORDER_TYPE_BUY_LIMIT=2,       // Buy Limit
   PENDING_ORDER_TYPE_SELL_LIMIT=3,      // Sell Limit
   PENDING_ORDER_TYPE_BUY_STOP=4,        // Buy Stop
   PENDING_ORDER_TYPE_SELL_STOP=5,       // Sell Stop
   PENDING_ORDER_TYPE_BUY_STOP_LIMIT=6,  // Buy Stop Limit
   PENDING_ORDER_TYPE_SELL_STOP_LIMIT=7, // Sell Stop Limit
  };

Genel konuşursak standart ENUM _ORDER_TYPE numaralandırmayla aynı görünür ancak yalnızca bekleyen talimatların veya daha doğrusu bu tür talimatların türlerinin seçilmesine izin verir.

Giriş parametrelerinde ilgili talimat türünü seçerken hatalardan korur (Şekil 2).

Şek. 2. Kullanılabilir talimat türlerinin açılır listesini içeren "Tür" alanı

Şek. 2. Kullanılabilir talimat türlerinin açılır listesini içeren "Tür" alanı

Bununla birlikte, ENUM _ORDER_TYPE standart numaralandırmayı kullanırsak yalnızca bekleyen talimatlarla ilgilendiğimiz için gerekli olmayan bir piyasa talimatı türü (ORDER_TYPE_BUY veya ORDER_TYPE_SELL) belirleyebiliriz.


2.3. Çift başlatılıyor

Yukarıda belirtildiği gibi, talimat çifti başlatma işleminde CiOcoObject::Init() yöntemi devreye girer.

Aslında, talimat çiftini kendisi yerleştirir ve yeni çift oluşumunun başarısını veya başarısızlığını kaydeder. Alım satım işlemlerini kendisi yaptığı için bunun aktif bir yöntem olduğunu söylemeliyim. Pasif yöntem de oluşturabiliriz. Bağımsız olarak yerleştirilmiş, halihazırda aktif bekleyen talimat çiftine bağlanacaktır.

Tüm yöntemin kodunu vermeyeceğim. Ancak, tüm fiyatları (açılış, durdur, kar, limit) hesaplamanın önemli olduğunu belirtmek isterim, bu nedenle CTrade::OrderOpen() alım satım sınıfı yöntemi bir alım satım talimatı gerçekleştirebilir. Bu amaçla iki şeyi dikkate almalıyız: talimat yönü (alış veya satış) ve bir talimat uygulama fiyatının cari bir fiyata (yukarı veya aşağı) göre pozisyonu.

Bu yöntem birkaç özel yöntemi çağırır: BaseOrderType() ve PendingType(). Birincisi talimat yönünü, ikincisi ise bekleyen talimat türünü belirler.

Talimat verilirse bileti m_order_tickets[] dizisine kaydedilir.

Bu yöntemi test etmek için basit bir Init_OCO.mq5 script dosyası kullandım.

#property script_show_inputs
//---
#include "CiOcoObject.mqh"
//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
sinput string Info_order1="+===--Order 1--====+";   // +===--Order 1--====+
input ENUM_PENDING_ORDER_TYPE InpOrder1Type=PENDING_ORDER_TYPE_SELL_LIMIT; // Type
input double InpOrder1Volume=0.02;                  // Volume
input uint InpOrder1PriceOffset=125;                // Offset for execution price, points
input uint InpOrder1LimitOffset=50;                 // Offset for limit price, points
input uint InpOrder1SL=250;                         // Stop loss, points
input uint InpOrder1TP=455;                         // Profit, points
input string InpOrder1Comment="OCO Order 1";        // Comment
//---
sinput string Info_order2="+===--Order 2--====+";   // +===--Order 2--====+
input ENUM_PENDING_ORDER_TYPE InpOrder2Type=PENDING_ORDER_TYPE_SELL_STOP; // Type
input double InpOrder2Volume=0.04;                  // Volume    
input uint InpOrder2PriceOffset=125;                // Offset for execution price, points
input uint InpOrder2LimitOffset=50;                 // Offset for limit price, points
input uint InpOrder2SL=275;                         // Stop loss, points
input uint InpOrder2TP=300;                         // Profit, points
input string InpOrder2Comment="OCO Order 2";        // Comment

//--- globals
CiOcoObject myOco;
SOrderProperties gOrdersProps[2];
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- property of the 1st order
   gOrdersProps[0].order_type=InpOrder1Type;
   gOrdersProps[0].volume=InpOrder1Volume;
   gOrdersProps[0].price_offset=InpOrder1PriceOffset;
   gOrdersProps[0].limit_offset=InpOrder1LimitOffset;
   gOrdersProps[0].sl=InpOrder1SL;
   gOrdersProps[0].tp=InpOrder1TP;
   gOrdersProps[0].comment=InpOrder1Comment;

//--- property of the 2nd order
   gOrdersProps[1].order_type=InpOrder2Type;
   gOrdersProps[1].volume=InpOrder2Volume;
   gOrdersProps[1].price_offset=InpOrder2PriceOffset;
   gOrdersProps[1].limit_offset=InpOrder2LimitOffset;
   gOrdersProps[1].sl=InpOrder2SL;
   gOrdersProps[1].tp=InpOrder2TP;
   gOrdersProps[1].comment=InpOrder2Comment;

//--- initialization of pair
   if(myOco.Init(gOrdersProps))
      PrintFormat("Id of new OCO pair: %I32u",myOco.Id());
   else
      Print("Error when placing OCO pair!");
  }

Burada çiftin gelecekteki talimatlarının çeşitli özelliklerini ayarlayabilirsiniz. MetaTrader 5, altı farklı bekleyen talimat türüne sahiptir.

Bu bağlamda, çiftlerin 15 varyant (kombinasyonu) olabilir (çiftte farklı talimatı olması şartıyla).

C(k,N) = C(2,6) = 15

Tüm varyantlar script dosyası yardımıyla test edilmiştir. Satın Al Durdur - Satın Al Durdur Sınırı çifti için bir örnek vereceğim.

Talimat türleri script dosyası parametrelerinde belirtilmelidir (Şekil 3).


Şek. 3. "Satın Al Durdur Sınırı" talimatı ile "Satın Al Durdur" talimatı çifti

Şek. 3. "Satın Al Durdur Sınırı" talimatı ile "Satın Al Durdur" talimatı çifti

"Expert'ler" kaydında aşağıdaki bilgiler görünecektir:

QO      0       17:17:41.020    Init_OCO (GBPUSD.e,M15) Code of request result: 10009
JD      0       17:17:41.036    Init_OCO (GBPUSD.e,M15) New order ticket: 24190813
QL      0       17:17:41.286    Init_OCO (GBPUSD.e,M15) Code of request result: 10009
JH      0       17:17:41.286    Init_OCO (GBPUSD.e,M15) New order ticket: 24190814
MM      0       17:17:41.379    Init_OCO (GBPUSD.e,M15) Id of new OCO pair: 3782950319

Ancak, döngüye başvurmadan script dosyası yardımıyla OCO talimatlarıyla en üst düzeyde çalışamayız.


2.4. Çiftin Başlatılmaması

Bu yöntem, talimat çifti üzerindeki kontrolden sorumludur. Herhangi bir talimat aktif talimatlar listesinden çıktığında çift "ölecektir".

Bu yöntemin EA kodunun OnTrade() veya OnTradeTransaction() tanıtıcılarına yerleştirilmesi gerektiğini düşünüyorum. Bu şekilde, EA herhangi bir çift talimatının aktivasyonunu gecikmeden işleyebilecektir.

//+------------------------------------------------------------------+
//| Deinitialization of pair                                         |
//+------------------------------------------------------------------+
bool CiOcoObject::Deinit(void)
  {
//--- if pair is initialized
   if(this.m_is_init)
     {
      //--- check your orders 
      for(int ord_idx=0;ord_idx<ArraySize(this.m_order_tickets);ord_idx++)
        {
         //--- current pair order
         ulong curr_ord_ticket=this.m_order_tickets[ord_idx];
         //--- another pair order
         int other_ord_idx=!ord_idx;
         ulong other_ord_ticket=this.m_order_tickets[other_ord_idx];

         //---
         COrderInfo order_obj;

         //--- if there is no current order
         if(!order_obj.Select(curr_ord_ticket))
           {
            PrintFormat("Order #%d is not found in active orders list.",curr_ord_ticket);
            //--- attempt to delete another order                 
            if(order_obj.Select(other_ord_ticket))
              {
               CTrade trade_obj;
               //---
               if(trade_obj.OrderDelete(other_ord_ticket))
                  return true;
              }
           }
        }
     }
//---
   return false;
  }

Bir ayrıntıdan bahsetmek istiyorum. Çift başlatma bayrağı, sınıf yönteminin gövdesinde kontrol edilir. Bayrak temizlenmişse talimatları kontrol etme girişimi yapılmayacaktır. Bu yaklaşım, henüz başka bir talimat verilmemişken bir aktif talimatın silinmesini önler.

Birkaç talimatın verildiği script dosyasına işlevsellik ekleyelim. Bu amaçla, Control_OCO_EA.mq5 test EA'sını oluşturacağız.

Genel konuşursak EA script dosyasından yalnızca kodundaki Trade() olay işleme bloğu ile farklılık gösterecektir:

//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
//--- OCO pair deinitialization
   if(myOco.Deinit())
     {
      Print("No more order pair!");
      //--- clear  pair
      CiOcoObject new_oco;
      myOco=new_oco;
     }
  }

Video, MetaTrader 5 terminalindeki her iki programın çalışmasını gösterir.



Ancak her iki test programının da zayıf yönleri vardır.

İlk program (script dosyası) yalnızca çifti aktif olarak oluşturabilir ancak daha sonra üzerindeki kontrolünü kaybeder.

İkinci program (Expert Advisor) çifti kontrol etse de, ilkinin oluşturulmasından sonra tekrar tekrar başka çiftler oluşturamaz. OCO talimat programını (script dosyası) tam özellikli hale getirmek için araç setini talimat verme fırsatı ile genişletmemiz gerekiyor. Bunu bir sonraki bölümde yapacağız.


3. EA'yı Kontrol Etme

Çiftli talimatların yerleştirilmesi ve parametrelerinin ayarlanması için grafik üzerinde OCO Talimat Yönetim Paneli oluşturalım.

Kontrol eden EA'nın bir parçası olacaktır (Şekil 4). Kaynak kodu Panel_OCO_EA.mq5 içinde bulunur.

Şek. 4. OCO talimatlarını oluşturma paneli: başlangıç durumu

Şek. 4. OCO talimatlarını oluşturma paneli: başlangıç durumu


Gelecekteki bir talimatın türünü seçmeli ve OCO talimat çiftini yerleştirmek için alanları doldurmalıyız.

Ardından panel üzerindeki tek buton üstündeki etiket değişecektir (metin özelliği, Şekil 5).

Şek. 5. OCO talimatlarını oluşturma paneli: yeni çift

Şek. 5. OCO talimatlarını oluşturma paneli: yeni çift


Panelimizi oluşturmak için aşağıdaki Standart Kitaplık sınıfları kullanıldı:

  • CAppDialog ana uygulama iletişim kutusudur;
  • CPanel dikdörtgen bir etikettir;
  • CLabel bir metin etiketidir;
  • CComboBox açılır liste içeren bir alandır;
  • CEdit bir giriş alanıdır;
  • CButton bir butondur.

Tabii ki, üst sınıf yöntemleri otomatik olarak çağrıldı.

Şimdi koda geçiyoruz. Standart Kitaplık'nin gösterge panelleri ve diyaloglar oluşturmaya ayrılmış bölümünün oldukça büyük olduğu belirtilmelidir.

Örneğin bir açılır liste kapatma olayını yakalamak istiyorsanız, çağrı yığınını derinlemesine araştırmanız gerekecektir (Şekil 6).

Şek. 6. Çağrı Yığını

Şek. 6. Çağrı Yığını


Bir geliştirici, belirli olaylar için %MQL5\\Include\\Controls\\Defines.mqh dosyasında makroları ve bir gösterimi ayarlar.

OCO çiftini oluşturmak için ON_OCO özel olayını oluşturdum.

#define ON_OCO (101) // OCO pair creation event 

Gelecekteki talimatların parametreleri doldurulur ve çift OnChartEvent() tanıtıcı gövdesinde oluşturulur. 

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- handling all chart events by main dialog
   myDialog.ChartEvent(id,lparam,dparam,sparam);

//--- drop-down list handling
   if(id==CHARTEVENT_CUSTOM+ON_CHANGE)
     {
      //--- if it is Panel list
      if(!StringCompare(StringSubstr(sparam,0,7),"myCombo"))
        {
         static ENUM_PENDING_ORDER_TYPE prev_vals[2];
         //--- list index
         int combo_idx=(int)StringToInteger(StringSubstr(sparam,7,1))-1;

         ENUM_PENDING_ORDER_TYPE curr_val=(ENUM_PENDING_ORDER_TYPE)(myCombos[combo_idx].Value()+2);
         //--- remember order type change
         if(prev_vals[combo_idx]!=curr_val)
           {
            prev_vals[combo_idx]=curr_val;
            gOrdersProps[combo_idx].order_type=curr_val;
           }
        }
     }

//--- handling input fields
   else if(id==CHARTEVENT_OBJECT_ENDEDIT)
     {
      //--- if it is Panel's input field
      if(!StringCompare(StringSubstr(sparam,0,6),"myEdit"))
        {
         //--- find object
         for(int idx=0;idx<ArraySize(myEdits);idx++)
           {
            string curr_edit_obj_name=myEdits[idx].Name();
            long curr_edit_obj_id=myEdits[idx].Id();
            //--- if names coincide
            if(!StringCompare(sparam,curr_edit_obj_name))
              {
               //--- get current value of field
               double value=StringToDouble(myEdits[idx].Text());
               //--- define gOrdersProps[] array index
               int order_num=(idx<gEditsHalfLen)?0:1;
               //--- define gOrdersProps structure field number
               int jdx=idx;
               if(order_num)
                  jdx=idx-gEditsHalfLen;
               //--- fill up gOrdersProps structure field
               switch(jdx)
                 {
                  case 0: // volume
                    {
                     gOrdersProps[order_num].volume=value;
                     break;
                    }
                  case 1: // execution
                    {
                     gOrdersProps[order_num].price_offset=(uint)value;
                     break;
                    }
                  case 2: // limit
                    {
                     gOrdersProps[order_num].limit_offset=(uint)value;
                     break;
                    }
                  case 3: // stop
                    {
                     gOrdersProps[order_num].sl=(uint)value;
                     break;
                    }
                  case 4: // profit
                    {
                     gOrdersProps[order_num].tp=(uint)value;
                     break;
                    }
                 }
              }
           }
         //--- OCO pair creation flag
         bool is_to_fire_oco=true;
         //--- check structure filling 
         for(int idx=0;idx<ArraySize(gOrdersProps);idx++)
           {
            //---  if order type is set 
            if(gOrdersProps[idx].order_type!=WRONG_VALUE)
               //---  if volume is set  
               if(gOrdersProps[idx].volume!=WRONG_VALUE)
                  //---  if offset for execution price is set
                  if(gOrdersProps[idx].price_offset!=(uint)WRONG_VALUE)
                     //---  if offset for limit price is set
                     if(gOrdersProps[idx].limit_offset!=(uint)WRONG_VALUE)
                        //---  if stop loss is set
                        if(gOrdersProps[idx].sl!=(uint)WRONG_VALUE)
                           //---  if take profit is set
                           if(gOrdersProps[idx].tp!=(uint)WRONG_VALUE)
                              continue;

            //--- clear OCO pair creation flag 
            is_to_fire_oco=false;
            break;
           }
         //--- create OCO pair?
         if(is_to_fire_oco)
           {
            //--- complete comment fields
            for(int ord_idx=0;ord_idx<ArraySize(gOrdersProps);ord_idx++)
               gOrdersProps[ord_idx].comment=StringFormat("OCO Order %d",ord_idx+1);
            //--- change button properties
            myButton.Text("New pair");
            myButton.Color(clrDarkBlue);
            myButton.ColorBackground(clrLightBlue);
            //--- respond to user actions 
            myButton.Enable();
           }
        }
     }
//--- handling click on button
   else if(id==CHARTEVENT_OBJECT_CLICK)
     {
      //--- if it is OCO pair creation button
      if(!StringCompare(StringSubstr(sparam,0,6),"myFire"))
         //--- if to respond to user actions
         if(myButton.IsEnabled())
           {
            //--- generate OCO pair creation event
            EventChartCustom(0,ON_OCO,0,0.0,"OCO_fire");
            Print("Command to create new bunch has been received.");
           }
     }
//--- handling new pair initialization command 
   else if(id==CHARTEVENT_CUSTOM+ON_OCO)
     {
      //--- OCO pair initialization
      if(gOco.Init(gOrdersProps,gOcoList.Total()+1))
        {
         PrintFormat("Id of new OCO pair: %I32u",gOco.Id());
         //--- copy pair
         CiOcoObject *ptr_new_oco=new CiOcoObject(gOco);
         if(CheckPointer(ptr_new_oco)==POINTER_DYNAMIC)
           {
            //--- add to list
            int node_idx=gOcoList.Add(ptr_new_oco);
            if(node_idx>-1)
               PrintFormat("Total number of bunch: %d",gOcoList.Total());
            else
               PrintFormat("Error when adding OCO pair %I32u to list!",gOco.Id());
           }
        }
      else
         Print("OCO-orders placing error!");

      //--- clear properties
      Reset();
     }
  }

Tanıtıcı kodu küçük değil. Birkaç blok üzerinde durmak istiyorum.

Tüm grafik olaylarının ilk işlenmesi ana iletişim kutusuna verilir.

Sonraki, çeşitli olayların ele alındığı bloklardır:

  • Bir talimat türünün tanımlanması için açılır listelerin değiştirilmesi;
  • Talimatların özelliklerini doldurmak için giriş alanlarını düzenleme;
  • ON_OCO olay oluşturma için düğmeye tıklayın;
  • ON_OCO olay yanıtı: talimat çifti oluşturma.

EA, panelin alanlarının doldurulmasının doğruluğunu doğrulamaz. Bu yüzden değerleri kendimiz kontrol etmeliyiz, aksi takdirde EA OCO talimatları yerleştirme hatası gösterecektir.

OnTrade() tanıtıcı gövdesinde çifti kaldırma ve kalan talimatı kapatma gerekliliği kontrol edilir.


Sonuç

Belirli görevlerin yerine getirilmesi için kullanılabilecek Standart Kitaplık sınıflarının zenginliklerini göstermeye çalıştım.

Özellikle, OCO talimatlarının işlenmesiyle ilgili bir sorunla uğraşıyorduk. OCO talimatlarının işlenmesi için Panelli EA kodunun, daha karmaşık talimat çiftlerinin oluşturulması açısından bir başlangıç noktası olacağını umuyorum.


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

Ekli dosyalar |
ciocoobject.mqh (27.71 KB)
crandom.mqh (5.19 KB)
init_oco.mq5 (6.42 KB)
control_oco_ea.mq5 (7.88 KB)
panel_oco_ea.mq5 (30.25 KB)
MetaTrader 5'te RSS Beslemelerini Görüntülemek için Etkileşimli Bir Uygulama Oluşturma MetaTrader 5'te RSS Beslemelerini Görüntülemek için Etkileşimli Bir Uygulama Oluşturma
Bu makalede RSS beslemelerinin görüntülenmesi için bir uygulama oluşturma olasılığına bakıyoruz. Makale, MetaTrader 5 için etkileşimli programlar oluşturmak için Standart Kitaplığın özelliklerinin nasıl kullanılabileceğini gösterecektir.
Teknik Analiz ve Piyasa Tahmini Yöntemleri Üzerine Teknik Analiz ve Piyasa Tahmini Yöntemleri Üzerine
Makale, görsel düşünme ve "kullanıma hazır" bir pazar görünümü ile birleştirilmiş iyi bilinen bir matematiksel yöntemin yeteneklerini ve potansiyelini göstermektedir. Bir yandan, yaratıcı zihinlerin alım satım paradigmasını yeniden gözden geçirmesini sağlayabildiği için geniş bir kitlenin dikkatini çekmeye hizmet eder. Öte yandan, analiz ve tahmin için çok çeşitli araçlarla ilgili alternatif geliştirmelere ve program kodu uygulamalarına yol açabilir.
Fiyat Yönüne ve Hareket Hızına Dayalı Alım Satım Fikirleri Fiyat Yönüne ve Hareket Hızına Dayalı Alım Satım Fikirleri
Makale, fiyatların hareket yönü ve hızlarının analizine dayanan bir fikrin gözden geçirilmesini sağlar. Düşünülmekte olan stratejinin uygulanabilirliğini araştırmak için expert advisor olarak sunulan MQL4 dilinde biçimlendirmesini gerçekleştirdik. Ayrıca makalede verilen bir örneğin kontrolü, incelenmesi ve optimizasyonu ile en iyi parametreleri belirliyoruz.
Yatırımcıların Altın Kuralı Yatırımcıların Altın Kuralı
Yüksek beklentilere dayalı kar elde etmek için iyi alım satımın üç temel ilkesini anlamalıyız: 1) piyasaya girerken riskinizi bilin; 2) zarardan erken dönün ve kârınızın artmasına izin verin; 3) sisteminizin beklentisini bilin; düzenli olarak test edin ve ayarlayın. Bu makale, kârın mümkün olan en yüksek seviyede artmasına izin verdiği için açılış pozisyonlarını takip eden ve ikinci altın prensibi gerçekleştiren bir program kodu sağlar.