簡體   English   中英

當我只需要指標在收盤價時,如何停止指標在每個刻度上的計算?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM