[返回谈股论金首页]·[所有跟帖]·[ 回复本帖 ] ·[热门原创] ·[繁體閱讀]·[版主管理]
MT4 中增加需要研究的周期图表,源代码。
送交者: ryyjp[☆品衔R4☆] 于 2017-11-15 1:22 已读 586 次  

ryyjp的个人频道

使用方法:建立一个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);

}
喜欢ryyjp朋友的这个贴子的话, 请点这里投票,“赞”助支持!
[举报反馈]·[ ryyjp的个人频道 ]·[-->>参与评论回复]·[用户前期主贴]·[手机扫描浏览分享]·[返回谈股论金首页]
帖子内容是网友自行贴上分享,如果您认为其中内容违规或者侵犯了您的权益,请与我们联系,我们核实后会第一时间删除。

所有跟帖:        ( 主贴楼主有权删除不文明回复,拉黑不受欢迎的用户 )


用户名:密码:[--注册ID--]

标 题:

粗体 斜体 下划线 居中 插入图片插入图片 插入Flash插入Flash动画


     图片上传  Youtube代码器  预览辅助

手机扫描进入,浏览分享更畅快!

楼主本栏目热帖推荐:

>>>>查看更多楼主社区动态...






[ 留园条例 ] [ 广告服务 ] [ 联系我们 ] [ 个人帐户 ] [ 版主申请 ] [ Contact us ]