下载交易品种历史记录的所有报价 - MetaTrader 5 专家
此专家顾问代码将扫描用户经纪商的市场观察并提取符号,并为其下载所有可用的报价或截至日期的报价。
它可以帮助您下载回测的所有交易品种历史记录,或从这些价格变动创建自定义图表。
终端会将蜱虫缓存在数据文件夹中,因此请确保您有足够的硬盘空间。
为了方便下载符号,我们首先需要一个下载管理器。
CDownloadManager 结构包含我们需要保留的所有信息。
结构体CD下载管理器 { 布尔值 m_开始,m_完成; 细绳 m_symbols[],m_current; 整数 m_索引;
我们还需要读取和写入硬盘驱动器,由于我们正在使用符号,因此我们创建了 2 个快速函数来从二进制文件写入和读取字符串。
将字符串保存到文件函数:
空白将字符串写入文件(整数f,细绳字符串) {//保存符号字符串 字符系统保存[]; 整数总字符数=字符串转字符数组(字符串,系统保存,0,字符串长度(字符串),CP_ACP); 文件写入整数(f,字符总数,INT_VALUE); 为了(整数我=0;i<字符总数;i++) { 文件写入整数(f,系统保存[i],CHAR_VALUE); } }
它接收:
它写入字符串中有多少个字符的整数长度,然后将每个字符存储在字符串中。
从文件加载字符串函数:
细绳从文件读取字符串(整数f) { 细绳结果=””;//加载符号字符串 字符syload[]; 整数总字符数=(整数)文件读取整数(f,INT_VALUE); 如果(字符总数>0) { 数组调整大小(syload、chartotal、0); 为了(整数我=0;i<字符总数;i++) { syload[i]=(字符)文件读取整数(f,CHAR_VALUE); } 结果=字符数组转字符串(系统负载,0,字符总数,CP_ACP); } 返回(结果); }
它读取文件中该点期望的字符数的整数长度。它继续将每个字符读入 char 数组,然后从该 char 数组创建一个字符串,该字符串作为字符串加载的结果返回。
回到CDownloadManager 结构。我们需要一种方法来初始化管理器并从市场观察中填充它:
//+------------------------------------------------------------------+ //|从市场观察中获取符号 | //+------------------------------------------------------------------+ 空白 抓取符号() { //!仅来自MW! 整数s=符号总数(真的); 数组调整大小(m_符号,s,0); 为了(整数我=0;我<数组大小(m_符号);i++) { m_符号[i]=符号名称(我,真的); } }
非常简单:
我们还负责管理符号数据的下载,因此我们需要一个本质上是管理器的函数:
//+------------------------------------------------------------------+ //|管理符号下载过程 | //+------------------------------------------------------------------+ 空白 管理(细绳文件夹,细绳文件名) { //本质上这会开始或导航到下一个符号 //如果设置 如果(数组大小(m_符号)>0) { //如果没有启动 如果(!m_开始) { m_开始=真的; //转到第一个符号 m_当前=m_符号[0]; m_索引=1; 保存(文件夹,文件名); 如果(_象征!=m_当前) { 图表集符号周期(图表ID(),m_当前,_时期); } 别的 { ENUM_TIMEFRAMES新时期=PERIOD_M1; 为了(整数p=0;p<数组大小(TFS);p++) { 如果(_时期!=TFS[p]) { new_period=TFS[p]; 休息; } } 图表集符号周期(图表ID(),m_current,new_period); } 返回; } //如果启动了 别的 { m_index++; 如果(m_index<=数组大小(m_符号)) { m_当前=m_符号[m_索引-1]; 保存(文件夹,文件名); 如果(_象征!=m_当前) { 图表集符号周期(图表ID(),m_当前,_时期); } 返回; } 别的 { m_完成=真的; 文件删除(文件夹+“\\”+文件名); 打印(“完成的”); 专家删除(); 返回; } } } 别的 { 打印(“请先抓取符号”); } //如果设置到这里结束 }
系统如何工作:
这是在计时器上进行下载的代码部分:
//+------------------------------------------------------------------+ //|计时器 | //+------------------------------------------------------------------+ 空白 定时器() {//--- 如果同步 如果(符号已同步(_象征)&&终端信息整数(TERMINAL_CONNECTED 终端已连接)==1) { 事件终止定时器(); //--- 在此加载系统 如果(MANAGER.load(MANAGER_FOLDER,MANAGER_STATUS_FILE)) { //--- 系统已加载,因此我们正在此处扫描符号 评论(“系统已加载,我们正在处理”+MANAGER.m_current); //--- 刻度负载 //--- 首先找到经纪商中最旧的可用报价 整数尝试=0; 整数平=-1; 日期时间光标=展平(时间交易服务器()); 长的光标MSC=((长的)光标)*1000; 长的跳跃=2592000000;//60*60*24*30*1000; MQTick接收者[]; 长的最旧=长_最大; 评论(“请稍等”); 尽管(尝试<5) { 平=复制标记(_象征,接收者,COPY_TICKS_ALL,光标MSC,1); 如果(平==1) { 如果(接收者[0].time_msc==最旧的) { 尝试++; } 别的 { 尝试=0; } 如果(接收者[0].time_msc<最旧的) { 最旧的=接收者[0].time_msc; } 光标MSC-=跳转; 如果(限制日期&&接收者[0].time<=oldestLimit) { 休息; } } 别的 { 尝试++; } 睡觉(44); 评论(“最旧的蜱虫:”+字符串时间((日期时间)(最古老的/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"\n光标("+字符串时间((日期时间)(光标MSC/1000),TIME_DATE|TIME_MINUTES|TIME_SECONDS)+")\n尝试("+整数转字符串(尝试)+")\n请等待回复..."); } //--- 此时我们有最旧的刻度 //--- 开始请求从最旧到最新的价格变动 如果(最古老!=长_最大) { 数组自由(接收者); 日期时间最新_刻度=0; //--- 接收存储在symbol_time中的该交易品种的最后报价时间 日期时间最近的蜡烛=(日期时间)符号信息整数(_象征,SYMBOL_TIME); 尽管(newest_tick//--- 请求从最旧的时间开始并指定刻度限制的新批次 整数拉=复制标记(_象征,接收者,COPY_TICKS_ALL,最旧的,tick_packets); 如果(拉>0) { //--- 如果我们提取新批次更新我们的下载时间 latest_tick=接收器[拉-1]。时间; 最旧=接收者[拉-1].time_msc; 数组自由(接收者); } //--- 超时服务器请求,如果需要可以更改它 睡觉(44); 评论(“拉到”+字符串时间(最新的刻度线,TIME_DATE|TIME_MINUTES|TIME_SECONDS)+“ 迄今为止”); } } 别的 { 警报(“请关闭终端 \n 前往刻度文件夹 \n 并删除空文件夹”); 专家删除(); } //--- 更新管理器并继续 MANAGER.管理(MANAGER_FOLDER,MANAGER_STATUS_FILE); } 别的 { //--- 获取市场观察符号以开始下载 评论(“抓住MW并开始”); MANAGER.grab_symbols(); MANAGER.管理(MANAGER_FOLDER,MANAGER_STATUS_FILE); } } }
