无法使用预建库使 MT4 指标正常工作

Cannot get MT4 indicator to work using prebuilt library

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

我已将 TimeCurrent() 修改为 iTime( _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); }

谢谢。


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

对于自定义指标,“new”-MQL4.56789 来源应改为
void OnInit(){ ... }

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


b) datetime

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

The datetime type is intended for storing the date and time as the number of seconds elapsed since January 01, 1970.

Values range from 1 January, 1970 to 31 December, 3000

因此,对于您的 new_time 赋值,正确的 iTime() 值除以 PeriodSeconds() 的数量,紧接着它被重新乘以完全相同的值,这不应该改变 iTime() 结果的值。

这样的操作虽然对结果没有理论上的影响,但在代码执行的实践中可能会引入数值不准确的风险,范围 overflow/underflow 以及关于 8 字节分辨率的理论通知class 存储没有帮助超过上限,在文档中说明为 3000 年 12 月 31 日。

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

生产级软件还有什么更糟糕的地方?因此,避免,避免并避免任何此类风险。

此类自定义指标计算步骤没有直接正值。


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

虽然 iTime() 总是可以被它的 "own" 时间范围整除 PeriodSeconds(),但 TimeCurrent() 不是 .

因此可以阅读

的原始(假定)结构
TimeCurrent() / PeriodSeconds()   // .DIV is subject to rounding to int
              * PeriodSeconds();  //      before the forthcoming .MUL

"hacks" 需要对齐 [ 最后已知服务器时间 ,最后报价收据时间 之一在 "Market Watch" window] 中选择的交易品种到一个当前柱时间开始的 "own" 时间帧值。


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-basedev/maint因类似的流沙而失踪。

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


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


new”-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
}