我正在尝试制作一个指示器,显示图表上出现相同颜色的x个蜡烛。但我得到一个超出范围错误的数组。
minCandles
是extern integer
,用于确定指向箭头的条数。我认为问题可能出在down[i] = Low[i]
,但我不知道原因。
以下是代码:
//+------------------------------------------------------------------+
//| SlayEm.mq4 |
//| Copyright 2016, Sebastian Bonilla. |
//| https://www.sebastianbonilla.me |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Sebastian Bonilla."
#property link "https://www.sebastianbonilla.me"
#property description "show X amount of candles of the same color."
#property version "1.00"
#property strict
#property indicator_chart_window
//--- input parameters
extern int minCandles = 4;
double up[];
double down[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,up); //assign up to the first buffer
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,233);
SetIndexLabel(0, "Up Arrow");
//stuff for 1
SetIndexBuffer(1,down); //assign down to the second buffer
SetIndexStyle(1,DRAW_ARROW);
SetIndexArrow(1,234);
SetIndexLabel(1, "Down Arrow");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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 limit = MathMax(rates_total-prev_calculated,2);
int i;
int bull_count = 0;
int bear_count = 0;
for (i = 1; i < limit; i++){
//--bears-----------------------------------------------------------------------------------
if(Open[i] >= Open[i-1]){
bear_count++;
if (bear_count > minCandles) up[i] = High[i];
}
else bear_count = 0; // this by itself works but from right to left
// --- bulls ----------------------------------------
if(Open[i] < Open[i-1]){
bull_count++;
if (bull_count > minCandles) down[i] = Low[i];
}
else bull_count = 0; //this part creates the array out of range error*/
}
Comment((string)bear_count+ " --- ", (string)bull_count +" --- ", (string)i);
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
答案 0 :(得分:1)
编写快速有效的[自定义指标] MQL4
- 代码背后有一些奇怪的事情。
首先,来自设计决策的实时头痛是将所有现有[自定义指标]的所有计算工作累积到单个线程中。
虽然这是隐藏的,但它增加了压力以最小化所有执行延迟,其代价是以分段小批量操作的colculus,从最深的历史(最远的左边的条)向前迭代向前进行到右边,朝着现在的酒吧。
人们可能会对酒吧的反向编号概念感到困惑,从 [0]
开始 - 对于最近的Bar(实时酒吧),计数,然后更深入并且更深入地了解最左边的历史。
如果还不够,[自定义指标]中还有一些额外的禁止内容,但由于您的网页显示您在商业基础上提供[自定义指标]编程,因此在这里重复它们是毫无价值的试。
Comment()
- s以避免损坏GUI / MMI #property strict
//--- input parameters
extern int minCandles = 4;
//--- input PROTECTIVE FUSES:
int minCandlesFUSED = MathMax( 2, minCandles ); // assign no less than 2 irrespective of the extern
double up[];
double down[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit() {
// indicator buffers mapping
SetIndexBuffer( 0, up ); // assign up[] to the first buffer
SetIndexStyle( 0, DRAW_ARROW );
SetIndexArrow( 0, 233 );
SetIndexLabel( 0, "Up Arrow" );
// stuff for 1
SetIndexBuffer( 1, down ); // assign down[] to the second buffer
SetIndexStyle( 1, DRAW_ARROW );
SetIndexArrow( 1, 234 );
SetIndexLabel( 1, "Down Arrow" );
// RET
return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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 limit = rates_total
- prev_calculated
+ minCandlesFUSED;
if ( Bars + limit < minCandlesFUSED + 1 ) return( 0 ); // --> JIT/RET( 0 )
// ^--------------------^--- MEANING-FULL value, ref prev_calculated mechanisation
// makes no sense to start indicator w/o at least minCandlesFUSED + 1 Bars ready
int bull_count = 0;
int bear_count = 0;
for ( int i = limit + 1; // iterator .SET to start [limit + 1] Bars back in time (towards left), moving forwards -> [0]
i > 0; // iterator .PRE-CONDITION to keep looping while i > [0] points to already exist. Bars->[1], leaving [0] out
i-- // iterator .DEC on loop-end, before re-testing next loop .PRE-CONDITION
){
// --------------------------------------------------------------BEARS
if ( Open[i] >= Open[i-1] ){
bear_count++;
if ( bear_count > minCandlesFUSED ) up[i] = High[i]; // ref. above the
}
else bear_count = 0; // this by itself works
// --------------------------------------------------------------BULLS
if ( Open[i] < Open[i-1] ){
bull_count++;
if ( bull_count > minCandlesFUSED ) down[i] = Low[i];
}
else bull_count = 0; // this part creates the array out of range error*/
}
Comment( (string)bear_count // rather use StringFormat( "TEMPLATE: %d UP --- %d DN --- ", bear_count,
+ " --- ", // bull_count
(string)bull_count // )
+ " --- "
);
return( rates_total ); // return( rates_total ) value becomes -> prev_calculated for the next call
}
//+------------------------------------------------------------------+