股票量化软件:Elder-Ray (多头力度和空头力度)

在本文中,我们将从简单到复杂遍历所有阶段,并检查两种类型的交易系统: 

  1. 同一图表上的所有指标(当然,在一个时间时间帧内);
  2. 与“三重选择”系统相结合。

本文中的 EA 仅适用于净持结算帐户。 

关键要点

为了掌握交易系统背后的理念,有必要了解每个 Elder-Ray 元素:价格,EMA,每根柱线上的多头/空头力度指标的高点和低点,以及多头和空头的强度。

  • 价格 — 关于资产价值的现行协约。 预期价格上涨的同时买入,在预期价格下跌的情况下卖出。 一笔成交仅在出现急切的买家和卖家时才能进行。
  • EMA — 指数均线。 它反映出某一区间内资产价值的平均值。 例如,D1 上的 EMA(13) 是过去 13 天的资产平均价值。 为什么使用指数均线比简单移动平均线更好? A. Elder 在其书中第 4.2 节(“移动平均线”)中回答了这个问题。 简言之,与简单平均值相比,EMA 对趋势变化更敏感。
  • 多头力度最大 显示给定柱线图上的最大多头力度。 当价格上涨时,多头赚取利润,因此直到价格达到最高价位前一直做多。 多头力度最大值是多头希望价格走向更高,但没有后续资金做多的时刻。
  • 空头力度最小 显示给定柱线上的最大空头强度。 当价格下跌时,空头获利,因此,在价格达到最低价格之前做空。 空头力度最小是空头希望价格进一步下调,但已无力做到这一点的时刻。
  • 多头力度 展示多头将价格提升到高于资产平均价值的能力。 通常,多头强度高于零。 如果它低于零,那么这意味着多头陷入恐慌,并即将失去动力。
  • 空头力度 反映出空头将价格拉低到资产平均价值以下的能力。 通常,空头强度低于零。 如果它高于零,则意味着多头太强,且空头即将失去动力。

选项 1:单一图表上的所有指标

我们将在 D1 时间帧内探索期货和股票。 所有三个指标(多头力度,空头力度和 EMA)都放在一张图表上。 所有指标的均化周期为 13。

买入规则

  • 趋势上升(根据 EMA);
  • 空头力度 低于零但走高;
  • BuyStop 挂单位于最近两天的最大值之上,而保护性止损位于最后的最小值以下。

CAT, Daily 买入信号

卖出规则

  • 趋势走低(根据 EMA);
  • 空头力度高于零但走低;
  • SellStop 挂单位于最近两天的最小值之下,而保护性止损位于最后的最大值以上。

CAT, Daily 卖出信号

交易规则

观察图例 1 和图例 2,我们可以看到在“单一图表上的所有指标”选项中,买入和卖出规则是在稳定趋势回滚时触发的。 这样的利好时刻极少,特别是由于分析的时间帧为 D1。 所以,在选项“单一图表上的所有指标”中,我们需要分析大量金融产品以便在交易账户上提升交易频率。

D1 图表也有相当大的优势:分析 EMA 斜率,以及多头力度和空头力度指标每天只能执行一次 — 当新柱线出现时。 这正是 EA 的工作方式:针对每个指定的品种在 D1 上等待新柱线,然后查找可能的入场信号。 股票量化软件_赫兹股票量化软件

由于期货和股票仅在净持结算模式下交易,因此此时不能反向开仓(对冲),但我们可以增加同向持仓量。 EA 可以仅针对当前品种进行交易,或是针对存储在文本文件中的若干品种进行交易。 尽管当前品种的一切都很清晰,但选择多品种可能会出现以下问题:

  • 我们需要指定一个市场内的大约一百个品种(例如,仅限证券);
  • 我们需要指定来自不同市场的多个品种(例如,期货和证券)。

如何从一个市场中选择所有品种? 假设,"CAT" 品种位于 "Stock Markets\USA\NYSE/NASDAQ(SnP100)\CAT"股票量化软件_赫兹股票量化软件

假设此品种适合我们,我们希望从“\NYSE/NASDAQ(SnP100)\”分支中选择所有其它金融产品。 在这种情况下,我们可以执行以下操作:

  1. 打开该品种图表;
  2. 启动脚本(我们将其命名为 Symbols on the specified path.mq5)它将接收品种路径(在上例中,对于“CAT”品种,它是“Stock Markets\USA\NYSE/NASDAQ(SnP100)“),并将所获路径中的所有品种保存到文本文件中。 文本文件将保存到公用数据文件夹;
  3. 它只是在 EA 设置中设定文本文件名。

如果我们需要来自多个市场的品种,则在每个市场上运行脚本(品种列表保存到它的唯一文件中),并手工将两个文本文件合并。

股票量化软件_赫兹股票量化软件

组装 EA。 选项1:单一图表上的所有指标

Symbols on the specified path.mq5 — 获取含品种的文本文件的脚本。 

注意: 仅当 "Everything is fine. There are no errors" 文字出现在智能系统栏时才保证脚本工作正常,并且所获含品种的文件可用于 EA 操作!

为了精简文件操作的代码,运用了 CFileTxt 类, 文本文件的操作通过 m_file_txt 执行 — CFileTxt 类对象。 脚本的操作分七步 执行:

//+------------------------------------------------------------------+
//|                                Symbols on the specified path.mq5 |
//|                                版权所有 © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "版权所有 © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.002"
#property script_show_inputs
//---
#include <Files\FileTxt.mqh>
CFileTxt       m_file_txt;                   // 文本文件对象
//--- 输入参数
input string   InpFileName="Enter a unique name.txt";  // 文件名
//+------------------------------------------------------------------+
//| 脚本程序开始函数                                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 第一步
   string current_path="";
   if(!SymbolInfoString(Symbol(),SYMBOL_PATH,current_path))
     {
      Print("ERROR: SYMBOL_PATH");
      return;
     }
//--- 第二步
   string sep_="\\";                 // 分隔符
   ushort u_sep_;                    // 分隔符的代码
   string result_[];                 // 保存字符串的数组 
//--- 获取分隔符代码 
   u_sep_=StringGetCharacter(sep_,0);
//--- 将字符串拆分为子字符串 
   int k_=StringSplit(current_path,u_sep_,result_);
//--- 第三步
//--- 现在输出所有获得的字符串 
   if(k_>0)
     {
      current_path="";
      for(int i=0;i<k_-1;i++)
         current_path=current_path+result_[i]+sep_;
     }
//--- 第四步
   string symbols_array[];
   int symbols_total=SymbolsTotal(false);
   for(int i=0;i<symbols_total;i++)
     {
      string symbol_name=SymbolName(i,false);
      string symbol_path="";
      if(!SymbolInfoString(symbol_name,SYMBOL_PATH,symbol_path))
         continue;
      if(StringFind(symbol_path,current_path,0)==-1)
         continue;
      
      int size=ArraySize(symbols_array);
      ArrayResize(symbols_array,size+1,10);
      symbols_array[size]=symbol_name];
     }
//--- 第五步
   int size=ArraySize(symbols_array);
   if(size==0)
     {
      PrintFormat("ERROR: On path \"%s\" %d symbols",current_path,size);
      return;
     }
   PrintFormat("On path \"%s\" %d symbols",current_path,size);
//--- 第六步
   if(m_file_txt.Open(InpFileName,FILE_WRITE|FILE_COMMON)==INVALID_HANDLE)
     {
      PrintFormat("ERROR: \"%s\" file in the Data Folder Common folder is not created",InpFileName);
      return;
     }
//--- 第七步
   for(int i=0;i<size;i++)
      m_file_txt.WriteString(symbols_array[i]+"\r\n");
   m_file_txt.Close();
   Print("Everything is fine. There are no errors");
//---
  }
//+------------------------------------------------------------------+

脚本操作算法:

  • 第一步: SYMBOL_PATH (品种树中的路径) 定义当前品种;
  • 第二步: 以“\”分隔符将所获路径拆分为子串;
  • 第三步: 舍弃最后一个子字符串并重新组合当前路径,因为最后字串包含品种名称;
  • 第四步: 循环遍历所有可用品种; 如果品种树中的路径与当前品种相匹配,选择品名并将其添加至检测到品种数组中;
  • 第五步: 检查检测到品种数组的大小;
  • 第六步: 创建文件;
  • 第七步: 将我们检测到的品种数组写入文件并关闭。

Elder-Ray 1 — 根据选项 1 进行交易的 EA (或若干个 EA),版本号为 1.xxx : 单一图表上的所有指标。

如何设置开仓量 — 最小手数可能不同

我们来进行一个简单的实验:检查期货和证券的最小手数:遍历与当前品种位于同一路径的所有品种(类似于 Symbols on the specified path.脚本), 但不必将品种保存到文件内部,而是显示最小手数的统计数据。

股票量化软件_赫兹股票量化软件— 用于显示品种组最小手数统计信息的脚本。 脚本以二维数组形式传递品种组和累积统计数据(minimal volume to close a deal 和 counter):

//--- 第四步
/* 
   symbols_array[][2]:
   [*][minimal volume to close a deal]
   [*][counter]
*/

完整的脚本代码:

//+------------------------------------------------------------------+
//|                                          Gets minimal volume.mq5 |
//|                                版权所有 © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "版权所有 © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//+------------------------------------------------------------------+
//| 脚本程序开始函数                                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 第一步
   string current_path="";
   if(!SymbolInfoString(Symbol(),SYMBOL_PATH,current_path))
     {
      Print("ERROR: SYMBOL_PATH");
      return;
     }
//--- 第二步
   string sep_="\\";                 // 分隔符
   ushort u_sep_;                    // 分隔符的代码
   string result_[];                 // 保存字符串的数组 
//--- 获取分隔符代码 
   u_sep_=StringGetCharacter(sep_,0);
//--- 将字符串拆分为子字符串 
   int k_=StringSplit(current_path,u_sep_,result_);
//--- 第三步
//--- 现在输出所有获得的字符串 
   if(k_>0)
     {
      current_path="";
      for(int i=0;i<k_-1;i++)
         current_path=current_path+result_[i]+sep_;
     }
//--- 第四步
/* 
   symbols_array[][2]:
   [*][minimal volume to close a deal]
   [*][counter]
*/
   double symbols_array[][2];
   int symbols_total=SymbolsTotal(false);
   for(int i=0;i<symbols_total;i++)
     {
      string symbol_name=SymbolName(i,false);
      string symbol_path="";
      if(!SymbolInfoString(symbol_name,SYMBOL_PATH,symbol_path))
         continue;
      if(StringFind(symbol_path,current_path,0)==-1)
         continue;

      double min_volume=0.0;
      if(!SymbolInfoDouble(symbol_name,SYMBOL_VOLUME_MIN,min_volume))
         continue;
      int size=ArrayRange(symbols_array,0);
      bool found=false;
      for(int j=0;j<size;j++)
        {
         if(symbols_array[j][0]==min_volume)
           {
            symbols_array[j][1]=symbols_array[j][1]+1;
            found=true;
            continue;
           }
        }
      if(!found)
        {
         ArrayResize(symbols_array,size+1,10);
         symbols_array[size][0]=min_volume;
         symbols_array[size][1]=1.0;
        }
     }
//--- 第五步
   int size=ArrayRange(symbols_array,0);
   if(size==0)
     {
      PrintFormat("ERROR: On path \"%s\" %d symbols",current_path,size);
      return;
     }
//--- 第六步
   for(int i=0;i<size;i++)
      PrintFormat("Minimal volume %.2f occurs %.1f times",symbols_array[i][0],symbols_array[i][1]);
   Print("Everything is fine. There are no errors");
//---
  }
//+------------------------------------------------------------------+

脚本操作算法:

  • 第一步: SYMBOL_PATH (品种树中的路径) 定义当前品种;
  • 第二步: 以“\”分隔符将所获路径拆分为子串;
  • 第三步: 舍弃最后一个子字符串并重新组合当前路径,因为最后字串包含品种名称;
  • 第四步: 循环遍历所有可用品种; 如果品种树中的路径与当前品种相匹配,选择品名的最小交易量并在品种数组中执行搜索。 如果此类值已存在,则计数器增加。 如果无此类值,则添加到数组,并将计数器设置为“1.0”;
  • 第五步: 检查检测到品种数组的大小;
  • 第六步: 显示统计。股票量化软件_赫兹股票量化软件

证券的启动结果:

Gets minimal volume (CAT,D1)    Minimal volume 1.00 occurs 100.0 times

以及期货:

Gets minimal volume (RTSRIU8,D1)        Minimal volume 1.00 occurs 77.0 times

- 在这两个市场上,手数大小是一样的 — 1.0。

因此,我们不要将系统过度复杂化,并设置最小手数为“1.0”。

可视化应用指标

当您在测试器中启动可视化测试时,您可以看到 EA 所应用的指标。 但若是在终端图表上启动 EA 时,不会显示指标。 在该交易系统中,我希望在图表上看到这些指标,以便对 EA 的工作进行可视化控制。 它看起来应该是这样的:

如您所见,此处我使用了所有指标的自定义颜色和线宽设置(当然,这是手工完成的)。 若要在终端图表上自动应用指标可视化,我们需要稍微重写移动平均线,多头力度和空头力度指标。 我已经在 自定义移动平均值输入颜色 代码中实现了类似的功能 — 指标颜色已包含在输入中:当从 EA 创建指标时,此输入参数可用。 现在,我们只需要开发三个类似的指标。

您可以从代码库中下载这些指标股票量化软件_赫兹股票量化软件。 将下载的指标放在根目录中 [数据文件夹]\MQL5\Indicators\。

Elder-Ray 1.001.mq5 — 应用指标可视化 您可以设置颜色和宽度。 它既可以在策略测试器中使用,也可在图表上启动 EA 时使用:

这是如何实现的?

股票量化软件_赫兹股票量化软件

指标的外观得以管理,周期可在输入中设定,而对于指标操作, 声明存储指标句柄的三个变量 (handle_iCustom_MAhandle_iCustom_Bulls and handle_iCustom_Bears)。

//+------------------------------------------------------------------+
//|                                                  Elder-Ray 1.mq5 |
//|                                版权所有 © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "版权所有 © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//---

//---
enum ENUM_INPUT_SYMBOLS
  {
   INPUT_SYMBOLS_CURRENT=0,   // 当前品种
   INPUT_SYMBOLS_FILE=1,      // 文本文件
  };
//--- 输入参数
input ENUM_INPUT_SYMBOLS   InpInputSymbol       = INPUT_SYMBOLS_FILE;   // 操作品种 ...
input uint                 InpNumberMinLots     = 1;                    // 最小手数
//--- 自定义移动平均线输入
input int                  Inp_MA_ma_period     = 13;                   // MA: 均化周期 
input int                  Inp_MA_ma_shift      = 0;                    // MA: 水平位移 
input ENUM_MA_METHOD       Inp_MA_ma_method     = MODE_EMA;             // MA: 平滑类型 
input ENUM_APPLIED_PRICE   Inp_MA_applied_price = PRICE_CLOSE;          // MA: 价格类型 
input color                Inp_MA_Color         = clrChartreuse;        // MA: 颜色
input int                  Inp_MA_Width         = 2;                    // MA: 宽度
//--- 自定义多头力度输入
input int                  Inp_Bulls_ma_period  = 13;                   // 多头力度: 均化周期 
input color                Inp_Bulls_Color      = clrBlue;              // 多头力度: 颜色
input int                  Inp_Bulls_Width      = 2;                    // 多头力度: 宽度
//--- 自定义空头力度输入
input int                  Inp_Bears_ma_period  = 13;                   // 空头力度: 均化周期
input color                Inp_Bears_Color      = clrRed;               // 空头力度: 颜色
input int                  Inp_Bears_Width      = 2;                    // 空头力度: 宽度

int    handle_iCustom_MA;                    // 用于存储 iCustom 指标句柄的变量
int    handle_iCustom_Bulls;                 // 用于存储 iCustom 指标句柄的变量
int    handle_iCustom_Bears;                 // 用于存储 iCustom 指标句柄的变量
//+------------------------------------------------------------------+
//| 智能系统初始化函数                                                  |
//+------------------------------------------------------------------+
int OnInit()

在 OnInit() 中,我们创建自定义指标的句柄(iCustom 已应用),并将创建的指标添加到图表中(ChartIndicatorAdd 已应用)。股票量化软件_赫兹股票量化软件

//+------------------------------------------------------------------+
//| 智能系统初始化函数                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 创建指标 iCustom 的句柄
   handle_iCustom_MA=iCustom(Symbol(),Period(),"Custom Moving Average Inputs",
                             Inp_MA_ma_period,
                             Inp_MA_ma_shift,
                             Inp_MA_ma_method,
                             Inp_MA_Color,
                             Inp_MA_Width,
                             Inp_MA_applied_price);
//--- 如果未创建句柄 
   if(handle_iCustom_MA==INVALID_HANDLE)
     {
      //--- 告之失败并输出错误代码 
      PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Moving Average Inputs\") for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- 指标提前停止 
      return(INIT_FAILED);
     }

//--- 创建指标 iCustom 的句柄
   handle_iCustom_Bulls=iCustom(Symbol(),Period(),"Custom Bulls Power Inputs",
                                Inp_Bulls_ma_period,
                                Inp_Bulls_Color,
                                Inp_Bulls_Width);
//--- 如果未创建句柄 
   if(handle_iCustom_Bulls==INVALID_HANDLE)
     {
      //--- 告之失败并输出错误代码 
      PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Bulls Power Inputs\") for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- 指标提前停止 
      return(INIT_FAILED);
     }

//--- 创建指标 iCustom 的句柄
   handle_iCustom_Bears=iCustom(Symbol(),Period(),"Custom Bears Power Inputs",
                                Inp_Bears_ma_period,
                                Inp_Bears_Color,
                                Inp_Bears_Width);
//--- 如果未创建句柄 
   if(handle_iCustom_Bears==INVALID_HANDLE)
     {
      //--- 告之失败并输出错误代码 
      PrintFormat("Failed to create handle of the iCustom indicator (\"Custom Bears Power Inputs\") for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- 指标提前停止 
      return(INIT_FAILED);
     }

   ChartIndicatorAdd(0,0,handle_iCustom_MA);
   int windows_total=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
   ChartIndicatorAdd(0,windows_total,handle_iCustom_Bulls);
   ChartIndicatorAdd(0,windows_total+1,handle_iCustom_Bears);
//---
   return(INIT_SUCCEEDED);
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值