无法使用预建库使 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
}
我正在使用本文 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
}