English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5 Tarif Defteri MetaTrader 5 Alım Satım Olayları için Sesli Bildirimler

MQL5 Tarif Defteri MetaTrader 5 Alım Satım Olayları için Sesli Bildirimler

MetaTrader 5Örnekler | 13 Ocak 2022, 16:48
272 0
Anatoli Kazharski
Anatoli Kazharski

Giriş

Bu makalede, Uzman Danışmanın dosyasına ses dosyaları eklenmesi ve böylece alım satım olaylarına sesli bildirimler eklenmesi gibi konuları ele alacağız. Dosyaların eklenmesi, ses dosyalarının Uzman Danışman içine yerleştirileceği anlamına gelir. Bu nedenle, Uzman Danışmanın derlenmiş sürümünü (*.ex5) başka bir kullanıcıya sağlarken, ses dosyalarını da sağlamanız ve nereye kaydedilmeleri gerektiğini açıklamanız gerekmez.

 

Geliştirme

Test amacıyla, aşağıdaki önceki makaleden Uzman Danışmanı alacağız: "MQL5 Tarif Defteri: Uzman Danışmanın Belirlenen Kriterlere Göre Optimizasyon Sonuçlarını Kaydetme." Bunu daha basit hale getirmek için, mevcut konuyla ilgili olmayan her şeyi kaldırdım.

MQL5 kaynaklarını kullanarak bir alım satım olayı sesli bildirimler eklemek için Alert() vePlaySound() fonksiyonlarını kullanabiliriz. Alert() fonksiyonunu seçerseniz, her zaman aynı sesli bildirimi oynatılacak ve ilgili mesajı içeren bir pencere açacaktır. Bunu aşağıdaki başlığa sahip makalede çalışırken görebilirsiniz: "MQL5 Tarif Defteri: Farklı Yazdırma Modlarını Kullanma."

Uyarı sesi terminal ayarlarında ayarlanabilir: Araçlar -> Seçenekler veya Ctrl+O. Ayrıca, olaylar için sesli bildirimleri etkinleştirmek için Olaylar sekmesinde "Etkinleştir" seçeneğini işaretlememiz ve uyarıların açılır listesinden uygun ses dosyasını seçmemiz gerekir.


Şekil 1. Terminal ayarlarındaki "Olaylar" sekmesi

Ancak, herhangi bir özel program olayı için benzersiz bir sesli bildirimi ayarlama imkanınız da vardır. Bunun için, PlaySound() fonksiyonunu kullanırız.

Uzman Danışmana sesli bildirimler eklemeden önce, test amacıyla bir Uzman Danışman oluşturalım. Grafiğe Uzman Danışman yüklerken bir ses paneli açma fikrini uygulayalım. Ses paneli, düğme (OBJ_BUTTON) gibi grafik nesnelerinden oluşacaktır. Her düğmenin kendisine atanmış kendi benzersiz sesi olacak ve bu, düğme tıklatıldığında oynatılacaktır.

Çevrimiçi oldum ve *.wav formatında 25 farklı ses dosyası buldum (makalenin sonundan indirilebilir). Bunlar MetaTrader 5\MQL5\Files\Sounds klasörüne yerleştirilmelidir. Ses dosyalarıyla çalışmaya alışmak için, şimdi MQL5 Sihirbazını kullanarak yeni bir Uzman Danışman oluşturacağız. En başta, ses panelindeki düğme sayısına (toplamda 26 düğme olacak) göre dizi boyutunu belirtiyoruz.

//--- Array size
#define ARRAY_SIZE 26

Ardından, Uzman Danışmana kaynak sağlayacak klasörleri ve dosya adlarını belirtmemiz gerekir. Bu da, #resource direktifini kullanılarak yapılabilir. Direktifin ardından, dosya konumunu çift tırnak içinde belirtiyoruz:

//--- Sound files
#resource "\\Files\\Sounds\\alert.wav"
#resource "\\Files\\Sounds\\AHOOGA.wav"
#resource "\\Files\\Sounds\\APPLAUSE.wav"
#resource "\\Files\\Sounds\\BONK.wav"
#resource "\\Files\\Sounds\\CARBRAKE.wav"
#resource "\\Files\\Sounds\\CASHREG.wav"
#resource "\\Files\\Sounds\\CLAP.wav"
#resource "\\Files\\Sounds\\CORKPOP.wav"
#resource "\\Files\\Sounds\\DOG.wav"
#resource "\\Files\\Sounds\\DRIVEBY.wav"
#resource "\\Files\\Sounds\\DRUMROLL.wav"
#resource "\\Files\\Sounds\\EXPLODE.wav"
#resource "\\Files\\Sounds\\FINALBEL.wav"
#resource "\\Files\\Sounds\\FROG.wav"
#resource "\\Files\\Sounds\\GLASS.wav"
#resource "\\Files\\Sounds\\GUNSHOT.wav"
#resource "\\Files\\Sounds\\LASER.wav"
#resource "\\Files\\Sounds\\LATNWHIS.wav"
#resource "\\Files\\Sounds\\PIG.wav"
#resource "\\Files\\Sounds\\RICOCHET.wav"
#resource "\\Files\\Sounds\\RINGIN.wav"
#resource "\\Files\\Sounds\\SIREN.wav"
#resource "\\Files\\Sounds\\TRAIN.wav"
#resource "\\Files\\Sounds\\UH_OH.wav"
#resource "\\Files\\Sounds\\VERYGOOD.wav"
#resource "\\Files\\Sounds\\WHOOSH.wav"

Şimdi, kaynak dosyalarının konumlarını, grafik nesnelerin adlarını ve grafik nesnelerde görüntülenen metni içerecek üç dize dizisi oluşturmamız gerekiyor. Dosya konumlarını belirtirken çift iki nokta üst üste kullanımına dikkat edin; bu, kaynağı ada göre çağırmak için özel bir göstergedir.

//--- Sound file location
string sound_paths[ARRAY_SIZE]=
  {
   "::Files\\Sounds\\alert.wav",
   "::Files\\Sounds\\AHOOGA.wav",
   "::Files\\Sounds\\APPLAUSE.wav",
   "::Files\\Sounds\\BONK.wav",
   "::Files\\Sounds\\CARBRAKE.wav",
   "::Files\\Sounds\\CASHREG.wav",
   "::Files\\Sounds\\CLAP.wav",
   "::Files\\Sounds\\CORKPOP.wav",
   "::Files\\Sounds\\DOG.wav",
   "::Files\\Sounds\\DRIVEBY.wav",
   "::Files\\Sounds\\DRUMROLL.wav",
   "::Files\\Sounds\\EXPLODE.wav",
   "::Files\\Sounds\\FINALBEL.wav",
   "::Files\\Sounds\\FROG.wav",
   "::Files\\Sounds\\GLASS.wav",
   "::Files\\Sounds\\GUNSHOT.wav",
   "::Files\\Sounds\\LASER.wav",
   "::Files\\Sounds\\LATNWHIS.wav",
   "::Files\\Sounds\\PIG.wav",
   "::Files\\Sounds\\RICOCHET.wav",
   "::Files\\Sounds\\RINGIN.wav",
   "::Files\\Sounds\\SIREN.wav",
   "::Files\\Sounds\\TRAIN.wav",
   "::Files\\Sounds\\UH_OH.wav",
   "::Files\\Sounds\\VERYGOOD.wav",
   "::Files\\Sounds\\WHOOSH.wav"
  };
//--- Names of graphical objects
string sound_names[ARRAY_SIZE]=
  {
   "sound_button01","sound_button02",
   "sound_button03","sound_button04",
   "sound_button05","sound_button06",
   "sound_button07","sound_button08",
   "sound_button09","sound_button10",
   "sound_button11","sound_button12",
   "sound_button13","sound_button14",
   "sound_button15","sound_button16",
   "sound_button17","sound_button18",
   "sound_button19","sound_button20",
   "sound_button21","sound_button22",
   "sound_button23","sound_button24",
   "sound_button25","sound_button26"
  };
//--- Text displayed on graphical objects
string sound_texts[ARRAY_SIZE]=
  {
   "ALERT","AHOOGA","APPLAUSE","BONK","CARBRAKE","CASHREG",
   "CLAP","CORKPOP","DOG","DRIVEBY","DRUMROLL","EXPLODE","FINALBEL",
   "FROG","GLASS","GUNSHOT","LASER","LATNWHIS","PIG",
   "RICOCHET","RINGIN","SIREN","TRAIN","UH_OH","VERYGOOD","WHOOSH"
  };

Belirtilen özelliklere sahip bir grafikte "Düğme" grafik nesnesini oluşturacak CreateButton() fonksiyonunu yazalım:

//+------------------------------------------------------------------+
//| Creating the Button object                                       |
//+------------------------------------------------------------------+
void CreateButton(long              chart_id,         // chart id
                  int               sub_window,       // window number
                  string            name,             // object name
                  string            text,             // displayed name
                  ENUM_ANCHOR_POINT anchor,           // anchor point
                  ENUM_BASE_CORNER  corner,           // chart corner
                  string            font_name,        // font
                  int               font_size,        // font size
                  color             font_color,       // font color
                  color             background_color, // background color
                  color             border_color,     // border color
                  int               x_size,           // width
                  int               y_size,           // height
                  int               x_distance,       // X-coordinate
                  int               y_distance,       // Y-coordinate
                  long              z_order)          // Z-order
  {
//--- Creating an object
   if(ObjectCreate(chart_id,name,OBJ_BUTTON,sub_window,0,0))
     {
      ObjectSetString(chart_id,name,OBJPROP_TEXT,text);                  // setting name
      ObjectSetString(chart_id,name,OBJPROP_FONT,font_name);             // setting font
      ObjectSetInteger(chart_id,name,OBJPROP_COLOR,font_color);          // setting font color
      ObjectSetInteger(chart_id,name,OBJPROP_BGCOLOR,background_color);  // setting background color
      ObjectSetInteger(chart_id,name,OBJPROP_BORDER_COLOR,border_color); // setting border color
      ObjectSetInteger(chart_id,name,OBJPROP_ANCHOR,anchor);             // setting anchor point
      ObjectSetInteger(chart_id,name,OBJPROP_CORNER,corner);             // setting chart corner
      ObjectSetInteger(chart_id,name,OBJPROP_FONTSIZE,font_size);        // setting font size
      ObjectSetInteger(chart_id,name,OBJPROP_XSIZE,x_size);              // setting width X
      ObjectSetInteger(chart_id,name,OBJPROP_YSIZE,y_size);              // setting height Y
      ObjectSetInteger(chart_id,name,OBJPROP_XDISTANCE,x_distance);      // setting X-coordinate
      ObjectSetInteger(chart_id,name,OBJPROP_YDISTANCE,y_distance);      // setting Y-coordinate
      ObjectSetInteger(chart_id,name,OBJPROP_SELECTABLE,false);          // cannot select the object if FALSE
      ObjectSetInteger(chart_id,name,OBJPROP_STATE,false);               // button state (clicked/unclicked)
      ObjectSetInteger(chart_id,name,OBJPROP_ZORDER,z_order);            // higher/lower Z-order
      ObjectSetString(chart_id,name,OBJPROP_TOOLTIP,"\n");               // no tooltip if "\n"
     }
  }

Bunu daha eğlenceli hale getirmek için, her düğmenin rengi rastgele seçilecektir. Bunu uygulamak için basit bir fonksiyon yazacağız: GetRandomColor():

//+------------------------------------------------------------------+
//| Returning a random color                                         |
//+------------------------------------------------------------------+
color GetRandomColor()
  {
//--- Select a random color from 0 to 25
   switch(MathRand()%26)
     {
      case 0  : return(clrOrange);           break;
      case 1  : return(clrGold);             break;
      case 2  : return(clrChocolate);        break;
      case 3  : return(clrChartreuse);       break;
      case 4  : return(clrLime);             break;
      case 5  : return(clrSpringGreen);      break;
      case 6  : return(clrMediumBlue);       break;
      case 7  : return(clrDeepSkyBlue);      break;
      case 8  : return(clrBlue);             break;
      case 9  : return(clrSeaGreen);         break;
      case 10 : return(clrRed);              break;
      case 11 : return(clrSlateGray);        break;
      case 12 : return(clrPeru);             break;
      case 13 : return(clrBlueViolet);       break;
      case 14 : return(clrIndianRed);        break;
      case 15 : return(clrMediumOrchid);     break;
      case 16 : return(clrCrimson);          break;
      case 17 : return(clrMediumAquamarine); break;
      case 18 : return(clrDarkGray);         break;
      case 19 : return(clrSandyBrown);       break;
      case 20 : return(clrMediumSlateBlue);  break;
      case 21 : return(clrTan);              break;
      case 22 : return(clrDarkSalmon);       break;
      case 23 : return(clrBurlyWood);        break;
      case 24 : return(clrHotPink);          break;
      case 25 : return(clrLightSteelBlue);   break;
      //---
      default : return(clrGold);
     }
//---
   return(clrGold);
  }

Şimdi ses panelini grafiğe ekleyecek fonksiyonu yazalım: SetSoundPanel():

//+------------------------------------------------------------------+
//| Adding the sound panel to the chart                              |
//+------------------------------------------------------------------+
void SetSoundPanel()
  {
   int   column_count =0;       // Column counter
   int   x_dist       =10;      // Indent from the left side of the chart
   int   y_dist       =15;      // Indent from the top of the chart
   int   x_size       =100;     // Button width
   int   y_size       =20;      // Button height
   color button_color =clrNONE; // Button color
//--- Set the objects
   for(int i=0; i<ARRAY_SIZE; i++)
     {
      //--- Increase the column counter
      column_count++;
      //--- Get the button color
      button_color=GetRandomColor();
      //--- Draw a button
      CreateButton(0,0,sound_names[i],sound_texts[i],
                   ANCHOR_LEFT_UPPER,CORNER_LEFT_UPPER,"Arial",8,
                   clrWhite,button_color,button_color,x_size,y_size,x_dist,y_dist,1);
      //--- If two buttons have already been set in the same row
      if(column_count==2)
        {
         x_dist=10;        // Move the X-coordinate to the initial position
         y_dist+=20;       // Set the Y-coordinate for the next row
         column_count=0;   // Zero out the counter
        }
      else
      //--- Set the X-coordinate for the next button 
         x_dist+=x_size;
     }
//--- Refresh the chart
   ChartRedraw(0);
  }

Paneli grafikten kaldırmak için aşağıda verilen fonksiyonları kullanacağız:

//+------------------------------------------------------------------+
//| Deleting the info panel                                          |
//+------------------------------------------------------------------+
void DeleteSoundPanel()
  {
//--- Delete position properties and their values
   for(int i=0; i<ARRAY_SIZE; i++)
      DeleteObjectByName(name_sound_object[i]);
//--- Redraw the chart
   ChartRedraw();
  }
//+------------------------------------------------------------------+
//| Deleting objects by name                                         |
//+------------------------------------------------------------------+
void DeleteObjectByName(string name)
  {
//--- If the object is found
   if(ObjectFind(ChartID(),name)>=0)
     {
      //--- If an error occurred when deleting, print the relevant message
      if(!ObjectDelete(ChartID(),name))
         Print("Error ("+IntegerToString(GetLastError())+") when deleting the object!");
     }
  }

Böylece, Uzman Danışmanı yüklerken, panel OnInit() fonksiyonundan grafikte ayarlanacaktır ve OnDeinit() fonksiyonu ile Uzman Danışmanı kaldırırken grafikten silinecektir.

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- Set the sound panel
   SetSoundPanel();
  }
//+------------------------------------------------------------------+
//| Deinitialization function of the expert advisor                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Delete the sound panel
   DeleteSoundPanel();
  }

Şimdi sadece belirli bir düğmeye tıklandığında uygun sesin oynatılması için panel ile etkileşimi uygulamamız gerekiyor. Bunu daha da eğlenceli hale getirmek için, ses paneli düğmelerinden birine basıldığında düğme renklerini değiştireceğiz. Bunu uygulamak için, kodu aşağıda verilen ChangeColorsOnSoundPanel() fonksiyonuna ihtiyacımız olacak:

//+------------------------------------------------------------------+
//| Changing colors on the sound panel                               |
//+------------------------------------------------------------------+
void ChangeColorsOnSoundPanel()
  {
   color clr=clrNONE; // Button color
//--- Iterate over all buttons in a loop and change their color
   for(int i=0; i<ARRAY_SIZE; i++)
     {
      //--- Get the new color
      clr=GetRandomColor();
      //--- Set the border color
      ObjectSetInteger(0,sound_names[i],OBJPROP_BGCOLOR,clr);
      //--- Set the background color
      ObjectSetInteger(0,sound_names[i],OBJPROP_BORDER_COLOR,clr);
      //--- Unclicked button
      ObjectSetInteger(0,sound_names[i],OBJPROP_STATE,false);
      //--- Refresh the chart
      ChartRedraw(0);
      //--- Wait for 20 ms (lag)
      Sleep(20);
     }
  }

Ve son olarak OnChartEvent() fonksiyonuna aşağıdaki kod eklenmelidir:

//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void OnChartEvent(const int     id,     // Event identifier  
                  const long&   lparam, // Parameter of the event of type long
                  const double& dparam, // Parameter of the event of type double
                  const string& sparam) // Parameter of the event of type string
  {
//--- If there was an event of left-clicking on the object
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      //--- If the object name contains "sound_button"
      if(StringFind(sparam,"sound_button",0)>=0)
        {
         //--- Play the sound based on the object name
         //    5019 - ERR_FILE_NOT_EXIST - The file does not exist
         if(!PlaySound(GetSoundPath(sparam)))
            Print("Error: ",GetLastError());
         //--- Change colors of all buttons
         ChangeColorsOnSoundPanel();
        }
     }
  }

Yukarıdaki kodda vurgulanan dize, ses dosyası konumunun özel GetSoundPath() fonksiyonu kullanılarak PlaySound() fonksiyonuna aktarıldığını belirtir. GetSoundPath() fonksiyon kodu aşağıda verilmektedir:

//+------------------------------------------------------------------+
//| Returning sound file location by the object name                 |
//+------------------------------------------------------------------+
string GetSoundPath(string object_name)
  {
//--- Iterate over all sound panel objects in a loop
   for(int i=0; i<ARRAY_SIZE; i++)
     {
      //--- If the name of the object clicked in the chart
      //    matches one of those available on the panel, return the file location
      if(object_name==name_sound_object[i])
         return(path_sound_object[i]);
     }
//---
   return("");
  }

Şimdi her şey hazır! Ses paneli (program makale eklerinden indirilebilir) Uzman Danışman grafiğe eklenir eklenmez ayarlanacaktır:

Grafikteki ses paneli

Şekil 2. Grafikteki ses paneli

Bu şekilde, ses dosyaları ile çalışma prensibi artık açıktır. Şimdi aşağıdaki başlığa sahip önceki makaleden Uzman Danışmanımıza geri dönelim: "MQL5 Tarif Defteri: Uzman Danışmanın Belirlenen Kriterlere Göre Optimizasyon Sonuçlarını Kaydetme" ve Uzman Danışmanda hangi sesleri kullanacağımıza karar verelim. Resources.mqh dosyası oluşturalım ve bunu Uzman Danışmanın ana dosyasına dahil edelim.

//--- Include custom libraries
#include "Include/Errors.mqh"
#include "Include/Enums.mqh"
#include "Include/Resources.mqh"
#include "Include/TradeSignals.mqh"
#include "Include/TradeFunctions.mqh"
#include "Include/ToString.mqh"
#include "Include/Auxiliary.mqh"

Şimdi ana alım satım olayları için dosyaları seçiyoruz.

//--- Sound files
#resource "\\Files\\Sounds\\AHOOGA.WAV"   // Error
#resource "\\Files\\Sounds\\CASHREG.WAV"  // Position opening/position volume increase/pending order triggering
#resource "\\Files\\Sounds\\WHOOSH.WAV"   // Pending order/Stop Loss/Take Profit setting/modification
#resource "\\Files\\Sounds\\VERYGOOD.WAV" // Position closing at profit
#resource "\\Files\\Sounds\\DRIVEBY.WAV"  // Position closing at loss
//--- Sound file location
string SoundError          = "::Files\\Sounds\\AHOOGA.WAV";
string SoundOpenPosition   = "::Files\\Sounds\\CASHREG.WAV";
string SoundAdjustOrder    = "::Files\\Sounds\\WHOOSH.WAV";
string SoundCloseWithProfit= "::Files\\Sounds\\VERYGOOD.WAV";
string SoundCloseWithLoss  = "::Files\\Sounds\\DRIVEBY.WAV";

Ayrıca, kaynak olarak kullanılan ses dosyalarının yanı sıra, Uzman Danışmanda arayüz amaçları, metin dosyaları ve hatta göstergeler için *.bmp görüntülerini de saklayabilirsiniz. MetaTrader 5 için EA'lar artık tamamen fonksiyonel uygulamalar olarak kabul edilir - birkaç dosya yerine sadece bir tane aktarmanız gerektiği için çok kullanışlıdır.

Devam edelim. Harici parametrelerde, sesleri devre dışı bırakma imkanına sahip olmamız için UseSound parametresini eklememiz gerekiyor:

//--- External parameters of the Expert Advisor
input  int        NumberOfBars =2;    // Number of one-direction bars
sinput double     Lot          =0.1;  // Lot
input  double     TakeProfit   =100;  // Take Profit
input  double     StopLoss     =50;   // Stop Loss
input  double     TrailingStop =10;   // Trailing Stop
input  bool       Reverse      =true; // Position reversal
sinput bool       UseSound     =true; // Sound notifications

Include\Enums.mqh içinde, sesler için ENUM_SOUNDS numaralandırması oluşturuyoruz.

//--- Sounds
enum ENUM_SOUNDS
  {
   SOUND_ERROR             =0,   // Error
   SOUND_OPEN_POSITION     = 1,  // Position opening/position volume increase/pending order triggering
   SOUND_ADJUST_ORDER      = 2,  // Stop Loss/Take Profit/pending order setting
   SOUND_CLOSE_WITH_PROFIT = 3,  // Position closing at profit
   SOUND_CLOSE_WITH_LOSS   = 4   // Position closing at loss
  };

Bu tanımlayıcılar, PlaySoundByID() özel fonksiyonu için gerekli olacaktır.

//+------------------------------------------------------------------+
//| Playing sounds                                                   |
//+------------------------------------------------------------------+
void PlaySoundByID(ENUM_SOUNDS id)
  {
//--- If it is the real-time mode and sounds are enabled
   if(IsRealtime() && UseSound)
     {
      //--- Play the sound based on the identifier passed
      switch(id)
        {
         case SOUND_ERROR              : PlaySound(SoundError);            break;
         case SOUND_OPEN_POSITION      : PlaySound(SoundOpenPosition);     break;
         case SOUND_ADJUST_ORDER       : PlaySound(SoundAdjustOrder);      break;
         case SOUND_CLOSE_WITH_PROFIT  : PlaySound(SoundCloseWithProfit);  break;
         case SOUND_CLOSE_WITH_LOSS    : PlaySound(SoundCloseWithLoss);    break;
        }
     }
  }

Uzman Danışman tarafından gerçekleştirilen alım satım işlemleri sırasında ses etkileri, uygun alım satım fonksiyonlarından PlaySoundByID() çağrılarak oynatılabilir. Bunun OpenPosition() fonksiyonuna nasıl uygulandığına bakalım:

//+------------------------------------------------------------------+
//| Opening a position                                               |
//+------------------------------------------------------------------+
void OpenPosition(double lot,
                  ENUM_ORDER_TYPE order_type,
                  double price,
                  double sl,
                  double tp,
                  string comment)
  {
//--- Set the magic number in the trading structure
   trade.SetExpertMagicNumber(0);
//--- Set the slippage in points
   trade.SetDeviationInPoints(CorrectValueBySymbolDigits(10));
//--- The Instant Execution and Market Execution modes
//    *** Starting with build 803, Stop Loss and Take Profit                             ***
//    *** can be set upon opening a position in the SYMBOL_TRADE_EXECUTION_MARKET mode ***
   if(symb.execution_mode==SYMBOL_TRADE_EXECUTION_INSTANT ||
      symb.execution_mode==SYMBOL_TRADE_EXECUTION_MARKET)
     {
      //--- If the position failed to open
      if(!trade.PositionOpen(_Symbol,order_type,lot,price,sl,tp,comment))
        {
         //--- Play the error sound and print the relevant message
         PlaySoundByID(SOUND_ERROR);
         Print("Error opening the position: ",GetLastError()," - ",ErrorDescription(GetLastError()));
        }
      //--- Otherwise play the position opening sound
      else
         PlaySoundByID(SOUND_OPEN_POSITION);
     }
  }

Ancak, bir pozisyon Zarar Durdur, Kâr Al, manuel veya başka şekilde kapatılırsa bu olay OnTrade() fonksiyonunda görüntülenmelidir. Bunu uygulamak için, gerekli kontrollerden sorumlu olarak bir başka fonksiyon - SoundNotification() - yazacağız: İşlem geçmişi mevcut sembol için DEAL_ENTRY_OUT veya DEAL_ENTRY_INOUT tanımlayıcısı (pozisyonun kısmi/tam kapatılması veya ters çevrilmesi) ile yeni bir işlem gösterirse, program bu işlemin kar ile mi yoksa zarar ile mi kapatıldığını kontrol edecek ve buna uygun sesi oynatacaktır.

//+------------------------------------------------------------------+
//| Sound notification                                               |
//+------------------------------------------------------------------+
void SoundNotification()
  {
//--- If it is the real-time mode and sounds are enabled
   if(IsRealtime() && UseSound)
     {
      ulong        ticket      =0; // Deal ticket
      int          total       =0; // Total deals
      static ulong last_ticket =0; // Last ticket prior to this check
      //--- Get the complete history
      if(!HistorySelect(0,TimeCurrent()+1000))
         return;
      //--- Get the number of deals in the obtained list
      total=HistoryDealsTotal();
      //--- In the obtained list, iterate over all deals from the last one to the first one
      for(int i=total-1; i>=0; i--)
        {
         //--- If the deal ticket by its position in the list has been obtained
         if((ticket=HistoryDealGetTicket(i))>0)
           {
            //--- get the symbol of the deal
            GetHistoryDealProperties(ticket,D_SYMBOL);
            //--- If the symbol of the deal and the current symbol are the same
            if(deal.symbol==_Symbol)
              {
               //--- get the direction of the deal
               GetHistoryDealProperties(ticket,D_ENTRY);
               //--- If it is position closing, volume decrease or reversal
               if(deal.entry==DEAL_ENTRY_OUT || deal.entry==DEAL_ENTRY_INOUT)
                 {
                  //--- If the ticket of the current deal from the list (the last deal for the symbol) is equal to the previous ticket
                  //    or this is the initialization of the ticket of the last deal
                  if(ticket==last_ticket || last_ticket==0)
                    {
                     //--- Save the ticket and exit
                     last_ticket=ticket;
                     return;
                    }
                  //--- Get the result of the deal
                  GetHistoryDealProperties(ticket,D_PROFIT);
                  //--- In case of profit
                  if(deal.profit>=0)
                    {
                     //--- Profit sound
                     PlaySoundByID(SOUND_CLOSE_WITH_PROFIT);
                     //--- Save the ticket number
                     last_ticket=ticket;
                     return;
                    }
                  //--- In case of loss
                  if(deal.profit<0)
                    {
                     //--- Loss sound
                     PlaySoundByID(SOUND_CLOSE_WITH_LOSS);
                     //--- Save the ticket number
                     last_ticket=ticket;
                     return;
                    }
                 }
              }
           }
        }
     }
  }

SoundNotification() fonksiyonu, OnInit() ve OnTrade() fonksiyonlarına yerleştirilmelidir:

//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Initialize the new bar
   CheckNewBar();
//--- Initialize tickets of the last deals for the symbol
   SoundNotification();
//--- Initialization completed successfully
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Monitoring trade events                                          |
//+------------------------------------------------------------------+
void OnTrade()
  {
//--- Sound notification
   SoundNotification();
  }

Sesli bildirim ayrıca, İz-süren Stop seviyesini değiştirirken ModifyTrailingStop() fonksiyonunun sonuna eklenmiştir.

 

Sonuç

Neredeyse hepsi bu. Test amaçlı tüm dosyalar makalenin eklerinden indirilebilir. Terminaldeki seslerden bahsetmek gerekirse, CMIDI (Integer tarafından) adında Code Base'de mevcut ilginç bir çözüme dikkatinizi çekmek isterim: bu çözüm, MetaTrader 5'te MIDI dosyalarını oynatmanıza olanak sağlar. İyi şanslar!

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

Ekli dosyalar |
sounds.zip (321.8 KB)
soundpanel.mq5 (14.07 KB)
MQL5 Tarif Defteri Birkaç Zaman Aralığını Tek bir Pencerede Görüntüleme MQL5 Tarif Defteri Birkaç Zaman Aralığını Tek bir Pencerede Görüntüleme
Analiz için MetaTrader 5'te kullanılabilir 21 zaman aralığı vardır. Mevcut grafiğe yerleştirebileceğiniz özel grafik nesnelerinden yararlanabilir ve sembolü, zaman aralığını ve diğer bazı özellikleri tam buradan ayarlayabilirsiniz. Bu makale, bu grafik nesnelerine dair ayrıntılı bilgi sağlayacaktır: bir alt pencerede aynı anda birçok grafik nesnesi ayarlamamıza olanak sağlayacak kontrollere (düğmelere) sahip bir gösterge oluşturacağız. Ayrıca, grafik nesneleri alt pencereye tam olarak sığar ve ana grafik veya terminal penceresi yeniden boyutlandırıldığında otomatik olarak ayarlanır.
MQL5 Tarif Defteri Uzman Danışmanın Belirlenen Kriterlere Göre Optimizasyon Sonuçlarını Kaydetme MQL5 Tarif Defteri Uzman Danışmanın Belirlenen Kriterlere Göre Optimizasyon Sonuçlarını Kaydetme
MQL5 programlamasına dair makaleler serisine devam ediyoruz. Bu sefer, Uzman Danışman parametre optimizasyonu sırasında her bir optimizasyon doğru geçişinin sonucunun nasıl elde edileceğini göreceğiz. Uygulama, harici parametrelerde belirtilen koşulların sağlanması durumunda ilgili geçiş değerlerinin bir dosyaya yazılmasını sağlayacak şekilde yapılacaktır. Test değerlerine ek olarak, bu sonuçlara neden olan parametreleri de kaydedeceğiz.
MQL5 Tarif Defteri Gösterge Alt Pencere Kontrolleri - Düğmeler MQL5 Tarif Defteri Gösterge Alt Pencere Kontrolleri - Düğmeler
Bu makalede, düğme kontrolleri ile bir kullanıcı arayüzünü geliştirme örneğini ele alacağız. Kullanıcı ile etkileşim fikrini iletmek için, imleç üzerlerine geldiğinde düğmelerin renkleri değişecektir. İmleç bir düğmenin üzerindeyken, düğme rengi hafifçe koyulaşacak ve düğmeye tıklandığında büyük ölçüde koyulaşacaktır. Ayrıca, her düğmeye araç ipuçları ekleyerek sezgisel bir arayüz oluşturacağız.
MQL5 Standart Kitaplığını Genişletme ve Kodu Yeniden Kullanma MQL5 Standart Kitaplığını Genişletme ve Kodu Yeniden Kullanma
MQL5 Standart Kitaplığı, bir geliştirici olarak hayatınızı kolaylaştırır. Ancak, dünyadaki bütün geliştiricilerin ihtiyaçlarını karşılamaz, bu yüzden daha özel bir şeye ihtiyacınız olduğunu düşünüyorsanız, bir adım daha ileri gidebilir ve bunu genişletebilirsiniz. Bu makale, size MetaQuotes'un Zig-Zag teknik göstergesini Standart Kitaplığa entegre etme konusunu anlatır. Amacımıza ulaşmak için MetaQuotes'un tasarım felsefesinden ilham aldık.