• Home
  • Forums
  • Trades
  • News
  • Calendar
  • Market
  • Brokers
  • Login
  • Join
  • User/Email: Password:
  • 8:03am
Menu
  • Forums
  • Trades
  • News
  • Calendar
  • Market
  • Brokers
  • Login
  • Join
  • 8:03am
Sister Sites
  • Metals Mine
  • Energy EXCH
  • Crypto Craft

Options

Bookmark Thread

First Page First Unread Last Page Last Post

Print Thread

Similar Threads

Indicators can't attach to a chart 33 replies

Can you attach an EA on an offline chart? 6 replies

How to Attach an EA to a Chart 20 replies

How to attach an indicator to MT4 chart 6 replies

  • Platform Tech
  • /
  • Reply to Thread
  • Subscribe
  • 3
Attachments: Attach Indicator to Chart using EA
Exit Attachments
Tags: Attach Indicator to Chart using EA
Cancel

Attach Indicator to Chart using EA

  • Last Post
  •  
  • Page 1 2 3
  • Page 1 2 3
  •  
  • Post #1
  • Quote
  • First Post: Edited Feb 1, 2010 12:31am Jan 31, 2010 10:57pm | Edited Feb 1, 2010 12:31am
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
So, is it possible to attach an indicator to a chart using an EA? If so, what should the code look like?

Also, I'm thinking it would be nice to set the parameters for the indicator within the EA and, that globals will probably work.

Any help would be greatly appreciated.

Thanks.
  • Post #2
  • Quote
  • Edited Feb 1, 2010 12:03am Jan 31, 2010 11:41pm | Edited Feb 1, 2010 12:03am
  •  CodeMeister
  • Joined Sep 2009 | Status: Making Code While Making Pips | 1,672 Posts
Use iCustom. Lots of documentation and examples on MQL4 website. Its a great way to verify an indicator's logic.
 
 
  • Post #3
  • Quote
  • Feb 1, 2010 3:07am Feb 1, 2010 3:07am
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Well, it's a place to start anyway.

Now I did find the iCustom function (also in Meta Editor help), but it looks like it's only used for "calculating and returning an indicator's value" ... whatever that means? I don't see how it specifically applies to opening an indicator from within an EA though. This is what I need to know.

It seems like all I should need is a single line of code ...
 
 
  • Post #4
  • Quote
  • Feb 1, 2010 6:11am Feb 1, 2010 6:11am
  •  CodeMeister
  • Joined Sep 2009 | Status: Making Code While Making Pips | 1,672 Posts
Quoting ecTrade
Disliked
Well, it's a place to start anyway.

Now I did find the iCustom function (also in Meta Editor help), but it looks like it's only used for "calculating and returning an indicator's value" ... whatever that means? I don't see how it specifically applies to opening an indicator from within an EA though. This is what I need to know.

It seems like all I should need is a single line of code ...
Ignored
I ignore the return value unless I am wrapping an EA around it. What I want to see is how the indicator performs on historical data by giving the alerts when it is supposed to for instance. Also I check the repainting of the indicator to see how much of an affect it has. These things can be done on live data, but why wait for hours when you know the setup on the historical data.

But if you had something else in mind, I'm not sure if it can be done.
 
 
  • Post #5
  • Quote
  • Edited 9:07am Feb 1, 2010 8:50am | Edited 9:07am
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
What I want to do is get the indicator to coincide with and run at the same time as the EA on the chart. That way I don't have to convert the indicator to an EA and still use it (as if it were) when I call up the EA. It seems like it would be much simpler that way.

Basically I describe what I'm trying to do in this thread here. While the most recent versions of the files (both indicator and EA - that work) are in this post. Both the indicator and the EA are already setup to communicate with each other (through global variables), just that it would be nice if I could get them to open at the same time. And, if it's possible, I suspect it may be possible to backtest both at the same time as well.

Oh well, if it's not possible, and I get ambitious enough, I may spend the actual time (and trouble) to try and convert it to an EA.
 
 
  • Post #6
  • Quote
  • Feb 1, 2010 4:01pm Feb 1, 2010 4:01pm
  •  CodeMeister
  • Joined Sep 2009 | Status: Making Code While Making Pips | 1,672 Posts
What you describe is what iCustom is meant to do. Play with it for a while and get comfortable with it and I think you'll agree with me. For simple indicators, I wouldn't use iCustom - just convert to an EA.
 
 
  • Post #7
  • Quote
  • Edited 8:36am Feb 2, 2010 8:09am | Edited 8:36am
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting ecTrade
Disliked
Both the indicator and the EA are already setup to communicate with each other (through global variables), just that it would be nice if I could get them to open at the same time. And, if it's possible, I suspect it may be possible to backtest both at the same time as well.
Ignored
Letting the indicator and the EA communicate through global variables is an ugly hack, you need to take care of symbol and timeframe and maybe even magic numbers and all that ugly stuff when creating the variable names to avoid collisions of multiple instances of the same indicator attached to different charts with different settings. All these things (having more than one chart window open, trading the same pair in different timeframes) are allowed and common scenarios, you would have to individually take care of each of these possible use cases (test and debug it) if you decide to leave the documented and recommended path and reimplement the whole mechanism of indicator<->EA communication in such a bizzarre and uncommon way for no reason!

You should really try to use indicator buffers for that, you have up to 8 buffers, if the indi for example already uses 3 buffers to draw three lines on the chart and the buy signals cant clearly be derived from these line buffers, then just modifiy the indi and let it use a 4th and a 5th (or even more buffers) to write the buy and sell signals (colored up and down arrows for example) or what else you previously used to write into the global variables. Then use iCustom in your EA to read the signal buffers. An advanced EA (or an advanced indicator based on this indicator) that may be written in the future could then even loop through historic values of these buffers to find historic signals the indicator would have given x bars before the current one (to count them, measure the distances between signals, find periods in them, your imagination is the limit), things that simply can't be done with 0-dimensional variables that can only show the current state.

An indicator should always be designed in such a way that it can be easily used with iCustom() and everything it has to tell is written into one of it's buffers. The reason for this is simply that you can completely avoid such problems and forum threads with ugly hacks and workarounds like this one. Such cleanly written indicators when used in EAs can be used in all sorts of backtests or paramter optimizations or EAs that trade or analyze a whole basket of pairs at once where there even is no chart to visually attach the indicator to.

If you want to load the EA visually onto the chart during a visual backtest (only to watch it's nice drawings while it works) then just create a template with the same name as the EA. This template will be loaded automatically whenever you backtest the EA in visual mode.

Please read all the above carefully and think a while (at least a day) about all the possible consequences of what you are going to do and all the avoided problems and the thankful EA developers (maybe even a future instance of yourself) if you decide to do it the recommended and documented way from the very beginning on.
 
 
  • Post #8
  • Quote
  • Edited 12:19pm Feb 2, 2010 9:27am | Edited 12:19pm
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Actually, the specific example given works without a hitch. So far, every time a signal is generated and the alert pops up (over the past few days) I've placed a successful trade. I don't see what's so ugly about that? Neither do I see what's so hard about keeping the globals specific, so long as you're aware of the application you are using it on and don't call it out elsewhere. Or else what's the point in using them? As for the environment, that's pretty much determined (automatically) by the EA, so long as they're attached to the same chart. Or, at least that's the way it's worked in this instance here. And, quite well in fact.

But hey, I don't claim to know all there is about indicators, in fact very little. This was my first attempt in working with them. And no, I'm not against learning the "proper" way of doing it. The bottom line, however, at least at this point, is to find something that works, and get on with the trading. I'm not doing it for the pure love of programming, although that's not without its merits either. Without a flair for accuracy, and attention to detail, you're basically wasting your time. This much I do know.
 
 
  • Post #9
  • Quote
  • Edited 10:22am Feb 2, 2010 9:56am | Edited 10:22am
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
So what are you supposed to do, without a lot of trouble, if you're tying to get an indicator to generate signals an EA can pickup and trade automatically with? You either convert it to an EA which, I'm not prepared to do at this point or, you go with globals, I guess? ...

Also, if it were a simple matter of calling up the indicator and placing it on the same chart as the EA (which is all I'm doing manually), why shouldn't it entail anything more than a "simple" line of code?
 
 
  • Post #10
  • Quote
  • Feb 2, 2010 12:24pm Feb 2, 2010 12:24pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting ecTrade
Disliked
So what are you supposed to do, without a lot of trouble, if you're tying to get an indicator to generate signals an EA can pickup and trade automatically with? You either convert it to an EA which, I'm not prepared to do at this point or, you go with globals, I guess? ...
Ignored
In your Indicator would assign 2 buffers that will contain the signals. A buffer works just like an array, index 0 is always the current bar. Buffers can be configured to draw their values as lines on the chart or into a separate indicator window or produce arrows in the chart when they contain a price instead of EMPTY_VALUE at that index. (this is what is well suited for indicators that produce signals). These buffers are what is returned when you read the indicator value with iCustom() or any other built in indicator.

An example:

Inserted Code
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Yellow
#property indicator_width1  1
#property indicator_width2  1

double upper_fr[];
double lower_fr[];


void init() {
  SetIndexBuffer(0, upper_fr);
  SetIndexBuffer(1, lower_fr);
  
  SetIndexEmptyValue(0, 0);
  SetIndexEmptyValue(1, 0);
  
  SetIndexStyle(0, DRAW_ARROW);
  SetIndexArrow(0, 234);

  SetIndexStyle(1, DRAW_ARROW);
  SetIndexArrow(1, 233);  
}
this is part of the code from the i-fractalsEx indicator where the buffers are defined, this indicator will mark the fractals with arrows in the chart but they can also be read with an iCustom(). iCustom() calls all look the same, the second last argument is the number of the buffer to read and the last argument is the shift (the bar number, counting backwards, 0 is current bar). In fact almost everey indicator's (even the built in ones) two last arguments are buffer_number and shift. iStochastic() for example will have the second last argument defining which line to read an the last argument is the index number of the bar.

The above indicator will have two buffers, when you read it you specify the buffer number and the bar index, just like the built in iFractal() indicator where you specify in the last two arguments whether you want to read the upper or the lower buffer and the bar index.

In the indicator itself (in the above example) where the two arrays upper_fr and lower_fr are defined as indicator buffers, these two arrays act as the output of the indicator. The logic in this indicator will assign values to these locations in the array where a fractal is detected and an arrow should appear. metatrader will use this to automatically draw the arrows and any call to iCustom() will find a price value
Inserted Code
  for (i=0+Fr.Period; i <= limit+Fr.Period; i++) 
  {
    upper_fr[i] = 0;
    lower_fr[i] = 0;
  
    if (is_upper_fr(i, Fr.Period)) upper_fr[i] = High[i]+dy;
    if (is_lower_fr(i, Fr.Period)) lower_fr[i] = Low[i]-dy;
  }
This is from somwhere inside the start function where the fractals are written to the buffers. As you can see it first clears the buffer completely and then if there is a fractal at this index (determined by some other helper functions) it will write the price into the buffer where the arrow should appear. metatrader will immediately place an arrow when the indicator is attached to a chart and when called via iCustom() you can read these arrays from the outside by specifying buffer number and index.

from the mql4 book:
Inserted Code
double iCustom( string symbol, int timeframe, string name, ..., int mode, int shift)
symbol - Symbol the data of which should be used to calculate indicator. NULL means current symbol.
timeframe - Timeframe. It can be any of Timeframe enumeration values. 0 means the current chart timeframe.
name - Custom indicator compiled program name.
... - Parameters set (if necessary). The passed parameters and their order must correspond with the desclaration order and the type of extern variables of the custom indicator.
mode - Line index. Can be from 0 to 7 and must correspond with the index used by one of SetIndexBuffer functions.
shift - Index of the value taken from the indicator buffer (shift relative to the current bar the given amount of periods ago).

They call it mode in this document and also in the documentation for the built in indicators, but it is nothing more complicated than just the buffer number used in the indicator. In the example above we could use 0 and 1 for the mode argument to access either the yellow or the red arrows, (either buffer1 or buffer2, buffer1 is 0, buffer2 is 1, ...), when it returns 0 then there is no arrow, when it returns a number then it is the price where the arrow appeared.

All your indicator must do is to create and maintain two such arrow buffers, write current price into yourBuyBuffer[0] or yourSellBuffer[0] as soon as a signal appears at the current position, 0 otherwise, and then magically an arrow appears and also every EA programmer can conveniently read these two arrays from the outside with an iCustom() call and use your indicator in the same way he also uses all the built in indicators.

HTH
 
 
  • Post #11
  • Quote
  • Feb 2, 2010 12:34pm Feb 2, 2010 12:34pm
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Hey 7bit, the more I read your (first) post the more it makes sense so, I'm not a complete lost cause. Thanks.
 
 
  • Post #12
  • Quote
  • Edited 1:06pm Feb 2, 2010 12:47pm | Edited 1:06pm
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Quoting 7bit
Disliked
In your Indicator would assign 2 buffers that will contain the signals. A buffer works just like an array, index 0 is always the current bar. Buffers can be configured to draw their values as lines on the chart or into a separate indicator window or produce arrows in the chart when they contain a price instead of EMPTY_VALUE at that index. (this is what is well suited for indicators that produce signals). These buffers are what is returned when you read the indicator value with iCustom() or any other built in indicator.
Ignored
Sorry, but this is too far beyond me at this point. I figure all I need is to determine what signal sets off the alarm, and determine which conditions generated it, and pass this on (as globals) to the EA. This is all that I've done and, it works great!

As for tweaking indicator variables, I pretty much have to accept them the way they are, that is, until I learn to work with them more. Right now, I'm mainly concerned that the signal is generated and, I can apply it to the EA. And no, there is nothing that says I have to open both at the same time. I just thought it would be nice.

But hey, I might come back and look at what you've written later on when I have a chance. Thanks.
 
 
  • Post #13
  • Quote
  • Feb 2, 2010 12:57pm Feb 2, 2010 12:57pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Maybe some words to what actually happens behind the scene when you call an indicator:

Whenever you call an indicator (built in or custom) for the first time ever it will be loaded (but stay invisible). From then on it will work, get its start() function called, just like it were be attached to a live chart, it doesn't even know that it is invisible or that there is no chart at all (in backtest mode or if you load it a second time for another timeframe).

Any subsequent call to the same indicator iSomethingBuiltIn() or iCustom() will only read the indicator buffers.

The indicator will silently move forward in time when the time goes forward and new ticks come in, even without calling iCustom() a second time, it will do its calculations and update its buffers in the background and then when the EA decides it wants to know what the indicator is doing it will just call iCustom() again to read the buffers.

So all you have to do is replace your writing to global variables to a writing to indicator buffers and iCustom can read them. iCustom() is just a wrapper around reading these arrays, just like iClose() is just a wrapper around reading the built-in Close[] array.

Abstract comparison: You could regard Close[] as the indicator buffer for the iClose() indicator which is always there by default and responsible for drawing the "indicator" called "Close Price" onto the chart, which cannot be removed.
 
 
  • Post #14
  • Quote
  • Feb 2, 2010 1:02pm Feb 2, 2010 1:02pm
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Okay, I will have a look at this later.

Again, thanks.
 
 
  • Post #15
  • Quote
  • Feb 2, 2010 1:03pm Feb 2, 2010 1:03pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting ecTrade
Disliked
Sorry, but this is too far beyond me at this point. I figure all I need is to determine what signal sets off the alarm, and determine which conditions generated it, and pass this on (as globals) to the EA. This is all that I've done and, it works great!
Ignored
You would just write something into the buffer (the array) instead of writing into a global variable. Thats the only difference.

on the EA side the reading of the globals is replaced by reading this same array with iCustom()

the buffer and iCustom() are just another way to pass data from the indicator to the EA. They both share the same array, much like they could share the same global variables, only that the buffers are shielded against any colissions with the outside world and have some other advantages.

The indicator writes into a specially designated array and iCustom can read this very same array. <-- This last sentence is basically everything there is to know about this. There is no more magic to it. It all boils down to the simple thing of knowing how to define such an array inside your indicator and telling it to be the buffer. The buffer is your new "global variable", it serves the same purpose.
 
 
  • Post #16
  • Quote
  • Feb 2, 2010 1:14pm Feb 2, 2010 1:14pm
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Quoting 7bit
Disliked
Quoting ecTrade
Disliked
Sorry, but this is too far beyond me at this point. I figure all I need is to determine what signal sets off the alarm, and determine which conditions generated it, and pass this on (as globals) to the EA. This is all that I've done and, it works great!
Ignored
You would just write something into the buffer (the array) instead of writing into a global variable. Thats the only difference.

on the EA side the reading of the globals is replaced by reading this same array with iCustom()
Ignored
Okay, so the indicator writes into the buffer (although I'm not sure what that's about?) which, the EA accesses though iCustom? Now that almost sounds do-able.
 
 
  • Post #17
  • Quote
  • Feb 2, 2010 1:26pm Feb 2, 2010 1:26pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting ecTrade
Disliked
Okay, so the indicator writes into the buffer (although I'm not sure what that's about?) which, the EA accesses though iCustom? Now that almost sounds do-able.
Ignored
Yes, it's absolutely doable. It took me some time to understand this too, but once you have understood the concept it is really easy.

As a first step just try to make the indicator draw buy and sell arrows. Dissect any simple indicator that draws such arrow buffers to see how it is done or use my previous example.

As soon as you see your indicator correctly producing these arrows you have solved more than half of the problem. As soon as there are arrows¹ you will be able to read them (and their exact position) through iCustom().

________
¹ Only arrows that are drawn with the help of buffers, ObjectCreate() does not work.
 
 
  • Post #18
  • Quote
  • Edited 1:59pm Feb 2, 2010 1:34pm | Edited 1:59pm
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
Quoting 7bit
Disliked
Yes, it's absolutely doable. It took me some time to understand this too, but once you have understood the concept it is really easy.
Ignored
So these variable are probably already set up in the buffer (I'm guessing), and all I need is to figure out which ones they are and call them up through iCustom() ... as I am not trying to create (or intercept) anything that isn't already there.
 
 
  • Post #19
  • Quote
  • Feb 2, 2010 2:03pm Feb 2, 2010 2:03pm
  •  7bit
  • Joined Mar 2009 | Status: Member | 1,231 Posts
Quoting ecTrade
Disliked
So these variable are probably already set up in the buffer (I'm guessing), and all I need is to figure out which ones they are and call them up through iCustom() ...
Ignored
I just had a look at the code of the macd divergence indicator you mentioned and (without trying it out) it looks like the following:

4 buffers, the first two of them are the arrows and the other two are the macd lines it draws:

SetIndexBuffer(0, bullishDivergence);
SetIndexBuffer(1, bearishDivergence);
SetIndexBuffer(2, macd);
SetIndexBuffer(3, signal);

so the bullish arrow would be read with
iCustom(...., 0, 0)

and the bearish arrow with
iCustom(...., 1, 0)

The last 0 is the bar number, just like with any other indicator too. I am not sure whether it draws the arrow at the current bar (0) or the previous bar (1) (haven't tried it), so if you use 1 it would check for an arrow at the position of the previously closed bar.

If it returns EMPTY_VALUE this means there is no arrow at that position, if it returns something else then there is an arrow. (the actual value is of no interest to us, it is only the exact y coordinate of the arrow in the indicator window, the macd value plus some displacement)

So you basically do something like

if (iCustom(...., 0, 0) != EMPTY_VALUE){
buy();
}

if (iCustom(...., 1, 0) != EMPTY_VALUE){
sell();
}

the .... is like in one of the previous postings defined by the mql book the symbol name (NULL for current symbol), the timeframe (0 for current timeframe), the indicator name and *all* indicator external parameters in their exact order.

We have the following parameters for the indicator, we have to specify them all in the iCustom call.

extern string separator1 = "*** MACD Settings ***";
extern int fastEMA = 12;
extern int slowEMA = 26;
extern int signalSMA = 9;
extern string separator2 = "*** Indicator Settings ***";
extern bool drawIndicatorTrendLines = true;
extern bool drawPriceTrendLines = true;
extern bool displayAlert = true;
extern int Test = 0;

in our case the call woulod be something like this:

Inserted Code
// i have inserted line breaks between each argument for readability
double bull = iCustom(
  NULL, 
  0, 
  "MACD_Divergence_V1.1_03", 
  "",
  12,
  26,
  9,
  "",
  true,
  true,
  true,
  0,
  0,
  0 
);

double bear = iCustom(
  NULL, 
  0, 
  "MACD_Divergence_V1.1_03", 
  "",
  12,
  26,
  9,
  "",
  true,
  true,
  true,
  0,
  1,
  0
);

if (bull != EMPTY_VALUE){
  // buy here
}

if (bear != EMPTY_VALUE){
  // sell here
}

I have not tested it and most likely there are a few typos and forgotten characters in the code above but this is basically how to do this kind of stuff with any indicator that can draw buy/sell arrows.
 
 
  • Post #20
  • Quote
  • Feb 2, 2010 2:09pm Feb 2, 2010 2:09pm
  •  ecTrade
  • | Joined Jul 2009 | Status: Member | 1,163 Posts
There are actually four conditions it produces, although they are pretty much just buy and sell signals, but I can't tell which is which by looking at that. Really all I need is the buy and sell signals, but I would pretty much like to know which conditions produced them, or be able to convey that on the EA.
 
 
  • Platform Tech
  • /
  • Attach Indicator to Chart using EA
  • Reply to Thread
    • Page 1 2 3
    • Page 1 2 3
0 traders viewing now
  • More
Top of Page
  • Facebook
  • Twitter
About FF
  • Mission
  • Products
  • User Guide
  • Media Kit
  • Blog
  • Contact
FF Products
  • Forums
  • Trades
  • Calendar
  • News
  • Market
  • Brokers
  • Trade Explorer
FF Website
  • Homepage
  • Search
  • Members
  • Report a Bug
Follow FF
  • Facebook
  • Twitter

FF Sister Sites:

  • Metals Mine
  • Energy EXCH
  • Crypto Craft

Forex Factory® is a brand of Fair Economy, Inc.

Terms of Service / ©2023