An EA interrogates a CCA with an iCustom() call.
The first thing I do is use my Experiments script to see if useful info can be dragged kicking and screaming from the CCA. It is attached and goes in your Scripts folder. No particular reason for calling it 'Experiments' - just did years and years ago and continued using it ever since. All of my coding conventions developed this way.
I code Experiments so that the code can be quickly and easily copied across to my shell ea. Download the script and open it in your code editor.
Note the commented out line 10:
//#property show_inputs
This prevents the inputs being shown when I drag the script - makes using it quicker. Remove the // if you want to see the inputs when you run the script.
Look at line 12
extern ENUM_TIMEFRAMES TradingTimeFrame=PERIOD_CURRENT;
PERIOD_CURRENT is a CrapQl4 'constant'. I love 'constants'. These look like variables but have a fixed value. PERIOD_CURRENT will hold the value of the current chart, and so strictly speaking is a variable I suppose. Don't care. PERIOD_M15 holds the value 15. PERIOD_D1 holds the value 1440. It is possible to define our own constants and my shells make great use of this, but more of that later.
I discovered ENUM a few weeks ago. It is glorious. In my head, this stands for 'enumerate'. By presenting the TradingTimeFrame as a member of the ENUM group, I present the user with a list of alternatives that cannot be inappropriate. Type ENUM into your editor and run help on it to see the extensive list of inputs this can cover.
My shells use TradingTimeFrame and all candle /indi values/times etc use it to allow the user to change time frames without disturbing the bot. I use it in this script so that I can code the calls to the indi in a way that is easily copied into the ea.
The iCustom call consists of:
- the chart symbol
- the required time frame
- the indi name without extension
- a list of parameters that match those that the indi shows in its inputs window
- the buffer the ea is interrogating
- the candle shift relative to the current candle. 0 = now; 2 = the close 2 candles ago etc
We need a list of inputs in our ea that matches those of the CCA. Look at line 14+ in the Experiments script code (line 1 here):
Code: Select all
extern string StepSet = "------- STEP MA SETTINGS --------";
extern double StepSensitivity = 0.12; // Sensivity factor (higher -> more senzitive)
extern double StepSize = 1; // Constant step size
extern int StepShift = 0; // Shift
extern ENUM_APPLIED_PRICE StepPrice = PRICE_TYPICAL; // Price to use
/*
We do not need these externs, and will send 'false' as every parameter
extern bool alertsOn = false; // Turn alert on?
extern bool alertsOnCurrent = true; // Alerts on current bar?
extern bool alertsMessage = true; // Show popup message
extern bool alertsSound = false; // Play alert sound
extern bool alertsEmail = false; // Send email
extern bool alertsNotification = false; // Send notification
*/
I copied this list from the CCA and added the 'Step' bit to the externs that I allowing the user to see, just in case another indi has an input such as 'Shift', to differentiate between them.
I have gradually learned over the years, from the Proper Coders here at SHF, to make code as reusable as possible. My iCustom call is contained within the function beginning at line 30 in the source code (line numbers shown here are different):
Code: Select all
double GetStupidStep(string symbol, int tf, double sensi, double size, int sshift, int ap, int buffer, int shift)
{
/*
Passed parameters:
- symbol = chart symbol
- tf = time frame
- sensi = StepSensitivity
- size = StepSize
- sshift = StepShift
- ap = StepPrice
- buffer = the indi buffer being interrogated
- shift = the candle shift to the left relative to now. shift = 0 means now.
shift = 4 means 4 candles ago etc
*/
return(iCustom(symbol, tf, "StepMA new 1.05", sensi, size, sshift, ap,
false, false, false, false, false, false, buffer, shift));
}//End double GetStupidStep(string symbol, int tf, double sensi, double size, int sshft, int ap, int buffer, int shift)
My use of 'string symbol' makes this function more easily portable into a multi-pair ea. Adopt it and you will quickly find your fingers typing double val = Getxxxx(Symbol()........) automatically.
My coding convention is to precede any function that calls and indi with 'Get'. That way I know where to find them. Press Alt + M in your code editor to see a list of functions; clicking on them will take you straight to the code. There are only two script functions, but my ea's contain umpteen.
You can see in the commented out (grey) section of code what each passed parameter represents. The power of taking the trouble to spell out the parameters will become apparent when I add a higher time frame function to the EA.
Now I have my list of extern inputs and a function that will return a value from the indi in a variety of ways, so now we come to how I interrogate it.
Code: Select all
void OnStart()
{
//Declare a shift variable to make experimenting with the calls quick and easy
int shift = 0;
//Buffer 1 is empty when the line is green, so find out what value it returns.
//This will either be zero or the EMPTY_VALUE constant 2147483647
//The current line on my chart is green.
double val = GetStupidStep(Symbol(), TradingTimeFrame, StepSensitivity, StepSize,
StepShift, StepPrice, 1, shift);
Alert("Value of buffer 1 when green = ", val);
//This cca uses EMPTY_VALUE, so now check that buffer 1 holds a price when it prints brown.
//The line was brown 8 candles ago on my chart.
shift = 8;
val = GetStupidStep(Symbol(), TradingTimeFrame, StepSensitivity, StepSize,
StepShift, StepPrice, 1, shift);
Alert("Value of buffer 1 when brown = ", val);
//Interrogating the buffers returns usable values, so we can use the cca in an EA
}
I am referring now to line numbers in the source code, not as shown here. The OnStart function begins at line 57. I already know that buffer 1 holds a price to give a red line, and is empty for a green line. I have in front of me a chart where the line is currently green.
Line 61 declares shift as 0 so I am looking at the current candle. Line 66 sends a call to the CCA which shows me both that the buffer is empty and what it holds when empty in the Alert that is sent at line 66.
I can see that the line was red 8 candles ago, so line 73 sets shift to 8, line 74 makes the call and the Alert fired at line 77 confirms my assumption.
The reason for the Alert showing the empty field value is this: CCA coders use two methods:
- filling it with 0.
- filling it with EMPTY_VALUE.
EMPTY_VALUE is a constant with the value 2147483647. It is a price that no market can ever reach. Coding an EA, I need to know which method the ea coder uses to indicate an empty buffer. Trust me guys; when dealing with really badly coded CCA's, some will use both methods so I need to check all fields.
You can see from the comment at the end of the script that the CCA is usable within an EA. My next post will describe how I port the code across to the shell ea.
Edit 4th October 2016:
Bruce contributed the attached indi. Details in his post here:
http://www.stevehopwoodforex.com/phpBB3 ... 36#p147136
.
You do not have the required permissions to view the files attached to this post.