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

Slopey Graeme: another pipEasy-inspired trend trading EA
https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?t=223
Page 10 of 14
Author:  jb68 [ Fri Feb 03, 2012 7:16 pm ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

Hi everybody,

I'm quite new here, however I have some forex experience especially countless screen hours. I did a few of my own EAs but I wanted to see what other people did so far in this area and I quite impressed by Steve's work. I'm still not decided if I should continue my work on my own libraries and EAs or just learn Steve's. Any way...

I loaded this EA and fired against the last 3 years of data. Before coming to an end screen was full of 130 errors so I stopped it, looked at the results. It looks like the modify works as it should and based on my experience I suspected it should be some crims crap so I decided to contribute a little. I looked at code where as I expected there is no check against crim's freeze level.

To save you from google it, each crims cand set it's own pair dependent "freeze level" variable and the distance between Sl/TP and Ask/Bid has to be bigger then this "freeze level". Some crims like Oanda has 0 while FXPro has 5pips, Alpari beeing in between.
this can be extracted with
double FreezeLevel=MarketInfo(Symbol(),MODE_STOPLEVEL);

Here are some changes..

Code: Select all


//line 794 instead of  modify = true; 

 if (Bid- NewStop > MarketInfo(Symbol(),MODE_STOPLEVEL)) modify = true; 

// line 801 instead of modify = true;

 if (NewStop - Ask > MarketInfo(Symbol(),MODE_STOPLEVEL)) modify = true; 


// line 839  instead of: if (Bid >=  sl + ((JumpingStopPips * 2) * Point) )//George

 if (Bid >=  sl + ((JumpingStopPips * 2) * Point) &&  Bid - sl - (JumpingStopPips * Point) >MarketInfo(Symbol(),MODE_STOPLEVEL) )//George

// line 855 instead of if (Bid <= sl - ((JumpingStopPips * 2) * Point) )//George 

if (Ask <= sl - ((JumpingStopPips * 2) * Point)  &&  sl - (JumpingStopPips * Point) - Ask > MarketInfo(Symbol(),MODE_STOPLEVEL))  //George


// line 896 instead of if (Bid >= sl + (TrailingStopPips * Point) )//George
if (Bid >= sl + (TrailingStopPips * Point) && Bid - sl - (JumpingStopPips * Point) >MarketInfo(Symbol(),MODE_STOPLEVEL))//George 

// line 912 instead of if (Bid <= sl  - (TrailingStopPips * Point))//George
if (Ask <= sl  - (TrailingStopPips * Point) &&  sl - (JumpingStopPips * Point) - Ask > MarketInfo(Symbol(),MODE_STOPLEVEL))//George

// line 956  instead of  modify = true; 

 if (Bid- NewStop > MarketInfo(Symbol(),MODE_STOPLEVEL)) modify = true; 

// line 966 instead of modify = true;

 if (NewStop - Ask > MarketInfo(Symbol(),MODE_STOPLEVEL)) modify = true; 

Plese note the SL and TP should be calculated using Bid when you buy and Ask when you sell.
The idea is simple, to buy you pay the Ask price, when you close you get the Bid.

2-3 pips between Ask and Bid will not make a difference when we want 100 but.. who knows...

I did these changes and 130 errors are gone. I don't know from resource point of view on Empty4 if is better to do only once at init a MarketInfo call or just put FreezeLevel into a variable and check against it. I have no idea if Criminals change the FreezeLevel when news comes in.

I still get some errors occasionally:
2012.02.03 11:02:56 2009.05.22 15:44 Graeme EURUSD,M15: OrderModify error 1

and

2012.02.03 11:07:07 2011.11.29 11:30 Graeme EURUSD,M15: object name passed to ObjectType function cannot be an uninitialized or empty string

I may look into this errors some time... but this Empty4 doesn't have too many debug options and there just a few errors not that bad.
Author:  SteveHopwood [ Fri Feb 03, 2012 10:45 pm ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

jb68 wrote:Hi everybody,

I'm quite new here, however I have some forex experience especially countless screen hours. I did a few of my own EAs but I wanted to see what other people did so far in this area and I quite impressed by Steve's work. I'm still not decided if I should continue my work on my own libraries and EAs or just learn Steve's. Any way...

I loaded this EA and fired against the last 3 years of data. Before coming to an end screen was full of 130 errors so I stopped it, looked at the results. It looks like the modify works as it should and based on my experience I suspected it should be some crims crap so I decided to contribute a little. I looked at code where as I expected there is no check against crim's freeze level.

To save you from google it, each crims cand set it's own pair dependent "freeze level" variable and the distance between Sl/TP and Ask/Bid has to be bigger then this "freeze level". Some crims like Oanda has 0 while FXPro has 5pips, Alpari beeing in between.
this can be extracted with
double FreezeLevel=MarketInfo(Symbol(),MODE_STOPLEVEL);

Here are some changes..

Code: Select all


//line 794 instead of  modify = true; 

 if (Bid- NewStop > MarketInfo(Symbol(),MODE_STOPLEVEL)) modify = true; 

// line 801 instead of modify = true;

 if (NewStop - Ask > MarketInfo(Symbol(),MODE_STOPLEVEL)) modify = true; 


// line 839  instead of: if (Bid >=  sl + ((JumpingStopPips * 2) * Point) )//George

 if (Bid >=  sl + ((JumpingStopPips * 2) * Point) &&  Bid - sl - (JumpingStopPips * Point) >MarketInfo(Symbol(),MODE_STOPLEVEL) )//George

// line 855 instead of if (Bid <= sl - ((JumpingStopPips * 2) * Point) )//George 

if (Ask <= sl - ((JumpingStopPips * 2) * Point)  &&  sl - (JumpingStopPips * Point) - Ask > MarketInfo(Symbol(),MODE_STOPLEVEL))  //George


// line 896 instead of if (Bid >= sl + (TrailingStopPips * Point) )//George
if (Bid >= sl + (TrailingStopPips * Point) && Bid - sl - (JumpingStopPips * Point) >MarketInfo(Symbol(),MODE_STOPLEVEL))//George 

// line 912 instead of if (Bid <= sl  - (TrailingStopPips * Point))//George
if (Ask <= sl  - (TrailingStopPips * Point) &&  sl - (JumpingStopPips * Point) - Ask > MarketInfo(Symbol(),MODE_STOPLEVEL))//George

// line 956  instead of  modify = true; 

 if (Bid- NewStop > MarketInfo(Symbol(),MODE_STOPLEVEL)) modify = true; 

// line 966 instead of modify = true;

 if (NewStop - Ask > MarketInfo(Symbol(),MODE_STOPLEVEL)) modify = true; 

Plese note the SL and TP should be calculated using Bid when you buy and Ask when you sell.
The idea is simple, to buy you pay the Ask price, when you close you get the Bid.

2-3 pips between Ask and Bid will not make a difference when we want 100 but.. who knows...

I did these changes and 130 errors are gone. I don't know from resource point of view on Empty4 if is better to do only once at init a MarketInfo call or just put FreezeLevel into a variable and check against it. I have no idea if Criminals change the FreezeLevel when news comes in.

I still get some errors occasionally:
2012.02.03 11:02:56 2009.05.22 15:44 Graeme EURUSD,M15: OrderModify error 1

and

2012.02.03 11:07:07 2011.11.29 11:30 Graeme EURUSD,M15: object name passed to ObjectType function cannot be an uninitialized or empty string

I may look into this errors some time... but this Empty4 doesn't have too many debug options and there just a few errors not that bad.
Welcome and thanks for all this.

Re the developing your own stuff or learning mine thingy, I suggest you keep on developing your own. Mine is not going to go away. It is always available in my shell code and you can hack into it anytime. Thing is, I am a pianist not a programmer, so my stuff is the work of a reasonable well informed amateur, so the more you can do for yourself the better.

Re the freeze level thingy, I am not going to do anything with this. Basically, so long as the user has a combination of inputs that the crim allows then there is not a problem; doing so is up to the user. I have already been down the road of fixing something that was not bust in the first place here, and am not eager to do so again. If you get deeply into coding and providing code for others to use, you will find that the more idiot-proofing you do, the more idiocy people will offer up and ask you to sort out.

Re the "object name passed to ObjectType function cannot be an uninitialized or empty string" you will be doing me a favour of epic proportions if you can work out what I am doing wrong here. It will be something simple, but I am buggered if I can work out what. This is a Stealth-related thingy.

In case you have not worked this out for yourself, HiddenPips initiates Stealth management. Taking a buy trade as an example, when >0, HP adds HiddenPips to the 'hard' take profit sent with the trade, and subtracts if from the stop loss. Then the bot draws tp/sl lines that represent the 'true' tp/sl (drawn by void ReplaceMissingSlTpLines() and called from within CountOpenTrades() which itself performs a variety of functions at each tick) and closes the trade when these lines are touched/crossed.

At some point just subsequent to this, the error you describe here is triggered. This is no biggy, but if you can solve it you will save coders who follow in your footsteps some angst when they come across it for the first time, and before learning to ignore it.

Cheers

:D
Author:  SteveHopwood [ Fri Feb 03, 2012 10:48 pm ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

jb68, as an addendum to the above, you will see functions/code snippets in my stuff that I attribute to others. These 'others' are seriously talented programmers whose work you should take very seriously - I do.

:D
Author:  jb68 [ Sat Feb 04, 2012 5:05 am ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

Steve, you have a 1000+ lines there. You are really way too modest.
I did a cheap and dirty look. You used only on one line the culprit function ObjectType

Code: Select all

 for (int cc = ObjectsTotal() - 1; cc >= 0; cc--)
   {
      string name = ObjectName(cc);
      
      if ((StringSubstr(name, 0, 2) == TpPrefix || StringSubstr(name, 0, 2) == SlPrefix) 
           && (ObjectType(name) == OBJ_HLINE || ObjectType(name) == OBJ_TREND))
---------------------------------

I'm not sure but how about if you're not doing anything wrong and..
if Empty4 for some stupid reason return an object without a name then ObjectType(name) will throw an error. However there will be no effect in how EA works. Easy and dirty fix would be to add a simple check

if (name!='') like this..

Code: Select all

  if (name!='' &&(StringSubstr(name, 0, 2) == TpPrefix || StringSubstr(name, 0, 2) == SlPrefix) 
           && (ObjectType(name) == OBJ_HLINE || ObjectType(name) == OBJ_TREND))
I don't know if '' (empty string) is different then NULL in mql4 so we could try as well

Code: Select all

if (name && name!='' &&(StringSubstr(name, 0, 2) == TpPrefix || StringSubstr(name, 0, 2) == SlPrefix) 
           && (ObjectType(name) == OBJ_HLINE || ObjectType(name) == OBJ_TREND))
so that would be if name is defined, not null and not empty string ... I didn't try this in code but I'll try maybe tomorrow, I'm on Pacific coast.

As for the freezing thing I got that error with default variables, 10px SL. Even 5px freeze + Bid instead of Ask should not throw 130. That means my criminal is more criminal then I think. You are right don't bother too much with it.
Author:  fx800 [ Sat Feb 04, 2012 6:18 am ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

Hi all,

Many thanks to Steve and many others who have contributed to the development of this EA.

It is early days yet and I am not getting too excited about the results. The demo has only been running for just over a week and has chalked up 13% gains.

Demo FXDD GMT+2 $10,000 account, H4 charts, 15 pairs, lot size 0.2, OOTB RSI Forexkiwi 500.

Initially, I was manually closing all trades when the daily gains were exceeding 3% of equity. However, since yesterday, I have started running Donefortheday EA from Changethecolor thread to do this automatically.

Will post again in a couple of weeks. It will be interesting to see how the bot progresses.

Cheers,
Peter
Author:  gaheitman [ Sat Feb 04, 2012 10:00 am ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

jb68 wrote:Steve, you have a 1000+ lines there. You are really way too modest.
I did a cheap and dirty look. You used only on one line the culprit function ObjectType

Code: Select all

 for (int cc = ObjectsTotal() - 1; cc >= 0; cc--)
   {
      string name = ObjectName(cc);
      
      if ((StringSubstr(name, 0, 2) == TpPrefix || StringSubstr(name, 0, 2) == SlPrefix) 
           && (ObjectType(name) == OBJ_HLINE || ObjectType(name) == OBJ_TREND))
---------------------------------
I believe the issue is the increment of the cc variable after a delete. The error only shows up if the only objects on the chart are the ones you want to delete OR they appear at the end of the list (which includes the first case I guess :>). Here's a version of your code without the checks for ticket number. etc. It should delete all horizontal and trend lines on a chart.

Code: Select all

void DeleteOrphanTpSlLines()
{

   if (ObjectsTotal() == 0) return;
   
   for (int cc = ObjectsTotal() - 1; cc >= 0; cc--)
   {
      string name = ObjectName(cc);
      Print("cc=".cc," name=",name);
      
      if ((ObjectType(name) == OBJ_HLINE || ObjectType(name) == OBJ_TREND))
      {
         {
            {
               ObjectDelete(name);
               cc++;
            }//if (!OrderSelect(tn, SELECT_BY_TICKET, MODE_TRADES) || OrderCloseTime() > 0)
            
         }//if (tn > 0) 
         
         
      }//if (StringSubstr(name, 0, 1) == TpPrefix)
      
   }//for (int cc = ObjectsTotal() - 1; cc >= 0; cc--)
   
   
}//End void DeleteOrphanTpSlLines()
If you run this with 2 horizontal lines and nothing else on the chart, you get the following output:

Code: Select all

04:46:10 tester EURUSD,Daily: cc=2 name=Horizontal Line 65133
04:46:10 tester EURUSD,Daily: cc=2 name=
04:46:10 tester EURUSD,Daily: object name passed to ObjectType function cannot be an uninitialized or empty string
04:46:10 tester EURUSD,Daily: object name passed to ObjectType function cannot be an uninitialized or empty string
04:46:10 tester EURUSD,Daily: cc=1 name=Horizontal Line 65131
04:46:10 tester EURUSD,Daily: cc=1 name=
04:46:10 tester EURUSD,Daily: object name passed to ObjectType function cannot be an uninitialized or empty string
04:46:10 tester EURUSD,Daily: object name passed to ObjectType function cannot be an uninitialized or empty string
04:46:10 tester EURUSD,Daily: cc=0 name=Horizontal Line 65129
04:46:10 tester EURUSD,Daily: cc=0 name=
04:46:10 tester EURUSD,Daily: object name passed to ObjectType function cannot be an uninitialized or empty string
04:46:10 tester EURUSD,Daily: object name passed to ObjectType function cannot be an uninitialized or empty string
04:46:10 tester EURUSD,Daily: uninit reason 0
04:46:10 tester EURUSD,Daily: removed
If you run it with two horizontal lines and one other object that comes after them in the list, you get the following:

Code: Select all

04:47:38 tester EURUSD,Daily: Alert: 3
04:47:38 tester EURUSD,Daily: cc=2 name=Vertical Line 65208
04:47:38 tester EURUSD,Daily: cc=1 name=Horizontal Line 65207
04:47:38 tester EURUSD,Daily: cc=1 name=Vertical Line 65208
04:47:38 tester EURUSD,Daily: cc=0 name=Horizontal Line 65206
04:47:38 tester EURUSD,Daily: cc=0 name=Vertical Line 65208
04:47:38 tester EURUSD,Daily: uninit reason 0
04:47:38 tester EURUSD,Daily: removed
In both cases, all the horizontal lines are deleted, as expected. We don't get the error, because when you increment to c++ you are telling Empty4 to look at the same object in the list we just looked at. When there is an object in the list after the one you deleted, this works fine because Empty4 looks at it again (notice the prints of Vertical Line 65208).

Remove the cc++ from the code, and you get the following output for each run:

Code: Select all

04:49:09 tester EURUSD,Daily: cc=1 name=Horizontal Line 65296
04:49:09 tester EURUSD,Daily: cc=0 name=Horizontal Line 65294
04:49:09 tester EURUSD,Daily: uninit reason 0
04:49:09 tester EURUSD,Daily: removed
and

Code: Select all

04:49:09 tester EURUSD,Daily: cc=2 name=Vertical Line 65343
04:49:09 tester EURUSD,Daily: cc=1 name=Horizontal Line 65342
04:49:09 tester EURUSD,Daily: cc=0 name=Horizontal Line 65340
04:49:09 tester EURUSD,Daily: uninit reason 0
04:49:09 tester EURUSD,Daily: removed
Again, in both cases all the horizontal lines are deleted. I'd recommend ditching the "c++" and giving it a go.

George
Author:  SteveHopwood [ Sat Feb 04, 2012 10:41 am ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

Thanks guys. jb, I will give George's thingy a try first as it is the easiest. If it doesn't, then I will try yours.

Peter, please do post your results. I am leaving G to run unmolested and am not being successful, so it will be interesting to compare results.

:D
Author:  fx800 [ Sat Feb 04, 2012 11:05 am ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

SteveHopwood wrote:Thanks guys. jb, I will give George's thingy a try first as it is the easiest. If it doesn't, then I will try yours.

Peter, please do post your results. I am leaving G to run unmolested and am not being successful, so it will be interesting to compare results.

:D

Steve, please consider it done.

Best regards,
Peter
Author:  gaheitman [ Sat Feb 04, 2012 11:38 am ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

SteveHopwood wrote:Thanks guys. jb, I will give George's thingy a try first as it is the easiest. If it doesn't, then I will try yours.

Peter, please do post your results. I am leaving G to run unmolested and am not being successful, so it will be interesting to compare results.

:D
As an aside, if mine doesn't work, you'll have to do the other one in a nested if statement, since silly ol' Empty4 evaluates everything in the if statement even if it can't evaluate to true after the first one. So,

Code: Select all

if (name!='' &&(StringSubstr(name, 0, 2) == TpPrefix || StringSubstr(name, 0, 2) == SlPrefix) 
           && (ObjectType(name) == OBJ_HLINE || ObjectType(name) == OBJ_TREND))
needs to be

Code: Select all

if (name!='')
    if ((StringSubstr(name, 0, 2) == TpPrefix || StringSubstr(name, 0, 2) == SlPrefix) 
           && (ObjectType(name) == OBJ_HLINE || ObjectType(name) == OBJ_TREND))
George
Author:  jb68 [ Sat Feb 04, 2012 5:46 pm ]
Post subject:  Re: Graeme: another pipEasy-inspired trend trading EA

gaheitman is right, you delete an object while you scan the list.
After a delete Empty4 should update the list. How or if that update is done I have no idea. For example if you have 0,1,2,3,4 and you delete #2 the first thing would be to have 3->2 and 4->3 but that is not necessary. It could be very well 0,1,NULL,3,4

If this 3 become 2 after a delete 2 then cc++ will have no effect because it will look again for former #3. However errors shows us Empty4 rebuilt list in a different or most probably it doesn't rebuild it in real time, just for every start so most probably it would have 0,1,NULL,3,4 . In this case ditching cc++ is the best way to go.

If the list is not 0,1,NULL,3,4 then we should first create a list with objects to delete and then delete them.

@gaheitman if Empty4 require nested "if", then it should have the worst compiler and optimization ever. Any decent language I know has optimization and would transform if (A && B) to a nested if and will return false at first false statement to take less cpu. However here things are different, some will execute the first on the right, others the first on left.
I don't have that much mql4 experience to know how Empty4 works so I decided to test this cause this has huge implications..

Code: Select all

bool A(){
Alert ("Left");
return (FALSE);
}
bool B(){
Alert ("Right");
return (FALSE);
}
void init(){
if (A()&&B()){
}
}
Conclusion, you are right, Empty4=Empty4. :lol:
Aside for the fact I just learn something new, from now on I should do nested "if" which I hate.
All times are UTC Page 10 of 14