0

我正在使用本文https://www.mql5.com/en/articles/159中的代码来计算新柱何时打开,但它不显示指标的历史数据。

我已修改TimeCurrent()toiTime( _Symbol, _Period, shift )以尝试处理此问题,但它不起作用。

你能告诉我我做错了什么吗?

#property indicator_separate_window #property indicator_buffers 1 #property indicator_color1 RoyalBlue #include <Lib_CisNewBar.mqh> CisNewBar current_chart; //---- input parameters extern int Length=18; // Bollinger Bands Period extern int Deviation=2; // Deviation was 2 extern double MoneyRisk=1.00; // Offset Factor extern int Signal=1; // Display signals mode: 1-Signals & Stops; 0-only Stops; 2-only Signals; extern int Line=1; // Display line mode: 0-no,1-yes extern int Nbars=1000; //---- indicator buffers double TrendBuffer[]; extern bool SoundON=true; bool TurnedUp = false; bool TurnedDown = false; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { string short_name; //---- indicator line SetIndexBuffer(0,TrendBuffer); SetIndexStyle(0,DRAW_LINE,0,1); IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)); short_name="Example ("+Length+","+Deviation+")"; IndicatorShortName(short_name); SetIndexLabel(0,"Trend Value"); //---- SetIndexDrawBegin(0,Length); //---- return(INIT_SUCCEEDED); } void deinit() { } 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 &tick_volume[], const long &volume[], const int &spread[]) { int shift; for (shift=Nbars;shift>=0;shift--) { TrendBuffer[shift]=0; } for (shift=Nbars-Length-1;shift>=0;shift--) { int period_seconds=PeriodSeconds(_Period); datetime new_time=iTime(_Symbol,_Period,shift)/period_seconds*period_seconds; if(current_chart.isNewBar(new_time)) { Print("time[shift] = "+TimeToString(time[shift])); if( Close[shift] > Close[shift+1] ) TrendBuffer[shift]=1; else if(Close[shift] < Close[shift+1] ) TrendBuffer[shift]=-1; else TrendBuffer[shift]=0; } } return(0); }

谢谢。

4

1 回答 1

1

a) " new "-MQL4.56789有另一种语法

对于自定义指标,“MQL4.56789源应改为阅读和
void OnInit(){ ... }

void OnDeinit( const int anMT4_Reason2callDeinit ){ ... }


b) 的datetime

您的代码定义了一个变量new_time,类型为datetime

datetime 类型用于将日期和时间存储为自 1970 年 1 月 1 日以来经过的秒数。

值范围从 1970 年 1 月 1 日到 3000 年 12 月 31 日

因此,在您new_time分配的情况下,正确的iTime()值除以数量,PeriodSeconds()然后再乘以完全相同的值,这不应该改变iTime()结果的值。

这种操作虽然对结果没有理论上的影响,但在代码执行的实践中可能会引入数值不准确、范围上溢/下溢的风险,并且关于解决 8 字节类存储的理论通知无济于事超过上限,在文档中声明为 3000 年 12 月 31 日。

在类似的情况下,无法预测的结果甚至 MT4 未处理的异常和 MQL4 代码终止都是可以预料的。

对于生产级软件,人们可能会期待什么更糟糕的情况?因此,避免、避免和避免任何此类风险。

这种自定义指标计算步骤没有直接的正值。


c)TimeCurrent() / PeriodSeconds()舍入的副作用

虽然iTime()总是可以被它的“自己的”时间框架整除,PeriodSeconds()TimeCurrent()不是

因此,人们可以阅读原始的(假设的)构造

TimeCurrent() / PeriodSeconds()   // .DIV is subject to rounding to int
              * PeriodSeconds();  //      before the forthcoming .MUL

“破解”需要将 [最后已知的服务器时间,在“市场观察”窗口中选择的符号之一的最后报价接收时间] 与当前开始的“自己的”时间范围值对齐酒吧时间。


d) 这篇文章来自 2010 年 10 月 11 日(!) - 请非常小心MQL4

当前MQL4的代码执行引擎是 Build 890(2015 年 9 月 25 日),因此您引用的源代码使用了MQL5大约 5 年的语言语法(!!),即在MQL4-domain 中表示 _be_very_carefull_

同时string-s不再是string-s,
许多 GUI 函数有多个并行调用协议,
并且
由于类似的移动沙子,无数人*年的 DLL/API-code-base dev/maint 丢失了。

所以 -5 年的差距本身就是一个警告。


一个人永远不会两次进入同一条河流


”的最近状态 -MQL4.56789允许一个干净的方法:

如果您的动机只是为了能够按需检测新栏开始的情况,Build-890/1174 编译器允许使用更简洁的方法:

bool aNewBarEVENT(   const string anFxSYMBOL,               // _Symbol,
                     const int    aTimeFRAME                // PERIOD_M6
                     )
{    static int   pBars  = EMPTY;                           // previous
            int   oBars  = iBars( anFxSYMBOL, aTimeFRAME ); // observed

     if (         pBars == oBars ) return( False );         // .NACK
                  pBars  = oBars,  return( True  );         // .UPD + .ACK
}
于 2015-10-06T05:34:57.587 回答