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

My shell EA code
https://www.stevehopwoodforex.com/phpBB3/viewtopic.php?t=79
Page 4 of 23
Author:  gaheitman [ Fri Dec 09, 2011 9:36 pm ]
Post subject:  Re: My shell EA code

ironrick wrote:
gaheitman wrote: Some options I've come up with to trigger a stop for the day:

The obvious ones:
  • MaxTrades, MaxLosingTrades, MaxWinningTrades
    MaxPipGain, MaxPipLoss
    MaxBalanceGain, MaxBalanceLoss
    MaxPercentGain, MaxPercentLoss
For the options above, there will be a switch for UseEquity or UseBalance as well as combinable options for UseMagicNumber and UseCurrencyPair. That way the code works for multi-currency bots as well as allows people running the same EA across several currencies. All the options make calculating percents difficult, but there it is...

The less obvious (need more idea here):
  • MaxADRPercent //generally if it's a big move day signals are out of whack
    HardStopDateTime //For example, hard coding to stop on next Thursday at 2:15 GMT
    StrategyDoneForTheDay() //a strategy specific procedure that the user modifies that by default just returns false
Now back to the subject at hand... :)

Because it has been on mind, I was thinking of other trade-length time-based options.

Rather then just a clock time -- End trade at 2:30pm, end the trade/trading after a certain AMOUNT of time -- Start at 7:00am/x signal/MA cross/whatever and end after 5.5 hours.

Just a thought.

Rick
I think that's a valid suggestion. One of the turtles books I read said that getting out of a trade after x amount of time was better than waiting for some other signal.

If you want to close individual trades after x minutes of being open, that's a change to "LookForTradeClosure()". If you want to stop all trading x minutes after the first trade of the day is triggered, that could easily be added to the StrategyDoneForTheDay() procedure that I'll be calling. :D

George
Author:  gaheitman [ Sun Dec 11, 2011 9:38 am ]
Post subject:  DoneForTheDay()

A couple of concepts that need explaining.

The procedure is based on the concept of a "Trading Day" as defined by the trader or strategy. The user will set a Reset Time (hh:mm) which acts as the beginning of the trading day. The procedure keeps track of the beginning and ending of the current trading day based on the reset time. For example, if it is 2011-12-07 14:00 (server time) and the reset time is 13:00, the procedure will consider the trading day to have just begun an hour earlier and last for another 23 hours. Mondays and Fridays are a special case in that the trading day can possibly span the weekend. The calculation looks for the previous/next trading day.

At the start of a Trading Day, the procedure captures the current account balance for use in percent changes to the account. In the case when the EA isn't actually watching at the time of the Trading Day start, account balance will be calculated by taking the then current account balance and subtracting the OrderProfit() value for trades that closed after the daily reset. This subtraction is done without concern for MagicNumber or Symbol settings and ignores any open trades.

The DFTDUseEquity setting only impacts the calculation of balance gain/loss, pip gain/loss and percent gain/loss. Winning/Losing/Max trades must be closed trades.

The action DFTDUseTightStop currently just turns on TrailingStops. You will need to set the appropriate stop in the original setting for TrailingStops.

All the *Loss settings expect you to enter the values as positive numbers. You "lose 80 pips", you don't "lose -80 pips". :D

For the ADR test, the daily range that is being compared to the calculated ADR is the range of the actual D1 bar that we are on, not the Trading Day defined by the Reset Time. I did it this way because the market is looking at the daily bar, and doesn't care about your trading day.

Instead of using bool variables to determine if we want to use one of the specific criterion, it just checks for non-zero values. So if you set it to something, it will use it. There is an overall setting to use DoneForTheDay(), bool UseDoneForTheDay, for when it is called in IsTradingAllowed()

It's also important to note that much of the logic in the procedure depends on the trade history covering the trading day. If the trades don't appear in the trading history, the procedure can't know about them and won't act on them. This is of particular importance at the change of a day/week/month since those are common history filter settings.

I have added a blank procedure StrategyDoneForTheDay() that is called at the end of DoneForTheDay() to allow for a non-generic test. It currently just returns false.

For the coders out there, I've added a new procedure called SaveOrder() which saves the current selected order as well as the TicketNo. It looks like this.

Code: Select all

#define push 1
#define pop 2
#define save 1
#define restore 2

void SaveOrder(int cmd) {

   static int ordernumber=0;
   static int ticketno=0;
   
   if (cmd == push) {ordernumber = OrderTicket(); ticketno = TicketNo; }
   if (cmd == pop) {OrderSelect(ordernumber,SELECT_BY_TICKET); TicketNo = ticketno;}
   GetLastError(); //ignore errors
}
I make a call to SaveOrder(push) before making any OrderSelect() calls and when I am done I call SaveOrder(pop). This way I can be sure I haven't unexpectedly changed the state for some other code down the road. You can also use SaveOrder(save) / SaveOrder(restore) if you don't want to think in terms of stacks. I don't know if this is necessary, but I feel better using it. ;)

I also added code to calculate the ADR. It is:

Code: Select all

double CalculateADR(int i, int Days) {
   double sum=0;
   double cnt=0;
   int offset=0;
   int day=0;
   
   while (cnt<Days) {
      offset = iBarShift(NULL,PERIOD_D1,Time[i]);
      //ignore Sundays
      if(TimeDayOfWeek(iTime(NULL,PERIOD_D1,day+1+offset)) != 0) {
         sum += iHigh(NULL,PERIOD_D1,day+1+offset)-iLow(NULL,PERIOD_D1,day+1+offset);
         cnt++;
      }//if(TimeDayOfWeek(iTime(NULL,PERIOD_D1,day+1+offset)) != 0) 
      day++;
   }
   return(sum/cnt);
}
Finally, I made a change so that multiplier is a global variable -- currently it is defined in init(). I use it to turn points into pips in my code and didn't want to recalculate it. If Steve doesn't want to do that, I'll probably add a function int GetMultiplier().

OK, the actual code to calculate DoneForTheDay() is attached. I have not yet written the notification code, so the only options when you are done for the day is to close all orders, close all pending orders, and/or turn on trailing stops.

I tried to make the code as insulated as possible so that it would be easier to add to existing bots. That being said, I'm not happy with the information we can get from it in it's current state. For example, I would like to be able to report in DisplayUserFeedback() why we have stopped and when we will be restarting.

Anyhow, I was able to test various scenarios last week while the market was still open, but I am sure there are some bugs left in there. No doubt some very obvious ones that I can't see because I typed them in. I will continue to test this week and will update any fixes I make.

Please take a look at the code and let me know if anything jumps out. If you'd like to try things out in DEMO or Strategy Tester, feel free. I would not use it in live, however. :D

George
Author:  dietcoke [ Sun Dec 11, 2011 1:52 pm ]
Post subject:  Re: My shell EA code

Super stuff George.

I noticed one thing in the ADR function.

Code: Select all

double CalculateADR(int i, int Days) {
   double sum=0;
   double cnt=0;
   int offset=0;
   int day=0;
   
   while (cnt<Days) {
      offset = iBarShift(NULL,PERIOD_D1,Time[i]);
      if(TimeDayOfWeek(iTime(NULL,PERIOD_D1,day+1+offset)) != 0) {
         sum += iHigh(NULL,PERIOD_D1,day+1+offset)-iLow(NULL,PERIOD_D1,day+1+offset);
         cnt++;
      }//if(TimeDayOfWeek(iTime(NULL,PERIOD_D1,day+1+offset)) != 0) 
      day++;
   }
   return(sum/cnt);

}
Maybe I'm mixed up. I assume this bit should be dropping from offset back to zero
day+1+offset

Should it not be

offset+1-day?

Can you think of a good way to, incorporate Sunday stub bars into Mondays range(if outside?) into this function.
Author:  rbetancor [ Sun Dec 11, 2011 3:30 pm ]
Post subject:  NewBar MTF version

Hi all, maybe this function could be usefull to someone else apart from me :)

It's the 'typical' NewBar function, but adapted to be MTF.

Code: Select all

bool NewBar(int period)// Funct. detecting a new bar 
{
   static datetime NewTime[8]={0,0,0,0,0,0,0,0};                 // Create a new static datetime variable “new_time” this value will not be lost after the function is over
   int Periods[]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
   int index=ArrayBsearch(Periods,period);
   datetime time=iTime(Symbol(),period,0);
    
   if(NewTime[index]!=time)// Compare time if our new_time static variable is not=to the current bars time then proceed
   {
     NewTime[index]=time;  // If we got this far new_time did not equal the time of the current bar.  So we’re now going to set it that way.
     return(true);                           
   }
   return(false);
}
Author:  gaheitman [ Sun Dec 11, 2011 6:17 pm ]
Post subject:  Re: My shell EA code

dietcoke wrote:Super stuff George.

I noticed one thing in the ADR function.

Code: Select all

double CalculateADR(int i, int Days) {
   double sum=0;
   double cnt=0;
   int offset=0;
   int day=0;
   
   while (cnt<Days) {
      offset = iBarShift(NULL,PERIOD_D1,Time[i]);
      if(TimeDayOfWeek(iTime(NULL,PERIOD_D1,day+1+offset)) != 0) {
         sum += iHigh(NULL,PERIOD_D1,day+1+offset)-iLow(NULL,PERIOD_D1,day+1+offset);
         cnt++;
      }//if(TimeDayOfWeek(iTime(NULL,PERIOD_D1,day+1+offset)) != 0) 
      day++;
   }
   return(sum/cnt);

}
Maybe I'm mixed up. I assume this bit should be dropping from offset back to zero
day+1+offset

Should it not be

offset+1-day?

Can you think of a good way to, incorporate Sunday stub bars into Mondays range(if outside?) into this function.
I lifted this code from the PriceTrap indicator I wrote a few days ago, so it is a generalized function and can calculate the ADR for any bar.

The code actually counts away from the current price since we don't know if we have Sunday bars or not. Offset doesn't change like it would in an indicator, and in the EA it will always be zero (and it should be outside of the main loop, but I missed that). We add the +1 because we have to take the calculation from the previous day, or we would be including today's data which is unfinished.

So, ignoring offset, we are counting backwards one day at a time. If it isn't a Sunday, we increment cnt and stop once cnt is equal to Days.

We could add the Sunday data to Monday without much trouble. I'm not sure how much it would change the calculation.

George
Author:  AnotherBrian [ Wed Dec 21, 2011 3:53 am ]
Post subject:  Re: My shell EA code

SteveHopwood wrote:Latest update in post 1.

For those of a delicate disposition, here is the sanitised rationale:
It appears that the markets can sometimes be moving so quickly that ECN criminals will be unable to allow modifications of trades that update stop losses and take profits. I have added code to CountOpenTrades() that will detect when this happens, and further call functions that will replace the missing tp/sl.


Now, here is what I really mean. Do not read on if bad language offends you.

Only a total tit fails to recognise that some bastard criminals have rabidly adopted ECN in the hope that this will happen:
  • Naive trader sends a trade.
    Platform freezes up before there is time to send the modification of the trade that adds a sl/tp.
    Said platform freeze can be encouraged/simulated by all sorts of thingies that are 'out of control of the criminal. Please be assured that we continue to develop our services to the benefit of our valued clients '.
Total shits.

So, these mindless, turd-brained (and I use the term 'brained' with reservation), manipulative fucking bastards are forcing those of us daft enough to play their game to accept that:
  • We can send trades without stops
    The stops we try to send as a second stage, will not be accepted. Ok, so they all offer that bloody silly order form that allow us to input stops, but it seems there is not guarantee that the stop modifications will actually happen
So, the latest mod tells the bot to keep on trying to add stops etc even though the fucking bastard wanking shits have done their best to stop this happening.

I will defeat these bastards.

:D
I read Steve`s posts and I find my self imaging how he sounds with the accent (I know Steve, I`m the one with the accent...) and I can`t focus any longer.... f`n funny...but at the same time not so funny.... and again, don`t hold back now!!! :twisted:
Author:  SteveHopwood [ Wed Dec 21, 2011 10:52 pm ]
Post subject:  Re: My shell EA code

Latest update in post 1. I have made the adjustments to the JS/RS functions that TIG highlighted in our Gday thread, and reintroduced AddBEP to the JS function.

:D
Author:  SteveHopwood [ Sun Jan 01, 2012 9:27 pm ]
Post subject:  Re: My shell EA code

Trader
Posts: 411
Joined: Wed Nov 16, 2011 7:22 am
Location: An insignificant village in England

PostPosted: Sat Dec 31, 2011 7:54 pm
Latest update in post 1.

I have added an Atr function for sl/tp. To save effort further down the line, this meant creating separate tp/sl calculation functions that are called from within LookForTradingOpps and InsertMissingxxxx

I added the sl/tp calculation function calls to HasBuy/SellFilled.

I decided to update the volatility calculator by leaving out the Saturday/Sunday candles. I got into a terrific tangle, then realised I was probably re-inventing the wheel. I have replaced the calculation loop with a call to ATR and used the existing multiplier to turn the result into more easily recognisable pips.

One or two other bits and bats, including enforcing BreakEven if JS/TS are used.

:D
Author:  gaheitman [ Tue Jan 17, 2012 9:48 am ]
Post subject:  Common Errors

I've been working on a function to call at the beginning of Init() to look for common errors that we've run in to when deploying new EAs. Currently it checks for the following:

  • DLLs Enabled
  • Connection to server
  • Experts Enabled
  • Lot size is > Min Lot size for pair
  • Criminal is ECN is checked if STOP_LEVEL = 0 (I am fairly sure this is a valid test for ECN)
  • Account Balance = 0
Example:
pic_02 2012-01-17 04.42.gif
I'll try to make a pass through the standard externs and call out any obvious errors (i.e. TrailingStop = true, but TrailingStopPips=0). Let me know what other tests you'd like added.

Code: Select all

void CheckForCommonErrors() {


   string msg = "";
  
   if (!IsDllsAllowed()) msg = msg + "DLLs are disabled. See <F7> | Common Tab | Allow DLL Imports.\n";
   if (!IsConnected()) msg = msg + "No connection to server.\n";
   if (!IsExpertEnabled()) msg = msg + "Experts are not enabled. See <Ctrl-O> | Expert Advisors tab.\n";
   
   if (Lot < MarketInfo(Symbol(),MODE_MINLOT)) msg = msg + "Lotsize is set too low for your account.  Min Lotsize allowed is " + DoubleToStr(MarketInfo(Symbol(),MODE_MINLOT),2) + " lots.\n";
   if (MarketInfo(Symbol(),MODE_STOPLEVEL) == 0 && CriminalIsECN == False) msg = msg + "You probably have an ECN, but have not set CriminalIsECN = true.\n";

   //zero account balance
   if (AccountBalance() == 0) msg = msg + "You have a ZERO account balance.\n";
   
   if (IsDllsAllowed()) {
      if (msg != "")
         MessageBox("Important, possible errors detected in configuration. \n\n" + msg + "\n EA will likely not work correctly.",WindowExpertName()+" - Configuration Errors Found",MB_ICONWARNING);
   }else
      Alert("Important, possible errors detected in configuration. \n\n" + msg + "\n EA will NOT work.");
}
George
Author:  magft [ Tue Jan 17, 2012 11:05 am ]
Post subject:  Re: My shell EA code

George great bit of work.

One thing i notice is if a StopLoss or TakeProfit value is set and it is below the broker stop level you get error 130 invalid stop errors so would be good to check.

Maybe check the other trade management values if set to true make sure no zero values, your basically adding error checking Steve left out to stop noobs doing silly things.

I think it is a good idea to keep building this excellent routines but maybe add to the Shell EA but name it different and add them all in in, like DFTD and checktrading times or see if Steve is happy to have it updated as you have done some great work.

Mike
All times are UTC Page 4 of 23