stevehopwoodforex.com
https://www.stevehopwoodforex.com/phpBB3/
Print view

Utility Procedures / Code Snippets
https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?t=166
Page 3 of 7
Author:  gaheitman [ Sat Feb 04, 2012 11:34 am ]
Post subject:  More Looping Considerations

The standard for loop looks something like this:

Code: Select all

for (int i=0;i<100;i++) {
  //do something 100 times (0-99), counting up
}

//or

for (int i=99;i>=0;i--) {
  //do something 100 times (99-0), counting down

}
Often we are iterating over an existing set of something: objects, trades, array items, etc. In these cases the number of items we iterate over is usually determined through a call to a function that returns the number of items (ObjectsTotal(), OrdersTotal(), ArraySize()).

When using these functions, it is common to include them in the for loop expressions, either in the initialization section or the conditional test. For example, to iterate over an array, we could do either

Code: Select all

//initialize array
int A[5]={1,2,3,4,5};

//iterate backwards
for (int i=ArraySize(A)-1;i>=0;i--)
   Print(A[i]);

//or 

//iterate forwards
for ( i=0; i < ArraySize(A);i++)
   Print(A[i]);
Other than the order of iteration, the major difference between the two is that ArraySize() is called once in the first loop and called 5 times in the second. The initialization portion of the loop is done once, but the conditional is re-evaluated every iteration. I suspect this isn't very costly when calling ArraySize(), but what about when calling OrdersTotal() or OrdersHistoryTotal()? Or even worse, our own functions like NumBarsClosingAboveAverage()?

The other concern is that sometimes the activity within the loop can change the number of items being iterated over. Deleting objects and closing orders comes to mind. In these cases, it's easy to miss out on evaluating items. Of course, if you are deleting items you should iterate over the list in reverse order anyway (but that's another post).

I recommend capturing the number of items you intend to iterate over into a temporary variable before the iteration. It should be faster and will likely have less troublesome bugs to track down.

Though there may be valid reasons to use a function call within the for loop's conditional expression, personally I think the code would be more readable if you structure the loop as a while loop instead of a for loop.

George
Author:  Tommy [ Thu Feb 23, 2012 5:43 am ]
Post subject:  Re: Utility Procedures / Code Snippets

Hi all, as I am clueless when it come to writing code, could anyone out there design a simple "market temperature" indicator based on the following idea:
if current bar closes higher than previous bar close then value = 2
if current bar closes lower than previous bar close then value = -2
if current bar closes equal to previous bar close then value = 0
if current bar closes higher than current bar open then value = 2
if current bar closes lower than current bar open then value = -2
if current bar closes equal to current bar open then value = 0
if current bar closes higher than previous bar high then value = 1
if current bar closes within previous bar high/low range then value = 0
if current bar closes lower than previous bar low then value = -1
The indicator line or histogram would need a max reading of 5, a minimum of -5 and zero in the middle. Cheers, Tommy.
PS please post the new indy on this forum so we can all try it out :D
Author:  dietcoke [ Thu Feb 23, 2012 1:35 pm ]
Post subject:  Some Functions I've found really useful

First up.

This is from one of Sqalou's ea's which is an elegant replacement for the multiplier code Steve uses for setting the pip mutliplier for 3 and 5 digit crims.

this just puts the various mutipliers in an array and the correct one is referenced with "Digits". Very Clever!

Code: Select all

int pipMult,pipMultTab[]={1,10,1,10,1,10,100,1000}; 
                                                                                            
double GetMultiplier()                                                                      
{                                                                                           
   return(pipMultTab[Digits]);                                                              
}                                                                                           
Then in your EA,

Code: Select all

int multiplier = GetMultiplier();
//OR
BreakevenPips *= GetMultiplier();
Author:  dietcoke [ Thu Feb 23, 2012 1:39 pm ]
Post subject:  Re: Utility Procedures / Code Snippets

This is a std deleter for mutiple objects. All they need is unique key at the same position in the object name(usually at the beginning).

This is great for tidying up just the objects you want to delete in the deinit().

I've found the best way to use this is to create all your objects with the same prefix e.g "My_EA"

then to delete them you use:

del_obj("My_EA");

Code: Select all

//+------------------------------------------------------------------+              
//| del_obj(string key)                                                             
//| deletes all object with a name containing  "key"                             
//+------------------------------------------------------------------+              
void del_obj(string key, int StartPos = 0)                                          
{                                                                                   
                                                                                   
   int k=0;
   
   while (k<ObjectsTotal())                                                         
   {                                                                                
      string objname = ObjectName(k);                                               
      if (StringSubstr(objname,StartPos,StringLen(key)- StartPos) == key)           
      {                                                                             
         ObjectDelete(objname);                                                     
      }                                                                             
      else                                                                          
      {                                                                             
         k++;                                                                       
      }                                                                             
   }                                                    
   return(0);                                                                       
}                                                
Author:  dietcoke [ Thu Feb 23, 2012 1:43 pm ]
Post subject:  Re: Utility Procedures / Code Snippets

These just make working with GlobalVariables easier on the fingers. There are functions which replicate
GlobalVariableGet
GlobalVariableSet
GlobalVariableCheck
GlobalVariableDel

without all the unwanted extra typing.

Code: Select all

//+---------------------------------------------------------------------------------
double gvg(string name, string prefix = "")
{
   name = prefix + name;
   return (GlobalVariableGet(name));
}

//+---------------------------------------------------------------------------------
void gvs(string name, double value)
{
   GlobalVariableSet(name, value);
}

//+---------------------------------------------------------------------------------
bool gvd(string name)
{
   return (GlobalVariableDel(name));
}

//+---------------------------------------------------------------------------------
bool gvc(string name)
{
   return (GlobalVariableCheck(name));
}
Author:  dietcoke [ Tue Mar 06, 2012 7:50 pm ]
Post subject:  SwitchChartTimeFrame

This function will switch the timeframe of the current chart to the timeframe passed as parameter.

It is a modification of a fantastic script by zznbrm (http://www.forexfactory.com/showthread. ... ost3876444) which globally changes the timeframe on all open charts

I've written it so the EA I'm developing can monitor in a higher timeframe and physically move into shorter timeframes and a completely different trading mode when a set up occurs.

I know its possible to read indcators on different timeframes but using this function makes it much easier to code entirely different behaviours depending on the timefrme the chart is on. It also allows me to visually see which pairs are active simply by observing the chart timeframe

Code: Select all

#property copyright "Copyright © 2010, zznbrm"
#import "user32.dll"
   int      PostMessageA(int hWnd,int Msg,int wParam,int lParam);
   int      GetWindow(int hWnd,int uCmd);
   int      GetParent(int hWnd);
#import

void SwitchChartTimeFrame(int timeframe)
{
   int handle =  WindowHandle( Symbol(), Period() );

   int Cmd;
   switch( timeframe )
   {
      case PERIOD_M1:   Cmd = 33137;  break;
      case PERIOD_M5:    Cmd = 33138;  break;
      case PERIOD_M15:  Cmd = 33139;  break;
      case PERIOD_M30:  Cmd = 33140;  break;
      case PERIOD_H1:   Cmd = 35400;  break;
      case PERIOD_H4:   Cmd = 33136;  break;
      case PERIOD_D1:   Cmd = 33134;  break;
      case PERIOD_W1:   Cmd = 33141;  break;
      case PERIOD_MN1:  Cmd = 33334;  break;
   }
    PostMessageA( handle, 0x0111, Cmd, 0 );
}
Author:  scalpz [ Thu Apr 26, 2012 12:43 am ]
Post subject:  Re: Utility Procedures / Code Snippets

Beginner coder stuff.
Reposted from how steve started coding thread. Is a better fit here.

Found a couple of gold nuggets in relation to Steve's coding methods.
Posting here so other cut & paste coders like me can see them when reading this thread.
SteveHopwood wrote:I see that someone other than Fmfx is interested in what is going on here, so a few more words of explanation.

Those of us who are not trained programmers have to adopt our own coding style. In doing so, consistency helps a lot. Look at the code snippet that offers up external inputs to the user when the EA uses a moving average:

Code: Select all

extern string  mai="----Moving average----";
extern int     MaTF=0;//Time frame defaults to current chart 
extern int     MaPeriod=50;
extern int     MaShift=0;//The MA Shift input
extern string  mame="Method: 0=sma; 1=ema; 2=smma;  3=lwma";
extern int     MaMethod=1;
extern string  maap="Applied price: 0=Close; 1=Open; 2=High";
extern string  maap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
extern int     MaAppliedPrice=0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double         MaVal;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Now remove the 'Ma' from each input:

Code: Select all

extern int     TF=0;//Time frame defaults to current chart 
extern int     Period=50;
extern int     Shift=0;//The MA Shift input
extern string ame="Method: 0=sma; 1=ema; 2=smma;  3=lwma";
extern int     Method=1;
extern string  ap="Applied price: 0=Close; 1=Open; 2=High";
extern string  ap1="3=Low; 4=Median; 5=Typical; 6=Weighted";
extern int     AppliedPrice=0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
double         Val;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
What we are left with is a generic set of inputs that relate to the fields of indi's that we use all the time on our charts.

So, all I do when setting up a group of external inputs is place a shortened form of the indi in front of the variables to customise them - RsiTF, AtrTF, BandsTF etc

As my amateur coding evolves, so does my ability to structure my code in such a way that LUC has fewer and fewer opportunities to invite his buddies for lunch. Variable naming consistency helps me a lot.

:D
Post from straight after in same Fmfx-auto trader thread:
SteveHopwood wrote:
SWG123 wrote:Timely. It so happens that - as a total coding tyro - I've been battling to adapt an EA to use an alternative indi to the one it natively references (nothing to do with this thread however). Thanks again, Maestro. :D
This can be impossible sometimes. How easy it is to do depends on how well the indi was coded in the first place.

The first thing I do when approaching a custom indi is pray that it was coded by squalou.

This is a rare event, so the second thing I do is pray that it was not coded by an idiot. This is also quite rare.

The third thing I do is open the Data window. This gives a rough idea of which buffers the coder has used to store information. Hover the mouse over a candle and you will read the value/s held by the buffers. Bear in mind that the buffer index starts at 0, but displayed Value fields start at 1, so that buffer 1 stores the value shown as Value 2 in the data window etc.

Mind, different indis display differently in the data window, so it takes some playing around to work out exactly how to interrogate the indi successfully.

All of which goes some way to explain why I bloody hate bloody custom indis. :lol:

I would say, "Welcome to my world" except that only an idiot enters it. Instead, I will simply say, "Good luck. You need it."

:D
And almost like Steve says, "Good luck. We need it."
cheers Scalpz :D
Author:  scalpz [ Thu Apr 26, 2012 12:51 am ]
Post subject:  Re: Utility Procedures / Code Snippets

And this 1 too.

Found another nugget, this one from Squalou in Scoob's Forex Robot thread -
squalou wrote: Hi all,

I spotted the same bug while backtesting.
And found the bloody CraaaaaaaaaaaaaaaaaapT4 bloop that i had already hunt many times in the past...

A note to coders for their future productions :
It has to do with comparisons of "double" values:
sometimes, simply comparing double values like this :

Code: Select all

if ( A == B )  they_are_equal();
when A seems to be equal to B, doesn't work...
Even if you Print() A and B you will NOT see ANY difference. :?
However the test fails... :shock:
This is due to the way Empty4 handles doubles internally.
Approximations lead to differences beyond the 8th decimal, and therefore the stored values are not identical anymore in memory.

In order to solve this issue, Empty4 designers provided a small function that is designed to prevent this issue:

CompareDoubles(A,B)
which needs
#include "stdlib.mqh"

You should either use this function like this:

Code: Select all

if ( CompareDoubles(A,B) )  they_are_equal();
or code its equivalent inline :

Code: Select all

if ( NormalizeDouble(A-B,8)==0 )  they_are_equal();
Soooo...
In the case of FR, here is the line that should be fixed :
go to the function "TradeExist()", and replace this line

Code: Select all

            if(OrderType() == cmd && OrderLots() == lots)
like this :

Code: Select all

            if(OrderType() == cmd && NormalizeDouble(OrderLots()-lots,8) == 0)
And that's it...
Damn Empty4... ! :evil:

Sq
And for you geeks (or those foolish enough to try to program), see "Warning, educational but geeky detail ahead:..." post by Sq at http://www.stevehopwoodforex.com/phpBB3 ... 469#p11469

cheers scalpz :D
Author:  tritom [ Sat Jul 21, 2012 7:09 pm ]
Post subject:  Re: Utility Procedures / Code Snippets

Nice thingies here :D
Adding this oneliner:

Code: Select all

int LotDigits  = MathLog(1 / MarketInfo(Symbol(), MODE_LOTSTEP)) / MathLog(10);
usage: rounding of calculated fractional lot sizes - NormalizeDouble() before OrderSend(), DoubleToStr() before screen output.
well, it's almost always 2 with most crims but not always ;)
Author:  Jimdandy [ Thu Jul 26, 2012 3:19 pm ]
Post subject:  Looking for mq4 of 10.2 TmaSlopeTrue NT

George Wrote:
"I suspect this isn't very costly when calling ArraySize(), but what about when calling OrdersTotal() or OrdersHistoryTotal()? Or even worse, our own functions like NumBarsClosingAboveAverage()"

Thank you for this George.... I had not thought of this. I can see how this could get pretty heavy when you have 15 charts running and all of them running these loops on every tick.... I will keep this in mind and go thru some of my stuff and see where I can eliminate some cpu usage.

Does anyone have the mq4 file for this indicator?
TMA_Slope_True_NT.png
I wanted to go in and hard code the colors that I use so as not to have to keep resetting it....
All I have found is the ex4 file.... I had a couple of other indies where one was coded "normal" and one was coded "true" but deleted them in favor of this "NT" one that you could toggle back and forth...

I didn't realize at the time that all I had was the ex4 for it....Now I can't find the ones I deleted..... Everybody look through there pile of toys and see if you have...
10.2 TmaSlopeTrue NT v1.4B 4.30.mq4
I may find it yet....

Thanks for looking......PipPip......JimDandy....
All times are UTC Page 3 of 7