作为交易人员的工具之一的由 MetaQuotes Software Corp. 开发的 MetaTrader 5 交易终端,包含支持面向对象编程的 MQL5 编程语言。一方面,MQL5 和前一版本的 MQL4 并不兼容;另一方面,它具有全功能 面向对象语言的大量新的可能性。因此,那些已经驾驭 MQL4 的交易人员,不得不学习这一(事实上的)新的语言,而他们正是本文的目标读者。
在本文中,我将给出下述问题的解决方案:有必要开发交易人员工具,以获得和分析商品期货交易委员会 (CFTC) 报告的不同数据。本主题已在 Meta COT 项目 - MetaTrader 4 CFTC 报告分析的新视野一文中进行讨论,因此我假设读者已熟知基本概念,而我们将讨论在文章中未涉及的详细信息。
理念如下:开发可从委员会提供的文件获取数据而无需中间处理和转换的单一指标。此外,该指标可用于不同目的:作为指标绘制数据;作为其他指标的数据源、在脚本中用于自动分析、在开发交易策略时用于“EA 交易”。
有三种类型的报告:旧式报告 (COT)、补充商品指数 (CIT) 和新式分类报告 (DCOT),它们之间的差异如表 1 所示。
说明 |
旧式报告 | 补充商品指数 | 新式分类报告 |
---|---|---|---|
短名称 | COT | CIT | DCOT |
参考 标题 |
旧式报告 |
补充商品指数 |
新式分类报告 |
最近的数据文件引用 |
deacot2010.zip |
dea_cit_txt_2010.zip |
fut_disagg_txt_2010.zip |
报告中出现的交易人员组别 |
非商业持仓 商业持仓 非报告持仓 |
非商业持仓 商业持仓 非报告持仓 指数型交易人员 |
生产商/贸易商/加工企业/用户 互换交易商 管理基金 其他报告持仓 非报告持仓 |
表 1. 交易人员持仓类型报告
有关交易人员、哪些人应在期货市场报告他们的持仓、分类原则和报告周期的信息可在 "Trade Stocks and Commodities With the Insiders:Secrets of the COT Report"(与业内人士交易股票和商品:COT 报告的秘密)一书和 Meta COT 项目 - MetaTrader 4 CFTC 报告分析的新视野一文中找到。
我将讨论两种未在以上材料中述及的报告。
首字母缩略词 CIT 表示 交易员承诺指数。此报告自 2007 年起发布。最新 CIT 报告网页的网址为 http://cftc.gov/dea/options/deaviewcit.htm。指数型交易人员属于套期保值者和投机者之外的组别。
补充报告的描述可在 http://www.cftc.gov/MarketReports/CommitmentsofTraders/AbouttheCOTReports/index.htm 找到。所有这些指数型交易人员经常在市场上建立买入持仓并在合约间操作。
自 2009 年起,委员会开始发布“交易人员持仓分类报告”,相关说明可在 注释说明中找到。
COT 分类报告把交易人员分为下述四种类别,相比 COT 旧式报告具有更高的透明性:生产商/贸易商/加工企业/用户;互换交易商;管理基金;以及其他报告持仓。
报告工具的完整列表在附录 2 中给出。还有一些列显示了在 CIT 和 DCOT 报告中存在特殊工具。
指标将按照如下所述的方式工作。报告类型(表 1 中列示的一种)、数据类型和交易人员组别在指标的输入参数中进行定义。
数据的类型可以是下述类型中的任一种:
可能的数据类型列表并不完整,它可轻松扩展以将我使用的最基本的数据包括在内。对于当前交易品种,需要从数据文件获取指定的数据(下载及解压缩方式在下文中说明)。 我们将 CCFTCReport 类用于数据访问,并从这些文件中下载数据。
指标具有如下所述的结构:
2.1. 常量
要定义常量,需要使用 enum 数据类型。指标支持的报告类型如下所示:enum cot_type_report // 报告类型 { COT, DCOT, CIT };
交易人员群组:
enum cot_type_traders // 交易者类型 { noncommercial, // 非商业 commercial, // 商业 nonreportable, // 无需报告 index, // 指数交易者 producer, // 生产商 swapdealers, // 掉期交易者 managedmoney, // 基金 otherreportables // 其他须报告交易者 };
可在指标中使用的数据类型:
enum cot_type_data // COT数据类型 { netlongs, // 净买入 netlongsrate, // 未平仓合约中的净买入比率 willams_index, // Williams指数 openinterest // 未平仓合约 };
2.2. 类
要在单一变量中存储不同的对象,可以使用结构和类。然而,分配两个结构类型的变量是不可能的,如果它们包含动态数组或字符串类型的值的话。这是我们使用类而不是结构来存储 COT 记录以及数据分配方法的原因之所在。
class cot_record // 用于COT报告数据记录的类 { public: datetime COT_DATE; //日期 double COT_OPENINTEREST; //未平仓合约 double COT_LONGNONCOM; //非商业交易者的买入 double COT_SHORTNONCOM; //非商业交易者的卖出 double COT_LONGCOM; //商业交易者的买入 double COT_SHORTCOM; //商业交易者的卖出 double COT_LONGNONREPORTABLE; //其他非报告交易者的买入 double COT_SHORTNONREPORTABLE; //其他非报告交易者的卖出 double COT_LONGINDEX; //指数交易者的买入 double COT_SHORTINDEX; //指数交易者的卖出 double COT_LONGPRODUCER; //生产商/贸易商/加工企业/用户的买入 double COT_SHORTPRODUCER; //生产商/贸易商/加工企业/用户的卖出 double COT_LONGSWAPDEALERS; //掉期交易者的买入 double COT_SHORTSWAPDEALERS; //掉期交易者的卖出 double COT_LONGMANAGEDMONEY; //基金交易者的买入 double COT_SHORTMANAGEDMONEY; //基金交易者的卖出 double COT_LONGOTHERREPORTABLES; //其他需报告者 double COT_SHORTOTHERREPORTABLES; string COT_ID; //交易品种标识符 string COT_NAME; //交易品种名称 void copyvar(const cot_record &from) // 从一个类中复制内容(变量值)到另一个类中 { COT_ID = from.COT_ID; COT_NAME = from.COT_NAME; COT_DATE = from.COT_DATE; COT_OPENINTEREST = from.COT_OPENINTEREST; COT_LONGNONCOM = from.COT_LONGNONCOM; COT_SHORTNONCOM = from.COT_SHORTNONCOM; COT_LONGCOM = from.COT_LONGCOM; COT_SHORTCOM = from.COT_SHORTCOM; COT_LONGNONREPORTABLE = from.COT_LONGNONREPORTABLE; COT_SHORTNONREPORTABLE = from.COT_SHORTNONREPORTABLE; COT_LONGINDEX = from.COT_LONGINDEX; COT_SHORTINDEX = from.COT_SHORTINDEX; COT_LONGPRODUCER = from.COT_LONGPRODUCER; COT_SHORTPRODUCER = from.COT_SHORTPRODUCER; COT_LONGSWAPDEALERS = from.COT_LONGSWAPDEALERS; COT_SHORTSWAPDEALERS = from.COT_SHORTSWAPDEALERS; COT_LONGMANAGEDMONEY = from.COT_LONGMANAGEDMONEY; COT_SHORTMANAGEDMONEY = from.COT_SHORTMANAGEDMONEY; COT_LONGOTHERREPORTABLES = from.COT_LONGOTHERREPORTABLES; COT_SHORTOTHERREPORTABLES = from.COT_SHORTOTHERREPORTABLES; }; };
从现在开始,我假设读者熟悉 CSV 格式的 COT 报告,这在 Meta COT 项目 - MetaTrader 4 CFTC 报告分析的新视野一文中业已讨论。该类型的类实例将被用于存储 COT 报告的单线。这些类实例的数组可使用它们存储和方便地访问 COT 记录的字段。CCFTCReport 类已被开发用于数据存储和访问:
class CCFTCReport //COT 报告 { private: cot_type_report type; //当前报告的类型 cot_record data[]; //cot报告数据 int sizedata; //当前报告的记录数目 string idsymbol; //持仓报告中的交易品种标识符,在字段"CFTC Contract Market Code"中 ) string terminalsymbol; //客户端中的交易品种名称 public: void ~CCFTCReport(){ sizedata=0; }; bool Init( cot_type_report passedtype, string sym="" ); //类实例的初始化 bool LoadFile( string filename ); //从文件中加载数据 string Name(); //返回报告的简短名称 bool Type(cot_type_report passedtype); //设置报告类型 cot_type_report Type(){return(type);}; //返回报告类型 bool TestGroup( cot_type_traders type_trader ); //检查特定交易者是否出现 bool DefineIdSymbol(); //持仓报告中id的定义 bool GetString( int handle, cot_record& arr ); //从csv文件中获取字符串(记录) string GetFieldCommaDelimited(string &str); //从csv字符串中获取字段 double At(datetime time,cot_type_traders type_trader,cot_type_data typedata=netlongs); //从报告中获取数据 };
CCFTCReport 类的实例包含单一交易品种的整个报告,报告类型可以是 COT、CIT 或 DCOT。枚举和类在 "cot.mqh" 包含文件中列出。
2.3. 输入参数
输入参数由输入变量定义。这些参数可用于指定交易人员组别、数据类型和必要的 COT 报告类型:
input cot_type_traders type_trader = noncommercial; //交易者类型 input cot_type_data type_data = netlongs; //指标类型 input cot_type_report type_report = COT; //报告的类型
2.4. OnInit 函数
指标具有 OnInit 函数,该函数用于以下目的:从报告文件下载数据、检查输入参数、分配指标的缓冲区。
通过 INDICATOR_DATA 属性初始化的缓冲区包含要在图表上绘制的数据。通过 INDICATOR_CALCULATIONS 属性初始化的缓冲区包含中间计算。
SetIndexBuffer( 0, BufferData, INDICATOR_DATA ); IndicatorSetString(INDICATOR_SHORTNAME,indname); SetIndexBuffer( 1, BufferCalculations, INDICATOR_CALCULATIONS );
2.5. OnCalculate 函数
该函数用于选择必要数据、计算请求的数据及其绘图。
让我们来具体讨论它的工作。我们使用第二种形式的调用:
int OnCalculate(const int rates_total, const int prev_calculated, const datetime &Time[], const double &Open[], const double &High[], const double &Low[], const double &Close[], const long &TickVolume[], const long &Volume[], const int &Spread[]){
让我们确定待计算和绘图的柱。
int pos=rates_total-prev_calculated-1; if( pos >= rates_total-1 )pos--;
我们指定元素必须按时序编排索引。
ArraySetAsSeries(Time, true); ArraySetAsSeries(BufferData, true); ArraySetAsSeries(BufferCalculations, true);
经过一系列尝试,我发现最好将时序索引用于所有与指标的缓冲区相关的数组。这对于作为参数传递至 OnCalculate 函数的数组而言同样是方便的,最后(最近)的元素索引等于 0。
计算循环如下所示:
for(int i=pos;i>=0;i--) { cot_type_data passed = type_data; if(type_data==netlongs || type_data==netlongsrate || type_data==willams_index) { // 数据类型:净买入,净买入率,威廉指数) 返回净买入 // 进一步的计算都基于这些数据。 passed = netlongs; } double res = Report.At(Time[i], type_trader, type_data ); //从报告中获取数据 BufferCalculations[i] = res; BufferData[i] = CalcData( type_data, i, Time ); }
BufferCalculations 数组用于存储从 COT 报告中选择的原始数据。
BufferData 数组包含在图表上绘制就绪的数据。数据可能是报告的值(净长仓、未平仓合约)以及计算的值(净长仓比率、威廉指标)。我想指出下述问题,该问题我尚未找出妥善的解决方案。传递至 OnCalculate 函数的数组,可能在后续水平中被要求,且数组仅当在这些调用中传递时我们才可以访问它们,因此我认为这样会使代码变得杂乱无章。
CalcData 函数调用:
BufferData[i] = CalcData( type_data, i, Time );
CalcData 函数调用 CalcIndex 函数:
double CalcData( cot_type_data type_data, int i, const datetime& Time[] ) { // 未平仓合约中的净买入比率 if( type_data == netlongsrate ) return( BufferCalculations[ i ] / Report.At( Time[i], type_trader, openinterest )); // 威廉指数 if( type_data == willams_index )return( CalcIndex( i, Time, BufferCalculations ) ); return(BufferCalculations[i]); }
我需要在 CalcIndex 函数内部访问时间数组,所以我不得不按照调用层次将其传递。想象一下,如果我们需要使用全部的 8 个数组,代码会变成什么样子。
所有文件链接均已在表 1 中给出。每年会有单独的文件发布,出版年号位于文件名中。例如,http://www.cftc.gov/files/dea/history/deacot2010.zip 文件包含 2010 年的报告,http://www.cftc.gov/files/dea/history/deacot2009.zip 文件包含 2009 年的报告等。
需要下载所有这些文件并将它们解压缩至客户端安装目录的 \MQL5\files\ 文件夹中。每年需要为其创建名为 deacotXXXX 的单独文件夹,其中 XXXX 对应于年号。如此一来,我们会得到下述文件夹结构:
图 1. 报告的文件夹结构。
我们可以简化数据准备的过程。所有下述操作(检查 CFTC 网站的更新、下载和解压缩至相应文件夹)均由 "Cotdownloader" 脚本执行。脚本内核(数据下载)基于 WININET_TEST 脚本。我使用 CProgressBar 类,该类在价格直方图(市场概况)及其在 MQL5 中的实施一文中发布。外部应用程序使用 Windows API 执行,相关说明请见实际交易中的交易机器人自动优化一文。
使用脚本十分简单:只要将其附加至任意图表即可。工作时,它通过图表上进度条的形式以及 EA 交易选项卡上文本消息的形式报告数据下载信息。
图 2. 数据下载过程。
要运行指标,需要将指标附加至所选交易品种的图表并指定输入参数。
图 3 COT 指标的输入参数
请注意,现在您可以指定用户友好的表示法来取代变量名和枚举数据类型的值。操作方法如下:要取代变量名,您应在声明一个输入变量时指定一则注释:
input cot_type_traders type_trader = noncommercial; //交易者类型 input cot_type_data type_data = netlongs; //指标类型 input cot_type_report type_report = COT; //报告的类型
对于值同样如此 - 当声明枚举值时,需要在注释中指定说明:
enum cot_type_data // 数据类型 { netlongs, // 净买入 netlongsrate, // 未平仓合约中的净买入比率 willams_index, // Williams指数 openinterest // 未平仓合约 };
如果输入参数已正确指定且文件已下载和解压缩,指标将在单独窗口中出现:
图 4 COT 指标
如果发生错误,错误将在 "Toolbox"(工具箱)窗口的 "Experts"(EA 交易程序)选项卡中列出。
图 5 错误消息
该指标并非定位为全功能的成品。这只是说明如何获得结果的示例,还可以通过编写简单的代码进一步使用。例如,我们没有开发模块,以允许使用由特定经纪人提供的客户端设置自定义 COT 报告数据的类型。该功能在 DefineIdSymbol 函数的内部实施。下面是最初的几行代码:
bool CCFTCReport::DefineIdSymbol() { idsymbol=""; if(terminalsymbol=="USDLFX" || terminalsymbol=="DX_CONT" || StringFind(terminalsymbol,"DX")==0)idsymbol="098662"; //U.S. 美元指数 - 美国CE期货 if( terminalsymbol == "FC_CONT" || StringFind( terminalsymbol, "FC")== 0)idsymbol = "061641"; //肉牛 if( terminalsymbol == "LC_CONT" || StringFind( terminalsymbol, "LC")== 0)idsymbol = "057642"; //活牛 if( terminalsymbol == "QM_CONT" || StringFind( terminalsymbol, "QM")== 0)idsymbol = "067651"; //原油,轻质原油 - 纽约商品交易所
如果您需要从报告分配交易品种至客户端交易品种,您应通过修改这些代码来手动完成这项工作。我使用的是 BrocoTrader4 终端的设置。在本文的示例中,我使用的是在 Metaquotes-Demo 和 Alpari-Demo 服务器上设立的演示帐户。仅有 2 个工具可用于 DCOT 报告:XAUUSD (gold)、XAGUSD (silver)。
目前还不支持 CIT 报告,因为这些服务器上没有任何金融工具。当有金融工具时,可通过取消注释和修改部分代码很容易地获得它们的支持。
我没有使用图 3 中所示形式的指标。使用 iCustom 函数,MQL5 语言可重复使用自定义指标。
6.1. 创建新指标
有多种方式用于 COT 报告直观分析。直方图正是其中之一,使用不同颜色显示不同交易人员群组的持仓情况。
我们讨论以下任务:创建 COTnet 指标,将不同交易人员群组(COT 报告中的商业持仓和非商业持仓)的持仓情况绘制成直方图。用户必须能够选择数据类型:净长仓、净长仓比率、威廉指标。
此过程可通过“MQL5 向导”进行简化,详情已在 “MQL5:创建自己的指标”一文中讨论。因此,指标(绘图风格由“MQL5 向导”创建)代码如下所示:
#property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 //---- 绘制非商业的 #property indicator_label1 "Noncommercial" #property indicator_type1 DRAW_HISTOGRAM #property indicator_color1 Blue #property indicator_style1 STYLE_SOLID #property indicator_width1 5 //---- 绘制商业的 #property indicator_label2 "Commercial" #property indicator_type2 DRAW_HISTOGRAM #property indicator_color2 Red #property indicator_style2 STYLE_SOLID #property indicator_width2 5 //--- 指标缓存输入变量、全局变量以及用于包含带类的库的预处理程序指令如下所示:
#include <cot.mqh> input cot_type_data type_data = netlongs; // 指标类型 double NoncommercialBuffer[]; double CommercialBuffer[]; //+------------------------------------------------------------------+ //| 自定义指标初始化函数 | //+------------------------------------------------------------------+ int handlecomm, handlenoncomm;
OnInit 函数的代码如下所示:
int OnInit() { SetIndexBuffer(0,NoncommercialBuffer,INDICATOR_DATA); SetIndexBuffer(1,CommercialBuffer,INDICATOR_DATA); cot_type_traders td = commercial; cot_type_report tr = COT; handlecomm = iCustom(NULL, 0, "cot", td, type_data, tr ); td = noncommercial; handlenoncomm = iCustom(NULL, 0, "cot", td, type_data, tr ); return(0); }让我们考虑一下如何使用自定义指标(以非商业持仓交易人员为例)。在首次调用 iCustom 函数后,下述参数(是我们的报告所必需的)被传递至函数:
结果,我们得到一个句柄,它将用于进一步获取指标的数据。
从指标获取数据通过函数 OnCalculate 完成:if(BarsCalculated(handlecomm)<rates_total || BarsCalculated(handlenoncomm)<rates_total) return(0); int to_copy = clctocopy(rates_total, prev_calculated ); if( !copycotbuf(handlecomm, CommercialBuffer, to_copy ) ) { Print("Error in data of commercial traders"); return( 0 ); } if( !copycotbuf(handlenoncomm, NoncommercialBuffer, to_copy ) ) { Print("Error in data of non-commercial traders"); return( 0 ); } return(rates_total);
我们花费一些时间,编写了一小段代码并获得如下所示的结果:
图 6 cotnet 指标
6.2. iCustom 也可用于脚本
我们讨论以下任务:创建 cotsignals 脚本以计算统计估计。
使用 COT 报告的不同数据,我们看看我们会获得什么样的统计优势。最简单的方法是估计正确确定每周烛形颜色的概率。考虑下述假设:我们将使用来自 COT 报告的数据。您可以使用这些示例来开发您自己的 COT 数据解释方法并充分利用它的优势。在您的案例中,我们将检查对应于 3 年时长的 150 个周柱的历史数据。在编写脚本前,我们必须定义必要的数据类型和类:
统计数据可能类型的枚举为:
enum cot_type_statistics //用于计算的统计 类型 { speculantsign, //非商业交易者的净买入的标志 speculantchange, //非商业交易者买入仓量的变化 willamszones //威廉指标的超买/超卖区 };
为获取指定交易品种的统计数据,我们创建特殊类:
class CCOTStatistic { private: int bars ; // 交易品种历史周线的数量 string symbol; // 客户端中交易品种的名称 double netlongsspeculantsdata[]; // 投机者的净买入数据 double willamsindexspeculantsdata[]; // 投机者净买入的威廉指标数据 cot_type_statistics liststatistic[]; // 统计列表 public: //初始化和初始设置 void Init( string symbol_passed, cot_type_statistics& listpassed[] ); //获取方向的预报 int GetCotSignalDirection( int ibar, cot_type_statistics type_stat ); bool Get( double& probably[] ); // 返回统计数据 };
请求的统计数据通过 Get 方法返回,让我们来说明一下它是如何工作的。首先,必要数组使用自定义指标填充数据。我们需要非商业持仓(投机者)交易人员的净长仓值和威廉指标值:
if (!LoadDataFromCOTIndicator(symbol, PERIOD_W1, noncommercial, netlongs, COT, netlongsspeculantsdata, bars)) return(false); //获取到相关数据 - 投机者 的净买入 if (!LoadDataFromCOTIndicator(symbol, PERIOD_W1, noncommercial, willams_index, COT, willamsindexspeculantsdata, bars)) return(false); //获取到数据 - 投机者的威廉指数
统计数据计算(我们只有一个参数需要计算 - 它是每周烛形颜色的预测概率)的代码如下所示:
for(int istat = 0; istat < ArraySize(liststatistic); istat++) { int cntsignals = 0; int cntsucsess = 0; for(int i=bars-1; i>=0; i--) { double colorcandle=iClose(symbol,PERIOD_W1,i)-iOpen(symbol,PERIOD_W1,i); if(symbol=="USDCHF" || symbol=="USDCAD" || symbol=="USDJPY") colorcandle=-colorcandle; double cotdirection=GetCotSignalDirection(i,liststatistic[istat]); if(cotdirection==0)continue; //无信号 cntsignals++; if(cotdirection*colorcandle>0) cntsucsess++; //颜色和方向一致 } if(cntsignals!=0) probably[istat]=1.*cntsucsess/cntsignals; Print("Calculation complete for ",symbol,GetStringTypeStatistic(liststatistic[istat]), " the correct forecast probability=",DoubleToString(probably[istat],2)); Print("Total signals:",cntsignals,"success:",cntsucsess); }LoadDataFromCOTIndicator 函数十分复杂,因为它需要执行数量庞大的检查以从指标获取数据,因此让我们对它进行详细讨论:
bool LoadDataFromCOTIndicator( string symbol, //交易品种名称 ENUM_TIMEFRAMES timeframe, //时间框架 cot_type_traders type_trader, //交易者群组的 类型 cot_type_data type_data , //指标 类型 cot_type_report type_report, //报告 类型 double& loadto[], //输出数据 数组 int nbars ) //需要的柱形数量 { int cothandle; nbars+=10 ; //用于反向 cothandle = iCustom( symbol , timeframe, "cot", type_trader, type_data, type_report );
在最后一行,我们获得自定义指标的句柄,该句柄可用于从缓冲器获取数据。
我们必须检查指标是否已成功创建:
if( cothandle == INVALID_HANDLE ){ Print("Error in indicator creation for symbol ", symbol ); return(false); }
检查历史数据,我们需要:
int n = BarsSinh( symbol, timeframe ); if( n < nbars ) {
如果没有足够的历史数据,我们可自己载入:
Print("Loading history for ", symbol ); //, " 始于 ", loadtm CheckLoadHistory( symbol ,timeframe, loadtm ); n = BarsSinh( symbol, timeframe ); if( n < nbars ) { Print("Not enough history for the "+symbol, " total ", n, "bars"); return(false); } }
BarsSinh(返回指定交易品种和时间表的可用柱数)和 CheckLoadHistory(下载历史数据)函数基于来自 script代码,该代码来自 MQL5 Reference。
在使用来自指标缓冲区的数据前,我们必须检查数据是否已准备就绪,因为仅凭句柄存在并不能保证计算已经完成。
如果计算已经完成,下一个调用执行检查并等待:
if( !WaitForCalculcateIndicator( cothandle ) ){ Print("Timeout for the COT indicator calculation"); return(false); }
数据已就绪,我们需要复制数据:
int res = CopyBuffer(cothandle, 0, 0, nbars, loadto );
接下来,我们检查数据是否已成功复制:
if( res != nbars ){ Print("Error in obtaining the data, ", MyErrorDescription(_LastError) ); return(false); }
最后:
return(true);
我们获得数据,并通过函数参数传递将数据返回至数组中。
结果统计数据将打印为 CSV 文件,为此我们创建 CCOTOutFile 类:
class CCOTOutFile { private: string filename; int handle; public: bool Init( string passedname ); void PutString( string symbol, double& probably[] ); void PutHeader( cot_type_statistics& arrheaders[] ) ; void ~CCOTOutFile(){ FileClose(handle); } };
它创建含输出数据的文件,以 .csv 格式编写字符串,在销毁类实例时生成头文件和关闭文件。
脚本的代码会比较短,因为所有必要的库已编写。
输入参数和包含库:
input int NBars =150; //历史数据深度 W1 #include <common.mqh> #include <cot.mqh>
用于分析的交易品种列表:
string listsymbols[] = {"EURUSD", "GBPUSD", "USDCHF", "USDCAD", "USDJPY", "AUDUSD", "XAUUSD"};
对象初始化:
void OnStart() { CCOTOutFile outfile; //结果文件 if( !outfile.Init("cotw1signals.csv") )return;
待计算的统计数据列表:
cot_type_statistics list_statistic[]= // 统计类型列表
{ speculantsign, speculantchange, willamszones };
编写 CSV 文件头:
outfile.PutHeader( list_statistic ); //向.csv文件写入头
在主循环中,我们获得每个交易品种和信号的统计数据,并将结果写入文件:
for( int i = 0; i < ArraySize(listsymbols); i++ ) //列表中的所有交易品种 { Print( "Analysis for "+listsymbols[i] ); CCOTStatistic stat; stat.Init( listsymbols[i ], list_statistic ); double probably[]; //一个信号的概率 if( !stat.Get( probably ) ) { Print( "Error in statistics calculation for the symbol ", listsymbols[i] ); return; } outfile.PutString( listsymbols[i], probably ); //向.csv 文件写入字符串 } Print("Calculation complete."); }
脚本已在 Alpari-Demo 服务器上测试。如果您在 MetaQuotes-Demo 服务器上运行脚本,服务器将打印消息 "Error in statistics calculation for the XAUUSD symbol"(XAUUSD 交易品种的统计数据计算发生错误),因为该交易品种目前尚不可用。
执行脚本后,我们将获得文件,如下所示:
为了让它更加清楚,我们用 Excel 打开,计算平均值并创建概率直方图:
图 8 预测概率
正如我们所见,非商业持仓交易人员的净长仓获得了最佳的预测结果。最差的结果来自威廉指标区域。值 0.48 表示白色烛形的概率为 0.52,即使威廉指标为超买,如果是超卖则为黑色。因此,它通过威廉指标表示的使用形式是不合理的。也许,使用较大的时间表会使结果得到改善:月或更大时间表。我们使用了演示服务器和 COT 报告中所有可用的交易品种。
缺点:
我的主要问题是访问历史数据:虽然有调试程序,但没有提供多少有用的功能:没有指标调试,也无法执行复杂对象的检查,比如数组和类。列表并不完整,我仅仅是列出在本文成文过程中碰到的优缺点。
所有文件均位于客户端文件夹中。从 sources.zip 将文件解压缩至客户端文件夹。
№ | 文件名 | 说明 |
---|---|---|
1 | MQL5\Files\unzip.exe | 解压缩 .zip 档案的 Windows 应用程序 |
2 | MQL5\Include\Cdownloader.mqh | 从网络下载 CFTC 档案的类 |
3 | MQL5\Include\ClassProgressBar.mqh | 用于在图表窗口中显示下载过程的类 CProgressBar |
4 | MQL5\Include\common.mqh | 用于所有指标和脚本的通用函数和常量 |
5 | MQL5\Include\cot.mqh | 用于从 COT 报告选择数据的类 CCFTCReport |
6 | MQL5\Include\ErrorDescription.mqh | 错误描述库 |
7 | MQL5\Indicators\cot.mq5 | 基础指标 cot |
8 | MQL5\Indicators\cotnet.mq5 | 指标 cotnet,将 cot.mq5 用作自定义用户指标的简单示例 |
9 | MQL5\Scripts\cotdownloader.mq5 | 脚本 cotdownloader,用于从互联网下载档案文件 |
10 | MQL5\Scripts\cotsignals.mq5 | 脚本 cotsignals,COT 报告统计分析的示例 |
表 2. 文件列表
№ |
交易品种名称 |
交易所 ID | 客户端 ID | 出现于 CIT 中 | 出现于 DCOT 中 |
---|---|---|---|---|---|
1 | 小麦 - 芝加哥交易所 | 001602 | ZW | x | x |
2 | 小麦 - 堪萨斯城交易所 | 001612 | x | x | |
3 | 小麦 - 明尼阿波利斯谷物交易所 | 001626 | x | ||
4 | 玉米 - 芝加哥交易所 | 002602 | ZC | x | x |
5 | 燕麦 - 芝加哥交易所 | 004603 | ZO | x | |
6 | 黄豆 - 芝加哥交易所 | 005602 | ZS | x | x |
7 | 大豆 - 芝加哥交易所 | 005603 | x | ||
8 | 硫金融工具 - 芝加哥气候期货交易所 | 006261 | x | ||
9 | 碳金融工具 - 芝加哥气候期货交易所 | 006268 | x | ||
10 | RGGI 二氧化碳配额 2009 - 芝加哥气候期货交易所 | 00626U | x | ||
11 | 黄豆油 - 芝加哥交易所 | 007601 | ZL | x | x |
12 | 美国国库债券 - 芝加哥交易所 | 020601 | ZB | ||
13 | 美国国库长期债券 - 芝加哥交易所 | 020604 | |||
14 | GULF # 6 燃料 3.0% 硫交换 - 纽约商品交易所 | 02165A | x | ||
15 | NY RES 燃料 1.0% 硫交换 - 纽约商品交易所 | 02165B | x | ||
16 | EUR 1% 燃油 NWE CAL 交换 - 纽约商品交易所 | 02165C | x | ||
17 | EUR 3.5% 燃油 RTD CAL 交换 - 纽约商品交易所 | 02165E | x | ||
18 | SING 燃油 180 CAL 交换 - 纽约商品交易所 | 02165G | x | ||
19 | 东西燃油 SPR 交换 - 纽约商品交易所 | 02165I | x | ||
20 | NY 1% V GULF 3% 燃油 SPR - 纽约商品交易所 | 02165T | x | ||
21 | 2 号热燃油 | 022651 | x | ||
22 | SING 汽油交换 - 纽约商品交易所 | 02265J | x | ||
23 | SING 汽油/RDAM 汽油交换 - 纽约商品交易所 | 02265T | x | ||
24 | NYMEX 热燃油/RDAM 汽油 - 纽约商品交易所 | 02265U | x | ||
25 | 汽油 (ICE) 交换 - 纽约商品交易所 | 02265V | x | ||
26 | 上下 GC ULSD VS HO SPR 交换 - 纽约商品交易所 | 022A13 | x | ||
27 | SING 汽油 BALMO 交换 - 纽约商品交易所 | 022A22 | x | ||
28 | 天然气 ICE 亨利港 - ICE OTC | 023391 | x | ||
29 | 天然气 - 纽约商品交易所 | 023651 | QG | x | |
30 | MICHCON 基差交换 - 纽约商品交易所 | 02365A | x | ||
31 | M-3 基差交换 - 纽约商品交易所 | 02365C | x | ||
32 | TCO 基差交换 - 纽约商品交易所 | 02365D | |||
33 | NGPL TEXOK 基差交换 - 纽约商品交易所 | 02365G | x | ||
34 | NGPL MIDCON 基差交换 - 纽约商品交易所 | 02365K | x | ||
35 | WAHA 基差交换 - 纽约商品交易所 | 02365O | x | ||
36 | 休斯敦航道利率交换 - 纽约商品交易所 | 023A10 | x | ||
37 | CBT 乙醇 - 芝加哥交易所 | 025601 | x | ||
38 | 芝加哥乙醇交换 - 纽约商品交易所 | 025651 | x | ||
39 | 黄豆粉 - 芝加哥交易所 | 026603 | ZM | x | |
40 | 日本 C&F NAPTHA 交换 - 纽约商品交易所 | 03265C | x | ||
41 | 2 号棉花 - ICE 美国期货交易所 | 033661 | CT | x | x |
42 | 亨利港基差交换 - 纽约商品交易所 | 035652 | x | ||
43 | 休斯敦航道基差交换 - 纽约商品交易所 | 035653 | x | ||
44 | NW PIPE ROCKIES 基差交换 - 纽约商品交易所 | 035654 | x | ||
45 | PANHANDLE 基差交换 - 纽约商品交易所 | 035655 | x | ||
46 | 亨利港交换 - 纽约商品交易所 | 03565B | |||
47 | 亨利港天然气倒数第二个工作日期满掉期 - 纽约商品交易所 | 03565C | x | ||
48 | 稻谷 - 芝加哥交易所 | 039601 | ZR | x | |
49 | 冻橙汁 - ICE 美国期货交易所 | 040701 | JO | x | |
50 | 美国两年债券 - 芝加哥交易所 | 042601 | |||
51 | 美国十年债券 - 芝加哥交易所 | 043602 | ZN | ||
52 | 美国五年债券 - 芝加哥交易所 | 044601 | |||
53 | 30 天联邦基金 - 芝加哥交易所 | 045601 | ZQ | ||
54 | 连续月第三级牛奶 - 芝加哥商品交易所 | 052641 | x | ||
55 | 瘦肉猪 - 芝加哥商品交易所 | 054642 | HE | x | x |
56 | 活牛 - 芝加哥商品交易所 | 057642 | LC | x | x |
57 | 任意长度木材 - 芝加哥商品交易所 | 058643 | LB | x | |
58 | 肉牛 - 芝加哥商品交易所 | 061641 | FC | x | x |
59 | PJM 月度电价 - 纽约商品交易所 | 064657 | x | ||
60 | ISO NEW ENGLAND LMP 交换 - 纽约商品交易所 | 06465H | x | ||
61 | PJM CAL 月度离峰 LMP 交换 - 纽约商品交易所 | 06465M | x | ||
62 | ISO NEW ENG 离峰 LMP 交换 - 纽约商品交易所 | 06465S | x | ||
63 | CINERGY CAL 月度 LMP 交换 - 纽约商品交易所 | 064A01 | x | ||
64 | CINERGY 离峰 LMP 交换 - 纽约商品交易所 | 064A02 | |||
65 | PJM N ILL 日前峰值 - 纽约商品交易所 | 064A34 | x | ||
66 | PJM JCPL 日前峰值 - 纽约商品交易所 | 064A48 | x | ||
67 | PJM PEPCO 日前峰值 - 纽约商品交易所 | 064A50 | x | ||
68 | PJM PSEG 日前峰值 - 纽约商品交易所 | 064A54 | x | ||
69 | PJM WESTERN 日前峰值 - 纽约商品交易所 | 064A56 | |||
70 | PJM WESTERN 实时峰值 - 纽约商品交易所 | 064A58 | x | ||
71 | PJM WESTERN 实时离峰 - 纽约商品交易所 | 064A59 | x | ||
72 | ISO NEW ENG INT HUB 峰值交换 - 纽约商品交易所 | 064A60 | x | ||
73 | MW IND TRANS 峰值交换 - 纽约商品交易所 | 064A62 | x | ||
74 | NYISO ZONE 5 MW 峰值交换 - 纽约商品交易所 | 064A66 | |||
75 | ISO NEW ENG HUB 离峰交换 - 纽约商品交易所 | 064A78 | |||
76 | MT BELVIEU 丙烷 5 DEC 交换 - 纽约商品交易所 | 06665O | |||
77 | MT BELVIEU 乙烷 5 DEC 交换 - 纽约商品交易所 | 06665P | x | ||
78 | MT BELV 标准丁烷 5 DEC 交换 - 纽约商品交易所 | 06665Q | x | ||
79 | MT BELV 天然汽油 5 DEC 交换 - 纽约商品交易所 | 06665R | x | ||
80 | 低硫轻质原油 - ICE 欧洲期货交易所 轻质原油 - ICE 欧洲期货交易所 | 067411 | x | ||
81 | 低硫轻质原油 - 纽约商品交易所 | 067651 | QM | x | |
82 | WTI 原油日历交换 - 纽约商品交易所 | 06765A | x | ||
83 | 迪拜原油日历交换 - 纽约商品交易所 | 06765G | x | ||
84 | WTI 原油金融工具 - 纽约商品交易所 | 06765I | x | ||
85 | 布伦特金融工具 - 纽约商品交易所 | 06765J | x | ||
86 | 布伦特 (ICE) 日历交换 - 纽约商品交易所 | 06765N | x | ||
87 | 布伦特-迪拜交换 - 纽约商品交易所 | 06765O | x | ||
88 | 可可 - ICE 美国期货交易所 | 073732 | CC | x | x |
89 | 钯金 - 纽约商品交易所 | 075651 | PA | x | |
90 | 白金 - 纽约商品交易所 | 076651 | PL | x | |
91 | 11 号糖 - ICE 美国期货交易所 | 080732 | SB | x | x |
92 | 咖啡 C - ICE 美国期货交易所 | 083731 | KC | x | x |
93 | 白银 - 商品交易所 | 084691 | SI,XAGUSD,ZI | x | |
94 | 高级铜 - 商品交易所 | 085692 | HG | x | |
95 | 黄金 - 商品交易所 | 088691 | GC,GOLD,XAUUSD | x | |
96 | 俄罗斯卢布 - 芝加哥商品交易所 | 089741 | USDRUB,USDRUR | ||
97 | 加拿大元 - 芝加哥商品交易所 | 090741 | 6C,USDCAD | ||
98 | 瑞士法郎 - 芝加哥商品交易所 | 092741 | 6S,USDCHF | ||
99 | 墨西哥比索 - 芝加哥商品交易所 | 095741 | |||
100 | 英镑 - 芝加哥商品交易所 | 096742 | 6B,GBPUSD | ||
101 | 日元 - 芝加哥商品交易所 | 097741 | 6J,USDJPY | ||
102 | 美元指数 - ICE 美国期货交易所 | 098662 | DX | ||
103 | 欧元 - 芝加哥商品交易所 | 099741 | 6E,EURUSD | ||
104 | 汽油搀配油 (RBOB) - 纽约商品交易所 | 111659 | XRB | x | |
105 | RBOB 日历交换 - 纽约商品交易所 | 11165K | x | ||
106 | 新西兰元 - 芝加哥商品交易所 | 112741 | 6N,NZDUSD | ||
107 | VIX 期货 - 芝加哥期货交易所 | 011700 | |||
108 | 道琼斯工业平均指数 - 芝加哥交易所 | 124601 | |||
109 | 3 月期欧洲美元期货 - 芝加哥商品交易所 | 132741 | |||
110 | 标普 500 指数 - 芝加哥商品交易所 | 138741 | |||
111 | 电子迷你标普 500 指数 - 芝加哥商品交易所 | 13874A | ES,SPX | ||
112 | 纳斯达克 100 指数 - 芝加哥商品交易所 | 209741 | NQ | ||
113 | 迷你纳斯达克 100 指数 - 芝加哥商品交易所 | 209742 | |||
114 | 道琼斯瑞银额外回报 - 芝加哥交易所 | 221602 | |||
115 | 澳元 - 芝加哥商品交易所 | 232741 | 6A,AUDUSD | ||
116 | 罗素 2000 迷你指数期货 - ICE 美国期货交易所 | 23977A | |||
117 | 日经股价指数 - 芝加哥商品交易所 | 240741 | |||
118 | 日经股价指数 YEN DENOM - 芝加哥商品交易所 | 240743 | |||
119 | 电子迷你 MSCI EAFE - 芝加哥商品交易所 | 244741 | |||
120 | 电子迷你 MSCI 新兴市场 - 芝加哥商品交易所 | 244742 | |||
121 | 10 年期利率交换 - 芝加哥交易所 | 246602 | |||
122 | 5 年期利率交换 - 芝加哥交易所 | 247602 | |||
123 | 标普 GSCI 商品指数 - 芝加哥商品交易所 | 256741 | |||
124 | SING JET KERO 交换 - 纽约商品交易所 | 26265D | |||
125 | 电子迷你标普 400 指数 - 芝加哥商品交易所 | 33874A | |||
126 | GULF JET NY 热燃油 SPR 交换 - 纽约商品交易所 | 86465A | x | ||
127 | SING JET KERO 汽油 SPR 交换 - 纽约商品交易所 | 86465C | x | ||
128 | JET CIF NWE/汽油期货 - 纽约商品交易所 | 86465D | x | ||
129 | GULF # 6 燃油裂解交换 - 纽约商品交易所 | 86565A | x | ||
130 | 3.5% 燃油 RDAM 裂解价差 - 纽约商品交易所 | 86565C | x | ||
131 | 石脑油裂解价差交换 - 纽约商品交易所 | 86665A | x | ||
132 | 汽油裂解价差交换 - 纽约商品交易所 | 86765C | x |
表 3. COT 报告中的可用交易品种列表
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程