MQL4 assign a value into array failed - mql4

This is my code trying to generate the ADC Cloud indicator.
At first, it can work if I just generate the cloud.
Currently, I am trying to make the histogram green when it is above zero, otherwise red. Then, I separate the Could array into two buffers, GreenBuffer and RedBuffer. At this step, I stuck in an unknown error.
I can make sure the problem is coming from the ERROR PART, marked by Sharp Sign in Code.
Thank you first!
#property strict
#property indicator_separate_window
#property indicator_buffers 2
//--- input parameters
input int ADX_period=14;
double Cloud[];
double GreenBuffer[];
double RedBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
//SetIndexBuffer(0, GreenBuffer);
SetIndexBuffer(0, Cloud);
SetIndexLabel(0, "Cloud");
SetIndexStyle(0, DRAW_HISTOGRAM, 0, 2, clrGreen);
//SetIndexBuffer(1, Cloud);
//SetIndexStyle(1, DRAW_HISTOGRAM, 0, 2, clrRed);
//---
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_calc = 0;
int BarCnt = IndicatorCounted();
Limit_calc = Bars - BarCnt;
for (int i = Limit_calc-1; i >= 0 ; i--)
{
double output = iADX(NULL, 0, ADX_period, PRICE_CLOSE, MODE_PLUSDI, i)
- iADX(NULL, 0, ADX_period, PRICE_CLOSE, MODE_MINUSDI, i);
Cloud[i] = output;
// #########################################
// ###### Error Part #######################
//if (output > 0)
// {
// GreenBuffer[i] = output;
// RedBuffer[i] = 0.00;
// }
//else
// {
// GreenBuffer[i] = 0.00;
// RedBuffer[i] = output;
// }
// ##########################################
}
//Comment(Cloud[1]);
//--- return value of prev_calculated for next call
return(rates_total);
}

int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0, GreenBuffer);
SetIndexLabel(0, "Green");
SetIndexStyle(0, DRAW_HISTOGRAM, 0, 2, clrGreen);
SetIndexBuffer(0, RedBuffer);
SetIndexLabel(0, "Red");
SetIndexStyle(0, DRAW_HISTOGRAM, 0, 2, clrRed);
//---
return(INIT_SUCCEEDED);
}
int OnCalculate( *** )
{
...
for (int i = Limit_calc-1; i >= 0 ; i--)
{
double output = iADX(NULL, 0, ADX_period, PRICE_CLOSE, MODE_PLUSDI, i)
- iADX(NULL, 0, ADX_period, PRICE_CLOSE, MODE_MINUSDI, i);
if (output > 0)
{
GreenBuffer[i] = output;
RedBuffer[i] = 0.00;
}
else
{
GreenBuffer[i] = 0.00;
RedBuffer[i] = output;
}
}
...
}

REPAIRED & [PASS]-on-TESTED CODE :
#property strict
#property indicator_separate_window
#property indicator_buffers 2
//--- input parameters
input int ADX_period = 14;
double GreenBuffer[],
RedBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer( 0, GreenBuffer );
SetIndexLabel( 0, "Green" );
SetIndexStyle( 0, DRAW_HISTOGRAM, 0, 2, clrGreen );
SetIndexBuffer( 1, RedBuffer );
SetIndexLabel( 1, "Red" );
SetIndexStyle( 1, DRAW_HISTOGRAM, 0, 2, clrRed );
//---
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 BarCnt = IndicatorCounted();
int Limit_calc = Bars - BarCnt;
for ( int i = Limit_calc - 1; i >= 0 ; i-- )
{
double output = iADX( NULL, 0, ADX_period, PRICE_CLOSE, MODE_PLUSDI, i )
- iADX( NULL, 0, ADX_period, PRICE_CLOSE, MODE_MINUSDI, i );
if ( output > 0 ) { GreenBuffer[i] = output; RedBuffer[i] = 0.00; }
else { GreenBuffer[i] = 0.00; RedBuffer[i] = output; }
}
//---
return( rates_total );
}

Related

Hello could somebody help me modify an interesting indicator?

I got this indicator for mt4, I would like somebody to help me modify it so I can input an integer to select how many bars should be plotted. normally it will plot infinite bars, I'd like to be able to select the number of MTF bars the indicator should plot. This to eliminate the lag when changin timeframes, I imagine the lag is because of the big amount of MTF candles plotted.
Other change that I would really apreciate, if you see when open and close price is exactly the same it will not create a doji, it will only show wicks, not the classic horizontal line for a doji.
I paid a coder to make this, now he's chargin plus to make this changes, I tried to make them myself copying an indicator that has that function but my coding skills are hugely limited.
Thanks.
//+------------------------------------------------------------------+
//| MTF_Candles.mq4 |
//+------------------------------------------------------------------+
#property copyright "Ab Moncada"
#property version "1.0"
#property strict
#property indicator_chart_window
enum enumTimeFrames{
m1 = PERIOD_M1, //M1
m5 = PERIOD_M5, //M5
m15 = PERIOD_M15, //M15
m30 = PERIOD_M30, //M30
h1 = PERIOD_H1, //H1
h4 = PERIOD_H4, //H4
d1 = PERIOD_D1, //D1
w1 = PERIOD_W1, //W1
mn1 = PERIOD_MN1 //MN1
};
//input ENUM_TIMEFRAMES MTF_Period = PERIOD_H1; //Timeframe
input enumTimeFrames MTF_Period = h1; //Timeframe
input color UpColor = clrGainsboro; //ColorBulls
input color DownColor = clrGainsboro; //ColorBears
input bool LineType = false; //Background
input ENUM_LINE_STYLE LineStyle = STYLE_DOT; //LineStyle
input int LineWidth = 3; //LineWidth
string indiName = "MTF_CandleStick";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit(){
//--- indicator buffers mapping
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason){
objDelete(indiName+IntegerToString(MTF_Period));
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
if(MTF_Period <= _Period) return(0);
int limit = rates_total - prev_calculated;
if(limit > 0){
objDelete(indiName+IntegerToString(MTF_Period));
limit = rates_total-1;
}
else{
if(MTF_Period < 1440) limit = MTF_Period/_Period;
else limit = 1;
}
for(int i=0; i<limit; i++){
double mtfOpen, mtfClose, mtfHigh, mtfLow;
int first, last=0;
if(MTF_Period < 1440){
if(MathMod(time[i], MTF_Period*60) != 0) continue;
first = i;
for(int t=i-1; t>=0; t--){
if(time[i]+MTF_Period*60 <= time[t]){
last = t+1;
break;
}
}
mtfOpen = open[first];
mtfClose = close[last];
mtfHigh = high[iHighest(NULL, 0, MODE_HIGH, first-last+1, last)];
mtfLow = low[iLowest(NULL, 0, MODE_LOW, first-last+1, last)];
}
else{
if(time[Bars-1] > iTime(NULL, MTF_Period, i)) break;
mtfOpen = iOpen(NULL, MTF_Period, i);
mtfClose = iClose(NULL, MTF_Period, i);
mtfHigh = iHigh(NULL, MTF_Period, i);
mtfLow = iLow(NULL, MTF_Period, i);
first = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i), false);
if(TimeHour(time[first]) != 0) first--;
if(i > 0){
last = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i-1), false);
if(TimeHour(time[last]) == 0) last++;
}
/*
if(MTF_Period == 1440){
first = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i), false);
if(i > 0) last = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i-1), false)+1;
}
else{
first = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i), false)-1;
if(i > 0) last = iBarShift(NULL, 0, iTime(NULL, MTF_Period, i-1), false);
}
*/
}
if(mtfOpen <= mtfClose){
Rectangle(indiName+IntegerToString(MTF_Period)+"_body"+IntegerToString(i), first, mtfOpen, last, mtfClose, UpColor, LineStyle, LineWidth);
TrendLine(indiName+IntegerToString(MTF_Period)+"_shadow"+IntegerToString(i), (first+last)/2, mtfClose, mtfHigh, UpColor, LineWidth);
TrendLine(indiName+IntegerToString(MTF_Period)+"_tail"+IntegerToString(i), (first+last)/2, mtfOpen, mtfLow, UpColor, LineWidth);
}
else{
Rectangle(indiName+IntegerToString(MTF_Period)+"_body"+IntegerToString(i), first, mtfOpen, last, mtfClose, DownColor, LineStyle, LineWidth);
TrendLine(indiName+IntegerToString(MTF_Period)+"_shadow"+IntegerToString(i), (first+last)/2, mtfOpen, mtfHigh, DownColor, LineWidth);
TrendLine(indiName+IntegerToString(MTF_Period)+"_tail"+IntegerToString(i), (first+last)/2, mtfClose, mtfLow, DownColor, LineWidth);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
void Rectangle(string name, int index1, double price1, int index2, double price2, color Rcolor, int Rstyle, int Rwidth){
long id = ChartID();
if (ObjectFind(name) != 0) {
ObjectCreate(id, name, OBJ_RECTANGLE, 0, Time[index1], price1, Time[index2], price2);
ObjectSetInteger(id, name, OBJPROP_COLOR, Rcolor);
if(LineType) ObjectSetInteger(id, name, OBJPROP_STYLE, Rstyle);
ObjectSetInteger(id, name, OBJPROP_WIDTH, Rwidth);
ObjectSetInteger(id, name, OBJPROP_BACK, !LineType);
//ObjectSetInteger(id, name, OBJPROP_RAY_RIGHT, false);
ObjectSetInteger(id, name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(id, name, OBJPROP_HIDDEN, true);
}
else{
ObjectMove(name, 0, Time[index1], price1);
ObjectMove(name, 1, Time[index2], price2);
}
ChartRedraw(id);
}
void TrendLine(string name, int position, double price1, double price2, color Tcolor, int Twidth){
long id = ChartID();
if (ObjectFind(name) != 0) {
ObjectCreate(id, name, OBJ_TREND, 0, Time[position], price1, Time[position], price2);
ObjectSetInteger(id, name, OBJPROP_COLOR, Tcolor);
ObjectSetInteger(id, name, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(id, name, OBJPROP_WIDTH, Twidth);
ObjectSetInteger(id, name, OBJPROP_BACK, true);
ObjectSetInteger(id, name, OBJPROP_RAY_RIGHT, false);
ObjectSetInteger(id, name, OBJPROP_SELECTABLE, false);
ObjectSetInteger(id, name, OBJPROP_HIDDEN, true);
}
else{
ObjectMove(name, 0, Time[position], price1);
ObjectMove(name, 1, Time[position], price2);
}
ChartRedraw(id);
}
void objDelete(string basicName){
for(int i=ObjectsTotal();i>=0;i--){
string ObjName = ObjectName(i);
if(StringFind(ObjName, basicName) >=0) ObjectDelete(ObjName);
}
}

i have some question about mql4 in ordersend and orderclose in my code

i have a small expert with mql4 for forex robot
but i have get some problem in getting code when running this code to backtest in metatrader 4
my code details is :
i have 2 ema and when cross up get buy and when cross down get sell
but its problem to get position after crosing 2 ema in backtest.
My stoplose is fix to 10 pip but tp is 0 and we have open trade until next cross from 2 ema and then close pervios position and get new position.
i add test sterategy and show my problem in getting position
#property copyright "Copyright 2018"
#property link "https://www.mql4.com"
#property version "1.00"
#property strict
input int Ema_Fast_Period = 62;
input int Ema_Slow_Period = 30;
input int MagicNumber = 1982;
input double Lots = 0.01;
input double StopLoss = 100;
input double TakeProfit = 0;
double FastMACurrent ,SlowMACurrent ,FastMAPrevious ,SlowMAPrevious;
bool BuyCondition = False, SellCondition = False, CrossPriseWithFastMAUpShado = False, CrossPriseWithFastMADownShado = False;
//---
int Slippage=5;
double OpenPosition = 0;
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| expert OnTick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(Volume[0]<=1)
{
FastMACurrent = iMA(Symbol() ,PERIOD_CURRENT ,Ema_Fast_Period ,0 ,MODE_EMA ,PRICE_CLOSE ,1 );
SlowMACurrent = iMA(Symbol() ,PERIOD_CURRENT ,Ema_Slow_Period ,0 ,MODE_EMA ,PRICE_CLOSE ,1 );
FastMAPrevious = iMA(Symbol() ,PERIOD_CURRENT ,Ema_Fast_Period ,0 ,MODE_EMA ,PRICE_CLOSE ,2 );
SlowMAPrevious = iMA(Symbol() ,PERIOD_CURRENT ,Ema_Slow_Period ,0 ,MODE_EMA ,PRICE_CLOSE ,2 );
//----------------------- BUY CONDITION
BuyCondition = (FastMAPrevious<SlowMAPrevious && FastMACurrent>SlowMACurrent);
//----------------------- SELL CONDITION
SellCondition = (FastMAPrevious>SlowMAPrevious && FastMACurrent<SlowMACurrent);
CrossPriseWithFastMADownShado = ( Low[1]<FastMACurrent && FastMACurrent<Open[1] );
if( BuyCondition )
{
//If we have open trade before get another trade close perivios trade and save money
if( OrderSelect(0, SELECT_BY_POS,MODE_TRADES) )
{
int a = OrderClose( OrderTicket(),OrderLots(),OrderClosePrice(), Slippage, clrWhite );
}
BuyCondition = False;
GetBuy();
}
if( SellCondition )
{
//If we have open trade before get another trade close perivios trade and save money
if( OrderSelect(0, SELECT_BY_POS,MODE_TRADES) )
{
int a = OrderClose( OrderTicket(),OrderLots(),OrderClosePrice(), Slippage, clrWhite );
}
SellCondition = False;
GetSell();
}
}
}
//+------------------------------------------------------------------+
//| expert Buy Or Sell function |
//+------------------------------------------------------------------+
int GetBuy(){
int getposition = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,Ask-(StopLoss*Point),0,"Buy",MagicNumber,0,Blue);
return True;
}
int GetSell(){
int getposition = OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,Bid+(StopLoss*Point),0,"Sell",MagicNumber,0,Red);
return True;
}
enter image description here
I edited your code. The main problem in your code is takeprofit!
In GetBuy() and GetSell() Functions you wrote:
Ask+(TakeProfit*Point)
It returns Ask! because your TakeProfit has been set to zero. If you don't want to set Takeprofit You should write:
int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,Ask-(StopLoss*Point),0,"Buy",MagicNumber,0,Blue);
This is the new code:
#property copyright "Copyright 2018"
#property link "https://www.mql4.com"
#property version "1.00"
#property strict
input int Ema_Fast_Period = 62;
input int Ema_Slow_Period = 30;
input int MagicNumber = 1982;
input double Lots = 0.01;
input int StopLoss = 100;
input int TakeProfit = 1000;
double FastMACurrent ,SlowMACurrent ,FastMAPrevious ,SlowMAPrevious;
bool BuyCondition = False, SellCondition = False, CrossPriseWithFastMAUpShado = False, CrossPriseWithFastMADownShado = False;
//---
int Slippage=5;
double OpenPosition = 0;
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| expert OnTick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(Volume[0]<=1)
{
FastMACurrent = iMA(Symbol() ,PERIOD_CURRENT ,Ema_Fast_Period ,0 ,MODE_EMA ,PRICE_CLOSE ,1 );
SlowMACurrent = iMA(Symbol() ,PERIOD_CURRENT ,Ema_Slow_Period ,0 ,MODE_EMA ,PRICE_CLOSE ,1 );
FastMAPrevious = iMA(Symbol() ,PERIOD_CURRENT ,Ema_Fast_Period ,0 ,MODE_EMA ,PRICE_CLOSE ,2 );
SlowMAPrevious = iMA(Symbol() ,PERIOD_CURRENT ,Ema_Slow_Period ,0 ,MODE_EMA ,PRICE_CLOSE ,2 );
//----------------------- BUY CONDITION
BuyCondition = (FastMAPrevious<SlowMAPrevious && FastMACurrent>SlowMACurrent);
//----------------------- SELL CONDITION
SellCondition = (FastMAPrevious>SlowMAPrevious && FastMACurrent<SlowMACurrent);
CrossPriseWithFastMADownShado = ( Low[1]<FastMACurrent && FastMACurrent<Open[1] );
if( BuyCondition )
{
//If we have open trade before get another trade close perivios trade and save money
if( OrderSelect(0, SELECT_BY_POS,MODE_TRADES) )
{
int a = OrderClose( OrderTicket(),OrderLots(),OrderType()==OP_SELL ? Ask : Bid, Slippage, clrWhite );
}
if(GetBuy()) BuyCondition = False;
}
if( SellCondition )
{
//If we have open trade before get another trade close perivios trade and save money
if( OrderSelect(0, SELECT_BY_POS,MODE_TRADES) )
{
int a = OrderClose( OrderTicket(),OrderLots(),OrderType()==OP_BUY ? Bid : Ask, Slippage, clrWhite );
}
if(GetSell()) SellCondition = False;
}
}
}
//+------------------------------------------------------------------+
//| expert Buy Or Sell function |
//+------------------------------------------------------------------+
bool GetBuy(){
int ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,Ask-(StopLoss*Point),Ask+ (TakeProfit*Point),"Buy",MagicNumber,0,Blue);
if(ticket > 0) return true;
return false;
}
bool GetSell(){
int ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,Bid+(StopLoss*Point),Bid- (TakeProfit*Point),"Sell",MagicNumber,0,Red);
if(ticket > 0) return true;
return false;
}

While there are no MQL4 errors, why there was no GUI drawing produced?

For a learning purpose, I am trying to code a simple MA indicator that changes color when price crosses. Though there are no errors, it draws nothing. Could you review the attached code to show me my mistake?
#property indicator_chart_window
#property indicator_buffers 2
extern int maperiod = 20;
extern int maprice = PRICE_CLOSE;
extern int mamethod = MODE_SMA;
extern color colorup = Green;
extern color colordn = Red;
double mamain[];
double bufferup[];
double bufferdn[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init(){
//--- indicator buffers mapping
SetIndexBuffer( 0, bufferup );
SetIndexStyle( 0, DRAW_LINE, 0, 2, colorup );
SetIndexBuffer( 1, bufferdn );
SetIndexStyle( 1, DRAW_LINE, 0, 2, colordn );
//---
return( 0 );
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start(){
//---
int counted_bars = IndicatorCounted();
if ( counted_bars < 0 ) return( -1 );
if ( counted_bars > 0 ) counted_bars--;
int limit = Bars - counted_bars;
for ( int i = limit; i >= 0 ; i-- )
{ mamain[i] = iMA( NULL, 0, maperiod, 0, 0, 0, i );
if ( mamain[i] >= iClose( NULL, 0, i ) ) bufferup[i] = mamain[i];
if ( mamain[i] <= iClose( NULL, 0, i ) ) bufferdn[i] = mamain[i];
}
//--- return value of prev_calculated for next call
return( 0 );
}
//+------------------------------------------------------------------+
"Old"-MQL4 may work for some time, but still, get used to new features:
extern ENUM_APPLIED_PRICE MAprice = PRICE_CLOSE; // AVOIDS incompatible values
extern ENUM_MA_METHOD MAmethod = MODE_SMA; // AVOIDS incompatible values
#define MAshift 0 // ADDS code == intent match-robustness
extern int MAperiod = 20;
extern color colorUP = clrGreen;
extern color colorDN = clrRed;
double bufferUP[];
double bufferDN[];
int init(){
ArrayInitialize bufferUP, EMPTY_VALUE );
SetIndexBuffer( 0, bufferUP );
SetIndexStyle( 0, DRAW_LINE, EMPTY, 2, colorUP );
SetIndexLabel( 0, "MA_ABOVE_Close" );
ArrayInitialize bufferDN, EMPTY_VALUE );
SetIndexBuffer( 1, bufferDN );
SetIndexStyle( 1, DRAW_LINE, EMPTY, 2, colorDN );
SetIndexLabel( 1, "MA_UNDER_Close" );
return( 0 );
}
int start(){
int counted_bars = IndicatorCounted();
if ( counted_bars < 0 ) return( -1 );
if ( counted_bars > 0 ) counted_bars--;
for ( int i = Bars - counted_bars; i >= 0 ; i-- ){
double C = iClose( _Symbol, PERIOD_CURRENT, i ),
A = iMA( _Symbol, PERIOD_CURRENT,
MAperiod,
MAshift,
MAmethod,
MAprice,
i
);
if ( A >= C ) bufferUP[i] = A;
if ( A <= C ) bufferDN[i] = A;
}
return( 0 );
}
New-MQL4.56789 uses another call-signature if #property strict:
int OnCalculate( const int rates_total,
const int prev_calculated,
const datetime &time_______ARR[],
const double &open_______ARR[],
const double &high_______ARR[],
const double &low________ARR[],
const double &close______ARR[],
const long &tick_volumeARR[],
const long &volume_____ARR[],
const int &spread_____ARR[]
){
//--- the main loop of calculations
for( int i = prev_calculated - 1;
( i < rates_total
&& !IsStopped() ); // AVOID SHARED (!) solo-THREAD BLOCKING
i++
){
// -----------------------------------------------------------------
double A = iMA( _Symbol, PERIOD_CURRENT,
MAperiod,
MAshift,
MAmethod,
MAprice,
i
);
if ( A >= close______ARR[i] ) bufferUP[i] = A;
if ( A <= close______ARR[i] ) bufferDN[i] = A;
// -----------------------------------------------------------------
}
return( rates_total );
}
your buffer mamain[] is not initialized.
int init(){
IndicatorBuffers(3);
SetIndexBuffer(2,mamain);
}
rates_total and prev_calculated seems preferred but of course you can use IndicatorCounted() but keep in mind the corner situation with the first bar: when you first attach the indicator to the chart, your counted_bars = 0 and limit = Bars, but mamain[] and other indicator buffers have Bars elements only, from 0 to Bars-1. so better to use
int limit = Bars - counted_bars - 1;
About resolving issues - in addition to asking here you can always try to attach your indicator to a chart and see it there's no error (terminal window - Experts folder), that will make delevopment faster

My First MQL4 EA does not generate any Orders. Why?

I'm trying to build a first EA, code below, but it doesn't execute any trades.
I know it is very simple, but logically, I think this should Buy and Sell.
I'm trying to only use a code that I understand.
I'd appreciate it if anyone had any feedback!
//
extern int sma_short = 10;
extern int sma_long = 20;
extern double fakeout = 0.0005 ;
extern double stoploss = 150;
extern double risk = 1;
extern int slippage = 5;
extern int magicnumber = 12345;
extern bool SignalMail = false;
extern bool UseTrailingStop = true;
extern int TrailingStop = 150;
double sma_short_t3;
double sma_short_t0;
double sma_long_t3;
double sma_long_t0;
double sma_diff_t3;
double sma_diff_t0;
double lots;
double stoplosslevel;
int P = 1;
int ticket, ticket2;
int total = OrdersTotal();
bool OpenLong = false;
bool OpenShort = false;
bool CloseLong = false;
bool CloseShort = false;
bool isYenPair = false;
bool OpenOrder = false;
int OnInit()
{
if ( Digits == 5 || Digits == 3 || Digits == 1 ) P = 10; else P = 1; // To account for 5 digit brokers
if ( Digits == 3 || Digits == 2 ) isYenPair = true; // Adjust for YenPair
return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit( const int reason )
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void Start()
{
sma_short_t3 = iMA( NULL, 0, sma_short, 0, MODE_SMA, PRICE_CLOSE, 3 );
sma_short_t0 = iMA( NULL, 0, sma_short, 0, MODE_SMA, PRICE_CLOSE, 0 );
sma_long_t3 = iMA( NULL, 0, sma_long, 0, MODE_SMA, PRICE_CLOSE, 3 );
sma_long_t0 = iMA( NULL, 0, sma_long, 0, MODE_SMA, PRICE_CLOSE, 0 );
sma_diff_t3 = sma_long_t3 - sma_short_t3;
sma_diff_t0 = sma_long_t0 - sma_short_t0;
if ( OpenOrder )
{
if ( CloseLong || CloseShort )
{
OrderClose( OrderTicket(), OrderLots(), Bid, slippage, MediumSeaGreen );
OpenOrder = False;
CloseLong = False;
CloseShort = False;
}
}
if ( sma_diff_t3 < 0 && sma_diff_t0 > fakeout )
{
OpenLong = True ;
CloseShort = True;
}
if ( sma_diff_t3 > 0 && sma_diff_t0 < -fakeout )
{
OpenShort = True;
CloseLong = True;
}
lots = risk * 0.01 * AccountBalance() / ( MarketInfo( Symbol(), MODE_LOTSIZE ) * stoploss * P * Point ); // Sizing Algo based on account size
if ( isYenPair == true ) lots = lots * 100; // Adjust for Yen Pairs
lots = NormalizeDouble( lots, 2 );
if ( OpenLong )
{
stoplosslevel = Ask - stoploss * Point * P;
OrderSend( Symbol(), OP_BUY, lots, Ask, slippage, stoplosslevel, 0, "Buy(#" + magicnumber + ")", magicnumber, 0, DodgerBlue );
OpenOrder = True;
}
if ( OpenShort )
{
stoplosslevel = Bid + stoploss * Point * P;
OrderSend( Symbol(), OP_SELL, lots, Ask, slippage, stoplosslevel, 0, "Buy(#" + magicnumber + ")", magicnumber, 0, DodgerBlue );
OpenOrder = True ;
}
}
//+------------------------------------------------------------------+
and why do you use (MarketInfo(Symbol(),MODE_LOTSIZE)? what is the idea of that? first try with double lots = 1.00; and if problem still exists - please add a line telling about the reason why ea failed to send. sth like int ticket = OrderSend(***); if(ticket<0)Print("error=",GetLastError()); or more complex telling about the actual prices, lots, stoploss etc.
Few things in MQL4 to rather get used to:
All PriceDOMAIN data has to be NormalizeDouble() before sending to MetaTrader 4 Server.
All EquityDOMAIN data has to follow a set of discrete values,having MathMin( aMinLOT_SIZE + N * aMinLOT_STEP, aMaxLOT_SIZE ). Normalisation of EquityDOMAIN data is broker-specificand instrument-specific, so need not be always 2.
For XTO, OrderSend(), OrderMOdify(), OrderClose(), one ought follow something like this:
if ( OpenLong )
{ stoplosslevel = NormalizeDouble( Ask - stoploss * Point * P, _Digits ); // ALWAYS NormalizeDouble()
int RetCODE = OrderSend( _Symbol,
OP_BUY,
lots,
Ask,
slippage,
stoplosslevel,
0,
"Buy(#" + magicnumber + ")",
magicnumber,
0,
DodgerBlue
);
if ( RetCODE < 0 )
{ Print( "EXC: Tried to go LONG, OrderSend() failed to get confirmed ( Errno: ", GetLastError(), " )" );
}
else
{ OpenOrder = True;
...
}
...
}

Why do I get array our of range in MQL4?

I am trying to make an indicator that shows when x candles of the same color appear on the chart. But I am getting an array out of range error.
There is a up and down array buffer (an arrow pointing up or down)
minCandles is an extern integer that determines after how many bars to point the arrow.
the bear part works but from right to left.
I think the problem may be in down[i] = Low[i] but I don't know why.
Here is the code:
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
There are a few strange things behind the writing a fast and efficient [ Custom Indicator ] MQL4-code.
First, the real-time headache coming from a design decision to accumulate all the computational efforts from all the present [ Custom Indicator ] into a single thread.
While this is hidden, it increases the pressure to minimise all execution latencies at a cost of the colculus being operated in segmented mini-batches, from the deepest history ( the bars farthest back to the left ) proceeding iteratively forwards to the right, towards the current Bar.
One might get confused from the concept of reversed-numbering of the Bars, starting from [0]-for the most recent Bar ( the live Bar ), counting up, while going deeper and deeper towards the history on the far left.
If it were not enough, there are some additional prohibited things inside a [ Custom Indicator ], but as your web-page shows that you provide [ Custom Indicator ] programming on a commercial basis, it is worthless to repeat 'em here again.
Production-grade code for [Custom Indicator] ought have at least:
protective fuses
minimised main duty-cycle overheads
zero raw-Comment()-s to avoid damages to 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
}
//+------------------------------------------------------------------+

Resources