股票量化软件:烛台方向统计再现的研究
烛台方向上的重复变化表明趋势产生了变化。
首先我们要在某些条款上达成一致。 尽管这些条款是常用的,但我们还是要再过一遍,避免曲解。 如果烛台的开盘价小于收盘价 - 则被称为上升烛(在给出的图形中,它们均涂以白色),反之则为下降烛,均涂以黑色。 如果开盘价等于收盘价,这些烛台将被称为等价烛台(我自己的术语)。 如果报价下跌了一段时间,则这段时间是下跌趋势,反之则为上涨趋势。
我们看一看图片:

图 1 USDJPY 的 4 小时时间范围的烛台图,时间范围为 2009 年 11 月 20 日至 2009 年 12 月 8 日
如图 1 中所示,如果是下跌趋势,则形成此趋势的烛台大部分是下跌的,如果是上涨趋势,则烛台也是上涨的。 如果是横向的,则烛台也会不停变换其方向。赫兹量化软件
实际上,我们的问题 是确定烛台中是否有再现情况,以及它相对于趋势的变更会作出怎样的反应 。赫兹量化软件
当然,所有这些都可以手动完成,例如我们可以采用小时图或任何其他类型的图,在纸上写下烛台方向,并相互比较一段时间。 工作有很多,但都能完成。 不过我们还有 MQL4 编程语言这个神奇的工具,我们可以用它轻松创建 Expert Advisor,它将自己进行所有计算并告知我们计算结果的所有相关信息。
所以,我们要做的是:
首先我们必须能够指定一个感兴趣的时间段。 15 分钟烛台是不太可能有的,因为在过去几年,每天在 7 点 15 分时百分百是下跌趋势。 然而,因为这种情况发生的概率虽小但仍存在,所以我们必须能够至少对过去六个月的时段测试这种情况。
第二,最好是能够了解所研究期间有多少烛台是上升烛,有多少是下降烛。 你必须同意这一点:如果在过去 10 天内,在 18:00 打开的小时烛台上升了 6 次,下降了 4 次,则此信息不太可能会给我们提供重要的参考。 现在,如果 10 次中有 9 次下降,则此信息需被纳入考虑范围,用于确定今天 18:00 在哪个方向上建仓等。赫兹量化软件
第三,最好还能了解烛台开盘价和收盘价之间的平均差距,以及它们在给定时段内的平均高度。
第四,我们应能够在不同时间范围上执行我们的计算。赫兹量化软件
所有这些都可在给出的脚本的外部变量 script_Statistics_candles 中定义 。
现在看看下图。

图 2 脚本的输入参数
图 2 显示可在脚本中更改的输入参数。
Open_session - 研究时段的开始时间
Close_session - 研究时段的结束时间
Period_time - 脚本考虑烛台再现可能性时所处的时间范围。 可取以下值之一 - 5、15、30、60、240。 请记住这些值,其他值都不是允许值。 相应地,这些值对应于 5 分钟、15 分钟、30 分钟、1 小时和 4 小时的图形周期。
下面是脚本代码。 我在代码中添加了尽可能多的注释,因为我自己也在学习一本关于 MQL4 的教材,并且经常求助于此网站上的 Expert Advisor,尤其是带详细注释的 Expert Advisor。 应该承认,对于刚接触 MQL4 的新手来说,此网站上的任何文章(除了其他东西)都有教学价值。
//+------------------------------------------------------------------+ //| script_Statistics_candles_V2.mq4 | //| Copyright © 2009, Igor Aleksandrov | //| sydiya@rambler.ru | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, Igor Aleksandrov" #property link "sydiya@rambler.ru" #property show_inputs //---- Input parameters extern string Open_session ="2009.11.20"; //Date of the opening of the studied session extern string Close_session = "2009.11.26"; //Date of the closing of the studied session extern int Period_time = 60; //Period of the graph on which the Expert Advisor will be working, //can take the value of 5;15;30;60;240 //----------------------------------------------------------------- int Day_bars_i; //Number for i bar in session double Mas_vira_maina[24,60]={0,0 0,0}, //Declare an array for bars with an equal opening-closing price Mas_vira[24,60]={0,0 0,0}, //Declare an array for calculating bullish bars Mas_maina[24,60]={0,0 0,0}, //Declare an array for calculating bearish bars Mas_kol_vo[24,60]={0,0 0,0}, //Declare an array for calculating the number of the counted bars Mas_profit[24,60]={0,0 0.0}, //Declare an array of the calculation of profit by open-close Mas_H_L[24,60]={0,0 0.0}; //Declare an array of calculating the profit by high-low string Symb; //Name of the financial. instrument on which the script is executed bool New_day = false; //Flag of the new day //-------------------------------------------------------------------- //----------------------------Starting-------------------------------- int start() { //-general opening bracket Print("----------------------------------------------------------------------"); Print(" Results of the script's work- Statistics_candles- ",TimeToStr(TimeCurrent()) ); Print(" Calculations completed from ",Open_session," to ",Close_session); //------------------------Declare the variables ---------------------- int Hour_open_bars, //Number of the hour of opening the i bar in session Minute_open_bars, //Number of the minute of opening i bar in session Shift_open, //Number of bar with opening time Open_session Shift_close, //Number of bar with opening time Close_session Shift_open_close, //Number of bars in session Total_day=0; //Counter of counted days double Open_bars_price, //Price of opening i bar of the session Close_bars_price, //Price of closing the i bar of the session Low_bars_price, //Minimum price of the i bar of the session High_bars_price, //Maximum price of the i bar of the session Total_bars=0; //Number of studied bars at the start of the script datetime Time_open_session, //Opening time of the first bar of the studied session //in datatime format Time_close_session, //Opening time of the last bar of the studying //session in datatime format Time_open_bars; //Opening time of bars in datatime format bool Session_vira=false, //Flag of the bullish session Session_maina=false; //Flag of the bearish session //-----------------------End of the variables declaration ------------------ Symb=Symbol(); //Name of the financial instrument //Request the starting time of the studied session in datatime format Time_open_session= StrToTime(Open_session); //Request the closing time of the studied session in datatime format Time_close_session= StrToTime(Close_session); //Request the number of the bar, opening the session Shift_open=iBarShift( Symb,Period_time, Time_open_session,false); //Request the number of the bar, which closes the session Shift_close=iBarShift( Symb,Period_time, Time_close_session,false); //--------------------------------------------------------------------- for(int i = Shift_open; i>=Shift_close; i --) //Cycle of bar searching in the session { //Opening bracket of the search cycle of bars Total_bars++; //Counter of the number of studied bars static int New_day_shift=0; //Number of the day of starting the Expert Advisor //Request the opening of the i bar in session Time_open_bars=iTime( Symb,Period_time,Shift_open-Total_bars); //Request the opening hour of the i bar in session Hour_open_bars=TimeHour(Time_open_bars); //Request the opening minute of the i bar in session Minute_open_bars=TimeMinute(Time_open_bars); //Request the day number for the i bar in session Day_bars_i=TimeDayOfYear( Time_open_bars); //If the number for the first bar in session is not equal to the i-th bar of the day,then if(New_day_shift!=Day_bars_i) { New_day = true; //flag for the new day is true New_day_shift=Day_bars_i; //and assign the number for the number of the i bar Total_day++; //Increase the day counter by one } else //otherwise, { New_day = false; //Flag for the new day is false } //Request the opening price of the i-th bar Open_bars_price= iOpen( Symb, Period_time,i); //Request the closing price of the i-th bar Close_bars_price=iClose( Symb, Period_time,i); //Request the minimum price of the i-th bar Low_bars_price=iLow( Symb, Period_time,i); //Request the maximum price of the i-th bar High_bars_price=iHigh( Symb, Period_time,i); //If the opening price of the bar is lower than the closing price, then the session is bullish if(Open_bars_price<Close_bars_price) { //Increase by one the values of the corrsponding element Mas_vira[Hour_open_bars,Minute_open_bars]=Mas_vira[Hour_open_bars,Minute_open_bars]+1; //Increase by one the values of the corrsponding element Mas_kol_vo[Hour_open_bars,Minute_open_bars]=Mas_kol_vo[Hour_open_bars,Minute_open_bars]+1; //Save the difference between the opening and closing price in points Mas_profit[Hour_open_bars,Minute_open_bars]= Mas_profit[Hour_open_bars,Minute_open_bars]+(Close_bars_price-Open_bars_price)/Point; //Save the difference between the maximum and minimum price in points Mas_H_L[Hour_open_bars,Minute_open_bars]= Mas_H_L[Hour_open_bars,Minute_open_bars]+(High_bars_price-Low_bars_price)/Point; } //If the opening price of the bar is higher than the closing price, then the session is bearish if(Open_bars_price>Close_bars_price) { //Increase by one the values of the corrsponding element Mas_maina[Hour_open_bars,Minute_open_bars]=Mas_maina[Hour_open_bars,Minute_open_bars]+1; //Increase by one the values of the corrsponding element Mas_kol_vo[Hour_open_bars,Minute_open_bars]=Mas_kol_vo[Hour_open_bars,Minute_open_bars]+1; //Save the difference between the opening and closing price in points Mas_profit[Hour_open_bars,Minute_open_bars]= Mas_profit[Hour_open_bars,Minute_open_bars]+(Open_bars_price-Close_bars_price)/Point; //Save the difference between the maximum and minimum price in points Mas_H_L[Hour_open_bars,Minute_open_bars]= Mas_H_L[Hour_open_bars,Minute_open_bars]+(High_bars_price-Low_bars_price)/Point; } //If the opening price is equal to the closing price, then session is undefined if(Open_bars_price==Close_bars_price) { ///Increase by one the corresponding array elements Mas_vira_maina[Hour_open_bars,Minute_open_bars]=Mas_vira_maina[Hour_open_bars,Minute_open_bars]+1; //Increase by one the corresponding array elements Mas_kol_vo[Hour_open_bars,Minute_open_bars]=Mas_kol_vo[Hour_open_bars,Minute_open_bars]+1; //Leave the value of the array as is Mas_profit[Hour_open_bars,Minute_open_bars]= Mas_profit[Hour_open_bars,Minute_open_bars]+0; //Save the difference between maximum and minimum bar prices in points Mas_H_L[Hour_open_bars,Minute_open_bars]= Mas_H_L[Hour_open_bars,Minute_open_bars]+(High_bars_price-Low_bars_price)/Point; } } //Closing bracket of the bar search cycle //--------------------------Print the information to the Expert Advisor Journal------------------- Print("Processed - ",Total_day," days; ",Total_bars," bars, period ",Period_time," minutes"); for (int h=0; h<=23; h++) //Hours cycle { for (int m=0; m<=60; m++) //Minutes cycle { if (Mas_kol_vo[h,m]!=0) //If the value of array is not equal to zero, then we continue counting { Print("For the period there are ",Mas_kol_vo[h,m], " bars with the time of the opening ",h,":",m, " .Bullish- ",Mas_vira[h,m], ".Bearish- ",Mas_maina[h,m], ".Equal - ",Mas_vira_maina[h,m]); Print("For the bars with the opening time ",h,":",m, " ,average distance between the Open-Close prices - ",Mas_profit[h,m]/Mas_kol_vo[h,m], " points. Between the High-Low prices - ",Mas_H_L[h,m]/Mas_kol_vo[h,m]," points."); } Mas_vira_maina[h,m]=0; //set to zero Mas_vira[h,m]=0; //set to zero Mas_maina[h,m]=0; //set to zero Mas_kol_vo[h,m]=0; //set to zero Mas_profit[h,m]=0; //set to zero Mas_H_L[h,m]=0; //set to zero } //End of the minute cycle } //End of the hour cycle Print("-------------- Script completed the work --------------------"); return(0); } //-general closing bracket
如你所见,我宣布了六个正在计算的全局级数组。
double Mas_vira_maina[24,60]={0,0 0,0}, //Declare the bar array with an equal price of opening-closing Mas_vira[24,60]={0,0 0,0}, //Declare the array for calculating the bullish bars Mas_maina[24,60]={0,0 0,0}, //Declare the array for calculating the bearish bars Mas_kol_vo[24,60]={0,0 0,0}, //Declare the array for calculating the number of counted bars Mas_profit[24,60]={0,0 0.0}, //Declare the array for calculating the profit for open-close Mas_H_L[24,60]={0,0 0.0}; //Declare the array for calculating the profit for high-low
我们将把条柱计数记录到 Mas_kol_vo 缓冲区中。 这么做的理由。 看起来,建仓-平仓和最高价-最低价的单元格数组的值能被计数天数除,尤其是代码中有计数器时 - Total_day 。 但我在处理脚本的过程中碰到了一个问题,即历史记录中缺少某些条柱,因此结果看上去非常有趣。 例如,所获得的某些条柱的高度完全是不现实的。赫兹量化软件
注释中可以很明显地看出剩余数组的用途。赫兹量化软件
实际上现在要检查不同趋势方向时的条柱的可重复性。 为此,让我们以 USDJPY 的小时图为例,如图 1 中所示。 我们可以看到,在 2009 年 11 月 20 日至 2009 年 11 月 26 日这段时间内,图中呈下跌趋势;从 2009 年 11 月 26 日至 2009 年 12 月 2 日,呈横盘趋势;从 2009 年 12 月 2 日至 2009 年 12 月 8 日,图中表现出上涨趋势。赫兹量化软件
让我们检查这段时间内是否有重复烛台,如果有,则算出其变更方向。赫兹量化软件
将脚本设置为小时图。 对于不明白怎么做的读者,我会提供更详细的说明。 将脚本 script_Statistics_candles_V2.mq4 下载到文件夹 \Program Files\TerminalName\expert\scripts 中。 复制。 脚本显示在“浏览器”窗口的左下角。 看起来就像这样:

赫兹量化软件
如果你用鼠标将脚本从此窗口拖动到终端窗口,你将看到一个属性窗口 - 图 2. 指定计算的开始和结束日期。赫兹量化软件