Adding indicator calls to my shell EA's

The forum for experienced coders to upload their helpful hints, tips and lessons.
User avatar
SteveHopwood
Owner
Posts: 9904
Joined: Tue Nov 15, 2011 8:43 am
Location: Misterton - an insignificant village in England. Very pleasant to live in.

More to add to ReadIndicatorValues()

Post by SteveHopwood »

Go back to ReadIndicatorValues(), to the end of the code you have added previously.

I have detected buy and sell signals, but these will in turn be cancelled after I add higher time frame CCA and Stochastic, and either of these filters do not allow a trade. I often have to code systems where one signal will close an opposite direction trade. This snippet is all about OCO stuff:

Code: Select all

   //Close trades on an opposite direction signal
   BuyCloseSignal = false;
   SellCloseSignal = false;
   
   if (BuySignal)
      SellCloseSignal = true;
   
   if (SellSignal)
      BuyCloseSignal = true;
Copy the snippet underneath the code that detects a trade signal.

That is usually ReadIndicatorValues() finished but LC does not want a trade opening during the same candle that saw a trade close. Copy this snippet to finish off ReadIndicatorValues()

Code: Select all

   /////////////////////////////////////////////////////////////////////////////////////
   //Anything else?
   
   //We do not want a trade sending if one has already closed during this candle.
   if (BuySignal)
      if (HasTradeAlreadyClosed(Symbol(), OP_BUY) )
      {
         BuySignal = false;
         return;//Nothing more to do
      }//if (HasTradeAlreadyClosed(OP_BUY) )
      
   if (SellSignal)
      if (HasTradeAlreadyClosed(Symbol(), OP_SELL) )
      {
         SellSignal = false;
      }//if (HasTradeAlreadyClosed(OP_SELL) )
 
The snippet above calls HasTradeAlreadyClosed(int type) , so copy this function somewhere - doesn't matter where so long as it is outside any other function.

Code: Select all

bool HasTradeAlreadyClosed(string symbol, int type)
{

   //Look at the trades in the History tab. Return 'true' if a trade closed
   //during the current candle, else return 'false'
   
   if (OrdersHistoryTotal() == 0)
      return(false);

   for (int cc = OrdersHistoryTotal() - 1; cc >= 0; cc--)
   {
      if (!OrderSelect(cc, SELECT_BY_POS, MODE_TRADES) ) continue;
      if (OrderSymbol() != symbol ) continue;
      if (OrderMagicNumber() != MagicNumber) continue;
      if (OrderType() != type) continue;
      
      //We find a trade that closed during the current candle
      //by comparing its close time with the open time of the candle.
      if (OrderCloseTime() >= iTime(symbol, TradingTimeFrame, 0) )  
         return(true);

   }//for (int cc = OrdersHistoryTotal() - 1; cc >= 0; cc--)

   //Got this far, so no relevant trade found
   return(false);
   
}//bool HasTradeAlreadyClosed(int type)
In case you are new to all this, learning as you go along and are feeling massively insecure, here is the entire ReadIndicatorValues() function:

Code: Select all

void ReadIndicatorValues()
{

    int cc = 0;
   
   //Declare a shift for use with indicators.
   int shift = 0;
   if (!EveryTickMode)
   {
      shift = 1;
   }//if (!EveryTickMode)
   
   //Declare a datetime variable to force cca reading only at the open of a new candle.
   static datetime OldCcaReadTime = 0;
   //Accommodate every tick mode
   if (EveryTickMode)
      OldCcaReadTime = 0;
   
   //Allow easy experimentation.
   //shift = 2;
      
   //Read the indi
   if (OldCcaReadTime != iTime(Symbol(), TradingTimeFrame, 0) )
   {
      OldCcaReadTime = iTime(Symbol(), TradingTimeFrame, 0);
      
      //Is the line green at shift?
      StepMaColour[1] = green;
      //Or is it red? The indi returns EMPTY_VALUE when the line is green.
      double val = GetStupidStep(Symbol(), TradingTimeFrame, StepSensitivity, StepSize,
                                 StepShift, StepPrice, 1, shift);
      //It returns a price if brown
      if (!CloseEnough(val, EMPTY_VALUE) )
         StepMaColour[1] = red;

      //Is the line green at shift  1?
      StepMaColour[2] = green;
      //Or is it red? The indi returns EMPTY_VALUE when the line is green.
      val = GetStupidStep(Symbol(), TradingTimeFrame, StepSensitivity, StepSize,
                                 StepShift, StepPrice, 1, shift + 1);
      //It returns a price if brown
      if (!CloseEnough(val, EMPTY_VALUE) )
         StepMaColour[2] = red;

      //What is the colour change status of the line?
      //Is it all green?
      if (StepMaColour[2] == green && StepMaColour[1] == green)
         StepMaChangeStatus = allgreen;
      
      //Is it all red?
      if (StepMaColour[2] == red && StepMaColour[1] == red)
         StepMaChangeStatus = allred;
      
      //Has it changed red to green?
      if (StepMaColour[2] == red && StepMaColour[1] == green)
         StepMaChangeStatus = justturnedgreen;
      
      //Has it changed green to red?
      if (StepMaColour[2] == green && StepMaColour[1] == red)
         StepMaChangeStatus = justturnedred;

   }//if (OldCcaReadTime != iTime(Symbol(), TradingTimeFrame, 0) )
   
   /////////////////////////////////////////////////////////////////////////////////////
   //IN HERE GOES CODE TO CALL OTHER CCA'S. I SHALL ADD THIS LATER
   
   /////////////////////////////////////////////////////////////////////////////////////
   
   /////////////////////////////////////////////////////////////////////////////////////
   //Now to calculate whether we have a trade signal or not. I do this
   //by combining all the indi's used by the trading system.
   //Turn off any previous signal
   BuySignal = false;
   SellSignal = false;
   
   //Look for a Buy signal
   if (StepMaChangeStatus == justturnedgreen)
      BuySignal = true;
      
   //Look for a sell signal
   if (!BuySignal)
      if (StepMaChangeStatus == justturnedred)
         SellSignal = true;   

   //Close trades on an opposite direction signal
   BuyCloseSignal = false;
   SellCloseSignal = false;
   
   if (BuySignal)
      SellCloseSignal = true;
   
   if (SellSignal)
      BuyCloseSignal = true;

   /////////////////////////////////////////////////////////////////////////////////////
   //Anything else?
   
   //We do not want a trade sending if one has already closed during this candle.
   if (BuySignal)
      if (HasTradeAlreadyClosed(Symbol(), OP_BUY) )
      {
         BuySignal = false;
         return;//Nothing more to do
      }//if (HasTradeAlreadyClosed(OP_BUY) )
      
   if (SellSignal)
      if (HasTradeAlreadyClosed(Symbol(), OP_SELL) )
      {
         SellSignal = false;
      }//if (HasTradeAlreadyClosed(OP_SELL) )
      
   
   
   /////////////////////////////////////////////////////////////////////////////////////
   
   
   
}//End void ReadIndicatorValues()

Next up: editing LookForTradeClosure()

:xm:
Read the effing manual, ok?

Afterprime is the official SHF broker. Read about them at https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=175790#p175790.

I still suffer from OCCD. Good thing, really.

Anyone here feeling generous? My paypal account is always in the market for a tiny donation. pianodoodler@hotmail.com is the account.

To see The Weekly Roundup of stuff you guys might have missed Click here

My special thanks to Thomas (tomele) for all the incredible work he does here.
User avatar
SteveHopwood
Owner
Posts: 9904
Joined: Tue Nov 15, 2011 8:43 am
Location: Misterton - an insignificant village in England. Very pleasant to live in.

Editing LookForTradeClosure()

Post by SteveHopwood »

The function that keeps track of the trading position is CountOpenTrades().

CountOpenTrades() includes a call to the LookForTradeClosure().

LookForTradeClosure() includes any special closure requirements. Here, I only need a trade closing on an opposite direction signal and this is already taken care of by the LookForTradeClosure() function in the latest shell versions.

If you are using an older version, just copy paste the entire function over the top of the existing one.

Code: Select all

bool LookForTradeClosure(int ticket)
{
   //Close the trade if the close conditions are met.
   //Called from within CountOpenTrades(). Returns true if a close is needed and succeeds, so that COT can increment cc,
   //else returns false

   if(!OrderSelect(ticket, SELECT_BY_TICKET) ) return(true);
   if(OrderSelect(ticket, SELECT_BY_TICKET) && OrderCloseTime() > 0) return(true);

   bool CloseThisTrade=false;

   string LineName=TpPrefix+DoubleToStr(ticket,0);
   //Work with the lines on the chart that represent the hidden tp/sl
   double take=ObjectGet(LineName,OBJPROP_PRICE1);
   if(CloseEnough(take,0)) take=OrderTakeProfit();
   LineName=SlPrefix+DoubleToStr(ticket,0);
   double stop=ObjectGet(LineName,OBJPROP_PRICE1);
   if(CloseEnough(stop,0)) stop=OrderStopLoss();

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
   if(OrderType()==OP_BUY)
   {
      //TP
      if(Bid>=take && !CloseEnough(take,0) && !CloseEnough(take,OrderTakeProfit())) CloseThisTrade=true;
      //SL
      if(Bid<=stop && !CloseEnough(stop,0) && !CloseEnough(stop,OrderStopLoss())) CloseThisTrade=true;

      //Close a trade on an opposite direction signal
      if (BuyCloseSignal)
         CloseThisTrade = true;
         
   }//if (OrderType() == OP_BUY)

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
   if(OrderType()==OP_SELL)
   {
      //TP
      if(Bid<=take && !CloseEnough(take,0) && !CloseEnough(take,OrderTakeProfit())) CloseThisTrade=true;
      //SL
      if(Bid>=stop && !CloseEnough(stop,0) && !CloseEnough(stop,OrderStopLoss())) CloseThisTrade=true;

      //Close a trade on an opposite direction signal
      if (SellCloseSignal)
         CloseThisTrade = true;

   }//if (OrderType() == OP_SELL)

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////
   
   if (CloseThisTrade)
   {
         bool result = CloseOrder(ticket);
      //Actions when trade close succeeds
      if (result)
      {
         DeletePendingPriceLines();
         TicketNo = -1;//TicketNo is the most recently trade opened, so this might need editing in a multi-trade EA
         OpenTrades--;//Rather than OpenTrades = 0 to cater for multi-trade EA's
         return(true);//Makes CountOpenTrades increment cc to avoid missing out ccounting a trade
      }//if (result)
   
      //Actions when trade close fails
      if (!result)
      {
         OldBarsTime = 0;//Allow a retry at the next tick to allow the EA to send a trade
         return(false);//Do not increment cc
      }//if (!result)
   }//if (CloseThisTrade)
   
   //Got this far, so no trade closure
   return(false);//Do not increment cc

}//End bool LookForTradeClosure()

Next up: mopping up

:xm:
Read the effing manual, ok?

Afterprime is the official SHF broker. Read about them at https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=175790#p175790.

I still suffer from OCCD. Good thing, really.

Anyone here feeling generous? My paypal account is always in the market for a tiny donation. pianodoodler@hotmail.com is the account.

To see The Weekly Roundup of stuff you guys might have missed Click here

My special thanks to Thomas (tomele) for all the incredible work he does here.
User avatar
SteveHopwood
Owner
Posts: 9904
Joined: Tue Nov 15, 2011 8:43 am
Location: Misterton - an insignificant village in England. Very pleasant to live in.

Mopping up

Post by SteveHopwood »

Steppy is complete so far as I understand Little Caro was attempting, so I have attached it so I can refer to line numbers in the .mq4 source code.
  • Line 135: time frame defaults to LC's preferred M15.
  • Line 136: EveryTickMode is a key input.
    • if 'true', the EA works in the here and now and compares indi values now with those of Close(1).
    • if 'false', the EA works with values and prices at the close of Close(1) and Close(2).
  • line 542 ensures that an ea that trades at the open of a new candle does not take a trade as soon as it is loaded. I often have this commented out when developing an EA.
  • add anything new that is necessary to CountOpenTrades() and IsTradingAllowed()
  • in OnTick(), make sure that CountOpenTrades() and ReadIndicatorValues() are called in the correct order. Steppy needs ReadIndicatorValues() called first so that LookForTradeClosure() operates properly when called from CountOpenTrades().
  • line 2533+: make any necessary edits to the 'Trading' code block.
Any EA created using my shells will contain a lot of redundant code. Don't worry about it.

I have shown you how to add an indicator to my Buggger All Included shell. You follow exactly the same procedure when using the other two; the additional features happen automatically - I never even think about them apart from setting default values.

Next up: adding higher time frame CCA consideration.

:xm:
You do not have the required permissions to view the files attached to this post.
Read the effing manual, ok?

Afterprime is the official SHF broker. Read about them at https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=175790#p175790.

I still suffer from OCCD. Good thing, really.

Anyone here feeling generous? My paypal account is always in the market for a tiny donation. pianodoodler@hotmail.com is the account.

To see The Weekly Roundup of stuff you guys might have missed Click here

My special thanks to Thomas (tomele) for all the incredible work he does here.
User avatar
SteveHopwood
Owner
Posts: 9904
Joined: Tue Nov 15, 2011 8:43 am
Location: Misterton - an insignificant village in England. Very pleasant to live in.

Adding higher time frame CCA consideration

Post by SteveHopwood »

I just know when coding an EA for the sort of CCA that we are using here, that somewhere down the line I will be asked to add a higher time frame filter. Usually I add this at the start to save some trouble later, but I am using Steppy for a different purpose.

Steppy with htf consideration is attached. Look at line 158:
string HigherTimeFrameDisplay="";
This is for the htf display on the chart.

Look at line 179+

Code: Select all

extern string  StepSet = "------- STEP MA SETTINGS --------";
extern string  ss1="-- Trading time frame --";
extern double  TtfStepSensitivity        = 0.12;        // Sensivity factor (higher -> more senzitive)
extern double  TtfStepSize           = 1;          // Constant step size
extern int     TtfStepShift              = 0;          // Shift
extern ENUM_APPLIED_PRICE TtfStepPrice = 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
*/
extern string  ss2="-- Higher time frame --";
extern bool    UseHtfStep=true;
extern ENUM_TIMEFRAMES HtfTimeFrame=PERIOD_H1;
extern double  HtfStepSensitivity        = 0.12;        // Sensivity factor (higher -> more senzitive)
extern double  HtfStepSize           = 1;          // Constant step size
extern int     HtfStepShift              = 0;          // Shift
extern ENUM_APPLIED_PRICE HtfStepPrice = PRICE_TYPICAL; // Price to use 
////////////////////////////////////////////////////////////////////////////////////////
//Declare strings to hold the line colour
string         TtfStepMaColour[3];//For shift 1 and 2. Will be one of the colour constants
                               //from line 23+
string         HtfStepMaColour;//I only need one value                               
//String to hold the change status of the line
string         TtfStepMaChangeStatus="";//Will be one of the status change constants at line 28+
////////////////////////////////////////////////////////////////////////////////////////
The original inputs now have Ttf placed in front of them. There is another bunch of inputs that are the same apart from having 'Htf' at their start, plus a boolean to turn this filter on and off and an ENUM for the htf.

The DisplayUserFeedback() ending at line 356 has this appended:

Code: Select all

if (UseHtfStep)
      SM("Higher time frame step colour" + HtfStepMaColour + ": Higher time frame " 
         + HigherTimeFrameDisplay + NL);
    
I have coded the htf CCA filter so that Steppy should only take a trade if the trade signal accords with the htf line. This line must be green for a buy and red for a sell. I have added this code at line 1425:

Code: Select all

      //Higher time frame CCA. I will obtain its value at the most recent tick
      if (UseHtfStep)
      {
         HtfStepMaColour = green;
         //Or is it red? The indi returns EMPTY_VALUE when the line is green.
         val = GetStupidStep(Symbol(), HtfTimeFrame, HtfStepSensitivity, HtfStepSize,
                                    HtfStepShift, HtfStepPrice, 1, 0);
         //It returns a price if brown
         if (!CloseEnough(val, EMPTY_VALUE) )
            HtfStepMaColour = red;
      }//if (UseHtfStep)
  
Then the trade signal spotting code looks like this:

Code: Select all

/////////////////////////////////////////////////////////////////////////////////////
   //Now to calculate whether we have a trade signal or not. I do this
   //by combining all the indi's used by the trading system.
   //Turn off any previous signal
   BuySignal = false;
   SellSignal = false;
   
   //Look for a Buy signal
   if (TtfStepMaChangeStatus == justturnedgreen)
      if (!UseHtfStep || HtfStepMaColour == green)
         BuySignal = true;
      
   //Look for a sell signal
   if (!BuySignal)
      if (TtfStepMaChangeStatus == justturnedred)
         if (!UseHtfStep || HtfStepMaColour == red)
            SellSignal = true;   

   //Close trades on an opposite direction signal
   BuyCloseSignal = false;
   SellCloseSignal = false;
   
   if (BuySignal)
      SellCloseSignal = true;
   
   if (SellSignal)
      BuyCloseSignal = true;

   /////////////////////////////////////////////////////////////////////////////////////
   
There you are. It is that simple.

Next up: adding one of the standard Empty4 indicators

:xm:
You do not have the required permissions to view the files attached to this post.
Read the effing manual, ok?

Afterprime is the official SHF broker. Read about them at https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=175790#p175790.

I still suffer from OCCD. Good thing, really.

Anyone here feeling generous? My paypal account is always in the market for a tiny donation. pianodoodler@hotmail.com is the account.

To see The Weekly Roundup of stuff you guys might have missed Click here

My special thanks to Thomas (tomele) for all the incredible work he does here.
User avatar
SteveHopwood
Owner
Posts: 9904
Joined: Tue Nov 15, 2011 8:43 am
Location: Misterton - an insignificant village in England. Very pleasant to live in.

Adding one of the standard Empty4 indicators

Post by SteveHopwood »

Adding any of the usual Empty4 indicators is no harder than is adding a CCA.

I have added Stochastic to Steppy. I have programmed him to: buy when Stoch is >= 50 and < 80; sell when <50 and > 20. All these levels are user inputs.

This gave me four possible states for Stoch, so here are the constants beginning at line 21

Code: Select all

//Declare some constants for Stochastic
#define  stochinbuyarea ": In the buy area"
#define  stochinsellarea ": In the sell area"
#define  stochoverbought ": Overbought"
#define  stochoversold ": Oversold"
The user inputs and my declared variables begin at line 217:

Code: Select all

extern string   sto="---- Stochastic inputs ----";
extern bool     UseStochastic=true;
extern ENUM_TIMEFRAMES StochTF=PERIOD_M15;
extern int      StochK = 5;
extern int      StochD = 3;
extern int      StochSlowing = 3;
extern ENUM_STO_PRICE StochPriceField=STO_LOWHIGH;
extern ENUM_MA_METHOD StochMaMethod=MODE_SMA;
extern string   sti="Mode: 0 = Main: 1 = Signal";
extern int      StochMode=0;
extern int      StochBuyAbove=50;//Buy at or above this
extern int      StochOverBought=80;
extern int      StochSellBelow=50;//Sell below this
extern int      StochOverSold=20;
////////////////////////////////////////////////////////////////////////////////////////
string          StochStatus;//Will use one of the constants defined at the top of this file
double          StochVal=0;
////////////////////////////////////////////////////////////////////////////////////////
The value displayed on the chart is that of the candle open, or latest tick following a restart, and is there only so that I can check that my code is producing the correct value.

I cannot find an ENUM for Stoch's mode, so I have used an integer instead.

StochBuyAbove etc offer users the ability to set their own limits.

The chart display starts at line 386;

GetStochastic() starts at line 1388:

Code: Select all

double GetStochastic(string symbol, int tf, int k, int d, int slowing, int method, int pf, int mode,int shift)
{
         
   return(iStochastic(symbol,tf,k,d,slowing,method,pf,mode,shift));
   
}//End double GetStochastic(int tf, int shift, int mode)
Stochastic is not a 'custom indicator'; it is one that is shipped with the platform and these have their own calls. These calls always start with 'i', as in iStochastic(), iMA() for moving averages etc. The easiest way to find the indy identifier is to google iStochastic and follow the first link to the Mql4 documentation; there is a list of the identifiers down the left of the page.

The code block that reads Stochastic and calculates which of the four states it can be in, starts at line 1471:

Code: Select all

      //Stochastic
      if (UseStochastic)
      {
         //Read stochastic at the open of the new candle
         StochVal = GetStochastic(Symbol(), StochTF, StochK, StochD, StochSlowing,
                                  StochMaMethod, StochPriceField, StochMode, 0);
         
         //Define stoch status
         //Overbought
         if (StochVal >= StochOverBought)
            StochStatus = stochoverbought;
            
         //Oversold
         if (StochVal <= StochOverSold)
            StochStatus = stochoversold;
            
         //In the buy area
         if (StochVal >= StochBuyAbove)
            if (StochVal < StochOverBought)
               StochStatus = stochinbuyarea;
            
         //In the sell area
         if (StochVal < StochSellBelow)
            if (StochVal > StochOverSold)
               StochStatus = stochinsellarea;
            
            
      }//if (UseStochastic)
The Buy/Sell signal detection code starts at line 1504 and now has reference to the Stoch filter:

Code: Select all

   /////////////////////////////////////////////////////////////////////////////////////
   //Now to calculate whether we have a trade signal or not. I do this
   //by combining all the indi's used by the trading system.
   //Turn off any previous signal
   BuySignal = false;
   SellSignal = false;
   
   //Look for a Buy signal
   if (TtfStepMaChangeStatus == justturnedgreen)
      if (!UseHtfStep || HtfStepMaColour == green)
         if (!UseStochastic || StochStatus == stochinbuyarea)
            BuySignal = true;
      
   //Look for a sell signal
   if (!BuySignal)
      if (TtfStepMaChangeStatus == justturnedred)
         if (!UseHtfStep || HtfStepMaColour == red)
            if (!UseStochastic || StochStatus == stochinsellarea)
               SellSignal = true;   

   //Close trades on an opposite direction signal
   BuyCloseSignal = false;
   SellCloseSignal = false;
   
   if (BuySignal)
      SellCloseSignal = true;
   
   if (SellSignal)
      BuyCloseSignal = true;

That's it. A lot of explanation for something that is simple, but only when you know how. I am not telling people how to code. I am explaining how I incorporate indicator calls into my shell EA's.

Adding them to the "Bare Bones" and "Bob stuff" versions is exactly the same. Optional features in "Bob stuff" such as Slope and CSS happen automatically. The code to read them is in ReadIndicatorValues() but the code that consults their values is in LookForTradingOpportunities() and cancels an impending trade should they not be correct for trading. I will move it to ReadIndicatorValues() for consistency some time, but I know where it is and so never think about it.

Steppy final version is attached. He will have bugs. I don't care. I coded him as training in how I use my shells - I would not even bother to have bad dreams about trading him. Set him up on demo if you want and debug him yourself - that will be good learning for you. Start your own thread about him if you want - just don't tell me about bugs here.

I am going to reserve one more post for hints and tips for beginner coders, then I shall unlock this thread. Feel free to ask questions about anything you do not understand - I do not guarantee to answer them but there is no harm in trying.

Have fun.

:xm:
You do not have the required permissions to view the files attached to this post.
Read the effing manual, ok?

Afterprime is the official SHF broker. Read about them at https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=175790#p175790.

I still suffer from OCCD. Good thing, really.

Anyone here feeling generous? My paypal account is always in the market for a tiny donation. pianodoodler@hotmail.com is the account.

To see The Weekly Roundup of stuff you guys might have missed Click here

My special thanks to Thomas (tomele) for all the incredible work he does here.
User avatar
SteveHopwood
Owner
Posts: 9904
Joined: Tue Nov 15, 2011 8:43 am
Location: Misterton - an insignificant village in England. Very pleasant to live in.

Hints and tips for beginner coders

Post by SteveHopwood »

Here are some tips for those of you just starting to code and trying to use my shells. These are not for the Proper Coders here - those guys are awesome and were born having forgotten more about programming than you or I will ever learn. They are thingies that help keep me from having to spend too many hours hunting down that bloody missing bracket..........................
-----------------------------------------------------------------------------------------

Comment absolutely everything. Code whose meaning and purpose is blindingly clear now will not appear so in 3 months time - or 3 weeks in my case.

You also have others to consider when sharing your code, especially when asking for help. You may think your code is so crystal clear that a 3 year old could read it, but nobody else will agree.
------------------------------------------------------------------

BuySignal is a Boolean so,
  • if (BuySignal) and if (BuySignal == true) mean the same thing.
  • if (!BuySignal) and if (BuySignal == false) mean the same thing.
----------------------------------------------------------------

The correct way to test if one variable is not equal to another is this:
if (var1 != var2)
--------------------------------------------------------------

If you do not fully grasp operator precedence, then use extra brackets for certainty. For example, if you are not sure if
double take = Ask + TakeProfit * factor;
will give the correct result, then make certain. Code within brackets is always parsed first, so
double take = Ask + (TakeProfit * factor) ;
will give the correct result. You can see from my code that I am clueless about operator precedence.
-------------------------------------------------------------

You have multiple conditions that must be met for an action to take place.
This construct:

Code: Select all

   if (condition1)
      if (condition2)
         if condition3)
            Do something;
and this construct

Code: Select all

   if (condition1 && condition2 && condition3)
      Do something;         
achieve the same result, but there is a piece of lunacy built into CrapQl4. If you use the (x && x && x) construct then the three conditions are checked even if either of the first two fail.

In the construct where each condition is tested separately, program control is passed to the next code block the instant any of the conditions fails. This can amount to a considerable cpu saving if you have multiple instances of an ea running.
------------------------------------------------------------------

Don't forget to use curly braces if you require more than one instruction to be carried out if a construct passes all the tests. For example, you forget the curly braces in this construct:

Code: Select all

   if (condition1)
      if (condition2)
         if condition3)
            Do something;
            Do something else;
will cause the 'Do something else' instruction to be followed even though some of the three conditions failed. 'Do something'; concludes the code block, so 'Do something else' is the next code block so far as the compiler is concerned. Here is where the curly braces come in:

Code: Select all

   if (condition1)
      if (condition2)
         if condition3)
         {
            Do something;
            Do something else;
         }//if condition3)         
The braces make it clear that the two lines of instructions are only to be implemented if all conditions fail.
----------------------------------------------------------------------------------------

I use the comment in the above snippet as it helps me read my own code. I know which closing brace applies to which opening brace. You will see what I mean immediately when you meet your first block of conditionals inside conditionals inside conditionals........ and haven't a clue which closing brace matches which opening brace.
----------------------------------------------------------------------------------------

You have a conditional or a loop. Outline the block first, before starting to fill it in and compile to make sure you have not got something wrong. Imagine that several instructions have to be followed out if a conditional passes. Outline your block first:
if (some condition)
{

}//if (some condition)
then compile to make sure you have not mucked up right from the start.

----------------------------------------------------------------------------------------
Compile regularly. I compile after every block outline then typing every line of code within the block.

You will discover why the first time you spend two hours hacking in code without compiling, then have to spend two days hunting down where you went wrong and all the compiler is telling you the the program has come to an unexpected end at line 2344. You will not be best pleased when you find that you missed out a bracket at line 133. Trust me in this, you really, really won't.
-----------------------------------------------------------------------------------------

Avoid complicated equations and split them up into readable chunks instead. Yes, complicated equations look really clever and make you feel really good, but they are a bugger to sort out if there is something wrong. Guess how I know?
-----------------------------------------------------------------------------------------
Read the effing manual, ok?

Afterprime is the official SHF broker. Read about them at https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=175790#p175790.

I still suffer from OCCD. Good thing, really.

Anyone here feeling generous? My paypal account is always in the market for a tiny donation. pianodoodler@hotmail.com is the account.

To see The Weekly Roundup of stuff you guys might have missed Click here

My special thanks to Thomas (tomele) for all the incredible work he does here.
User avatar
FxEon
Posts: 1
Joined: Sun Apr 12, 2015 5:18 pm
Location: Vanderbijlpark, South Africa

Adding indicator calls to my shell EA's

Post by FxEon »

Thanks for this Steve.

I normally code low-level embedded systems using assembler and C/C++.
So I have an idea of what's going on with the programming but i need to learn/understand how to use the Empty4 environment properly.
Your coding structure (with the comments) makes it easy to see what your up to and accelerates learning exponentially.
Was busy breaking down the shell ea function calls to get a handle on program flow.
Its easier for me if I can get a flowchart view of code execution and function calling.

So this write-up on the indicator calls, decision making and trade execution is extremely useful to me as it saves me two weeks of figuring things out.
Have until end January to apply myself to this, then back to being busy surviving life.

Again, thank you for the time you spent to make this readable and easy to understand and also for making this available to beginner fx coders.

Regards, Eben
User avatar
SteveHopwood
Owner
Posts: 9904
Joined: Tue Nov 15, 2011 8:43 am
Location: Misterton - an insignificant village in England. Very pleasant to live in.

Adding indicator calls to my shell EA's

Post by SteveHopwood »

FxEon » Wed Dec 09, 2015 1:49 pm wrote:Thanks for this Steve.

I normally code low-level embedded systems using assembler and C/C++.
So I have an idea of what's going on with the programming but i need to learn/understand how to use the Empty4 environment properly.
Your coding structure (with the comments) makes it easy to see what your up to and accelerates learning exponentially.
Was busy breaking down the shell ea function calls to get a handle on program flow.
Its easier for me if I can get a flowchart view of code execution and function calling.

So this write-up on the indicator calls, decision making and trade execution is extremely useful to me as it saves me two weeks of figuring things out.
Have until end January to apply myself to this, then back to being busy surviving life.

Again, thank you for the time you spent to make this readable and easy to understand and also for making this available to beginner fx coders.

Regards, Eben
You are most welcome Eben. Thanks for your kind words.

One of the mistakes I made whilst writing the tutorial was to leave the trade signal detection code outside the indicator reading construct, which needs to be:

Code: Select all

   //Read the indi
   if (OldCcaReadTime != iTime(Symbol(), TradingTimeFrame, 0) )
   {
      OldCcaReadTime = iTime(Symbol(), TradingTimeFrame, 0);

      Indi reading stuff

      Trade signal detection

   }//if (OldCcaReadTime != iTime(Symbol(), TradingTimeFrame, 0) )
You would have worked that out for yourself quickly enough. I mention it just to save you some brain pain.

I have uploaded my latest shell versions to the shell thread, with the corrected construct.

As a C/C++ coder, you will find CrapQl4 a doddle.

:xm:
Read the effing manual, ok?

Afterprime is the official SHF broker. Read about them at https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=175790#p175790.

I still suffer from OCCD. Good thing, really.

Anyone here feeling generous? My paypal account is always in the market for a tiny donation. pianodoodler@hotmail.com is the account.

To see The Weekly Roundup of stuff you guys might have missed Click here

My special thanks to Thomas (tomele) for all the incredible work he does here.
zaguy
Trader
Posts: 43
Joined: Wed Feb 03, 2016 7:42 am

Adding indicator calls to my shell EA's

Post by zaguy »

Hello Steve. Thank you for also making it possible for dimwits like me to try and learn some coding. I have been playing around with the coding of some of your recent EAs to see the result in backtesting. I am a newbie to coding (not so much new to forex - but still have a heck of a lot to learn - and your forum has been a great help). Mtw. I have not been involved in Forex for a few years, but remembered you from FF and managed, through Google, to find this amazing forum.

I want try something with your "BOB 'n Grid and his ma" EA, but cannot figure out how to do it. If you can assist with the coding, it would be greatly appreciated - although it might just be a waste of time! I want to try out the following:
1. With the triggering of the main trade, 3 pending orders are placed in a grid in the direction of the trade, x pip distance from the main trade and each other, but each trade allowing user input for lot sizes. Eg. Main trade = 0.04 lots, 1st pending trade = 0.03, 2nd pending trade = 0.02 and 3rd pending trade = 0.01. Thank you.

I have also read about another strategy that might be interested to look at? - and have attached documents for perusing (it is freely available from a guy called Jordan Lindsey (JCL's Forex, http://www.forextrading.jcls-forex.com). Mayeb we can try it on your trend EAs?
You do not have the required permissions to view the files attached to this post.
User avatar
SteveHopwood
Owner
Posts: 9904
Joined: Tue Nov 15, 2011 8:43 am
Location: Misterton - an insignificant village in England. Very pleasant to live in.

Adding indicator calls to my shell EA's

Post by SteveHopwood »

zaguy » Sun Feb 21, 2016 6:40 pm wrote:Hello Steve. Thank you for also making it possible for dimwits like me to try and learn some coding. I have been playing around with the coding of some of your recent EAs to see the result in backtesting. I am a newbie to coding (not so much new to forex - but still have a heck of a lot to learn - and your forum has been a great help). Mtw. I have not been involved in Forex for a few years, but remembered you from FF and managed, through Google, to find this amazing forum.

I want try something with your "BOB 'n Grid and his ma" EA, but cannot figure out how to do it. If you can assist with the coding, it would be greatly appreciated - although it might just be a waste of time! I want to try out the following:
1. With the triggering of the main trade, 3 pending orders are placed in a grid in the direction of the trade, x pip distance from the main trade and each other, but each trade allowing user input for lot sizes. Eg. Main trade = 0.04 lots, 1st pending trade = 0.03, 2nd pending trade = 0.02 and 3rd pending trade = 0.01. Thank you.
The bot uses the OpenTrades variable to know how many trades there are on the individual chart, so go to void SendPendingMultipleBuyTrades(double price, string comment, int TradesAllowed), and then to line 2168, which is a blank line, and insert
OpenTrades = 1;

Then line 2181:
SendSingleTrade(Symbol(), OP_BUYSTOP, TradeComment, MultiTradeLot, price, stop, take);

Change this to
SendSingleTrade(Symbol(), OP_BUYSTOP, TradeComment, MultiTradeLot - (OpenTrades / 100), price, stop, take);
(or MainTradeLot - depends what you want to do)

Insert into the blank line at 2181:
OpenTrades++;

Same process for void SendPendingMultipleSellTrades(double price, string comment, int TradesAllowed)

I have not tested this, so try it and see.

:xm:
Read the effing manual, ok?

Afterprime is the official SHF broker. Read about them at https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?p=175790#p175790.

I still suffer from OCCD. Good thing, really.

Anyone here feeling generous? My paypal account is always in the market for a tiny donation. pianodoodler@hotmail.com is the account.

To see The Weekly Roundup of stuff you guys might have missed Click here

My special thanks to Thomas (tomele) for all the incredible work he does here.
Post Reply

Return to “Coding Lessons - info for all”