WHRoeder: Here's mine minus the actual trading logic.
I had a PM concerning the trading time/day filter. The request was 1800-0600 Monday-Friday. That requires excluding 0-0600 Monday and 1800-close on Friday. The code allowed for roll over of time but not for days. Enhancement:
/*++++ Day/Time allowed to open*/{
datetime now = TimeGMT();
//extern double TradeHr.UTC.Start = 7.3; // London-1//extern double TradeHr.UTC.End = 12.9; // NY openint secStart = 3600*TradeHr.UTC.Start,
secEnd = 3600*TradeHr.UTC.End,
hrBeg = (now-secStart+86400)%86400,
hrEnd = (now-secEnd +86400)%86400;
if (hrBeg > hrEnd){ double Tminus=hrBeg/3600.-24;
StrApnd(EA.status," HR", DoubleToStr(Tminus,2)); return; }
// TradeHr: 0600-1800 1800-0600 1800-0600// TOD: 0600-1800 1800-2359 0000-0600// DOW: DOW(today) DOW(today) DOW(yesterday)int TOD = now % 86400; // Time of the daydatetime BOD = now - TOD; // Beginning of the day (today 0000z)if (TOD < secStart) int DOW = TimeDayOfWeek(BOD - 1); // Yesterday.else DOW = TimeDayOfWeek(BOD), /* https://www.mql5.com/en/forum/127483
// reports DayOfWeek() always returns 5 in the tester. No refresh?*/int DayMask = 1 << DOW; // #define DAYS_MAX 0x3F// 1<<6-1=63. (S-F)//extern int Days.Mask = 55; // Not Wedif ((Days.Mask & DayMask) == 0){ StrApnd(EA.status," Day=",DOW); return; }
/*---- Day/Time allowed to open*/}
double PointValuePerLot(string pair="") {
/* Value in acnSum currency of a Point of Symbol.
* In tester I had a sale: open=1.35883 close=1.35736 (0.00147)
* gain$=97.32/6.62 lots/147 points=$0.10/point or $1.00/pip.
* IBFX demo/mini EURUSD TICKVALUE=0.1 MAXLOT=50 LOTSIZE=10,000
* IBFX demo/standard EURUSD TICKVALUE=1.0 MAXLOT=50 LOTSIZE=100,000
* $1.00/point or $10.00/pip.
*
* https://www.mql5.com/en/forum/127584 CB: MODE_TICKSIZE will usually return the
* same value as MODE_POINT (or Point for the current symbol), however, an
* example of where to use MODE_TICKSIZE would be as part of a ratio with
* MODE_TICKVALUE when performing money management calculations which need
* to take acnSum of the pair and the acnSum currency. The reason I use
* this ratio is that although TV and TS may constantly be returned as
* something like 7.00 and 0.00001 respectively, I've seen this
* (intermittently) change to 14.00 and 0.00002 respectively (just example
* tick values to illustrate). */if (pair == "") pair = Symbol();
return( MarketInfo(pair, MODE_TICKVALUE)
/ MarketInfo(pair, MODE_TICKSIZE) ); // Not Point.
}
WHRoeder: And my correction for RaptorUK'scomment:
I renamed PointValuePerLot to DeltaValuePerLot since aCurrencyChange = aPriceChange * OrderSize() * DeltaValuePerLot(). Also added more comments.
double PipValuePerLot(string pair=""){ return(DeltaValuePerLot() * pips2dbl); }
double DeltaValuePerLot(string pair=""){
/* Value in account currency of a Point of Symbol.
* In tester I had a sale: open=1.35883 close=1.35736 (0.0147)
* gain$=97.32/6.62 lots/147 points=$0.10/point or $1.00/pip.
* IBFX demo/mini EURUSD TICKVALUE=0.1 MAXLOT=50 LOTSIZE=10,000
* IBFX demo/standard EURUSD TICKVALUE=1.0 MAXLOT=50 LOTSIZE=100,000
* $1.00/point or $10.0/pip.
*
* https://www.mql5.com/en/forum/127584 CB: MODE_TICKSIZE will usually return the
* same value as MODE_POINT (or Point for the current symbol), however, an
* example of where to use MODE_TICKSIZE would be as part of a ratio with
* MODE_TICKVALUE when performing money management calculations which need
* to take account of the pair and the account currency. The reason I use
* this ratio is that although TV and TS may constantly be returned as
* something like 7.00 and 0.0001 respectively, I've seen this
* (intermittently) change to 14.00 and 0.0002 respectively (just example
* tick values to illustrate).
* https://www.mql5.com/en/forum/135345 zzuegg reports for non-currency DE30:
* MarketInfo(Symbol(),MODE_TICKSIZE) returns 0.5
* MarketInfo(Symbol(),MODE_DIGITS) return 1
* Point = 0.1
* Prices to open must be a multiple of ticksize */if (pair == "") pair = Symbol();
return( MarketInfo(pair, MODE_TICKVALUE)
/ MarketInfo(pair, MODE_TICKSIZE) ); // Not Point.
}
WHRoeder: From a post about indicator drawing on both main chart and sub chart, TLine could be used for both with modifications. To draw on the sub chart just use iWin = WindowFind("indicatorName");
I wanted to close all orders before end of the week (market close Friday,) to prevent loss should the market gap over the week end, by passing the SL. (This is not modeled in the tester.)
So the question is when does the market close (or open.) All of the postings and searching on the net are plain wrong. From Forex Education - Introduction to Forex - IBFXForex market operates 24 hours a day, 5.5 days a week (6:00 PM ET on Sunday until 4:00 PM ET on Friday) That's ET - New York local time.
This means that All postings depends on when they were made, as DST boundary's varies from year to year.
This means that it is necessary to compute when NY DST starts and ends, for the bar in question. (For back testing we need values to 2000 at least.) The problem is that Windows does not provide conversion routines except between the current TZ and UTC and only for the current year. If the PC isn't on ET it can't be done directly. Further more, until Windows8 comes out, you can't get conversions for ET and prior years. And looking at the Registry on Win7 the values only cover 2005 on (and those were wrong if I read them correctly.) So I'm not betting Win8 will be better.
This means that it is necessary to compute DST myself. I've updated my code: TimeGmt() and LocalTimeGMT() with default arguments, some additional documentation, and checks, and wrote code to compute market close time. Enjoy.
#define HR2400 86400// 24 * 3600datetime TimeOfDay(datetime when){ return( when % HR2400 ); }
datetime DateOfDay(datetime when){ return( when - TimeOfDay(when) ); }
datetime now.srv, now.utc, mkt.closes.srv;
:
now.srv = TimeCurrent();
now.utc = TimeGMT(now.srv); // May update Srvr.To.UTC.Hoursif (now.srv > mkt.closes.srv){ // Compute next market close// Market closes Friday 4PM ET (NY local time) and opens Sunday 6PM ET.// That's either 2100z or 2000z depending on DST.// 18:00 Friday in America/New_York// 12:00 Friday in Pacific/Honolulu// 08:00 Saturday in Australia/Melbourne// 07:00 Saturday in Asia/Tokyo#define DOW_FRIDAY 5#define HR2100 75600// 21 * 3600#define NY_TZ -18000// -5 * 3600 UTC-5 (STD) or UTC-4 (DST)datetime mktClosesUTC = DateOfDay(now.utc)
+ HR2400*(DOW_FRIDAY - TimeDayOfWeek(now.utc))
+ HR2100;
if (IsNYonDST(mktClosesUTC + NY_TZ)) mktClosesUTC -= 3600; // UTC-4
mkt.closes.srv = TimeServer(mktClosesUTC);
} // Compute next market close
:
//+------------------------------------------------------------------+//| GMT Time |//+------------------------------------------------------------------+datetimeTimeGMT(datetime serverTime=0){ // Server time to GMT time.if (serverTime == 0) serverTime = TimeCurrent();
staticdatetime nextAutoUpdate; if (serverTime >= nextAutoUpdate){
nextAutoUpdate = serverTime + 7200;
if (Srvr.To.UTC.Auto
)if(IsDllsAllowed()){ // Complained @ initint srvrToUTC = LocalTimeGMT() - TimeCurrent();
double nearestHalfHour = MathRound(srvrToUTC / 1800.);
Srvr.To.UTC.Hours = nearestHalfHour / 2.; // Update external
} }
return (serverTime + Srvr.To.UTC.Hours*3600.);
}
datetime TimeServer(datetime gmtTime){ // Server time to GMT time.return (gmtTime - Srvr.To.UTC.Hours*3600.);
}
#import "kernel32.dll"int GetTimeZoneInformation(int& TZInfoArray[]);
#importdatetime LocalTimeGMT(){ // TimeLocal to GMT forum.mql4.com/12057#522900// This is called only by TimeGMT. Check for IsDLLsAllowed() done there.int TZInfoArray[43];
int tz = GetTimeZoneInformation(TZInfoArray);
int GMTshift = TZInfoArray[0]; // GetTimeZoneInformation will return#define TIME_ZONE_ID_DAYLIGHT 2// the right Bias even when it returns#define TIME_ZONE_ID_UNKNOWN 0// UNKNOWNif (tz == TIME_ZONE_ID_DAYLIGHT || tz == TIME_ZONE_ID_UNKNOWN)
GMTshift += TZInfoArray[42];
return (TimeLocal() + GMTshift*60);
/*
* msdn.microsoft.com/en-us/library/windows/desktop/ms724421%28v=vs.85%29.aspx
* typedef struct _TIME_ZONE_INFORMATION { typedef struct _SYSTEMTIME {
* LONG Bias; [ 0] (min) WORD wYear; [0]
* WCHAR StandardName[32]; [ 1] WORD wMonth; Jan=1
* SYSTEMTIME StandardDate; [17] WORD wDayOfWeek; [1] Sun=1
* LONG StandardBias; [21] WORD wDay;
* WCHAR DaylightName[32]; [22] WORD wHour; [2]
* SYSTEMTIME DaylightDate; [38] WORD wMinute;
* LONG DaylightBias; [42] WORD wSecond; [3]
* } WORD wMilliseconds; }
*/
}
bool IsNYonDST(datetime whenNY){
// Market opens Sunday 6PM ET (NY local time) and closes Friday 4PM ET.// DST changes at 2AM Sunday, when the market is closed. I don't have to// worry about the passed time here, only the date.int year = TimeYear( whenNY); #define MARCH 3int mon = TimeMonth( whenNY); #define APRIL 4int dom = TimeDay( whenNY); #define OCTOBER 10int dow = TimeDayOfWeek(whenNY); #define NOVEMBER 11// http://en.wikipedia.org/wiki/Daylight_saving_time_in_the_United_States// #History_of_DST_in_the_United_States// 1986-2006 DST the first Sunday in April to the last Sunday in October// 2007 on second Sunday March first Sunday in Novemberif (year < 2007){ int monBeg=APRIL, secndSun=0, monEnd=OCTOBER; }
else{ monBeg=MARCH; secndSun=7; monEnd=NOVEMBER; }
if (mon < monBeg ) return(false); // Early spring.if ( mon > monEnd) return(false); // Late fall.if (mon != monBeg){ if (mon != monEnd) return(true); // Summer.if (year < 2007){ // Find last Sun = dom - (dow-SUNDAY) but SUNDAY==0for (int lastSun = dom-dow; lastSun+7 <= 31; lastSun += 7){}
return (dom < lastSun); // DST Before Sun. &
} } // not on markt open// Otherwise first or second Sunday of MonBegin or first Sunday of MonEndfor (int firstSun = dom + 7-dow; firstSun > 7; firstSun--){}
if (mon == monBeg) return (firstSun+secndSun <= dom); // DST On/Afterreturn (dom < firstSun); // DST Before Sun.
}
// Otherwise first or second Sunday of MonBegin or first Sunday of MonEnd// for (int firstSun = dom + 7-dow; firstSun > 7; firstSun--){}for (int firstSun = dom + 7-dow; firstSun > 7; firstSun -= 7){}
These are good points, there are many more things that are a guesswork even with MT4 functions, which not always return the correct value. For example broker and serverinfo on server and trading parameters, like variable spread, ECN or not, SL required or not turns out only from error handling, symbols info, etc.
Many of them are simply basic things which can not be (and should be) easily checked. For example info on opened charts and history data, time info (like GMT, timezone, DST), market open, close info.
Disaster Recovery would be really good, starting with MT4 not shutting down and restarting as it wants to (update), also terminal.exe proper shutdown, which stays frozen in task manager even hours later than the terminal was closed (and thought to be closed properly with close button without any error message).
Some kind of local datacenter support would be also good, it would make work easier instead of limited global variables and opened files. Not to mention storage of ask, bid, (spread) tick data which is missing.
There are many simple missing things which make life much harder together, and is an awful amount of work to handle them correctly if possible. Many external tips nad tricks even hacks are needed for extensive proper operation. I don't blame anyone who publishes a strategy on codebase and not handles all the possible (many of them broker-specific) problems with MT4 or the server - especially when the point is on the strategy not on error handling.
Even very simple things are missing, we cannot handle logfiles which can easily grow hundreds of megabytes or larger when something goes really wrong. They grow until the disk is full and nothing can be done, not even an optinon in the terminal settings on logfile handling.
Here's mine minus the actual trading logic.
And my correction for RaptorUK's comment:
I modified the Polyline code to allow overlays, ..
TLne Backwards compatible:
To draw on the sub chart just use iWin = WindowFind("indicatorName");
From a post about indicator drawing on both main chart and sub chart, TLine could be used for both with modifications.
To draw on the sub chart just use iWin = WindowFind("indicatorName");
Thanks
Market close time.
I wanted to close all orders before end of the week (market close Friday,) to prevent loss should the market gap over the week end, by passing the SL. (This is not modeled in the tester.)
So the question is when does the market close (or open.) All of the postings and searching on the net are plain wrong. From Forex Education - Introduction to Forex - IBFX Forex market operates 24 hours a day, 5.5 days a week (6:00 PM ET on Sunday until 4:00 PM ET on Friday) That's ET - New York local time.
This means that All postings depends on when they were made, as DST boundary's varies from year to year.
This means that it is necessary to compute when NY DST starts and ends, for the bar in question. (For back testing we need values to 2000 at least.) The problem is that Windows does not provide conversion routines except between the current TZ and UTC and only for the current year. If the PC isn't on ET it can't be done directly. Further more, until Windows8 comes out, you can't get conversions for ET and prior years. And looking at the Registry on Win7 the values only cover 2005 on (and those were wrong if I read them correctly.) So I'm not betting Win8 will be better.
This means that it is necessary to compute DST myself. I've updated my code: TimeGmt() and LocalTimeGMT() with default arguments, some additional documentation, and checks, and wrote code to compute market close time. Enjoy.
These are good points, there are many more things that are a guesswork even with MT4 functions, which not always return the correct value. For example broker and serverinfo on server and trading parameters, like variable spread, ECN or not, SL required or not turns out only from error handling, symbols info, etc.
Many of them are simply basic things which can not be (and should be) easily checked. For example info on opened charts and history data, time info (like GMT, timezone, DST), market open, close info.
Disaster Recovery would be really good, starting with MT4 not shutting down and restarting as it wants to (update), also terminal.exe proper shutdown, which stays frozen in task manager even hours later than the terminal was closed (and thought to be closed properly with close button without any error message).
Some kind of local datacenter support would be also good, it would make work easier instead of limited global variables and opened files. Not to mention storage of ask, bid, (spread) tick data which is missing.
There are many simple missing things which make life much harder together, and is an awful amount of work to handle them correctly if possible. Many external tips nad tricks even hacks are needed for extensive proper operation. I don't blame anyone who publishes a strategy on codebase and not handles all the possible (many of them broker-specific) problems with MT4 or the server - especially when the point is on the strategy not on error handling.
Even very simple things are missing, we cannot handle logfiles which can easily grow hundreds of megabytes or larger when something goes really wrong. They grow until the disk is full and nothing can be done, not even an optinon in the terminal settings on logfile handling.