English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Alım Satım Raporları ve SMS Bildirimi Oluşturma ve Yayınlama

Alım Satım Raporları ve SMS Bildirimi Oluşturma ve Yayınlama

MetaTrader 5Örnekler | 15 Aralık 2021, 09:41
63 0
Denis Zyatkevich
Denis Zyatkevich

Giriş

Bu makalede, alım satım sonuçları raporunun (Expert Advisor, Gösterge veya Script Dosyası kullanılarak) HTML dosyası olarak nasıl oluşturulacağı ve FTP yoluyla WWW-sunucusuna nasıl yükleneceği açıklanmaktadır. Ayrıca alım satım etkinliklerine ilişkin bildirimlerin cep telefonuna SMS olarak gönderilmesini de değerlendireceğiz.

Bu makalede açıklanan materyali daha rahat kullanabilmek için okuyucunun HTML (Köprü Metni Biçimlendirme Dili) hakkında bilgi sahibi olması önerilir.

Yükleme raporlarını uygulamak için FTP yoluyla veri alınabilen bir WWW-sunucusuna (herhangi bir bilgisayar olabilir) ihtiyacımız var. Alım satım etkinlikleriyle ilgili bildirimleri SMS olarak alma olasılığını uygulamak için bir E-POSTA-SMS ağ geçidine ihtiyacımız var (bu hizmet birçok cep telefonu operatörü ve üçüncü taraf kuruluş tarafından sağlanmaktadır).

1. Rapor Oluşturma ve FTP aracılığıyla Gönderme

Bir alım satım raporu oluşturan ve FTP-protokolü aracılığıyla gönderen bir MQL5-programı oluşturalım. İlk olarak, bunu Script dosyası olarak yapıyoruz. Gelecekte bunu, Expert Advisor'lara ve Göstergelere eklenebilecek bitmiş bir blok olarak kullanabiliriz. Örneğin, Expert Adviser'larda bu bloğu, alım satım talebinden sonra bu bloğu çalıştırmak veya ChartEvent olayı için bazı işlemleri ayarlamak için Alım Satım veya Zamanlayıcı olay işleyicisi olarak kullanabilirsiniz. Göstergelerde, bu bloğu Zamanlayıcı veya ChartEvent olay işleyicilerine dahil edebilirsiniz.

Program tarafından oluşturulan rapor örneği Şekil 1, 2 ve 3'te gösterilmiştir. Veya bu raporu makalenin sonunda bulunan bağlantıdan indirebilirsiniz.

Şekil 1. Rapor Örneği - Yatırımlar ve Pozisyonlar Tablosu.

Şekil 1. Rapor Örneği - Yatırımlar ve Pozisyonlar Tablosu.

Şekil 2. Rapor Örneği - Denge Grafiği.

Şekil 2. Rapor Örneği - Denge Grafiği.

 Şekil 3. Rapor Örneği - Mevcut Enstrüman Fiyat Grafiği.

Şekil 3. Rapor Örneği - Mevcut Enstrüman Fiyat Grafiği.

Yatırımlar ve pozisyonlar tablosunda (Şekil 1) kolaylık sağlamak için tüm yatırımlar pozisyonlara ayrılmıştır. Tablonun sol tarafında, piyasaya giriş hacmi, zamanı ve fiyatı (açılış pozisyonları ve eklemeler) gösterilmiştir. Tablonun sağ tarafında, piyasadan çıkmak için aynı parametreler gösterilmiştir (pozisyonun kısmen veya tamamen kapanması). Giriş/çıkışta yatırım iki kısma ayrılmıştır; bir pozisyonun kapanması ve bir sonraki pozisyonun açılması.

Yatırımlar ve pozisyonlar tablosunun altında denge tablosu (yatay eksen - zaman) ve altta mevcut enstrümanın fiyat grafiği gösterilmiştir.

Program, MetaTarder5_istall_dir\MQL5\Files klasöründe "report.html", "picture1.gif" ve "picture2.gif" dosyalarını (raporun html-dosyası, denge grafiği ve fiyat grafiğinin resim dosyaları) oluşturur. Ve FTP yayınlama özelliği, terminal ayarlarında etkinleştirilir - Bu üç dosyayı belirtilen sunucuya gönderir. Ayrıca, iki dosyaya daha ihtiyacımız olacak - oklarla açık pozisyonu gösteren resimler - Al veya Sat ("buy.gif" ve "sell.gif"). Bu resimleri (makalenin sonundaki indirme bağlantısı) alabilir veya herhangi bir grafik düzenleyicisinde kendiniz çizebilirsiniz. Bu iki dosya, "report.html" dosyası ile WWW-sunucusunun aynı klasörüne yerleştirilmelidir.

Giriş parametreleri olarak program, raporun oluşturulduğu dönemin başlangıç ve bitiş zamanını kabul eder. Örneğimizde, rapor döneminin sonu geçerli saattir ve kullanıcı rapor döneminin varyantını seçer: Tüm dönem, son gün, geçen hafta, geçen ay veya geçen yıl.

Raporun nasıl oluşturulduğu hakkında birkaç şey söyleyeceğim. Mevcut tüm yatırım geçmişi için alım satım sunucusu istenir. Elde edilen yatırımlar art arda işlenir. Deal_status[] dizisi, yatırımın işlenip işlenmediği hakkında bilgi depolar. Bu dizinin öğe indeksleri, yatırımların alım satım sunucusu listesinden alınan yatırım numaralarıdır. Ve öğe değerleri şu şekilde yorumlanır: 0 - yatırım henüz işlenmedi, 1 - yatırım zaten kısmen işlendi (giriş/çıkış), 127 - yatırım zaten işlendi (diğer değerler kullanılmadı ve ileride kullanılmak üzere ayrıldı).

Symb_list[] dizisi, alım satım işleminin gerçekleştirildiği finansal enstrüman adlarının listesini ve lot_list[] dizisi yatırımın işlenmesi sırasında her bir enstrüman için açık pozisyonların hacimlerini içerir. Pozitif hacim değerleri uzun pozisyonlara, negatif hacim değerleri kısa pozisyonlara karşılık gelir. Hacim sıfıra eşitse, bu, aracın açık pozisyonu olmadığı anlamına gelir. Yatırımlar sırasında listede olmayan (symb_list[] dizisinde) bir finansal enstrümanın işlenmesiyle karşılaşılırsa, oraya eklenir ve finansal enstrümanların sayısı (symb_total değişkeni) 1 değer artırılır.

Her yatırımda, sonraki her yatırımın işlenmesi, pozisyon kapanana veya giriş/çıkışa kadar aynı finansal enstrüman tarafından analiz edilir. Yalnızca deal_status[] dizisinin değeri 127'den küçük olan yatırımlar analiz edilir. Yatırım işlendikten sonra, deal_status[] dizisinin karşılık gelen öğesine 127 değeri atanır ve yatırım pozisyonun içinde/dışındaysa 1 değeri atanır. Pozisyonun açıldığı zaman, rapor dönemiyle eşleşirse (StartTime ve EndTime değişkenleri tarafından tanımlanır) - bu pozisyon raporlanmak üzere günlüğe kaydedilir (tüm girişler ve çıkışlar).

Yatırımlar tablosuna ek olarak, mevcut finansal enstrüman için yeni bir grafik açılır. Bu grafik için gerekli tüm özellikler sağlanır ve ChartScreenShot() işlevi kullanılarak bir ekran görüntüsü alınır; böylece mevcut enstrüman için fiyat grafiğini içeren bir resim dosyası elde ederiz. Daha sonra bu grafikte fiyat grafiği maskelenir ve bakiye değişim grafiği çizilir ve ardından başka bir ekran görüntüsü oluşturulur.

Grafikler içeren iki resim dosyası ve rapor içeren bir HTML dosyası oluşturulduğunda, FTP üzerinden dosya gönderme özelliği kontrol edilir. İzin verilmesi halinde, "report.html", "picture1.gif" ve "picture2.gif" dosyaları MetaTrader 5'te belirtilen ayarlara göre SendFTP() işlevi kullanılarak gönderilir.

MetaQuotes Dil Düzenleyicisini başlatın ve bir script dosyası oluşturmaya başlayın. Sabitleri tanımlayın; grafik yenileme zaman aşımı (saniye cinsinden), fiyat grafiğinin genişliği ve yüksekliği ve denge grafiğinin maksimum genişliği. Bakiye değişim eğrisini gösterecek olan grafiğin dönemi, rapor döneminin süresine ve grafiğin maksimum genişliğine göre seçilir. Grafiğin genişliği, denge grafiği için gerekli olan boyuta göre ayarlanır.

Grafiğin yüksekliği otomatik olarak genişliğin yarısı olarak hesaplanır. Ayrıca, dikey eksenin genişliğini sabit olarak belirleyeceğiz; bu, dikey eksen nedeniyle grafik alanının resmin genişliğine kıyasla azaldığı piksel sayısıdır.

#define timeout 10           // chart refresh timeout
#define Picture1_width 800   // max width of chart in report
#define Picture2_width 800   // width of price chart in report
#define Picture2_height 600  // height of price chart in report
#define Axis_Width 59        // width of vertical axis (in pixels)

Giriş parametrelerinin kullanıcıdan talep edileceğini belirtin.

// request input parameters
#property script_show_inputs

Rapor dönemlerinin numaralandırmasını oluşturun.

// enumeration of report periods
enum report_periods
  {
   All_periods,
   Last_day,
   Last_week,
   Last_month,
   Last_year
  };

Kullanıcıdan rapor dönemini isteyin (bu, varsayılan olarak tüm süredir).

// ask for report period
input report_periods ReportPeriod=0;

OnStart() işlevinin gövdesini yazın.

void OnStart()
  {

Rapor döneminin başlangıcını ve sonunu belirleyin.

  datetime StartTime=0;           // beginning of report period
  datetime EndTime=TimeCurrent(); // end of report period

  // calculating the beginning of report period
  switch(ReportPeriod)
    {
     case 1:
        StartTime=EndTime-86400;    // day
        break;
     case 2:
        StartTime=EndTime-604800;   // week
        break;
     case 3:
        StartTime=EndTime-2592000;  // month
        break;
     case 4:
        StartTime=EndTime-31536000; // year
        break;
    }
  // if none of the options is executed, then StartTime=0 (entire period)

Programda kullanılacak değişkenleri bildirin. Değişkenlerin amacı açıklamalarda belirtilmiştir.

   int total_deals_number;  // number of deals for history data
   int file_handle;         // file handle
   int i,j;                 // loop counters 
   int symb_total;          // number of instruments, that were traded
   int symb_pointer;        // pointer to current instrument
   char deal_status[];      // state of deal (processed/not processed)
   ulong ticket;            // ticket of deal
   long hChart;             // chart id

   double balance;           // current balance value
   double balance_prev;      // previous balance value
   double lot_current;       // volume of current deal
   double lots_list[];       // list of open volumes by instruments
   double current_swap;      // swap of current deal
   double current_profit;    // profit of current deal
   double max_val,min_val;   // maximal and minimal value
   
   string symb_list[];       // list of instruments, that were traded
   string in_table_volume;   // volume of entering position
   string in_table_time;     // time of entering position
   string in_table_price;    // price of entering position
   string out_table_volume;  // volume of exiting position
   string out_table_time;    // time of exiting position
   string out_table_price;   // price of exiting position
   string out_table_swap;    // swap of exiting position
   string out_table_profit;  // profit of exiting position

   bool symb_flag;           // flag that instrument is in the list

   datetime time_prev;           // previous value of time
   datetime time_curr;           // current value of time
   datetime position_StartTime;  // time of first enter to position
   datetime position_EndTime;    // time of last exit from position
   
   ENUM_TIMEFRAMES Picture1_period;  // period of balance chart

Yeni bir grafik açın ve özelliklerini ayarlayın; bu, raporun alt kısmındaki çıkış olacak fiyat grafiğidir.

 // open a new chart and set its properties
hChart=ChartOpen(Symbol(),0);
ChartSetInteger(hChart,CHART_MODE,CHART_BARS);            // bars chart
ChartSetInteger(hChart,CHART_AUTOSCROLL,true);            // autoscroll enabled
ChartSetInteger(hChart,CHART_COLOR_BACKGROUND,White);     // white background
ChartSetInteger(hChart,CHART_COLOR_FOREGROUND,Black);     // axes and labels are black
ChartSetInteger(hChart,CHART_SHOW_OHLC,false);            // OHLC are not shown
ChartSetInteger(hChart,CHART_SHOW_BID_LINE,true);         // show BID line
ChartSetInteger(hChart,CHART_SHOW_ASK_LINE,false);        // hide ASK line
ChartSetInteger(hChart,CHART_SHOW_LAST_LINE,false);       // hide LAST line
ChartSetInteger(hChart,CHART_SHOW_GRID,true);             // show grid
ChartSetInteger(hChart,CHART_SHOW_PERIOD_SEP,true);       // show period separators
ChartSetInteger(hChart,CHART_COLOR_GRID,LightGray);       // grid is light-gray
ChartSetInteger(hChart,CHART_COLOR_CHART_LINE,Black);     // chart lines are black
ChartSetInteger(hChart,CHART_COLOR_CHART_UP,Black);       // up bars are black
ChartSetInteger(hChart,CHART_COLOR_CHART_DOWN,Black);     // down bars are black
ChartSetInteger(hChart,CHART_COLOR_BID,Gray);             // BID line is gray
ChartSetInteger(hChart,CHART_COLOR_VOLUME,Green);         // volumes and orders levels are green
ChartSetInteger(hChart,CHART_COLOR_STOP_LEVEL,Red);       // SL and TP levels are red
ChartSetString(hChart,CHART_COMMENT,ChartSymbol(hChart)); // comment contains instrument <end segm

Bir grafiğin ekran görüntüsünü alın ve "picture2.gif" olarak kaydedin.

// save chart as image file
ChartScreenShot(hChart,"picture2.gif",Picture2_width,Picture2_height);

Tüm hesap varlığı süresi için yatırım geçmişi isteyin.

// request deals history for entire period
HistorySelect(0,TimeCurrent());

Rapor içeren (ANSI kodlaması) HTML sayfasını yazacağımız "report.html" dosyasını açın.

// open report file
file_handle=FileOpen("report.html",FILE_WRITE|FILE_ANSI);

HTML-belgesinin başlangıç kısmını yazın:

  • html-belgesinin başlangıcı (<html>)
  • Tarayıcı pencerenizin üst kısmında görüntülenecek olan başlık (<head><title>Expert Alım Satım Raporu</title></head>)
  • arka plan rengiyle html-belgesinin ana bölümünün başlangıcı (<body bgcolor='#EFEFEF'>)
  • Orta hizalama (<center> )
  • Yatırımlar ve pozisyonlar tablosunun başlığı (<h2>Alım Satım Raporu</h2>)
  • Hizalama, kenarlık genişliği, arka plan rengi, kenarlık rengi, hücre aralığı ve hücre dolgusu ile yatırımlar ve pozisyonlar tablosunun başlangıcı (<table align='center' border='1' bgcolor='#FFFFFF' bordercolor='#7F7FFF' cellspacing='0' cellpadding='0'>)
  • Tablo başlığı 
// write the beginning of HTML
   FileWrite(file_handle,"<html>"+
                           "<head>"+
                              "<title>Expert Trade Report</title>"+
                           "</head>"+
                              "<body bgcolor='#EFEFEF'>"+
                              "<center>"+
                              "<h2>Trade Report</h2>"+
                              "<table align='center' border='1' bgcolor='#FFFFFF' bordercolor='#7F7FFF' cellspacing='0' cellpadding='0'>"+
                                 "<tr>"+
                                    "<th rowspan=2>SYMBOL</th>"+
                                    "<th rowspan=2>Direction</th>"+
                                    "<th colspan=3>Open</th>"+
                                    "<th colspan=3>Close</th>"+
                                    "<th rowspan=2>Swap</th>"+
                                    "<th rowspan=2>Profit</th>"+
                                 "</tr>"+
                                 "<tr>"+
                                    "<th>Volume</th>"+
                                    "<th>Time</th>"+
                                    "<th>Price</th>"+
                                    "<th>Volume</th>"+
                                    "<th>Time</th>"+
                                    "<th>Price</th>"+
                                 "</tr>");

Listedeki yatırım sayısını alma.

// number of deals in history
total_deals_number=HistoryDealsTotal();

symb_list[], lots_list[] ve deal_status[] dizileri için boyutları ayarlama.

// setting dimensions for the instruments list, the volumes list and the deals state arrays
ArrayResize(symb_list,total_deals_number);
ArrayResize(lots_list,total_deals_number);
ArrayResize(deal_status,total_deals_number);

deal_status[] dizisinin tüm öğeleri 0 değeriyle başlatılıyor - Tüm yatırımlar işlenmez.

// setting all elements of array with value 0 - deals are not processed
ArrayInitialize(deal_status,0);

Bir önceki bakiye değerini saklamak için kullanılan bakiye ve değişkenin başlangıç değerlerinin ayarlanması.

balance=0;       // initial balance
balance_prev=0;  // previous balance

Listedeki finansal enstrümanların sayısını saklamak için kullanılan değişkenin başlangıç değerinin ayarlanması.

// number of instruments in the list
symb_total=0;

Listedeki her yatırımı sıralı olarak işleyen bir döngü oluşturun.

// processing all deals in history
for(i=0;i<total_deals_number;i++)
  {

Mevcut yatırımı seçin ve biletini alın.

//select deal, get ticket
ticket=HistoryDealGetTicket(i);

Bakiyenin mevcut yatırımdaki kar miktarına göre değiştirilmesi.

// changing balance
balance+=HistoryDealGetDouble(ticket,DEAL_PROFIT);

Yatırım zamanının elde edilmesi; bu, daha sık kullanılacaktır.

// reading the time of deal
time_curr=HistoryDealGetInteger(ticket,DEAL_TIME);

Bu, listedeki ilk yatırım ise rapor döneminin sınırlarını ayarlamamız ve rapor döneminin süresine ve grafiğin çizileceği bölgenin genişliğine bağlı olarak bakiye grafiği için dönemi seçmemiz gerekir. Maksimum ve minimum bakiyelerin başlangıç değerlerinin ayarlanması (bu değişkenler, grafiğin maksimum ve minimum değerlerini ayarlamak için kullanılacaktır.)

// if this is the first deal
if(i==0)
  {
   // if the report period starts before the first deal,
   // then the report period will start from the first deal
   if(StartTime<time_curr) StartTime=time_curr;
   // if report period ends before the current time,
   // then the end of report period corresponds to the current time
   if(EndTime>TimeCurrent()) EndTime=TimeCurrent();
   // initial values of maximal and minimal balances
   // are equal to the current balance
   max_val=balance;
   min_val=balance;
   // calculating the period of balance chart depending on the duration of
   // report period
   Picture1_period=PERIOD_M1;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)) Picture1_period=PERIOD_M2;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*120) Picture1_period=PERIOD_M3;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*180) Picture1_period=PERIOD_M4;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*240) Picture1_period=PERIOD_M5;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*300) Picture1_period=PERIOD_M6;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*360) Picture1_period=PERIOD_M10;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*600) Picture1_period=PERIOD_M12;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*720) Picture1_period=PERIOD_M15;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*900) Picture1_period=PERIOD_M20;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*1200) Picture1_period=PERIOD_M30;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*1800) Picture1_period=PERIOD_H1;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*3600) Picture1_period=PERIOD_H2;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*7200) Picture1_period=PERIOD_H3;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*10800) Picture1_period=PERIOD_H4;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*14400) Picture1_period=PERIOD_H6;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*21600) Picture1_period=PERIOD_H8;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*28800) Picture1_period=PERIOD_H12;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*43200) Picture1_period=PERIOD_D1;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*86400) Picture1_period=PERIOD_W1;
   if(EndTime-StartTime>(Picture1_width-Axis_Width)*604800) Picture1_period=PERIOD_MN1;
   // changing the period of opened chart
   ChartSetSymbolPeriod(hChart,Symbol(),Picture1_period);
  }

Bu ilk yatırım değilse bakiye değişikliği grafiğinin çizildiği "çizgi" nesnesini oluşturun. Çizgi, yalnızca en az birinin ucu rapor dönemindeyse çizilir. Her iki uç da rapor dönemindeyse çizgi "kalın" olacaktır. Bakiye çizgisinin rengi yeşildir. Bakiye, minimum ve maksimum bakiye aralığının dışındaysa bu aralık ayarlanır.

else
  // if this is not the first deal
  {
   // plotting the balance line, if the deal is in the report period,
   // and setting properties of the balance line
   if(time_curr>=StartTime && time_prev<=EndTime)
     {
      ObjectCreate(hChart,IntegerToString(i),OBJ_TREND,0,time_prev,balance_prev,time_curr,balance);
      ObjectSetInteger(hChart,IntegerToString(i),OBJPROP_COLOR,Green);
      // if both ends of line are in the report period,
      // it will be "thick"
      if(time_prev>=StartTime && time_curr<=EndTime)
        ObjectSetInteger(hChart,IntegerToString(i),OBJPROP_WIDTH,2);
     }
   // if new value of balance exceeds the range
   // of minimal and maximal values, it must be adjusted
   if(balance<min_val) min_val=balance;
   if(balance>max_val) max_val=balance;
  }

Karşılık gelen değişkene zamanın önceki değerini atayın.

// changing the previous time value
time_prev=time_curr;

Yatırım henüz işlenmediyse işleyin.

// if the deal has not been processed yet
if(deal_status[i]<127)
  {

Bu yatırım bakiye yükü ise ve rapor döneminde ise rapora karşılık gelen dize yazılır. Yatırım, işlendi olarak işaretlenir.

// If this deal is balance charge
if(HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_BALANCE)
  {
   // if it's in the report period - write the corresponding string to report.
   if(time_curr>=StartTime && time_curr<=EndTime)
     FileWrite(file_handle,"<tr><td colspan='9'>Balance:</td><td align='right'>",HistoryDealGetDouble(ticket,DEAL_PROFIT),
     "</td></tr>");
   // mark deal as processed
   deal_status[i]=127;
  }

Bu yatırım Al veya Sat ise, bu enstrümanın listede olup olmadığını kontrol edin (symb_list[] dizisi). Listede yoksa listeye dahil edin. symb_pointer değişkeni, geçerli yatırımın enstrüman adını içeren symb_list[] dizisinin öğesini gösterir.

// if this deal is buy or sell
if(HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_BUY || HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_SELL)
  {
   // check if there is instrument of this deal in the list
   symb_flag=false;
   for(j=0;j<symb_total;j++)
     {
      if(symb_list[j]==HistoryDealGetString(ticket,DEAL_SYMBOL))
        {
         symb_flag=true;
         symb_pointer=j;
        }
     }
   // if there is no instrument of this deal in the list
   if(symb_flag==false)
     {
      symb_list[symb_total]=HistoryDealGetString(ticket,DEAL_SYMBOL);
      lots_list[symb_total]=0;
      symb_pointer=symb_total;
      symb_total++;
     }

İlk ve son pozisyonun ömrünü saklayan position_StartTime ve position_EndTime değişkenlerinin başlangıç değerlerini ayarlayın.

// set the initial value for the beginning time of deal
position_StartTime=time_curr;
// set the initial value for the end time of deal
position_EndTime=time_curr;

in_table_volume, in_table_time, in_table_price, out_table_volume, out_table_time, out_table_price, out_table_swap ve out_table_profit değişkenleri tabloları depolayacaktır; bunlar daha büyük tablonun hücrelerinde olacaktır: Hacim, piyasaya giriş zamanı ve fiyatı, hacim, zaman, fiyat, swap ve piyasadan çıkış karı. in_table_volume değişkeni ayrıca finansal enstrümanın adını depolar ve açık pozisyonun yönüne karşılık gelen bir resme bağlantı verir. Tüm bu değişkenlere başlangıç değerleri atayın.

// creating the string in report - instrument, position direction, beginning of table for volumes to enter the market
if(HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_BUY)
   StringConcatenate(in_table_volume,"<tr><td align='left'>",symb_list[symb_pointer],
   "</td><td align='center'><img src='buy.gif'></td><td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>");

if(HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_SELL)
   StringConcatenate(in_table_volume,"<tr><td align='left'>",symb_list[symb_pointer],
   "</td><td align='center'><img src='sell.gif'></td><td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>");
// creating the beginning of time table to enter the market
in_table_time="<td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>";
// creating the beginning of price table to enter the market
in_table_price="<td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>";
// creating the beginning of volume table to exit the market
out_table_volume="<td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>";
// creating the beginning of time table to exit the market
out_table_time="<td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>";
// creating the beginning of price table to exit the market
out_table_price="<td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>";
// creating the beginning of swap table to exit the market
out_table_swap="<td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>";
// creating the beginning of profit table to exit the market
out_table_profit="<td><table border='1' width='100%' bgcolor='#FFFFFF' bordercolor='#DFDFFF'>";

Mevcut ile başlayan tüm yatırımları pozisyon kapanana kadar işleyin. Bunlar daha önce işlenmemişlerse, hepsini işleyin.

// process all deals for this position starting with the current(until position is closed)
for(j=i;j<total_deals_number;j++)
  {
   // if the deal has not been processed yet - process it
   if(deal_status[j]<127)
     {

Yatırımı seçin ve biletini alın.

// select deal, get ticket
ticket=HistoryDealGetTicket(j);

Yatırım, açık pozisyonla aynı enstrümandaysa bunu işleyin. Yatırım zamanını alın. Yatırım süresi, pozisyon süresi aralığının ötesine geçerse aralığı genişletin. Yatırım hacmini alın.

// if the instrument of deal matches the instrument of position, that is processed
if(symb_list[symb_pointer]==HistoryDealGetString(ticket,DEAL_SYMBOL))
  {
   // get the deal time
   time_curr=HistoryDealGetInteger(ticket,DEAL_TIME);
   // If the deal time goes beyond the range of position time
   // - extend position time
   if(time_curr<position_StartTime) position_StartTime=time_curr;
   if(time_curr>position_EndTime) position_EndTime=time_curr;
   // get the volume of deal
   lot_current=HistoryDealGetDouble(ticket,DEAL_VOLUME);

Al ve Sat yatırımları ayrı olarak işlenir. Al yatırımlarıyla başlayın.

// if this deal is buy
if(HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_BUY)
  {

Halihazırda Sat için pozisyon açtıysanız bu Al yatırımı piyasadan çıkacaktır. Ve yatırım hacmi, açılan kısa pozisyon hacminden daha büyük olacaksa, bu giriş/çıkış olacaktır. Dize değişkenlerine gerekli değerleri atayın. deal_status[] dizisine, yatırım tam olarak işleniyorsa 127 değerini veya giriş/çıkış ise 1 değerini atayın; bu yatırım başka bir pozisyon için analiz edilmelidir.

// if position is opened for sell - this will be exit from market
if(NormalizeDouble(lots_list[symb_pointer],2)<0)
  {
   // if buy volume is greater than volume of opened short position - then this is in/out
   if(NormalizeDouble(lot_current+lots_list[symb_pointer],2)>0)
     {
      // creating table of volumes to exit the market - indicate only volume of opened short position
      StringConcatenate(out_table_volume,out_table_volume,"<tr><td align='right'>",DoubleToString(-lots_list[symb_pointer],2),"</td></tr>");
      // mark position as partially processed
      deal_status[j]=1;
     }
   else
     {
      // if buy volume is equal or less than volume of opened short position - then this is partial or full close
      // creating the volume table to exit the market
      StringConcatenate(out_table_volume,out_table_volume,"<tr><td align='right'>",DoubleToString(lot_current,2),"</td></tr>");
      // mark deal as processed
      deal_status[j]=127;
     }

   // creating the time table to exit the market
   StringConcatenate(out_table_time,out_table_time,"<tr><td align='center'>",TimeToString(time_curr,TIME_DATE|TIME_SECONDS),"</td></tr>");

   // creating the price table to exit the market
   StringConcatenate(out_table_price,out_table_price,"<tr><td align='center'>",DoubleToString(HistoryDealGetDouble(ticket,DEAL_PRICE),
   (int)SymbolInfoInteger(symb_list[symb_pointer],SYMBOL_DIGITS)),"</td></tr>");

   // get the swap of current deal
   current_swap=HistoryDealGetDouble(ticket,DEAL_SWAP);

   // if swap is equal to zero - create empty string of the swap table to exit the market
   if(NormalizeDouble(current_swap,2)==0) StringConcatenate(out_table_swap,out_table_swap,"<tr></tr>");
   // else create the swap string in the swap table to exit the market
   else StringConcatenate(out_table_swap,out_table_swap,"<tr><td align='right'>",DoubleToString(current_swap,2),"</td></tr>");

   // get the profit of current deal
   current_profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);

   // if profit is negative (loss) - it is displayed as red in the profit table to exit the market
   if(NormalizeDouble(current_profit,2)<0) StringConcatenate(out_table_profit,out_table_profit,"<tr><td align=right><SPAN style='COLOR: #EF0000'>",
   DoubleToString(current_profit,2),"</SPAN></td></tr>");
   // else - it is displayed as green
   else StringConcatenate(out_table_profit,out_table_profit,"<tr><td align='right'><SPAN style='COLOR: #00EF00'>",
        DoubleToString(current_profit,2),"</SPAN></td></tr>");
  }

Halihazırda uzun pozisyon açtıysanız bu yatırımdaki satın alma, piyasaya giriş olacaktır (ilk veya ek). Bu yatırıma karşılık gelen deal_status[] dizi öğesi 1 değerine sahipse giriş/çıkış yapılmış demektir. Dize değişkenlerini gerekli değerlerle atayın ve yatırımı işlendi olarak işaretleyin (dege_status[] dizisinin karşılık gelen öğesini 127 değerine atayın).

else
   // if position is opened for buy - this will be the enter to the market
   {
    // if this deal has been already partially processed (in/out)
    if(deal_status[j]==1)
      {
       // create the volume table of entering the market (volume, formed after in/out, is put here)
       StringConcatenate(in_table_volume,in_table_volume,"<tr><td align='right'>",DoubleToString(lots_list[symb_pointer],2),"</td></tr>");
       // indemnity of volume change, which will be produced (the volume of this deal is already taken into account)
       lots_list[symb_pointer]-=lot_current;
      }
    // if this deal has not been processed yet, create the volume table to enter the market
    else StringConcatenate(in_table_volume,in_table_volume,"<tr><td align='right'>",DoubleToString(lot_current,2),"</td></tr>");

    // creating the time table of entering the market
    StringConcatenate(in_table_time,in_table_time,"<tr><td align center>",TimeToString(time_curr,TIME_DATE|TIME_SECONDS),"</td></tr>");

    // creating the price table of entering the market
    StringConcatenate(in_table_price,in_table_price,"<tr><td align='center'>",DoubleToString(HistoryDealGetDouble(ticket,DEAL_PRICE),
    (int)SymbolInfoInteger(symb_list[symb_pointer],SYMBOL_DIGITS)),"</td></tr>");

    // mark deal as processed
    deal_status[j]=127;
   }

Pozisyon hacmini mevcut yatırım hacmi olarak değiştirin. Pozisyon kapalıysa (hacim sıfıra eşitse) bu pozisyonu işlemeyi bırakın (j değişkenli döngüden çıkın) ve sonraki işlenmemiş yatırımı arayın (i değişkenli döngüde).

 // change of position volume by the current instrument, taking into account the volume of current deal
 lots_list[symb_pointer]+=lot_current;
 // if the volume of opened position by the current instrument became equal to zero - position is closed
 if(NormalizeDouble(lots_list[symb_pointer],2)==0 || deal_status[j]==1) break;
}

Sat yatırımları benzer şekilde işlenir ve ardından j değişkenli döngüden çıkarız.

       // if this deal is sell
       if(HistoryDealGetInteger(ticket,DEAL_TYPE)==DEAL_TYPE_SELL)
         {
          // if position has been already opened for buy - this will be the exit from market
          if(NormalizeDouble(lots_list[symb_pointer],2)>0)
            {
             // if sell volume is greater than volume of opened long position - then this is in/out
             if(NormalizeDouble(lot_current-lots_list[symb_pointer],2)>0)
               {
                // creating table of volumes to exit the market - indicate only volume of opened long position
                StringConcatenate(out_table_volume,out_table_volume,"<tr><td align='right'>",DoubleToString(lots_list[symb_pointer],2),"</td></tr>");
                // mark position as partially processed
                deal_status[j]=1;
               }
             else
               {
                // if sell volume is equal or greater than volume of opened short position - then this is partial or full close
                // creating the volume table to exit the market
                StringConcatenate(out_table_volume,out_table_volume,"<tr><td align='right'>",DoubleToString(lot_current,2),"</td></tr>");
                // mark deal as processed
                deal_status[j]=127;
               }

             // creating the time table to exit the market
             StringConcatenate(out_table_time,out_table_time,"<tr><td align='center'>",TimeToString(time_curr,TIME_DATE|TIME_SECONDS),"</td></tr>");

             // creating the price table to exit the market
             StringConcatenate(out_table_price,out_table_price,"<tr><td align='center'>",DoubleToString(HistoryDealGetDouble(ticket,DEAL_PRICE),
             (int)SymbolInfoInteger(symb_list[symb_pointer],SYMBOL_DIGITS)),"</td></tr>");

             // get the swap of current deal
             current_swap=HistoryDealGetDouble(ticket,DEAL_SWAP);

             // if swap is equal to zero - create empty string of the swap table to exit the market
             if(NormalizeDouble(current_swap,2)==0) StringConcatenate(out_table_swap,out_table_swap,"<tr></tr>");
             // else create the swap string in the swap table to exit the market
             else StringConcatenate(out_table_swap,out_table_swap,"<tr><td align='right'>",DoubleToString(current_swap,2),"</td></tr>");

             // get the profit of current deal
             current_profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);

             // if profit is negative (loss) - it is displayed as red in the profit table to exit the market
             if(NormalizeDouble(current_profit,2)<0) StringConcatenate(out_table_profit,out_table_profit,"<tr><td align='right'>
             <SPAN style='COLOR: #EF0000'>",DoubleToString(current_profit,2),"</SPAN></td></tr>");
             // else - it is displayed as green
             else StringConcatenate(out_table_profit,out_table_profit,"<tr><td align='right'><SPAN style='COLOR: #00EF00'>",
                  DoubleToString(current_profit,2),"</SPAN></td></tr>");
            }
          else
            // if position is opened for sell - this will be the enter to the market
            {
             // if this deal has been already partially processed (in/out)
             if(deal_status[j]==1)
               {
                // create the volume table of entering the market (volume, formed after in/out, is put here)
                StringConcatenate(in_table_volume,in_table_volume,"<tr><td align='right'>",DoubleToString(-lots_list[symb_pointer],2),"</td></tr>");

                // indemnity of volume change, which will be produced (the volume of this deal is already taken into account)
                lots_list[symb_pointer]+=lot_current;
               }
             // if this deal has not been processed yet, create the volume table to enter the market
             else StringConcatenate(in_table_volume,in_table_volume,"<tr><td align='right'>",DoubleToString(lot_current,2),"</td></tr>");

             // creating the time table of entering the market
             StringConcatenate(in_table_time,in_table_time,"<tr><td align='center'>",TimeToString(time_curr,TIME_DATE|TIME_SECONDS),"</td></tr>");

             // creating the price table of entering the market
             StringConcatenate(in_table_price,in_table_price,"<tr><td align='center'>",DoubleToString(HistoryDealGetDouble(ticket,DEAL_PRICE),
             (int)SymbolInfoInteger(symb_list[symb_pointer],SYMBOL_DIGITS)),"</td></tr>");

             // mark deal as processed
             deal_status[j]=127;
            }
          // change of position volume by the current instrument, taking into account the volume of current deal
          lots_list[symb_pointer]-=lot_current;
          // if the volume of opened position by the current instrument became equal to zero - position is closed
          if(NormalizeDouble(lots_list[symb_pointer],2)==0 || deal_status[j]==1) break;
         }
      }
   }
}

Pozisyonun açıldığı zaman rapor dönemindeyse (en azından kısmen) ilgili giriş "report.html" dosyasına gönderilir.

// if the position period is in the the report period - the position is printed to report
if(position_EndTime>=StartTime && position_StartTime<=EndTime) FileWrite(file_handle,
in_table_volume,"</table></td>",
in_table_time,"</table></td>",
in_table_price,"</table></td>",
out_table_volume,"</table></td>",
out_table_time,"</table></td>",
out_table_price,"</table></td>",
out_table_swap,"</table></td>",
out_table_profit,"</table></td></tr>");

balance_prev değişkenini bakiye değeriyle atayın. i değişkenli döngüden çıkın.

   }
 // changing balance
 balance_prev=balance;
}

HTML-dosyasının sonunu yazın (resimlere bağlantılar, orta hizalamanın sonu, ana bölümün sonu, HTML-belgesinin sonu). "report.html" dosyasını kapatın.

// create the end of html-file
   FileWrite(file_handle,
         "</table><br><br>"+
            "<h2>Balance Chart</h2><img src='picture1.gif'><br><br><br>"+
            "<h2>Price Chart</h2><img src='picture2.gif'>"+
         "</center>"+
         "</body>"+
   "</html>");
// close file
   FileClose(file_handle);

Zaman aşımı sabitinde belirtilen süreden daha uzun olmayan grafik güncellemesinin beklenmesi.

// get current time
time_curr=TimeCurrent();
// waiting for chart update
while(SeriesInfoInteger(Symbol(),Picture1_period,SERIES_BARS_COUNT)==0 && TimeCurrent()-time_curr<timeout) Sleep(1000);

Grafiğin sabit maksimum ve minimum değerlerinin ayarlanması.

// setting maximal and minimal values for the balance chart (10% indent from upper and lower boundaries)
ChartSetDouble(hChart,CHART_FIXED_MAX,max_val+(max_val-min_val)/10);
ChartSetDouble(hChart,CHART_FIXED_MIN,min_val-(max_val-min_val)/10);

Bakiye grafiğinin özelliklerinin ayarlanması.

// setting properties of the balance chart
ChartSetInteger(hChart,CHART_MODE,CHART_LINE);                // chart as line
ChartSetInteger(hChart,CHART_FOREGROUND,false);               // chart on foreground
ChartSetInteger(hChart,CHART_SHOW_BID_LINE,false);            // hide BID line
ChartSetInteger(hChart,CHART_COLOR_VOLUME,White);             // volumes and orders levels are white
ChartSetInteger(hChart,CHART_COLOR_STOP_LEVEL,White);         // SL and TP levels are white
ChartSetInteger(hChart,CHART_SHOW_GRID,true);                 // show grid
ChartSetInteger(hChart,CHART_COLOR_GRID,LightGray);           // grid is light-gray
ChartSetInteger(hChart,CHART_SHOW_PERIOD_SEP,false);          // hide period separators
ChartSetInteger(hChart,CHART_SHOW_VOLUMES,CHART_VOLUME_HIDE); // hide volumes
ChartSetInteger(hChart,CHART_COLOR_CHART_LINE,White);         // chart is white
ChartSetInteger(hChart,CHART_SCALE,0);                        // minimal scale
ChartSetInteger(hChart,CHART_SCALEFIX,true);                  // fixed scale on vertical axis
ChartSetInteger(hChart,CHART_SHIFT,false);                    // no chart shift
ChartSetInteger(hChart,CHART_AUTOSCROLL,true);                // autoscroll enabled
ChartSetString(hChart,CHART_COMMENT,"BALANCE");               // comment on chart

Bakiye grafiğinin yeniden çizilmesi.

// redraw the balance chart
ChartRedraw(hChart);
Sleep(8000);

Grafiğin ekran görüntüsünü alın ("picture1.gif" resmini kaydedin). Grafiğin genişliği rapor döneminin genişliğine göre ayarlanır (ancak tatil günleri nedeniyle genellikle yanlışlıklar olur ve grafik, bakiye değişikliği eğrisinden daha geniş olur), yükseklik genişliğin yarısı olarak hesaplanır.

// screen shooting the balance chart
ChartScreenShot(hChart,"picture1.gif",(int)(EndTime-StartTime)/PeriodSeconds(Picture1_period),
(int)(EndTime-StartTime)/PeriodSeconds(Picture1_period)/2,ALIGN_RIGHT);

Grafikteki tüm nesneleri silin ve kapatın.

// delete all objects from the balance chart
ObjectsDeleteAll(hChart);
// close chart
ChartClose(hChart);

FTP aracılığıyla dosya gönderimine izin veriliyorsa üç dosya gönderin: "report.html", picture1.gif "and" picture2.gif ".

// if report publication is enabled - send via FTP
// HTML-file and two images - price chart and balance chart
if(TerminalInfoInteger(TERMINAL_FTP_ENABLED))
   {
    SendFTP("report.html");
    SendFTP("picture1.gif");
    SendFTP("picture2.gif");
   }
}

Şimdilik program açıklamasını tamamladık. FTP aracılığıyla dosya göndermek için MetaTrader 5 ayarlarını yapmalısınız - Araçlar menüsüne, ardından Seçenekler'e gidin ve Yayıncı sekmesini açın (Şekil 4).

Şekil 4. FTP aracılığıyla rapor yayınlama seçenekleri.

Şekil 4. FTP aracılığıyla rapor yayınlama seçenekleri.

Seçenekler iletişim kutusunda "Etkinleştir" seçeneğini işaretlemeniz, erişim için hesap numarası, FTP adresi, yol, oturum açma ve parola belirtmeniz gerekir. Yenileme dönemselliği önemli değildir.

Şimdi script dosyasını çalıştırabilirsiniz. Çalıştırdıktan sonra bakiye grafiği ekranda birkaç saniyeliğine belirir ve ardından kaybolur. Günlük'te olası hatayı bulabilir ve dosyaların FTP aracılığıyla gönderilip gönderilmediğini görebilirsiniz. Her şey yolunda giderse, sunucuda belirtilen klasörde üç yeni dosya görünecektir. Oraya ok resimleri içeren iki dosya yerleştirirseniz ve WWW-sunucusu yapılandırılmışsa ve çalışıyorsa web tarayıcısı aracılığıyla bir rapor açabilirsiniz.

2. Cep telefonuna SMS olarak bildirim gönderme

Bilgisayarınızdan ve diğer elektronik cihazlarınızdan uzakta olduğunuz ve elinizin altında yalnızca bir cep telefonunun bulunduğu zamanlar vardır. Ancak, hesabınızdaki alım satımı kontrol etmek veya finansal enstrüman için fiyat tekliflerini izlemek istiyorsunuzdur. Bu durumda, cep telefonuna SMS ile bildirim gönderme seçeneğini ayarlayabilirsiniz. Birçok cep telefonu operatörü (ve üçüncü taraflar), belirli bir e-posta adresine gönderilen mesajları mektup olarak almanıza olanak tanıyan E-POSTA-SMS hizmeti sağlar.

Bunun için bir e-posta kutunuz olmalıdır (özellikle SMTP sunucunuzu bilmelisiniz). MetaTrader 5 ayarlarınızı yapın; Araçlar menüsüne, ardından Seçenekler'e gidin ve E-posta sekmesini açın (Şekil 5).

Şekil 5. E-posta yoluyla bildirim gönderme özelliğini ayarlama

Şekil 5. E-posta yoluyla bildirim gönderme özelliğini ayarlama

"Etkinleştir" seçeneğini işaretleyin, SMTP sunucu adresini, kullanıcı adını ve parolayı, gönderenin adresini (e-postanız) ve alıcı adresini - SMS olarak mesaj göndermek için kullanılan e-posta adresini belirtin (cep telefonu operatörünüze danışın). Her şey doğruysa, "Test" düğmesine tıkladığınızda bir doğrulama mesajı gönderilecektir (Günlük'teki ek bilgilere bakınız).

Fiyat belirli bir düzeye ulaştığında haberdar olmanın en kolay yolu uyarı oluşturmaktır. Bunu yapmak için uygun "Araç Kutusu" sekmesini açın, sağ tıklayın ve "Oluştur" seçeneğini seçin (Şekil 6).

Şekil 6. Uyarı oluşturma.

Şekil 6. Uyarı oluşturma.

Bu pencerede "Etkinleştir" seçeneğini işaretleyin, "E-posta" eylemini seçin, finansal enstrüman, durum seçin, durum için değer girin ve mesaj metnini yazın. Mesajın tekrar tekrar gelmesini istemiyorsanız "Maksimum yineleme" alanına 1 değerini girin. Tüm alanlar doldurulduğunda, Tamam'a tıklayın.

Bir MQL5 programından mesaj gönderirsek daha fazla imkanımız olacaktır. SendMail() işlevini kullanacağız. Bunun iki parametresi vardır. İlki başlık, ikincisi mesajın gövdesidir.

SendMail() işlevini alım satım talebinden sonra (OrderSend() işlevi) veya Alım Satım olay işleyicisinde çağırabilirsiniz. Böylece alım satım etkinlikleriyle ilgili bildirimler alacağız; piyasaya giriş, talimatlar verme, pozisyonları kapatma. Veya SendMail() işlevini OnTimer() işlevinin içine yerleştirebilirsiniz - mevcut fiyat teklifleri hakkında periyodik bildirimler alacağız. Belirli alım satım sinyalleri göründüğünde - gösterge çizgileri kesiştiğinde, fiyat bazı çizgilere ve düzeylere ulaştığında vb. - bildirimlerin gönderilmesini düzenleyebilirsiniz.

Birkaç örneği ele alalım.

Bir Expert Advisor'da veya Script dosyasında

OrderSend(request,result};

 şunları değiştirdikten sonra

string msg_subj,msg_text;
if(OrderSend(request,result))
  {
   switch(request.action)
     {
      case TRADE_ACTION_DEAL:
         switch(request.type)
           {
            case ORDER_TYPE_BUY:
               StringConcatenate(msg_text,"Buy ",result.volume," ",request.symbol," at price ",result.price,", SL=",request.sl,", TP=",request.tp);
               break;
            case ORDER_TYPE_SELL:
               StringConcatenate(msg_text,"Sell ",result.volume," ",request.symbol," at price ",result.price,", SL=",request.sl,", TP=",request.tp);
               break;
           }
         break;
      case TRADE_ACTION_PENDING:
         switch(request.type)
           {
            case ORDER_TYPE_BUY_LIMIT:
               StringConcatenate(msg_text,"Set BuyLimit ",result.volume," ",request.symbol," at price ",request.price,", SL=",request.sl,", TP=",request.tp);
               break;
            case ORDER_TYPE_SELL_LIMIT:
               StringConcatenate(msg_text,"Set SellLimit ",result.volume," ",request.symbol," at price ",request.price,", SL=",request.sl,", TP=",request.tp);
               break;
            case ORDER_TYPE_BUY_STOP:
               StringConcatenate(msg_text,"Set BuyStop ",result.volume," ",request.symbol," at price ",request.price,", SL=",request.sl,", TP=",request.tp);
               break;
            case ORDER_TYPE_SELL_STOP:
               StringConcatenate(msg_text,"Set SellStop ",result.volume," ",request.symbol," at price ",request.price,", SL=",request.sl,", TP=",request.tp);
               break;
            case ORDER_TYPE_BUY_STOP_LIMIT:
               StringConcatenate(msg_text,"Set BuyStopLimit ",result.volume," ",request.symbol," at price ",request.price,", stoplimit=",request.stoplimit,
               ", SL=",request.sl,", TP=",request.tp);
               break;
            case ORDER_TYPE_SELL_STOP_LIMIT:
               StringConcatenate(msg_text,"Set SellStop ",result.volume," ",request.symbol," at price ",request.price,", stoplimit=",request.stoplimit,
               ", SL=",request.sl,", TP=",request.tp);
               break;
           }
         break;
       case TRADE_ACTION_SLTP:
          StringConcatenate(msg_text,"Modify SL&TP. SL=",request.sl,", TP=",request.tp);
          break;
       case TRADE_ACTION_MODIFY:
          StringConcatenate(msg_text,"Modify Order",result.price,", SL=",request.sl,", TP=",request.tp);
          break;
       case TRADE_ACTION_REMOVE:
          msg_text="Delete Order";
          break;
     }
  }
  else msg_text="Error!";
StringConcatenate(msg_subj,AccountInfoInteger(ACCOUNT_LOGIN),"-",AccountInfoString(ACCOUNT_COMPANY));
SendMail(msg_subj,msg_text);

alım satım talebinden sonra OrderSend() işlevi SendMail() işlevini kullanarak bir mesaj gönderecektir. Bu, alım satım hesap numarası, brokerin adı ve yapılan işlemler (alma, satma, bekleyen talimat verme, talimatı değiştirme veya silme) hakkında aşağıdakiler gibi bilgileri içerecektir:

59181-MetaQuotes Software Corp. Buy 0.1 EURUSD at price 1.23809, SL=1.2345, TP=1.2415

Ve OnInit() gövdesi içindeki herhangi bir Expert Advisor veya Göstergedeyse, zamanlayıcıyı EventSetTimer() işlevini kullanarak başlatacaksınız (bu, yalnızca bir parametre içerir - saniye cinsinden zamanlayıcı dönemi):

void OnInit()
  {
   EventSetTimer(3600);
  }

 OnDeinit() içinde, EventKillTimer() kullanarak kapatmayı unutmayın:

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

ve SendMail() kullanarak mesajlar göndermek için OnTimer() içinde:

void OnTimer()
  {
   SendMail(Symbol(),DoubleToString(SymbolInfoDouble(Symbol(),SYMBOL_BID),_Digits));
  }

o zaman mevcut finansal enstrümanın fiyatı ile ilgili belirli dönemlerle ilgili mesajlar alacaksınız.

Sonuç

Bu makalede, resim dosyaları ve bir HTML oluşturmak için MQL5 programının nasıl kullanılacağı ve bunların FTP aracılığıyla WWW-sunucusuna nasıl yükleneceği açıklanmıştır. Ayrıca cep telefonunuza SMS olarak bildirim gönderme özelliğini nasıl yapılandıracağınız da ele alınmıştır.  

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

Ekli dosyalar |
report.zip (33.08 KB)
sendreport_en.mq5 (32.06 KB)
Alım Satım için MQL5'te Aktif Kontrol Panelleri Oluşturma Alım Satım için MQL5'te Aktif Kontrol Panelleri Oluşturma
Makalede, MQL5'te aktif kontrol panellerinin geliştirilmesi sorunu ele alınmaktadır. Arayüz öğeleri, olay işleme mekanizması tarafından yönetilir. Ayrıca, kontrol öğeleri özelliklerinin esnek bir şekilde ayarlanması seçeneği de mevcuttur. Aktif kontrol paneli, pozisyonlarla çalışılmasına ve piyasa ve bekleyen talimatların ayarlanmasına, değiştirilmesine ve silinmesine izin verir.
Farklı Kıtalardaki Saat Dilimi Farklılıklarına Dayalı Bir Alım Satım Stratejisi Örneği Farklı Kıtalardaki Saat Dilimi Farklılıklarına Dayalı Bir Alım Satım Stratejisi Örneği
İnternette gezinirken, size çeşitli önerilerde bulunacak birçok strateji bulmak kolaydır. İç yüzünü bilen bir kişinin yaklaşımını ele alalım ve farklı kıtalardaki saat dilimlerindeki farklılıklara dayalı olarak strateji oluşturma sürecini inceleyelim.
Expert Advisor'ın MQL5'te ICQ ile Bağlantısı Expert Advisor'ın MQL5'te ICQ ile Bağlantısı
Bu makalede, Expert Advisor ve ICQ kullanıcıları arasındaki bilgi alışverişi yöntemi açıklanmakta olup birkaç örnek sunulmaktadır. Sunulan materyal, bir istemci terminalinden, bir ICQ istemcisi aracılığıyla cep telefonlarına veya PDA'larına alım satım bilgilerini uzaktan almak isteyen kişiler için ilgi çekici olacaktır.
Genetik Algoritmalar - Çok Kolay! Genetik Algoritmalar - Çok Kolay!
Bu makalede yazar, kişisel olarak geliştirilmiş bir genetik algoritmanın kullanımıyla gelişimsel hesaplamaları ele almaktadır. Algoritmanın işleyişini örnekler kullanarak göstermekte olup kullanımı için pratik öneriler sunmaktadır.