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

Holy Graily Bob's Candle Power
https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?t=5272
Page 16 of 36
Author:  dreambig2 [ Fri Sep 29, 2017 3:44 pm ]
Post subject:  Holy Graily Bob's Candle Power

Decided to try some Neg Correlated pairs next week see if helps overall DD.

UC/AU....EC/CJ....XA/AC...GJ/EG

Cheers
Author:  TraderJoeForex [ Fri Sep 29, 2017 6:47 pm ]
Post subject:  Holy Graily Bob's Candle Power

TraderJoeForex » Tue Sep 26, 2017 10:36 am wrote:I am trying a couple of things this week:

I decided on H4 for a higher time frame test:

HGI activated
No fixed SL
20 pip spacing
100pip JS
10pip BE

I am also trying M5 same set as last week and adding GTWV to add stacked trades after the 2pip BE. I am thinking this may provide a better balance when we get a directional move.
No trades closed on H4 yet and adding GTWV to CP didn't do much although GJ has been in such a tight range it will be interesting to see if next week makes any difference. Great results again from M5 CP though
Author:  c1borg [ Sat Sep 30, 2017 10:33 am ]
Post subject:  Holy Graily Bob's Candle Power

Ok here are some initial results only traded over 2 days and always on v1e. Definately consistent profit but small loss on EURUSD. First 10hrs seems to be significant, after that less trades and higher losses, too early to say yet though, will continue next week. 0.22% gain :good:
1.png
2.png
3.png
4.png
5.png
Author:  c1borg [ Sat Sep 30, 2017 11:04 am ]
Post subject:  Holy Graily Bob's Candle Power

All the big losses appear to be 11hrs + not sure if rebooting every 10hrs or so will reduce these but will try again next week.
6.png
Author:  SteveHopwood [ Sat Sep 30, 2017 4:13 pm ]
Post subject:  Holy Graily Bob's Candle Power

V 1f is in post 1. Make sure you save a set file from your current version before loading it onto a chart so you can resume with your own settings.

------------

I had no more invalid stop errors after removing the NormalizeDouble() command from the code. I know some of you are at an early stage in looking under the bonnet at the code, so here are some explanations.

Here is an input that you will see throughout my bots:
extern int StopLossPips=200;
  • 'extern' makes the variable StopLossPips into one that is shown to the user in the inputs window.
  • 'int' declares the variable as an integer i.e. with no decimal point.
A little further down you will see this:
double StopLoss;
  • a 'double' is a variable that has a decimal point - for example any of the market prices of the standard Forex pars.
In the human world, if we divide 1 by 2 then the calculation has a result of 0.5, but not in the wacky world of crapql4, where it results in zero. It makes no difference if we make the variable that holds the result a double. Take this code snippet:

Code: Select all

   double x = 0;
   int y = 1;
   int z = 2;
   x = y / z;
   Alert(x);
  


Add the code to a script, compile and run it. The Alert will show you "0.0".

The StopLossPips variable is an integer shown to the user to make it clear that it is a pips input and to avoid confusion caused by a decimal point. It cannot be used to calculate a stop loss, which is why I have the double StopLoss as a converter. You will see this line of code in OnInit():
StopLoss=StopLossPips;

This stores the user input in a double that can be interrogated throughout the code. This solves one problem and introduces another that is a features of doubles variables and it is this: the value of the variable that we can see may not be quite the same as the value the code is working with.

I was reaching the wrist-slashing stage very early on in the life of SHF when the program was steadfastly refusing to recognise that two doubles that had to be the same but were not being recognised as equal. Take this very simplified example of what was happening:

Code: Select all

   double x = 1;
   double y = 1;
   if (x == y)
      Alert("x is equal to y");
   else
      Alert("x is NOT equal to y");

Hard to get x any more equal to y, but the damn code was refusing to recognise this.

garyfritz explained. A variable of the 'double' type has 8 decimal places and that a rogue digit can appear in the 8th decimal place. So the code might be comparing x with a value of 1.00000000, to y with a value of 1.00000001. They are not equal.

This is why we have this function, supplied at the time by Gary and used ever since:

Code: Select all

bool CloseEnough(double num1,double num2)
{
/*
   This function addresses the problem of the way in which mql4 compares doubles. It often messes up the 8th
   decimal point.
   For example, if A = 1.5 and B = 1.5, then these numbers are clearly equal. Unseen by the coder, mql4 may
   actually be giving B the value of 1.50000001, and so the variable are not equal, even though they are.
   This nice little quirk explains some of the problems I have endured in the past when comparing doubles. This
   is common to a lot of program languages, so watch out for it if you program elsewhere.
   Gary (garyfritz) offered this solution, so our thanks to him.
   */

   if(num1==0 && num2==0) return(true); //0==0
   if(MathAbs(num1 - num2) / (MathAbs(num1) + MathAbs(num2)) < 0.00000001) return(true);

//Doubles are unequal
   return(false);

}//End bool CloseEnough(double num1, double num2)
I call this function whenever I need to compare two variables of type double. So not:
if (StopLoss != 0)
DoSomething;
because this will fail if the code thinks the value of StopLoss is 0.00000001

Instead:
if (!CloseEnough(StopLoss, 0) )
DoSomething;
because here the code will recognise that StopLoss is in fact zero and so will not do the 'something' in the following code.

Here is where NormalizeDouble() comes in. Imagine this calculation with a buy order stop loss of 1.53245 and a jumping stop of 20 pips:
double NewStop = OrderStopLoss() + (JumpingStopPips / factor);

'factor' is the pip factor that transforms the value of a doubles variable into Points. The code was originally supplied by lifesys. Tommaso has since supplied even better code that I see has not made its way here or into my shells - another little thingy for my todo list tomorrow.

The above calculation should result in NewStop having the falue of 1.53445 i.e. 20 pips above the current stop loss. Trouble is, being a double, the value recognised in code might be 1.53445001; this will throw up an invalid stop error because the broker will not accept a price of 1.53445001.

NormalizeDouble() removes any excess digits after the number of decimal places in the quote. We normally combine this all on one line as in:
double NewStop = NormalizeDouble(OrderStopLoss() + (JumpingStopPips / factor), Digits);

Breaking down the equation, the (JumpingStopPips / factor) is evaluated first. Imagine it is GU so the equation without normalising after the first bracket evaluation is:
double NewStop = OrderStopLoss() + 0.002;

Using our buy stop loss example, NewStop should be 1.53445 but we check for the extra rogue digit by 'normalising' it:
NewStop - NormalizeDouble(NewStop, Digits);

Incidentally, don't be afraid to bread equations down into simpler steps, especially when you are starting out. This is the complicated-looking version:
double NewStop = NormalizeDouble(OrderStopLoss() + (JumpingStopPips / factor), Digits);

You might find it easier to have the two step separated out instead:
  • double NewStop = OrderStopLoss() + (JumpingStopPips / factor);
  • NewStop - NormalizeDouble(NewStop, Digits);
'Digits' truncates the NewStop doubles variable to the 5 decimial places in the GU quote.

To return to Candle Power and the invalid stop quotes, the command intended to prevent them appears to have been creating them. Removing said command appears to have stopped them.

Welcome to my world. :arrrg: :arrrg: :arrrg: :arrrg: :arrrg: :arrrg: :arrrg: :arrrg: :arrrg: :arrrg: :arrrg:

There should be a sign at the opening saying, "Abandon hope all ye who enter here." :twisted: :twisted: :twisted:

:xm:
Author:  RisklessPips [ Sat Sep 30, 2017 4:57 pm ]
Post subject:  Holy Graily Bob's Candle Power

Many thanks for shortening the learning curve Steve.

Is the doubles thing described anywhere in the literature or do Empty4 expect coders to find this type of thing out by trial and error in a situation where money or the loss of it is a consequence? :evil:

Charles
Author:  SteveHopwood [ Sat Sep 30, 2017 5:16 pm ]
Post subject:  Holy Graily Bob's Candle Power

RisklessPips » Sat Sep 30, 2017 4:57 pm wrote:Many thanks for shortening the learning curve Steve.

Is the doubles thing described anywhere in the literature or do Empty4 expect coders to find this type of thing out by trial and error in a situation where money or the loss of it is a consequence? :evil:

Charles
In my case, mostly when people have told me in the past.

You will see lots of appreciations of other coders' work as you read through my code; these people have taught me a lot. Hehe. Not much of the code is actually mine. :yahoo:

:xm:
Author:  tomele [ Sat Sep 30, 2017 7:49 pm ]
Post subject:  Holy Graily Bob's Candle Power

Ok. Giving the wisenheimer here.

You are not alone. Mql4 is a subset of the C language. And there, as in many other languages, the result of an int divided by an int is not a float, but the floor of the division. You can avoid this by implicit or explicit typecasting.

Implicit typecasting in this case can be done by introducing a double (here a simple "1.0") somewhere in the early part of the equation:

Code: Select all

double x = 0;
int y = 1;
int z = 2;
x = y / (z * 1.0);


Explicit typecasting means making one part of the equation explicitely a double:

Code: Select all

double x = 0;
int y = 1;
int z = 2;
x = y / (double) z;


Dont rely on automatic type conversion and cast your data as early as you can.

Cheers, Thomas
Author:  SteveHopwood [ Sat Sep 30, 2017 8:10 pm ]
Post subject:  Holy Graily Bob's Candle Power

tomele » Sat Sep 30, 2017 7:49 pm wrote:Ok. Giving the wisenheimer here.

You are not alone. Mql4 is a subset of the C language. And there, as in many other languages, the result of an int divided by an int is not a float, but the floor of the division. You can avoid this by implicit or explicit typecasting.

Implicit typecasting in this case can be done by introducing a double (here a simple "1.0") somewhere in the early part of the equation:

Code: Select all

double x = 0;
int y = 1;
int z = 2;
x = y / (z * 1.0);


Explicit typecasting means making one part of the equation explicitely a double:

Code: Select all

double x = 0;
int y = 1;
int z = 2;
x = y / (double) z;


Dont rely on automatic type conversion and cast your data as early as you can.

Cheers, Thomas
This is ridiculous. From the point of view of a normal human being: something * 1 = something; 1 * something = something; something * 1.0 = something etc because 1.0 = 1.

Yet when I try this:

Code: Select all

   double x = 0;
   int y = 1;
   int z = 2;
   x = y / (z * 1);
   Alert(x);
 
The return is 0.

Yet when I try this:
double x = 0;
int y = 1;
int z = 2;
x = y / (z * 1.0);
Alert(x);
the return is 0.5

Why?

And what does this have to do with problems with NormalizeDouble() that have sprung from nowhere after over a decade of seamless use?

:xm:
Author:  tomele [ Sat Sep 30, 2017 8:35 pm ]
Post subject:  Holy Graily Bob's Candle Power

Yet when I try this:

Code: Select all

   double x = 0;
   int y = 1;
   int z = 2;
   x = y / (z * 1);
   Alert(x);
The return is 0.
The compiler thinks: All integers here. Lets be lazy and treat them as integers. Result of divided integers is the floor of the result. Why should I care for decimal places? Steve wants integer from me. And the I translate it into a double.
Yet when I try this:

Code: Select all

   double x = 0;
   int y = 1;
   int z = 2;
   x = y / (z * 1.0);
   Alert(x);
 
the return is 0.5

Why?
Now you have introduced a float into the equation. That forces the compiler into float computing mode and maybe to think: WTF? You want me to work? Ok. You will get a trizillion of decimal places from me. Hope you sleep bad.

And what does this have to do with problems with NormalizeDouble() that have sprung from nowhere after over a decade of seamless use?
I dont know. Yet.

Cheers
All times are UTC Page 16 of 36