[英]How to stop Indicator from calculating on every tick, when I only need the indicator at bar close?
这是我从互联网上下载的指标,但是我做了一些修改。 我注意到该指标计算线性回归线以及每个刻度线的上下频带。
我发现这很浪费资源,因为我只需要在每个小节的末尾计算行; 即,当小节0结束并形成新的小节0时。
条0仍不完整时,它不应计算任何内容。
我如何进行必要的更改?
谢谢!!
//+------------------------------------------------------------------+
//| Linear Regression Line.mq4 |
//| MQL Service |
//| scripts@mqlservice.com |
//+------------------------------------------------------------------+
#property copyright "MQL Service"
#property link "www.mqlservice.com"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 White
#property indicator_width1 2
#property indicator_color2 Orange
#property indicator_width2 2
#property indicator_color3 Orange
#property indicator_width3 2
//---- input parameters
extern int LRLPeriod = 20;
extern int Number_SD = 2;
//---- buffers
double LRLBuffer[], LRLBuffer_Upper[], LRLBuffer_Lower[];
//int shift = 0;
int n = 0;
double sumx = 0;
double sumy = 0;
double sumxy = 0;
double sumx2 = 0;
double sumy2 = 0;
double yint = 0;
double r = 0;
double m = 0;
//+------------------------------------------------------------------+
//| INITIALIZATION FUNCTION |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0, DRAW_LINE);
SetIndexBuffer(0, LRLBuffer);
SetIndexStyle(1, DRAW_LINE);
SetIndexBuffer(1, LRLBuffer_Upper);
SetIndexStyle(2, DRAW_LINE);
SetIndexBuffer(2, LRLBuffer_Lower);
IndicatorDigits(Digits);
if (LRLPeriod < 2)
LRLPeriod = 2;
IndicatorShortName("Linear Regression Line ("+LRLPeriod+")");
SetIndexDrawBegin(0, LRLPeriod+2);
IndicatorDigits(MarketInfo(Symbol(), MODE_DIGITS)+4);
return(0);
}
//+------------------------------------------------------------------+
//| DEINITIALIZATION FUNCTION |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| ITERATION FUNCTION |
//+------------------------------------------------------------------+
int start()
{
int limit, j, Counted_bars;
int counted_bars = IndicatorCounted();
if (counted_bars < 0)
counted_bars = 0;
if (counted_bars > 0)
counted_bars--;
limit = Bars - counted_bars;
for (int shift=limit-1; shift >= 0; shift--)
{
sumx = 0;
sumy = 0;
sumxy = 0;
sumx2 = 0;
sumy2 = 0;
for (n = 0; n <= LRLPeriod-1; n++)
{
sumx = sumx + n;
sumy = sumy + Close[shift + n];
sumxy = sumxy + n * Close[shift + n];
sumx2 = sumx2 + n * n;
sumy2 = sumy2 + Close[shift + n] * Close[shift + n];
}
double temp = LRLPeriod * sumx2 - sumx * sumx;
if (temp == 0)
temp = .0000001;
// m = (LRLPeriod * sumxy - sumx * sumy) / (LRLPeriod * sumx2 - sumx * sumx);
m = (LRLPeriod * sumxy - sumx * sumy) / temp;
temp = LRLPeriod;
if (temp == 0)
temp = .0000001;
yint = (sumy + m * sumx) / temp; // was LRLPeriod (obviously)
temp = MathSqrt((LRLPeriod * sumx2 - sumx * sumx) * (LRLPeriod * sumy2 - sumy * sumy));
if (temp == 0)
temp = .0000001;
r = (LRLPeriod * sumxy - sumx * sumy) / temp;
LRLBuffer[shift] = yint - m * LRLPeriod;
//Print (" "+shift+" "+LRLBuffer[shift]);
}
//----------Added Upper and Lower Bands--------------//
int nBARs = 0;
double LRLBuffer_CPY[];
ArraySetAsSeries(LRLBuffer_CPY,True);
j = Bars - Counted_bars - 1;
while( j > 0 )
{
ArrayCopy( LRLBuffer_CPY, LRLBuffer, 0, j, WHOLE_ARRAY );
double StDev = iStdDevOnArray( LRLBuffer_CPY, nBARs, LRLPeriod, 0, MODE_SMA, 0 );
LRLBuffer_Upper[j] = LRLBuffer[j] + (Number_SD * StDev);
LRLBuffer_Lower[j] = LRLBuffer[j] - (Number_SD * StDev);
j--;
}
return(0);
}
//+------------------------------------------------------------------+
最简单的方法是使用标准的OnCalculate(***)
函数并仅if(rates_total>prev_calculated)
运行主循环。
另外,在主循环中,尝试使for(int shift=limit-1;shift>0;shift--){
(注意),顺便说一句,您确定需要shift=limit-1
而不只是shift=limit
?
MQL4
语法OnCalculate()
将不利于实现这一目标, 可以使用OnCalculate()
语法,但是代码块实际上在您的控制之外,在启动时以及允许其处理多少个逐步步骤的情况下,都OnCalculate()
您控制。
解决方案是使用“旧”语法并添加“软”锁定。
如果使用移位寄存器只是从刚冻结的[1]小节进行更新,则使用static
变量有助于将临时值存储在调用之间,并且刚好进行热端重新计算,因此无需从整个深度重新进行迭代。 Bar [0]持续时间的其余部分都执行.NOP / JIT / RET,并且您的代码不会破坏由所有自定义指标共享(是!共享!)的单线程性能的脆弱性(真正的恶魔般的反-New New-MQL4更新中的模式...):
int start(){
static aCurrentTIME = EMPTY;
if ( aCurrentTIME == Time[0] ) return 0; // .NOP/JIT/RET --^
aCurrentTIME = Time[0]; // .MOV/LOCK
// -------------------------------------------- // .CALC:
int limit = Bars - counted_bars;
...
/* update just the "HOT"-end has just got into OHLCVT[1]-cells */
// -------------------------------------------- // .FIN
}
根据情况,您还可以:
datetime calculatedBarTime;
void OnCalculate()
{
if ( calculatedBarTime != Time[0] )
{
onBar();
}
}
void onBar()
{
calculatedBarTime = Time[0];
// on bar logic....
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.