
Elder-Ray (多头力度和空头力度)
概述
Alexander Elder 在他的著作“为生活而交易”中描述了 Elder-Ray 交易系统。 它基于 多头力度 和 空头力度 振荡器,以及 移动平均 趋势跟踪指标(EMA - 指数平均)。
该系统既简单又复杂:
- 如果我们从字面上理解它就很简单:如果趋势向上(EMA)并且 空头力度 低于零,,但正在增加,则应买入;
- 说它复杂,如果我们仔细阅读并查看 EMA 和空头力度的图表:结果表明,它并不像看起来那么简单,因为这些条件很稀少。
在本文中,我们将从简单到复杂遍历所有阶段,并检查两种类型的交易系统:
- 同一图表上的所有指标(当然,在一个时间时间帧内);
- 与“三重选择”系统相结合。
本文中的 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)\”分支中选择所有其它金融产品。 在这种情况下,我们可以执行以下操作:
- 打开该品种图表;
- 启动脚本(我们将其命名为 Symbols on the specified path.mq5)它将接收品种路径(在上例中,对于“CAT”品种,它是“Stock Markets\USA\NYSE/NASDAQ(SnP100)“),并将所获路径中的所有品种保存到文本文件中。 文本文件将保存到公用数据文件夹;
- 它只是在 EA 设置中设定文本文件名。
下面描述的是 Symbols on the specified path.mq5 脚本实现。
组装 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.mq5 脚本), 但不必将品种保存到文件内部,而是显示最小手数的统计数据。
Gets minimal volume.mq5 — 用于显示品种组最小手数统计信息的脚本。 脚本以二维数组形式传递品种组和累积统计数据(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 时使用:
这是如何实现的?
主要条件是 [数据文件夹]\MQL5\Indicators\ 中存在 自定义移动平均值输入,自定义多头力度输入 和 自定义空头力度输入 指标
指标的外观得以管理,周期可在输入中设定,而对于指标操作, 声明存储指标句柄的三个变量 (handle_iCustom_MA, handle_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); }
保存资源。 Elder-Ray 1.010.mq5
单个组中可能有大约一百个已分析品种。 因此,节省内存的问题需要考虑,因为每个图表都包含三个指标。 与最小手数一样,最好的办法是检查 EA 的资源消耗情况。 与此同时,我们还需在组装 EA 时添加更多的代码,从文本文件中读取一个组的品种名称并使用它们。
CFileTxt 类 (我们已已在脚本里用过它 Symbols on the specified path.mq5) 已包含在 EA 当中。 它的 m_file_txt 对象负责存取文本文件并从文件里读取数据。 我们还包含了 CSymbolInfo 类。 其对象 m_symbol 负责检查品种的存在并将其添加到市场观察窗口。 为什么我选择 CSymbolInfo,而不是通过 SymbolInfoInteger 和 SymbolSelect 实现该函数? 一切都很简单:在 CSymbolInfo 类中,用于检查、添加或通知错误的所有代码都隐藏在类中,我们只需要在 EA 中添加以下三个字符串:
if(!m_symbol.Name(name)) // 设置品名 { m_file_txt.Close(); return(INIT_FAILED); }
在此,我们应记住,多货币 EA 的所有品种都应添加到市场观察窗口中:在市场报价中为多货币 EA 交易启用所需品种。
因此,EA 根据以下算法操作:在 OnInit() 中打开文本文件,读取品种并立即尝试为其在当前时间帧创建三个自定义指标(自定义移动平均值输入,自定义多头力度输入和自定义空头力度输入)。 如果尝试失败(例如,由于创建自定义移动平均值输入的柱线数量不足),则循环继续前进。 如果创建了指标,则将品种名称写入 m_symbols_array,同时将三个指标的句柄发送到三维数组 m_handles_array。 所以,通过第一维,两个数组同步包含品名和品种句柄数据:
//--- if(m_file_txt.Open(InpFileName,FILE_READ|FILE_COMMON)==INVALID_HANDLE) { PrintFormat("ERROR: \"%s\" file in the Data Folder Common folder is not open: %d",InpFileName,GetLastError()); return(INIT_FAILED); } //--- 品种信息对象或文件 txt 对象 if(InpInputSymbol==INPUT_SYMBOLS_FILE) { //--- 从文件读数据 int counter=0; while(!m_file_txt.IsEnding()) { counter++; Print("Iteration ",counter); string name=m_file_txt.ReadString(); if(!m_symbol.Name(name)) // 设置品名 { m_file_txt.Close(); return(INIT_FAILED); } int MA,Bulls,Bears; if(!CreateHandles(name,Period(),MA,Bulls,Bears)) continue; //return(INIT_FAILED); int size=ArraySize(m_symbols_array); ArrayResize(m_symbols_array,size+1,10); ArrayResize(m_handles_array,size+1,10); m_symbols_array[size]=name; m_handles_array[size][0]=MA; m_handles_array[size][1]=Bulls; m_handles_array[size][2]=Bears; } m_file_txt.Close(); } else { if(!m_symbol.Name(Symbol())) // 设置品名 return(INIT_FAILED); } //--- ChartIndicatorAdd(0,0,handle_iCustom_MA);
指标句柄在 CreateHandles() 当中创建。
因此,通过 TERMINAL_MEMORY_USED 来测量内存消耗,并在 Windows 10 任务管理器中直观显示。 若要按步骤定义内存消耗,在 1.010 版本中故意禁用了(注释掉)某些字符串。 在最终的 1.010 版本中,添加品种和创建指标的所有字符串均未取消注释。
- EA 以通常的方式启动 — 将它加载到图表上:
- 启动终端(文本文件中的品种尚未添加到市场观察窗口) — TERMINAL_MEMORY_USED 345 MB, 任务管理器从 26 至 90 MB;
- 在市场观察窗口中添加大约一百个品种 — TERMINAL_MEMORY_USED 433 MB, 任务管理器 + 10 MB;
- 为每个品种创建三个指标 — TERMINAL_MEMORY_USED 5523 MB, 任务管理器 300 MB。
- 启动测试器(非可视化) — TERMINAL_MEMORY_USED 420 MB, 二在任务管理器中 — 5 GB。
结论: TERMINAL_MEMORY_USED 显示内存和磁盘空间的总消耗量。 由于正常模式下的内存消耗不超过 300 MB,因此无需节省资源。
趋势 (EMA) 为...
EA 的主要目标是定义趋势( EMA )方向。 趋势无法通过单根柱线来判断。 我们需要来自若干根柱线的数据。 我们将此参数标记为 "bars"。 以下是三张证券图表 — CAT, MCD 和 V。趋势定义如下: "+1" 为上行趋势, "0" 为无趋势,"—1" 为下行趋势
"CAT" 图表显示趋势 "0" (4 根阳线和 4 根阴线, 而剩余的柱线变化微不足道), "MCD" 显示趋势 "—1" (8 根阳线, 而其它的处于不确定状态)。 最终, "V" 显示趋势 "0" (6 根阳线, 2 或 3 根阴线)。 我们也许需要 'different' 参数 — 相邻柱线上指标读数之间的最小差值。
定义趋势。Elder-Ray 1.020.mq5
趋势存在条件: bars 范围内的 EMA 应处于特定方向。 之后应检查两个附加参数:
- different — 相邻柱线上指标读数之间的最小差值;
- trend percentage — 指示读数在单一方向上的最小百分比 (在截图上: CAT 品种 — EMA 指标在 bars 区间逆趋势, 而在 MCD 上, 所有 (或几乎所有) EMA 指标读数有特定方向)。
版本 1.020 中添加以及删除的内容:
- 参数 different 未实现 — 相邻柱线上指标读数之间的最小差值;
- "—" enum ENUM_INPUT_SYMBOLS 枚举 — EA 仅适用于文本文件中的品种;
- "+" 参数 number of bars for identifying the trend — EMA 识别趋势所需柱线数;
- "+" 参数 minimum percentage of the trend — 最低趋势品质(特定方向);
- "+" m_prev_bars 数组 — 用于存储之前的柱线开盘时间;
- "+" 60 秒记时器 — 检查一根新柱线。
用于捕捉新柱线并定义趋势方向的模块
在 OnTimer() 当中,每 60 秒遍历从文本里下载的品种数组 (m_symbols_array),并 从数组中捕捉品种的新柱线。 获取足以判断趋势的 EMA 指标数据至 ema_array 数组。 执行计算: 指标上行和下行移动的柱线数。 输出检测形态。
//+------------------------------------------------------------------+ //| 计时器函数 | //+------------------------------------------------------------------+ void OnTimer() { //--- int size=ArraySize(m_symbols_array); for(int i=0;i<size;i++) { //--- 我们仅在新柱线诞生时工作 datetime PrevBars=m_prev_bars[i]; datetime time_0=iTime(m_symbols_array[i],Period(),0); if(time_0==PrevBars) continue; m_prev_bars[i]=time_0; double ema_array[]; ArraySetAsSeries(ema_array,true); /* m_handles_array[*][MA][Bulls][Bears] */ if(!iMAGetArray(m_handles_array[i][0],0,InpBarsEMA+2,ema_array)) continue; int upwards=0; int downward=0; for(int j=1;j<InpBarsEMA+1;j++) { if(ema_array[j]>ema_array[j+1]) upwards++; else if(ema_array[j]<ema_array[j+1]) downward++; } if((double)upwards>InpBarsEMA*InpMinTrendPercentage/100.0) Print("On ",m_symbols_array[i]," trend UP!"); else if((double)downward>InpBarsEMA*InpMinTrendPercentage/100.0) Print("On ",m_symbols_array[i]," trend DOWN!"); else Print("On ",m_symbols_array[i]," trend NONE!"); } }
趋势搜索结果。 设置: number of bars for identifying the trend — 6, minimum percentage of the trend — 75%。 请记住,出现新柱线时操作不会考虑零号柱线:
设置挂单 (BuyStop 或 SellStop). Elder-Ray 1.030.mq5
开仓时能否避免资金匮乏错误? 由于我们是用挂单操作,答案是“否”。 也许会有半路措施,但没有任何保证。 主要原因是没有人知道挂单在什么时候被激活,以及它是否会被激活。
既然 EA 知道如何定义趋势,我们需要使用 买入 和 卖出 规则来查找适合放置挂单的点位。 对于买入,将进行简单的检查:#1 柱线上的空头力度应小于零,且大于 #2 柱线上的空头力度。 对于卖出,条件相反:#1 柱线上的多头力度应大于零,且小于 #2 柱线上的空头力度。
策略描述,亚历山大·埃尔德 (Alexander Elder) 指出:对于开多头仓位,保护性止损应该低于最后一个低点,而对于开空头仓位,它应该高于最后一个高点。 “最后”的概念相当模糊,所以我会检查两个选项:
- 参照 #1 柱线价格设定止损,且
- 搜索最近的极点。
选项 1 的结果证明是不可靠的 - 触发止损过于频繁。 因此,我在 Elder-Ray 1.030.mq5 的 EA 代码中实现了选项 2(搜索最近的极值)。
搜索最近的极值
该函数搜索最近的极值:
如果未找到极值或检测到错误,则返回“false”:
//+------------------------------------------------------------------+ //| 搜索最近的极值 | //+------------------------------------------------------------------+ bool NearestExtremum(ENUM_SERIESMODE type,double &price) { if(type==MODE_LOW) { //--- 搜索最近的低点极值 double low_array[]; ArraySetAsSeries(low_array,true); int copy=CopyLow(m_symbol.Name(),Period(),0,100,low_array); if(copy==-1) return(false); double low=DBL_MAX; for(int k=0;k<copy;k++) { if(low_array[k]<low) low=low_array[k]; else if(low_array[k]>low) break; } if(low!=DBL_MAX) { price=low; return(true); } } else if(type==MODE_HIGH) { //--- 搜索最近的高点极值 double high_array[]; ArraySetAsSeries(high_array,true); int copy=CopyHigh(m_symbol.Name(),Period(),0,100,high_array); if(copy==-1) return(false); double high=DBL_MIN; for(int k=0;k<copy;k++) { if(high_array[k]>high) high=high_array[k]; else if(high_array[k]<high) break; } if(high!=DBL_MIN) { price=high; return(true); } } //--- return(false); }
版本 1.030 中的添加和删除的内容:
- "+" CPositionInfo 交易类 (m_position 是其对象);
- "+" CTrade 交易类 (m_trade 是其对象);
- "+" COrderInfo 交易类 (m_order 是其对象);
- "+" 尾随 (Trailing Stop 和 Trailing Step 参数);
- "+" magic number — 独有的 EA 标识符;
- "+" OnInit() — 检查帐户类型:如果这是一个对冲帐户,则禁用交易、卸载并返回错误;
- OnInit() — 可视化顺序已变化: 如果已启动策略测试器,且当前品种(启动 EA 的那个)出现在文本文件中,则不会向当前品种添加指标(不调用 ChartIndicatorAdd);
- OnTimer() — 添加信号确认代码和交易操作,用于设置 BuyStop 和 SellStop 挂单;
- OnTradeTransaction() — 增加补偿机制处理仓位反转或部分平仓;
- "+" 激活补偿算法时,OnTradeTransaction() 中不会设置止损。 代之,尾随函数得到改善:如果在检查仓位时检测到未设止损的持仓,则根据搜索最近极值点的规则设置止损。;
- "+" 添加 m_magic_compensation 变量 — 补偿交易标识符。
为了处理将要触发的挂单与当前持仓相反的情况,我们需要考虑触发 BuyStop 挂单后的三种典型情况:
# | 有持仓,交易量 | 挂单触发, 交易量 | 持仓结算, 交易量 | 请注意挂单触发时刻 | 持仓的前魔幻数字 | 补偿算法 (注意:在补偿之前,魔幻数字设置为 m_magic_compensation) | 持仓的新魔幻数字 |
---|---|---|---|---|---|---|---|
1 | Sell 1.0 | Buy Stop 3.0 | Buy 2.0 | 持仓反转 (DEAL_ENTRY_INOUT 成交方向) | m_magic | 开仓交易量 3.0 — 2.0 = 1.0 | m_magic_compensation |
2 | Sell 1.0 | Buy Stop 1.0 | --- | 完全平仓 (DEAL_ENTRY_OUT 成交方向) | m_magic | 搜索持仓 若无持仓,则以手数 1.0 开仓买入 | m_magic_compensation |
3 | Sell 2.0 | Buy Stop 1.0 | Sell 1.0 | 部分平仓 (DEAL_ENTRY_OUT 成交方向) | m_magic | 搜索持仓 若有持仓,且与买入相反, 开仓买入交易量 1.0 + 1.0 = 2.0 | m_magic_compensation |
对于这三种情况中的每一种,我都准备了成交和订单的打印输出(在真实的净持结算账户以及测试器中进行测试)。 为了生成成交和订单报告,我使用了 历史成交和订单 脚本中的代码。
#1: Sell 1.0 -> Buy Stop 3.0
Sell 1.0, Buy Stop 3.0 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |1 |0 |2016.12.08 00:00:00 |1481155200000 |DEAL_TYPE_BALANCE |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |0 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |0.00 |0.00000 |0.00 |0.00 |50000.00 | | | Order 0 is not found in the trade history between the dates 2010.08.07 11:06:20 and 2018.08.10 00:00:00 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |2 |2 |2016.12.08 00:00:00 |1481155200100 |DEAL_TYPE_SELL |DEAL_ENTRY_IN |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.31 |0.00 |0.00 |0.00 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |2 |2016.12.08 00:00:00 |ORDER_TYPE_SELL |ORDER_STATE_FILLED |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100 |1481155200100 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.31 |0.00 |0.00 |79.39 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |3 |3 |2016.12.08 17:27:37 |1481218057877 |DEAL_TYPE_BUY |DEAL_ENTRY_INOUT |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |3.00 |79.75 |0.00 |0.00 |-0.44 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |3 |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100 |1481218057877 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |3.00 |0.00 |79.74 |75.17 |0.00 |79.74 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |4 |4 |2016.12.09 23:59:00 |1481327940000 |DEAL_TYPE_SELL |DEAL_ENTRY_OUT |0 |DEAL_REASON_CLIENT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |2.00 |79.13 |0.00 |0.00 |-1.24 |V |end of test | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |4 |2016.12.09 23:59:00 |ORDER_TYPE_SELL |ORDER_STATE_FILLED |2016.12.09 23:59:00 |2016.12.09 23:59:00 |1481327940000 |1481327940000 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |79.13 |0.00 |0.00 |79.13 |0.00 |Symbol |Comment |Extarnal id |V |end of test |
#2: Sell 1.0 -> Buy Stop 1.0
Sell 1.0, Buy Stop 1.0 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |1 |0 |2016.12.08 00:00:00 |1481155200000 |DEAL_TYPE_BALANCE |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |0 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |0.00 |0.00000 |0.00 |0.00 |50000.00 | | | Order 0 is not found in the trade history between the dates 2010.08.07 11:06:20 and 2018.08.10 00:00:00 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |2 |2 |2016.12.08 00:00:00 |1481155200100 |DEAL_TYPE_SELL |DEAL_ENTRY_IN |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.31 |0.00 |0.00 |0.00 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |2 |2016.12.08 00:00:00 |ORDER_TYPE_SELL |ORDER_STATE_FILLED |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100 |1481155200100 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.31 |0.00 |0.00 |79.39 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |3 |3 |2016.12.08 17:27:37 |1481218057877 |DEAL_TYPE_BUY |DEAL_ENTRY_OUT |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.75 |0.00 |0.00 |-0.44 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |3 |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100 |1481218057877 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.74 |75.17 |0.00 |79.74 |0.00 |Symbol |Comment |Extarnal id |V | |
#3: Sell 2.0 -> Buy Stop 1.0
Sell 2.0, Buy Stop 1.0 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |1 |0 |2016.12.08 00:00:00 |1481155200000 |DEAL_TYPE_BALANCE |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |0 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |0.00 |0.00000 |0.00 |0.00 |50000.00 | | | Order 0 is not found in the trade history between the dates 2010.08.07 11:06:20 and 2018.08.10 00:00:00 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |2 |2 |2016.12.08 00:00:00 |1481155200100 |DEAL_TYPE_SELL |DEAL_ENTRY_IN |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |2.00 |79.31 |0.00 |0.00 |0.00 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |2 |2016.12.08 00:00:00 |ORDER_TYPE_SELL |ORDER_STATE_FILLED |2016.12.08 00:00:00 |2016.12.08 00:00:00 |1481155200100 |1481155200100 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |79.31 |0.00 |0.00 |79.39 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |3 |3 |2016.12.08 17:27:37 |1481218057877 |DEAL_TYPE_BUY |DEAL_ENTRY_OUT |15489 |DEAL_REASON_EXPERT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.75 |0.00 |0.00 |-0.44 |V | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |3 |2016.12.08 14:30:00 |ORDER_TYPE_BUY_STOP |ORDER_STATE_FILLED |2016.12.08 14:30:00 |2016.12.08 17:27:37 |1481207400100 |1481218057877 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |15489 |ORDER_REASON_EXPERT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.74 |75.17 |0.00 |79.74 |0.00 |Symbol |Comment |Extarnal id |V | | Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |4 |4 |2016.12.09 23:59:00 |1481327940000 |DEAL_TYPE_BUY |DEAL_ENTRY_OUT |0 |DEAL_REASON_CLIENT |2 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |79.13 |0.00 |0.00 |0.18 |V |end of test | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |4 |2016.12.09 23:59:00 |ORDER_TYPE_BUY |ORDER_STATE_FILLED |2016.12.09 23:59:00 |2016.12.09 23:59:00 |1481327940000 |1481327940000 |ORDER_FILLING_FOK |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |2 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |1.00 |0.00 |79.13 |0.00 |0.00 |79.13 |0.00 |Symbol |Comment |Extarnal id |V |end of test |
以下是真实账户和实时(不是在测试器)的另一个案例:市价买入订单,交易量为 2.0(买入交易订单产生两笔成交,交易量为 1.0 — 20087494 和 20087495),然后放置一笔交易量 2.0 的 SellLimit 挂单用以止盈并平仓。 稍后,SellLimit 分两部分完成 (成交 20088091 和 20088145)。 打印输出:
Buy 2.0, Sell limit 2.0 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |20087494 |29080489 |2018.08.10 07:23:34 |1533885814000 |DEAL_TYPE_BUY |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |29080489 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |14595 |-0.10 |0.00 |0.00 |RTSGZU8 | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |29080489 |2018.08.10 07:23:34 |ORDER_TYPE_BUY |ORDER_STATE_FILLED |2018.08.10 07:23:34 |2018.08.10 07:23:34 |1533885814000 |1533885814000 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |29080489 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |0 |0 |0 |14588 |0 |Symbol |Comment |External id |RTSGZU8 | |13_31861873584 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |20087495 |29080489 |2018.08.10 07:23:34 |1533885814000 |DEAL_TYPE_BUY |DEAL_ENTRY_IN |0 |DEAL_REASON_CLIENT |29080489 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |14595 |-0.10 |0.00 |0.00 |RTSGZU8 | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |29080489 |2018.08.10 07:23:34 |ORDER_TYPE_BUY |ORDER_STATE_FILLED |2018.08.10 07:23:34 |2018.08.10 07:23:34 |1533885814000 |1533885814000 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |29080489 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |0 |0 |0 |14588 |0 |Symbol |Comment |External id |RTSGZU8 | |13_31861873584 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |20088091 |29080662 |2018.08.10 08:03:08 |1533888188000 |DEAL_TYPE_SELL |DEAL_ENTRY_OUT |0 |DEAL_REASON_CLIENT |29080489 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |14626 |-0.10 |0.00 |0.46 |RTSGZU8 | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |29080662 |2018.08.10 07:27:19 |ORDER_TYPE_SELL_LIMIT |ORDER_STATE_FILLED |2018.08.10 07:27:19 |2018.08.10 08:05:42 |1533886039000 |1533888342000 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |29080489 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |14626 |0 |0 |14624 |0 |Symbol |Comment |External id |RTSGZU8 | |13_31862155871 Deal: |Ticket |Order |Time |Time msc |Type |Entry |Magic |Reason |Position ID |20088145 |29080662 |2018.08.10 08:05:42 |1533888342000 |DEAL_TYPE_SELL |DEAL_ENTRY_OUT |0 |DEAL_REASON_CLIENT |29080489 |Volume |Price |Commission |Swap |Profit |Symbol |Comment |External ID |1.00 |14626 |-0.10 |0.00 |0.46 |RTSGZU8 | | Order: |Ticket |Time setup |Type |State |Time expiration |Time done |Time setup msc |Time done msc |Type filling |29080662 |2018.08.10 07:27:19 |ORDER_TYPE_SELL_LIMIT |ORDER_STATE_FILLED |2018.08.10 07:27:19 |2018.08.10 08:05:42 |1533886039000 |1533888342000 |ORDER_FILLING_RETURN |Type time |Magic |Reason |Position id |Position by id |1970.01.01 00:00:00 |0 |ORDER_REASON_CLIENT |29080489 |0 |Volume initial |Volume current |Open price |sl |tp |Price current |Price stoplimit |2.00 |0.00 |14626 |0 |0 |14624 |0 |Symbol |Comment |External id |RTSGZU8 | |13_31862155871
测试 1.xxx 的提示
- 尝试在文本文件中保留数值大致相同的证券。
- 在文本文件中进行测试时,最好只保留少量品种。 最完美的情况是仅保留一个品种并对其进行测试。
选项 2: 与“三重选则”系统相结合
在选项 1(单一图表上的所有指标)中,趋势指标在同一时间帧内。 在选项 2 中,趋势指标将处于更高的时间帧内。 因此,仅添加一个新参数 — 趋势时间帧 (Trend timeframe)。
选项 2 已在 Elder-Ray 2.000.mq5 EA 中实现。
本文附属的文件:
名称 | 文件类型 | 说明 |
---|---|---|
Symbols on the specified path.mq5 | 脚本 | 将品种归组形成文本文件,并保存在公共数据文件夹中 |
Gets minimal volume.mq5 | 脚本 | 显示有关组的最小交易量的统计信息。 |
Elder-Ray 1.001.mq5 | 智能交易系统 | 可视化显示所应用指标 |
Elder-Ray 1.010.mq5 | 智能交易系统 | 开始操纵文本文件,并为文件中的品种创建指标。 该 EA 用于监视内存消耗 |
Elder-Ray 1.020.mq5 | 智能交易系统 | 定义趋势。 检查趋势定义的有效性 |
Elder-Ray 1.030.mq5 | 智能交易系统 | “选项 1:单一图表上的所有指标”的运行时版本 |
Elder-Ray 2.000.mq5 | 智能交易系统 | 选项 2: 与“三重选则”系统相结合 |
结束语
Elder-Ray(多头力度和空头力度)交易系统足够可靠,特别是与“三重选择”系统相结合,当计算 EMA 趋势指标的时间帧比多头力度和空头力度的时间帧更高时。
在测试 EA 时,我们应该记住,准备好的文本文件最多可包含 100 个品种。 考虑到这个数字,您启动测试时需要高达 10 分钟,以及在测试期间高达 5 GB 的内存。
无论您是否信任该 EA,您肯定希望介入这个过程,就像我在撰写文章和测试该版本 EA 时所做的那样:
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/5014
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.


一个地方谈的是期货,另一个地方谈的是多货币战略。这里提到了数字,但没有。我在这里的讨论中看到了一个数字,但出版物本身却是空白。而最合理的建议是从别人的书中引用的:
"通常,牛市的力量 高于零,如果低于零,则意味着牛群中出现恐慌,牛市正在下沉"。
关于 metatrader 功能的出版物很多。毫无疑问,该程序非常出色,可能是最好的。我希望能见到这样一位作者的出版物,他努力刨根问底,一丝不苟,在他的出版物中不仅不允许语义上的错误,也不允许文体上的错误。
您是认真对待出版物的写作,还是不相信有人会读它呢?
哇@Vladimir Karputov,这篇文章写得太棒了。谢谢你花时间写了这么多细节。
我刚刚了解了 Elder-Ray,现在我要深入研究这篇文章和代码。我正在考虑将它与其他可能提高概率的指标相结合。
你对哪些指标适合与 Elder Ray 结合有什么建议吗?我在考虑成交量指标,也许还有 IKH。您怎么看?
最终是否会以传播速度倾泻而下?