[返回谈股论金首页]·[所有跟帖]·[ 回复本帖 ] ·[热门原创] ·[繁體閱讀]·[版主管理] | |||
使用方法:建立一个txt文件,把内容拷贝到txt文件中,保存关闭txt,把txt文件名给为Period_Converter_Opt.mq4就行了。 代码内容包括使用方法。具体的可以百度搜Period_Converter_Opt.mq4文件使用方法。 源代码如下: //+------------------------------------------------------------------+ //| Period_Converter_Opt.mq4| //| Copyright (c)2005, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //| Ver.1.6 Modified by micclly| //| Ver.1.5 Modified by fai | //| Modified by wfy05@talkforex based on Period_Converter| //| http://www.talkforex.com | //+------------------------------------------------------------------+ #property copyright "wfy05@talkforex.com" #property link "http://www.mql4.com/codebase/indicators/277/" #property indicator_chart_window #include /* Readme: I. Features: This is an improved version of period converter for MT4 based on the MT4's default period converter by metaquotes. The default period converter script do not support real-time refreshing, and consume lots of CPU (50%-9x%) making the whole system slow. Also, the default one is a script which do not save when you exit MT4, so you have to apply every converter script again after restarting, quite annoying. This one fixed all above problems: 1. Real-time updating or custom interval millisecond level updating. 2. Low CPU cost, average 5%-10% or less. 3. Works as an indicator, so can be saved and reloaded during restart. 4. There is no one converter per chart limitation as it is not script any more, you can only use one window as source to generate as many new timeframe chart as possible. 5. Auto updating if there is new history block loaded. II. How to use: Copy the mq4 file to your MT4 indicators folder (expertsindicators) to install it as an indicator, NOT script. then in the custom indicator list, attach period_converter_opt to the chart you want. It support 4 parameters: PeriodMultiplier: new period multiplier factor, default is 2 UpdateInterval: update interval in milliseconds, zero means update real-time. default is zero. Enabled: You can disable it without remove it with this option. Other parameters are comments or for debugging, it is safe to ignore them. Also Make sure you have Allow Dll imports option checked in common tab or it won't work After that, File->Open Offline to open the generated offline data. then the offline data will be updated automatically. As long as you keep the source chart open and the converter indicator running, the generated chart including indicators inside will always be updated. also you can close the generated chart and open again later from File->Open Offline without problem. If you want to quit MT4, you can leave those offline chart as other normal online charts. when you start MT4 next time, those charts will also be loaded and updated. III. Notes: 1. Do NOT uncheck the "offline chart" option in offline chart common properties. or after MT4 restart, it will treat that chart as online chart and request the data from server, resulting empty chart window. 2. You can attach more than one converter to same window with different PeriodMultiplier, e.g: you can attach 3 converter with PeriodMultiplier = 2, 4, 10 to M1 to generate M2, M4, M10 at the same time. It is even ok to use the M1 chart to generate Hourly chart like H2, which only cost a few more CPU resource during initial conversion. but usually most server don't have much data for those short period. resulting the generated data isn't long enough for long period. so it is suggested to use Hourly/Daily charts as source when needed. 3. The real-time updating mode updates quotes as fast as possible, but as this is done via script, and MT will skip calling start() function when your PC is busy and lots of quotes income. anyway, this seldom happen, and you can at least get 10 updates each seconds which is much more than enough. 4. The offline chart don't have a bid line showing in chart, but all data in the chart including the indicators is still being updated, so don't worry. you can show the bid line by unclick the "offline chart" option in chart properties. but which don't helps much and if you forget to check "offline chart" option before exit. it will cause errors and become empty on next startup. you have to close the window and open again from File->Open offline, which don't worth the trouble. IV. History: 2014.03.10 1.6 Modified to support build 600 and later 2009.08.07 1.5 Added 3 options.(ShiftTiming,GMTShift,OmitDigit) 2005.12.24 1.4 faster to detect if data changed by removing float point operations, added support to output CSV file in real time. OutputCSVFile = 0 means no CSV. OutputCSVFile = 1 means CSV + HST OutputCSVFile = 2 CSV only, no HST . (useful if you want to generate CSV for builtin periods) CSV Filename will be the same as HST file except the extension. added safe checking for PeriodMultiplier. 2005.12.04 1.3 Fixed missing data when there is large amount of data loaded in several blocks, and support auto updating when new history is loaded. 2005.11.29 1.2 Additional fix for missing data and server changing. 2005.11.29 1.1 Fixed missing partial data after restart. Reinitialize after changing server or data corrupted. 2005.11.28 1.0 Initial release 读我: 一,特点: 这一次更新解决了以上所有问题: 1.实时更新或自定义间隔毫秒级别更新。 2.低CPU成本,平均5%-10%或更少。 3.作为一个指标,所以可以在重新启动时保存和重新加载。 4.可以用一个转换器生成多个图表没有限制,因为它不是脚本 而且,您可以使用一个窗口作为源来生成多个新的时间表图窗口。 5.如果有新的历史块加载,会自动更新。 这是基于MT4的周期转换器的改进版本 旧版本MT4的默认时段转换器由metaquotes。默认周期转换器脚本不支持实时刷新,并消耗大量的 CPU(50%-9x%),使整个系统变慢。另外,默认的是当你退出MT4时不保存的脚本,所以你必须 在重新启动后重新应用每个转换器脚本非常烦人。 二,如何使用: 将mq4文件复制到您的MT4指标文件夹(expertsindicators)安装它作为一个指标,而不是脚本。 然后在自定义指标列表中,将period_converter_opt附加到所需的图表。 它支持4个参数: PeriodMultiplier:新周期乘数,默认为2 UpdateInterval:更新间隔(以毫秒为单位)零意味着更新实时。默认为零。 启用:您可以禁用它,而不必使用此选项将其删除。 其他参数是注释或调试,忽略它们是安全的。 此外请确保您有共同选项卡或选中选中允许Dll导入选项,它不会工作。 之后,File-> Open Offline打开生成的离线数据。然后离线数据将自动更新。 只要你保持源图开放和转换指标运行,生成的图表包括里面的指标将一直存在及被更新。也可以关 闭生成的图表并重新打开,稍后从File-> Open Offline打开也没有问题。 如果你想退出MT4,你可以离开这些离线图表作为其他正常的在线图表。当你下一次启动MT4时,这 些图表就会出现也被加载和更新。 三,笔记: 1.不要在离线图表公共属性中取消选中“离线图表”选项。否则在MT4重新启动后,会将该图表视为在 线图表和请求来自服务器的数据,产生空图表窗口。 2.您可以将多个转换器连接到不同的同一窗口 PeriodMultiplier,例如:你可以连接3个转换器 PeriodMultiplier = 2,4,10到M1以同时生成M2,M4,M10。 甚至可以使用M1图来生成像H2这样的小时图,但是在初始转换期间需要花费更多的CPU资源。通常 大多数服务器在短时间内不能提供太多的数据而造成的生成数据用时非常长。为避免CPU用时长建 议H1以上图表在需要时使用小时/每日图表作为来源。 3.实时更新模式尽可能快地更新报价,但是这是通过作为脚本来完成的,MT会在调用start()函数时 跳过很多报价收入,致使你的电脑很忙。不过,这很少发生,而且每秒至少可以获得10次自动更新, 这就足够了。 4.离线图表中没有出现在图表中的出价线,而是所有数据 在图表中包括指标仍在更新中, 所以不要担心您可以通过点击“离线图表”来显示出价线 图表属性中的选项。但是如果你忘记的话,这些帮助不大 在退出前检查“离线图表”选项。它会导致错误和 在下次启动时变空。你必须关上窗户并打开 再次从文件 - >打开离线,这是不值得的麻烦。 IV。历史: 2014.03.10 1.6修改为支持构建600及更高版本 2009.08.07 1.5增加了3个选项(ShiftTiming,GMTShift,OmitDigit) 2005.12.24 1.4通过删除浮点数来更快地检测数据是否改变操作,增加了对实时输出CSV文件的支持。 OutputCSVFile = 0表示没有CSV。 OutputCSVFile = 1表示CSV + HST OutputCSVFile = 2仅CSV,无HST。 (如果您想为内置的时间段生成CSV,除扩展名外,CSV文件名将与HST文件相同。增加了对 PeriodMultiplier的安全检查。) 2005.12.04 1.3修复了大量数据时丢失的数据加载在几个块中,并支持自动更新当新的历史被加载。 2005.11.29 1.2缺少数据和服务器更改的其他修复程序。 2005.11.29 1.1修复重启后丢失的部分数据。更改服务器或数据损坏后重新初始化。 2005.11.28 1.0初始版本 */ extern double Version = 1.6; // 代码版本 extern string BuildInfo = "2014.03.10 by micclly";//构建信息 extern int PeriodMultiplier = 1; // 新周期乘数:默认为2 extern int OutputCSVFile = 0; // 输出CSV文件:0表示没有CSV;1表示CSV + HST;2仅CSV,无HST; extern int UpdateInterval = 0; // 实时更新。默认为零毫秒。 extern bool Enabled = true;//启用 extern bool Debug = false;//调试 extern int ShiftTiming = 0;//0-3,Using H1Chart and PeriodMultiplier=4; //if 1, ServerH4Chart = 00:00/04:00/08:00/12:00... // =>OfflineH4Chart = 01:00/05:00/09:00/13:00... extern int GMTShift = 0;// if 9, ServerTime = GMT+0 -> OfflineChartTime = GMT+9 extern int OmitDigit = 0;// if 1, 5Digits -> 4Digits int FileHandle = -1; int CSVHandle = -1; int NewPeriod = 0; string MySymbol = ""; int ShiftBase; #define OUTPUT_HST_ONLY 0 #define OUTPUT_CSV_HST 1 #define OUTPUT_CSV_ONLY 2 #define CHART_CMD_UPDATE_DATA 33324 void DebugMsg(string msg) { if (Debug) Alert(msg); } int init() { ShiftBase = Period() * 60;//sec string suffix = ""; if(ShiftTiming != 0) suffix =StringConcatenate(suffix,"s",ShiftTiming); if(GMTShift != 0) suffix =StringConcatenate(suffix,"g",GMTShift); if(OmitDigit != 0) suffix =StringConcatenate(suffix,"o"/*,OmitDigit*/); MySymbol =Symbol() + "_" + suffix; if(StringLen(MySymbol)>11) MySymbol = StringConcatenate(StringSubstr(MySymbol,0,11-StringLen(suffix)),suffix); //安全检查周期乘数。 if (PeriodMultiplier = 0) { FileClose(FileHandle); FileHandle = -1; } if (CSVHandle >= 0) { FileClose(CSVHandle); CSVHandle = -1; } } int OpenHistoryFile() { string name; name = MySymbol + NewPeriod; if (OutputCSVFile != OUTPUT_CSV_ONLY) { FileHandle = FileOpenHistory(name + ".hst", FILE_BIN|FILE_WRITE|FILE_SHARE_READ); if (FileHandle < 0) return(-1); } if (OutputCSVFile != OUTPUT_HST_ONLY) { CSVHandle = FileOpen(name + ".csv", FILE_CSV|FILE_WRITE|FILE_SHARE_READ|FILE_ANSI, ','); if (CSVHandle < 0) return(-1); } return (0); } int WriteHistoryHeader() { string c_copyright; int i_digits = Digits-OmitDigit; int i_unused[13] = {0}; int version = 400; if (FileHandle < 0) return (-1); c_copyright = "(C)opyright 2003, MetaQuotes Software Corp."; FileWriteInteger(FileHandle, version, LONG_VALUE); FileWriteString(FileHandle, c_copyright, 64); FileWriteString(FileHandle, MySymbol, 12); FileWriteInteger(FileHandle, NewPeriod, LONG_VALUE); FileWriteInteger(FileHandle, i_digits, LONG_VALUE); FileWriteInteger(FileHandle, 0, LONG_VALUE); //timesign FileWriteInteger(FileHandle, 0, LONG_VALUE); //last_sync FileWriteArray(FileHandle, i_unused, 0, ArraySize(i_unused)); return (0); } static double d_open, d_low, d_high, d_close, d_volume; static int i_time; void WriteHistoryData() { if (FileHandle >= 0) { FileWriteInteger(FileHandle, i_time+GMTShift*60*60, LONG_VALUE); FileWriteDouble(FileHandle, d_open, DOUBLE_VALUE); FileWriteDouble(FileHandle, d_low, DOUBLE_VALUE); FileWriteDouble(FileHandle, d_high, DOUBLE_VALUE); FileWriteDouble(FileHandle, d_close, DOUBLE_VALUE); FileWriteDouble(FileHandle, d_volume, DOUBLE_VALUE); } if (CSVHandle >= 0) { int i_digits = Digits-OmitDigit; FileWrite(CSVHandle, TimeToStr(i_time, TIME_DATE), TimeToStr(i_time, TIME_MINUTES), DoubleToStr(d_open, i_digits), DoubleToStr(d_high, i_digits), DoubleToStr(d_low, i_digits), DoubleToStr(d_close, i_digits), d_volume); } } int UpdateHistoryFile(int start_pos, bool init = false) { static int last_fpos, csv_fpos; int i, ps; // if (FileHandle < 0) return (-1); // normalize open time ps = NewPeriod * 60; i_time = (Time[start_pos]-ShiftBase*ShiftTiming)/ps; i_time = i_time*ps + ShiftBase*ShiftTiming; if (init) { //first time, init data d_open = Open[start_pos]; d_low = Low[start_pos]; d_high = High[start_pos]; d_close = Close[start_pos]; d_volume = Volume[start_pos]; i = start_pos - 1; if (FileHandle >= 0) last_fpos = FileTell(FileHandle); if (CSVHandle >= 0) csv_fpos = FileTell(CSVHandle); } else { i = start_pos; if (FileHandle >= 0) FileSeek(FileHandle,last_fpos,SEEK_SET); if (CSVHandle >= 0) FileSeek(CSVHandle, csv_fpos, SEEK_SET); } if (i < 0) return (-1); int cnt = 0; int LastBarTime; //processing bars while (i >= 0) { LastBarTime = Time[i]; //a new bar if (LastBarTime >= i_time+ps) { //write the bar data WriteHistoryData(); cnt++; i_time = (LastBarTime-ShiftBase*ShiftTiming)/ps; i_time = i_time*ps + ShiftBase*ShiftTiming; d_open = Open[i]; d_low = Low[i]; d_high = High[i]; d_close = Close[i]; d_volume = Volume[i]; } else { //no new bar d_volume += Volume[i]; if (Low[i]d_high) d_high = High[i]; d_close = Close[i]; } i--; } //record last_fpos before writing last bar. if (FileHandle >= 0) last_fpos = FileTell(FileHandle); if (CSVHandle >= 0) csv_fpos = FileTell(CSVHandle); WriteHistoryData(); cnt++; d_volume -= Volume[0]; //flush the data writen if (FileHandle >= 0) FileFlush(FileHandle); if (CSVHandle >= 0) FileFlush(CSVHandle); return (cnt); } int UpdateChartWindow() { static int hwnd = 0; if (FileHandle < 0) { //no HST file opened, no need updating. return (-1); } if(hwnd == 0) { //trying to detect the chart window for updating hwnd = WindowHandle(MySymbol, NewPeriod); } if(hwnd!= 0) { if (IsDllsAllowed() == false) { //DLL calls must be allowed DebugMsg("Dll calls must be allowed"); return (-1); } if (PostMessageA(hwnd,WM_COMMAND,CHART_CMD_UPDATE_DATA,0) == 0) { //PostMessage failed, chart window closed hwnd = 0; } else { //PostMessage succeed return (0); } } //window not found or PostMessage failed return (-1); } /* int PerfCheck(bool Start) { static int StartTime = 0; static int Index = 0; if (Start) { StartTime = GetTickCount(); Index = 0; return (StartTime); } Index++; int diff = GetTickCount() - StartTime; Alert("Time used [" + Index + "]: " + diff); StartTime = GetTickCount(); return (diff); } */ static int LastStartTime = 0; static int LastEndTime = 0; static int LastBarCount = 0; void reinit() { deinit(); init(); LastStartTime = Time[Bars-1]; LastEndTime = Time[0]; LastBarCount = Bars; } bool IsDataChanged() { /* static int LastBars = 0, LastTime = 0, LastVolume = 0; static double LastOpen = 0, LastClose = 0, LastHigh = 0, LastLow = 0; if (LastVolume != Volume[0] || LastBars != Bars || LastTime != Time[0]|| LastClose != Close[0] || LastHigh != High[0] || LastLow != Low[0] || LastOpen != Open[0]) { LastBars = Bars; LastVolume = Volume[0]; LastTime = Time[0]; LastClose = Close[0]; LastHigh = High[0]; LastLow = Low[0]; LastOpen = Open[0]; return (true); } return (false); */ /* fast version without float point operation */ static int LastBars = 0, LastTime = 0, LastVolume = 0; bool ret; ret = false; if (LastVolume != Volume[0]) { LastVolume = Volume[0]; ret = true; } if (LastTime != Time[0]) { LastTime = Time[0]; ret = true; } if (LastBars != Bars) { LastBars = Bars; ret = true; } return (ret); } int CheckNewData() { static string LastServer = ""; if (Bars < 2) { //the data is not loaded yet. DebugMsg("Data not loaded, only " + Bars + " Bars"); return (-1); } string serv = ServerAddress(); if (serv == "") { //no server yet DebugMsg("No server connected"); return (-1); } //server changed? check this and reinit to prevent wrong data while changing server. if (LastServer != serv) { DebugMsg("Server changed from " + LastServer + " to " + serv); LastServer = serv; reinit(); return (-1); } if (!IsDataChanged()) { //return if no data changed to save resource //DebugMsg("No data changed"); return (-1); } if (Time[Bars-1] != LastStartTime) { DebugMsg("Start time changed, new history loaded or server changed"); reinit(); return (-1); } int i, cnt; //try to find LastEndTime bar, which should be Time[0] or Time[1] usually, //so the operation is fast for (i = 0; i < Bars; i++) { if (Time[i] = Bars || Time[i] != LastEndTime) { DebugMsg("End time " + TimeToStr(LastEndTime) + " not found"); reinit(); return (-1); } cnt = Bars - i; if (cnt != LastBarCount) { DebugMsg("Data loaded, cnt is " + cnt + " LastBarCount is " + LastBarCount); reinit(); return (-1); } //no new data loaded, return with LastEndTime position. LastBarCount = Bars; LastEndTime = Time[0]; return (i); } //+------------------------------------------------------------------+ //| program start function | //+------------------------------------------------------------------+ int start() { static int last_time = 0; if (!Enabled) return (0); //always update or update only after certain interval if (UpdateInterval != 0) { int cur_time; cur_time = GetTickCount(); if (MathAbs(cur_time - last_time) < UpdateInterval) { return (0); } last_time = cur_time; } //if (Debug) PerfCheck(true); int n = CheckNewData(); //if (Debug) PerfCheck(false); if (n < 0) return (0); //update history file with new data UpdateHistoryFile(n); //refresh chart window UpdateChartWindow(); //if (Debug) PerfCheck(false); return(0); } | |||
|
|||
帖子内容是网友自行贴上分享,如果您认为其中内容违规或者侵犯了您的权益,请与我们联系,我们核实后会第一时间删除。 |
所有跟帖: ( 主贴楼主有权删除不文明回复,拉黑不受欢迎的用户 )
楼主本栏目热帖推荐:
>>>>查看更多楼主社区动态... |