Alexander Elder 在他的著作“为生活而交易”中描述了 Elder-Ray 交易系统。 它基于 多头力度 和 空头力度 振荡器,以及 移动平均 趋势跟踪指标(EMA - 指数平均)。
该系统既简单又复杂:
在本文中,我们将从简单到复杂遍历所有阶段,并检查两种类型的交易系统:
本文中的 EA 仅适用于净持结算帐户。
为了掌握交易系统背后的理念,有必要了解每个 Elder-Ray 元素:价格,EMA,每根柱线上的多头/空头力度指标的高点和低点,以及多头和空头的强度。
我们将在 D1 时间帧内探索期货和股票。 所有三个指标(多头力度,空头力度和 EMA)都放在一张图表上。 所有指标的均化周期为 13。
买入规则
CAT, Daily 买入信号
卖出规则
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 脚本实现。
组装 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"); //--- } //+------------------------------------------------------------------+
脚本操作算法:
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"); //--- } //+------------------------------------------------------------------+
脚本操作算法:
证券的启动结果:
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 版本中,添加品种和创建指标的所有字符串均未取消注释。
结论: 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 应处于特定方向。 之后应检查两个附加参数:
版本 1.020 中添加以及删除的内容:
用于捕捉新柱线并定义趋势方向的模块
在 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 的结果证明是不可靠的 - 触发止损过于频繁。 因此,我在 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 中的添加和删除的内容:
为了处理将要触发的挂单与当前持仓相反的情况,我们需要考虑触发 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 的提示
在选项 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 时所做的那样:
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程