It looks like you've cobbled together some old-style code to make some modifications.
I suggest you start with a basic, blank layout of the new style. For an indicator it should look something like this:
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| 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[])
{
return(rates_total);
}
If this is an indicator, you can't use MessageBox().
You can read about why in the documentation, which is a great place to learn.
In MetaEditor, move your cursor inside the word MessageBox and press F1.
So you will need to use Alert() instead.
Also, keep your code simple.
#property indicator_chart_window
input double AlertPrice = 1.5000;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| 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(Open[1] < AlertPrice && Close[1] > AlertPrice) Alert("Buy");
return(rates_total);
}
Your code only checks the Open / Close of the previous bar. So next, you may want to make your code only check this condition once per bar, rather than every tick.
HTH
PS don't forget you need a semicolon ; at the end of each line in MQLI edited my original post to show the whole code :)
Thank you so much for the detailed reply!
I'm going to get that alert set, instead of the messagebox. That will print in the terminal, correct?
I've been learning from a youtube series, but they are old videos, so I realize there might be some discrepancies.
I'll also look at getting it to focus on bar closes, not sure why I didn't think of that! :D
I've been learning from a youtube series, but they are old videos, so I realize there might be some discrepancies.
Yes, unfortunately a lot! MQL4 was majorly overhauled back in 2014 (from Build 600 onwards). Sadly much of the information you will find in tutorials pre-dates this change.
OK, a few things.
Forget about:
That's the old stuff. If you are writing an indicator it is:
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[])
And for an EA it is:
__________________________
I'm going to get that alert set, instead of the messagebox. That will print in the terminal, correct?
No, that would be Print().
Alert() will pop up on the screen, kind of like a messagebox (but not a messagebox).
__________________________
#property link ""
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Alert
#property indicator_label1 "Alert"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input double AlertPrice;
//--- indicator buffers
double AlertBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,AlertBuffer);
//---
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[])
{
//---
//--- return value of prev_calculated for next call
return(rates_total);
}
int start()
{
int i;
for (i=1)
{
if (Open[i]<AlertPrice && Close[i]>AlertPrice)MessageBox("Buy")
return(0);
}
}
You have created a buffer but I'm not seeing any use for it in your code. If you don't need it, get rid of it.
Yes, unfortunately a lot! MQL4 was majorly overhauled back in 2014 (from Build 600 onwards). Sadly much of the information you will find in tutorials pre-dates this change.
OK, a few things.
Forget about:
That's the old stuff. If you are writing an indicator it is:
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[])
And for an EA it is:
__________________________
No, that would be Print().
Alert() will pop up on the screen, kind of like a messagebox (but not a messagebox).
__________________________
#property link ""
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Alert
#property indicator_label1 "Alert"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input double AlertPrice;
//--- indicator buffers
double AlertBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,AlertBuffer);
//---
return(INIT_SUCCEEDED);
}
You have created a buffer but I'm not seeing any use for it in your code. If you don't need it, get rid of it.
I want a line to be drawn at the level I use for the "AlertPrice" input. I thought you needed buffers to have it drawn? I haven't gotten to that part yet, but basiaclly I'd like a horizontal line drawn at my "AlertPrice" level. I think those buffers were auto-populated in the code when I started building the indicator..
But! I just did a test on a live chart. I used the "PlaySound" function to make it easy see if it would work, and it did!
alert sound played over and over after it got activated, I'm assuming this is because I am having it call per-tick, like you said? I'm thinking a FOR loop, which would check using the "Bars" function? Or is there a much simpler way to do this?
I'm going to try to find an updated video tutorial series, if you had any suggestions, it would be GREATLY appreciated! :D
I want a line to be drawn at the level I use for the "AlertPrice" input. I thought you needed buffers to have it drawn? I haven't gotten to that part yet, but basiaclly I'd like a horizontal line drawn at my "AlertPrice" level. I think those buffers were auto-populated in the code when I started building the indicator..
But! I just did a test on a live chart. I used the "PlaySound" function to make it easy see if it would work, and it did!
alert sound played over and over after it got activated, I'm assuming this is because I am having it call per-tick, like you said? I'm thinking a FOR loop, which would check using the "Bars" function? Or is there a much simpler way to do this?
I'm going to try to find an updated video tutorial series, if you had any suggestions, it would be GREATLY appreciated! :D
You could use a buffer to draw your horizontal line, but it might be easier to create an OBJECT_HLINE
Restricting code to running once per bar is very simple e.g.
//| 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[])
{
static datetime last_bar = 0;
datetime this_bar = Time[0];
if(last_bar != this_bar)
{
// do stuff here only once per bar
last_bar = this_bar;
}
return(rates_total);
}
I don't really know of any up-to-date tutorials. Fortunately, much of the MQL5 material now works on MQL4 (notable exceptions being iCustom and trade functions).
You could use a buffer to draw your horizontal line, but it might be easier to create an OBJECT_HLINE
Hey! I'm currently looking up how to draw a line on the chart. I would want to put that code in the "indicator initialization function" area, correct? Because I'd want the object (line) drawn when I drop the indicator on the chart?
Ok! I got it figured out!
Here's the finished code!
Lastly, I want to add the option to change the color of the line. But, it looks like it works! I need to wait for markets to open to test it, but it looks good, and THERE'S NO ERRORS! hahaha
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- input parameters
input double AlertPrice;
//--- indicator buffers
double AlertBuffer[];
string obj_name = "AlertLine";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
ObjectCreate("AlertLine",OBJ_HLINE,0,TimeCurrent(),AlertPrice);
ObjectSet("AlertLine",OBJPROP_COLOR,clrDarkOrchid);
ObjectSet("AlertLine",OBJPROP_STYLE,STYLE_DASH);
ObjectSet("AlertLine",OBJPROP_WIDTH,1);
//---
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[])
{
//---
static datetime last_bar = 0;
datetime this_bar = Time[0];
if(last_bar != this_bar)
{
if (Open[1]<AlertPrice && Close[1]>AlertPrice) Alert("Bullish Breakout");
if (Open[1]>AlertPrice && Close[1]<AlertPrice) Alert("Bearish Breakout");
last_bar = this_bar;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ObjectDelete("AlertLine");
}
@honest_knave Thank you so much for your help!
Nice!
Just be careful with your naming. You did create a name then you didn't use it, and used 2 different names!
{
//--- indicator buffers mapping
string obj_name = "AlertLine";
ObjectCreate("Hline",OBJ_HLINE,0,TimeCurrent(),AlertPrice);
ObjectSet("AlertLine",OBJPROP_COLOR,clrDarkOrchid);
ObjectSet("AlertLine",OBJPROP_STYLE,STYLE_DASH);
ObjectSet("AlertLine",OBJPROP_WIDTH,1);
//---
return(INIT_SUCCEEDED);
}
You will also probably want your code to delete your object when you remove the indicator:
{
ObjectDelete(0,"AlertLine");
}
Tip: typos with object names can be easy to miss because the compiler won't throw up an error. Try something like this:
input double AlertPrice;
//--- indicator buffers
double AlertBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
ObjectCreate(alert_line,OBJ_HLINE,0,TimeCurrent(),AlertPrice);
ObjectSet(alert_line,OBJPROP_COLOR,clrDarkOrchid);
ObjectSet(alert_line,OBJPROP_STYLE,STYLE_DASH);
ObjectSet(alert_line,OBJPROP_WIDTH,1);
//---
return(INIT_SUCCEEDED);
}
Oops, looks like I edited my post while you were replying :)
It's all nicely figured out! I spotted that error after I posted, hadn't had my coffee yet hahaha
Lastly, I want to add the option to change the color of the line. But, it looks like it works! I need to wait for markets to open to test it, but it looks good, and THERE'S NO ERRORS! hahaha
You can test it now through the strategy tester.
You won't see the Alert() popup, but it will print in the Journal.So when the Alert is activated, it will pop up a message ? I'm going to make it so that the alert says "EURUSD bullish breakout" or "EURUSD bearish breakout" depending on what the alert is.
Also, I'd like to tie the horizontal line to the alert better, so that you can drag the line and it will drag the alert, also. I think I saw something about that in my searches :)
Also going to add inputs so they can change the color/type of the horizontal line.
I'm really loving this! Once you understand the format of how to write the code, it really all comes together beautifully! :)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hey, I'm trying my hand at creating a simple alert indicator. I keep getting what look like simple syntax errors, but can't figure out what's wrong.
#property copyright "Me"
#property link ""#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Alert
#property indicator_label1 "Alert"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input double AlertPrice;
//--- indicator buffers
double AlertBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,AlertBuffer);
//---
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[])
{
//---
//--- return value of prev_calculated for next call
return(rates_total);
}
int start()
{
int i;
for (i=1)
{
if (Open[i]<AlertPrice && Close[i]>AlertPrice)MessageBox("Buy")
return(0);
}
}
Any help would be greatly appreciated :)