外部指标的提醒和注释。 通过外部扫描进行多货币分析

Vladimir | 11 四月, 2016

简介

在之前的文章中,我们看到了如何从使用图表中显示的 Wingdings 符号作为信息源的指标获得信息(“外部指标的提醒和注释”)以及如何对使用指标缓冲区储存信息的指标创建基于指标的提醒(“外部指标的提醒和注释 第二部分”),但信息输出是通过颜色变化实现。

存储在指标缓冲区中的指标线的交叉代表了另一种告知用户指标行为的方式。

正如我们所见,从指标缓冲区获得值本身并不复杂,不会影响处理器的负载。 在我们的指标中,我们将实现显示多货币信息的可能性。

如果可用的金融工具数量较大,交易者会因为持续的图表监控导致眼睛过于疲劳。 因此交易者通常只选择几个交易品种进行交易。

之后可能出现其他货币对进行一次交易或多次交易的机遇,但它们的图表并未在适当的时刻在屏幕上打开。 这就是我们需要可用金融工具的多货币分析的原因。

基于这种考虑,我产生了一个想法,利用基于指标的提醒功能,快速显示可用金融工具列表的变动信息。



基于多货币指标的提醒

我们先来看一下从外部指标的指标缓冲区获得信息的数据处理程序块的代码。

double buffer1, buffer2, buffer12, buffer22;
// Analyze the first and second bars in the charts
            buffer1  = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 1);
            buffer12 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 2);
            buffer2  = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 1);
            buffer22 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 2);
            if(buffer12<=buffer22&&buffer1>buffer2)
               {
                  Alert (text+"UP"); // There is a crossover
                  send_email (text+"UP");
                  return (1);
               }
            if(buffer12>=buffer22&&buffer1<buffer2)
               {
                  Alert (text+"DN"); // There is a crossover
                  send_email (text+"DN");
                  return (1);
               } 
            return (0);

可见,这里的内容都很简单。 在上一篇文章中,我们遇到过类似的逻辑。 上一次我们使用了所显示缓冲区的颜色变化,这里 我们使用这些缓冲区相互之间的位置值

必要的处理将作为单独的程序块实现。 多货币和多时间范围分析需要反复使用该过程。

可用金融工具列表将储存在外部文件中,在未来需要改动时,允许我们简化进行改动的过程。 使用这种方法,如果要修改可用金融工具列表,用户可以独立的重新创建或改动可用金融工具的文件,而不必修改指标的程序代码。

在文章的末尾,你将会看到如何创建可用金融工具的自定义文件。

下面提供了一个读取文件数据的子程序。

//+------------------------------------------------------------------+
//|                                           SymbolList_fromSet.mq4 |
//|                                      Copyright © 2006, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+
void LoadFileToSymbol()
   {
      {
              int file_handle = FileOpen(SetFile_name + ".set", FILE_READ);
              //---- If an error occurred
              if(file_handle < 0)
                {
                         Print("Error No.", GetLastError(), " when opening the file!!!");
                         return(-1);
                }
              int SymbolsCount = 0;
              while(true)
                {
                         Symbols[SymbolsCount] = FileReadString(file_handle);
                         //---- If you have reached the end of the file, stop
                         if(GetLastError() == 4099) 
                             break;
                         if(FileIsEnding(file_handle)) 
                             break;
                         SymbolsCount ++;
                         ArrayResize(Symbols, SymbolsCount + 1);
                }
              FileClose(file_handle);
      }
   
   }  
//--------------------------------------------------------------+

现在,准备好金融工具的数组后,我们只需要实现每个金融工具的多时间范围处理。

我们将从当前的时间范围开始计算。

// Analyze the array of symbols (Calculations on the current and all lower time frames)
         for (int i=0; i<ArraySize(Symbols); i++)
            {  Total = 0;
               switch (Period())
                  {
                     case 43200: Total = Total +  process ( Symbols[i], 43200);
                     case 10080: Total = Total +  process ( Symbols[i], 10080);
                     case  1440: Total = Total +  process ( Symbols[i],  1440);
                     case   240: Total = Total +  process ( Symbols[i],   240);
                     case    60: Total = Total +  process ( Symbols[i],    60);
                     case    30: Total = Total +  process ( Symbols[i],    30);
                     case    15: Total = Total +  process ( Symbols[i],    15);
                     case     5: Total = Total +  process ( Symbols[i],     5);
//                     case     1: Total = Total +  process ( Symbols[i],     1);
                  }

计算从当前时间范围到最小的时间范围进行。 所以,如果你需要计算从日时间范围开始的提醒,指标所在的图表应该以日时间范围打开。 如果你需要得到从小时时间范围开始的信号,图表时间范围必须是小时,以此类推。 指标仅在每个新柱上重新计算。

这种方法可以使用户更加方便的处理指标的重新计算:只需更改工作时间范围,而不必添加额外的参数和计算函数到代码中。

对工作于一分钟时间范围上的字符串添加注释。 如果你需要使用一分钟时间范围的指标,需要对其取消注释。

//                     case     1: Total = Total +  AlertComment ( Symbols[i],     1);

本文随附的 2MA_forAlert.mq4 指标用作我们指标的数据源。 2MA_forAlert 是一个显示两条移动平均线的简单指标。 你也可以使用任何其他具有两个缓冲区(两条线)的指标,例如,随机指标和 MACD 指标等。

下面是使用不同的指标时终端提醒的外观。

储存线值的缓冲区可能有不同的顺序。 例如:

0 - 主线

1 - 信号线

或者:

0 - 信号线

1 - 主线

所以,在使用外部指标时,你应该自己确定使用线的顺序。 在出现错误的提醒通知时,应改变输入参数。

extern int       ExtBuff1      = 0;
extern int       ExtBuff2      = 1;

所有的 8 个可用缓冲区(编号从 0 到 7)可以用作参数。

既然指标使用了具有金融工具列表的外部文件,我将展示如何在终端中生成该外部文件。

首先,我们在数据窗口创建所有的必要金融工具。为此,我们需要:

1. 打开所有的可用金融工具。

2. 只留下我们需要获得其信号的金融工具。

应该有交易中使用的尽可能多的金融工具。

3. 然后在“市场报价”窗口上右击以保存文件。

4. 文件应保存在包含 MetaTrader 的 Expert Advisor 文件的文件夹。

文件可以任意命名,但是不能修改 .set 文件扩展名。 本文提供的示例使用了 forexall.set 文件。

extern string    SetFile_name  = "forexall"; // File that contains symbols of user instruments

创建文件后,你应该为每个交易品种逐个打开图表,使终端加载历史数据。 否则,可能有的金融工具没有经过处理。

如果你将文件保存在默认的文件夹 \experts\ symbolsets,确保将其复制到 MetaTrader 的 \experts\files 文件夹,因为这是指标可以从中打开文件的唯一文件夹(MetaTrader 限制)。 在指标中,你应该进一步输入文件的名称,用来读取其中包含的可用金融工具的数据。

你也可以将多货币扫描程序上的信息发送到电子邮件。 只要将相应的参数值设为真,就可以通过电子邮件获得信号。

extern bool      Signal_email  = false;

有的用户继续对代码进行开发,通过实现重定向将信号通过短信服务发送至他们的手机。 每人的方法都不相同。

所有的指标应位于 MetaTrader 的 \experts\indicators文件夹。



总结

这种方法可以让你使用提醒功能构建各种模块的信息空间,而不必学习编程或寻找能够在程序中实现你想法的专家。 对我们来说,最重要的事情是获得及时的信息。

最后,我将提供提醒指标的完整代码。

//+------------------------------------------------------------------+
//|                                                    Alert_MT4.mq4 |
//|                                      Copyright © 2009, Fibook.ru |
//|                                             http://www.fibook.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Fibook.ru"
#property link      "http://www.fibook.ru"

#property indicator_chart_window

extern string    SetFile_name="forexall"; // File that contains symbols of user instruments
extern string    nameIndicator = "input indicator name";
extern int       ExtBuff1      = 0;
extern int       ExtBuff2      = 1;
extern string    UserText      = "Cross";
extern bool      Signal_email  = false;

string Symbols[1],text;
int expBars=0;
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
// If there is no new bar, exit
   if(!isNewBar()) return;
   int Total;
//---- Check for input parameter errors
   if(ControlError()==false) return;
//---- Load symbols from the file to the Symbols array
   LoadFileToSymbol();
//----

// Analyze the array of symbols (Calculations on the current and all lower time frames)
   for(int i=0;i<ArraySize(Symbols);i++)
     {
      Total=0;
      switch(Period())
        {
         case 43200: Total = Total +  process ( Symbols[i], 43200);
         case 10080: Total = Total +  process ( Symbols[i], 10080);
         case  1440: Total = Total +  process ( Symbols[i],  1440);
         case   240: Total = Total +  process ( Symbols[i],   240);
         case    60: Total = Total +  process ( Symbols[i],    60);
         case    30: Total = Total +  process ( Symbols[i],    30);
         case    15: Total = Total +  process ( Symbols[i],    15);
         case     5: Total = Total +  process ( Symbols[i],     5);
         //                     case     1: Total = Total +  process ( Symbols[i],     1);
        }
      if(Total>1)
        {
         text=StringConcatenate(" Warning!!!      ",Symbols[i]," have ",UserText," for ",Total," TF");
         Alert(text);
         send_email(text);
        }
     }

//----
   return(0);
  }
//+------------------------------------------------------------------+

int process(string Sym_,int TF)
  {
   text=StringConcatenate(Sym_," ",TF," indicator ",nameIndicator," Crossing line ");
   double buffer1,buffer2,buffer12,buffer22;
// Analyze the first and second bars in the charts
   buffer1  = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 1);
   buffer12 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff1, 2);
   buffer2  = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 1);
   buffer22 = iCustom(Sym_, TF, nameIndicator, 0, ExtBuff2, 2);
   if(buffer12<=buffer22 && buffer1>buffer2)
     {
      Alert(text+"UP"); // There is a crossover
      send_email(text+"UP");
      return(1);
     }
   if(buffer12>=buffer22 && buffer1<buffer2)
     {
      Alert(text+"DN"); // There is a crossover
      send_email(text+"DN");
      return(1);
     }
   return(0);

  }
//+------------------------------------------------------------------+
//|                                           SymbolList_fromSet.mq4 |
//|                                      Copyright © 2006, komposter |
//|                                      mailto:komposterius@mail.ru |
//+------------------------------------------------------------------+

void LoadFileToSymbol()
  {
     {
      int file_handle=FileOpen(SetFile_name+".set",FILE_READ);
      //---- If an error occurred
      if(file_handle<0)
        {
         Print("Error No.",GetLastError()," when opening the file!!!");
         return(-1);
        }
      int SymbolsCount=0;
      while(true)
        {
         Symbols[SymbolsCount]=FileReadString(file_handle);
         //---- If you have reached the end of the file, stop
         if(GetLastError()==4099)
            break;
         if(FileIsEnding(file_handle))
            break;
         SymbolsCount++;
         ArrayResize(Symbols,SymbolsCount+1);
        }
      FileClose(file_handle);
     }

  }
//--------------------------------------------------------------+
void send_email(string text)
  {
   if(Signal_email==true) SendMail("Alert ",text);
  }
//--------------------------------------------------------------+
bool ControlError()
  {
// Check whether the indicator name has been entered
   if(nameIndicator=="input indicator name")
     {
      Alert("Enter the indicator name ");
      return(false);
     }
// Check whether the file containing the symbols exists
   int handle;
   handle=FileOpen(SetFile_name+".set",FILE_CSV|FILE_READ,';');
   if(handle<1)
     {
      Alert("The ",SetFile_name,".set file could not be found, last error ",GetLastError());
      return(false);
     }
// Check if there is any error in the assignment of input variables of the analyzed indicator buffers
   if(ExtBuff1>7 || ExtBuff2>7)
     {
      Alert("Incorrect parameters of the ExtBuff1 or ExtBuff2 buffer");
      return(false);
     }
   if(ExtBuff1==ExtBuff2)
     {
      Alert("Error: ExtBuff1 and ExtBuff2 cannot be equal");
      return(false);
     }

   return(true);
  }
/*----------------------------------------------------------------------+
 |The function will return true if the new bar appears, otherwise false |
 +---------------------------------------------------------------------*/
bool isNewBar()
  {
   bool res=false;
   if(expBars!=Bars)
     {
      expBars=Bars;
      res=true;
     }
   return(res);
  }
//+------------------------------------------------------------------+