Should both the EA and the CustomIndicator share one global External Variable Value????
They can do that.
Have the EA write the period value, have the indicator read it and use it.
Should both the EA and the CustomIndicator share one global External Variable Value????
They can do that.
Have the EA write the period value, have the indicator read it and use it.
Thanks for the reply phy, but I already do this when calling the iCustom function. I pass the EA's CURRENT values (for Period, Symbol, etc.) to my indicator as they are external variables there. However, I would like my indicator to be redrawn to reflect the new settings when I change them via my EA.
Here's the breakdown. I can have my indicator on a chart and use it independently of the EA...so it has external variables that may or may not match those of the EA. I control what the Indicator looks like via its own external variables. Now...consider adding the EA to the chart that is already running the indicator. The EA also has its own set of External Variables to control how it is making decisions. The iCustom call in the EA is using the indicator on the chart.....The EA uses the Indicator's calculation for signals based on what values it send to it via the iCustom call.....maybe I should have a function to identify when I change the external variable values of the EA and then trigger the indicator to be redrawn using those values?
The confusing part to me is...wouldn't this produce some kind of cyclical issue? How can the EA "control" the Indicator when the Indicator is the one that is supposed to "control" the EA???
Thanks
There would be no cyclical issue, unless the output(s) from the indicator affect the indicators input parameters. The OP wants the indicator to use the EAs values.
The simplest method would be for the indicator to read global variables and override its externals when they exist. But this requires changes to both EA and indicator.
Option two would be to have the EA do the following- Perform a template save #define's for known commands that can be used for PostMessageA()
- Copy the template file Automated Optimization of a Trading Robot in Real Trading
- Read and modify adding/modifying the indicator
- Copy back
- Perform a template attach.
I don't have the time to try this, but searching shows many would like it.
unfortunately this is not possible. the indicator loaded by iCustom() and the same indicator manually added to the chart are two separate instances. Unfortunalely iCustom() indicators are always invisible and there is no way to simply unhide them.
I have solved this problem in the past by simply letting my EA plot chart objects (many line segments to plot the indicator curve or arrow objects to visualize arrow buffers) from the values that the EA retrieved through iCustom() into the chart.
" I would like changes made to the external variables of the EA to be reflected on the Chart visually...."
Method 1.
Have the EA draw stuff as 7bit suggested.
Method 2.
Modify your indicator to look for parameters using GlobalVariableGet().
Attach your indicator to the chart.
Have the EA write values using GlobalVariableSet() that the Indicator will read using GlobalVariableGet() to control the indicator from the EA.
Ok,
I'm not a total noob to programming and I've been working with MQL4 on and off for a little while now....although not consistently enough I might add.
Here's the question. I have a couple EA's built and a few Custom Indicators and I would like changes made to the external variables of the EA to be reflected on the Chart visually....Please follow the steps below for example:
Steps:
1. Change Moving Average period from EA's external variables (This is passed in to the CustomIndicator during the iCustom call in order to determine trade conditions)
2. EA is now running using new value for Moving Average's period....I would like the chart in the window (Drawn by the CustomIndicator which has it's own external variables) to be redrawn to reflect the new variable values (in this case...the moving average period)
Am I confusing the issue here on how things should work?
Should I even be doing it this way?
Should both the EA and the CustomIndicator share one global External Variable Value????
Thanks...
" I would like changes made to the external variables of the EA to be reflected on the Chart visually...."
Method 1.
Have the EA draw stuff as 7bit suggested.
Method 2.
Modify your indicator to look for parameters using GlobalVariableGet().
Attach your indicator to the chart.
Have the EA write values using GlobalVariableSet() that the Indicator will read using GlobalVariableGet() to control the indicator from the EA.
Thanks for the responses everyone!
I will try to let you know which method turns out to be a good solution for me.
Regards,
T.
//+------------------------------------------------------------------+ //| EA equivalent of indicator buffers | //+------------------------------------------------------------------+ /* Example 1: * if (...) Ordermodify(...); * Polyline("SL"+(oo.ticket%99), oo.SL, Color.Dn, 0); * * Example 2: * double ELineCurr = iMA(NULL,0, ELine.Period, 0, MODE_EMA, PRICE_CLOSE, 1); * Polyline("ELine", ELineCurr, Color.ELine, 1); ******************************************************************************/ #define POLYLINE_MAX 10 // Must match priceM double price0[], price1[], price2[], price3[], price4[], // \ Export from price5[], price6[], price7[], price8[], price9[]; // \ Polyline int LRU[POLYLINE_MAX], segNo[POLYLINE_MAX]; // > import to string lineName[POLYLINE_MAX]; // _/ PLHelper datetime mem0[POLYLINE_MAX]; void Polyline(string name, double price, color clr, int shift){ if (!Show.Objects) return; for (int idx=0; idx < POLYLINE_MAX; idx++){ LRU[idx]++; } for (idx=0; idx < POLYLINE_MAX; idx++){ bool new = lineName[idx] != name; if (!new) break; } if (new) idx=ArrayMaximum(LRU); LRU[idx] = 0; switch (idx){ case 0: PLHelper(name, price, clr, idx, new, shift, price0); return; case 1: PLHelper(name, price, clr, idx, new, shift, price1); return; case 2: PLHelper(name, price, clr, idx, new, shift, price2); return; case 3: PLHelper(name, price, clr, idx, new, shift, price3); return; case 4: PLHelper(name, price, clr, idx, new, shift, price4); return; case 5: PLHelper(name, price, clr, idx, new, shift, price5); return; case 6: PLHelper(name, price, clr, idx, new, shift, price6); return; case 7: PLHelper(name, price, clr, idx, new, shift, price7); return; case 8: PLHelper(name, price, clr, idx, new, shift, price8); return; case 9: PLHelper(name, price, clr, idx, new, shift, price9); return; } } void PLHelper( string name, double price, color clr, int idx, bool new , int shift, double& mem[] ){ if (new){ ArrayResize(mem, 1); lineName[idx]=name; segNo[idx]=0; } else if (Time[shift] != mem0[idx]){ // Shift values m[2]=m[1]; m[1]=m[0] ArraySetAsSeries(mem, true); ArrayResize(mem, ArraySize(mem)+1); ArraySetAsSeries(mem, false); } mem0[idx]=Time[shift]; mem[0]=price; int firstBar=ArraySize(mem)-1; if (ObjectMove(name, 1, Time[shift], price)) ObjectMove(name, 0, Time[shift+firstBar], mem[firstBar]); else if (!ObjectCreate( name, OBJ_TREND, WINDOW_MAIN, Time[shift], price, Time[shift+firstBar], mem[firstBar] )){ Alert( "ObjectCreate(", name, "Trend) [1] failed: ",GetLastError()); return;} else if (!ObjectSet( name, OBJPROP_COLOR, clr )) Alert( "ObjectSet(", name, "Color) [2] failed: ", GetLastError()); else if (!ObjectSet( name, OBJPROP_RAY, false )) Alert( "ObjectSet(", name, "Ray) [1] failed: ", GetLastError()); double maxError=0; int maxBar; for (int pos=0; pos <= firstBar; pos++){ double error=MathAbs(ObjectGetValueByShift(name, pos+shift)-mem[pos]); if (error > maxError){ maxError=error; maxBar=pos; } } if (maxError >= pips2dbl){ // Split the line into two segments at the max. segNo[idx]++; string newName=name+"-"+segNo[idx]; if (ObjectMove(newName, 0, Time[firstBar+shift], mem[firstBar])) ObjectMove(newName, 1, Time[maxBar +shift], mem[maxBar]); else if (!ObjectCreate( newName, OBJ_TREND, WINDOW_MAIN, Time[firstBar+shift], mem[firstBar], Time[maxBar +shift], mem[maxBar] )){ Alert( "ObjectCreate(", newName, "Trend) [2] failed: ",GetLastError()); return;} else if (!ObjectSet( newName, OBJPROP_COLOR, clr )) Alert( "ObjectSet(", newName, "Color) [3] failed: ", GetLastError()); else if (!ObjectSet( newName, OBJPROP_RAY, false )) Alert( "ObjectSet(", newName, "Ray) [2] failed: ", GetLastError()); ArrayResize(mem, maxBar+1); // Drop firstBar..(maxBar+1) if (!ObjectMove(name, 0, Time[maxBar+shift], mem[maxBar])){ Alert( "ObjectMove(",name,") [2] failed: ", GetLastError()); return;} } }
Try this:
//+------------------------------------------------------------------+ //| EA equivalent of indicator buffers | //+------------------------------------------------------------------+ /* Example 1: * if (...) Ordermodify(...); * Polyline("SL"+(oo.ticket%99), oo.SL, Color.Dn, 0); * * Example 2: * double ELineCurr = iMA(NULL,0, ELine.Period, 0, MODE_EMA, PRICE_CLOSE, 1); * Polyline("ELine", ELineCurr, Color.ELine, 1); ******************************************************************************/ #define POLYLINE_MAX 20 // Must match priceXX double price00[], price01[], price02[], price03[], price04[], // \ Export price05[], price06[], price07[], price08[], price09[], // \ from price10[], price11[], price12[], price13[], price14[], // | Polyline price15[], price16[], price17[], price18[], price19[]; // | int LRU[POLYLINE_MAX], segNo[POLYLINE_MAX]; // > Import to string lineName[POLYLINE_MAX]; // _/ PLHelper datetime time0[POLYLINE_MAX]; void Polyline(string name, double price, color clr, int shift){ if (!Show.Objects) return; for (int idx=0; idx < POLYLINE_MAX; idx++){ LRU[idx]++; } for (idx=0; idx < POLYLINE_MAX; idx++){ bool new = lineName[idx] != name; if (!new) break; } if (new){ idx=ArrayMaximum(LRU); lineName[idx]=name; segNo[idx]=0; } LRU[idx] = 0; switch (idx){ case 0: PLHelper(name, price, clr, idx, new, shift, price00); return; case 1: PLHelper(name, price, clr, idx, new, shift, price01); return; case 2: PLHelper(name, price, clr, idx, new, shift, price02); return; case 3: PLHelper(name, price, clr, idx, new, shift, price03); return; case 4: PLHelper(name, price, clr, idx, new, shift, price04); return; case 5: PLHelper(name, price, clr, idx, new, shift, price05); return; case 6: PLHelper(name, price, clr, idx, new, shift, price06); return; case 7: PLHelper(name, price, clr, idx, new, shift, price07); return; case 8: PLHelper(name, price, clr, idx, new, shift, price08); return; case 9: PLHelper(name, price, clr, idx, new, shift, price09); return; case 10: PLHelper(name, price, clr, idx, new, shift, price10); return; case 11: PLHelper(name, price, clr, idx, new, shift, price11); return; case 12: PLHelper(name, price, clr, idx, new, shift, price12); return; case 13: PLHelper(name, price, clr, idx, new, shift, price13); return; case 14: PLHelper(name, price, clr, idx, new, shift, price14); return; case 15: PLHelper(name, price, clr, idx, new, shift, price15); return; case 16: PLHelper(name, price, clr, idx, new, shift, price16); return; case 17: PLHelper(name, price, clr, idx, new, shift, price17); return; case 18: PLHelper(name, price, clr, idx, new, shift, price18); return; case 19: PLHelper(name, price, clr, idx, new, shift, price19); return; } } void PLHelper( string name, double price, color clr, int idx, bool new , int shift, double& mem[] ){ datetime t0 = Time[shift]; int firstBar = ArraySize(mem); if (new){ t0 += 60*Period(); firstBar=0; } if (new || t0 != time0[idx]){ ArraySetAsSeries(mem, true); // Shift values m[2]=m[1]; m[1]=m[0] firstBar=ArrayResize(mem, firstBar+1)-1; if (firstBar < 0){ Alert( "ArrayResize failed: ",GetLastError()); return;} ArraySetAsSeries(mem, false); time0[idx]=Time[shift]; mem[0]=price; } else firstBar--; if (ObjectMove(name, 1, t0, price)) ObjectMove(name, 0, Time[shift+firstBar], mem[firstBar]); else if (!ObjectCreate( name, OBJ_TREND, WINDOW_MAIN , t0, price , Time[shift+firstBar], mem[firstBar] )){ Alert( "ObjectCreate(", name, "Trend) [1] failed: ",GetLastError()); return;} else if (!ObjectSet( name, OBJPROP_COLOR, clr )) Alert( "ObjectSet(", name, "Color) [2] failed: ", GetLastError()); else if (!ObjectSet( name, OBJPROP_RAY, false )) Alert( "ObjectSet(", name, "Ray) [1] failed: ", GetLastError()); double maxError=0; int maxBar; for (int pos=1; pos < firstBar; pos++){ double error=MathAbs(ObjectGetValueByShift(name, pos+shift)-mem[pos]); if (error > maxError){ maxError=error; maxBar=pos; } } if (maxError >= pips2dbl){ // Split the line into two segments at the max. segNo[idx]=(segNo[idx]+1)%1000; string newName=name+"-"+segNo[idx]; /**/ if (ObjectMove(newName, 0, Time[firstBar+shift], mem[firstBar])) ObjectMove(newName, 1, Time[maxBar +shift], mem[maxBar]); else if (!ObjectCreate( newName, OBJ_TREND, WINDOW_MAIN, Time[firstBar+shift], mem[firstBar], Time[maxBar +shift], mem[maxBar] )) Alert( "ObjectCreate(", newName, "Trend) [2] failed: ",GetLastError()); else if (!ObjectSet( newName, OBJPROP_COLOR, clr )) Alert( "ObjectSet(", newName, "Color) [3] failed: ", GetLastError()); else if (!ObjectSet( newName, OBJPROP_RAY, false )) Alert( "ObjectSet(", newName, "Ray) [2] failed: ", GetLastError()); ArrayResize(mem, maxBar+1); // Drop firstBar..(maxBar+1) if (!ObjectMove(name, 0, Time[maxBar+shift], mem[maxBar])) Alert( "ObjectMove(",name,") [2] failed: ", GetLastError()); } // Split the line into two segments at the max. } // PLHelper

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Ok,
I'm not a total noob to programming and I've been working with MQL4 on and off for a little while now....although not consistently enough I might add.
Here's the question. I have a couple EA's built and a few Custom Indicators and I would like changes made to the external variables of the EA to be reflected on the Chart visually....Please follow the steps below for example:
Steps:
1. Change Moving Average period from EA's external variables (This is passed in to the CustomIndicator during the iCustom call in order to determine trade conditions)
2. EA is now running using new value for Moving Average's period....I would like the chart in the window (Drawn by the CustomIndicator which has it's own external variables) to be redrawn to reflect the new variable values (in this case...the moving average period)
Am I confusing the issue here on how things should work?
Should I even be doing it this way?
Should both the EA and the CustomIndicator share one global External Variable Value????
Thanks...