test_WeekendData_v2

Author: Calli
0 Views
0 Downloads
0 Favorites
test_WeekendData_v2
ÿþ/*+------------------------------------------------------------------+

//|                                             test_WeekendData.mq5 |

//|                                                            Calli |

//|                              https://www.mql5.com/de/users/gooly |

//| DST USA spring: 2nd. Su. in Mar. autum: 1st. Su. in Nov.         |

//| DST EU  spring: last Su. in Mar. autum: last Su. in Oct.         |

//| DST AUS spring: 1st. Su. in Apr. autum: 1st. Su. in Oct.         |

//| Seq. of Chg: Summer USA, Summer EU, Autum EU, Autum USA          |

//| Timeline Summer: AUS 1st  Su.Mar,USA 2nd Su.Mar, EU last Su.Mar  |

//| Timeline Winter: AUS 1st  Su.Oct,EU last Su.Oct, USA 1st  Su.Nov |

//+------------------------------------------------------------------*/



/*+---------------  Comment Russian/English  -------------------------+

 A>60;5=8N, O >1=0@C68;, GB> =5:>B>@K5 1@>:5@K

7<5=5=85 2@5<5=8 =0 A5@25@5 =5<=>3> =5:>@@5:B=>, G53> O =5 >6840;.

8 GB> <5=O >G5=L C4828;>.

>B A:@8?B, :>B>@K9 :064K9 <>65B 8A?>;L7>20BL 4;O ?@>25@:8 A2>53> 1@>:5@0.



!5AA8O FOREX 4;8BAO @>2=> 120 G0A>2:

A 2>A:@5A5=LO 17:00 ?> 2>AB>G=><C AB0=40@B=><C 2@5<5=8 (!525@=0O <5@8:0) 8;8 EST

4> 17:00 ?OB=8FK ?> 2>AB>G=><C 2@5<5=8.



@>1;5<0 2>7=8:05B 87-70 ?5@5E>40 =0 ;5B=55 8 78<=55 2@5<O,

:>B>@K5 =5 ?@>2>4OBAO 2 >4=8 8 B5 65 2>A:@5A5=LO 2 @07=KE @538>=0E <8@0.



 !(, =0?@8<5@, A<5=0 ?@>8AE>48B 2> 2B>@>5 2>A:@5A5=L5 <0@B0 8 ?5@2>5 2>A:@5A5=L5 =>O1@O.

GB> B0:65 2;8O5B =0 =0G0;> 8 :>=5F A5AA88 FOREX.



! ?@54AB028B A2>9 5653>4=K9 >BG5B 2 ?>A;54=55 2>A:@5A5=L5 <0@B0, ?>A;5 !(, 0 2

?>A;54=55 2>A:@5A5=L5 >:BO1@O, B.5. 2 !( (A<. E@>=>;>38N 2KH5).



-B> A>7405B ?5@5E>4=CN D07C, 2 :>B>@>9 !( 8 ! 8<5NB @07=K5

 07=8F0 2> 2@5<5=8 1>;LH5 >1KG=>9 @07=8FK 2 5 G0A>2.

G0A>2 (>=4>=), 6 G0A>2 ($@0=:DC@B, CET) 8;8 7 G0A>2 (8?@, EET).



 B> 65 2@5<O MB> 87<5=5=85 @07=8FK 2> 2@5<5=8 4>;6=> 1KBL >B@065=> 2

7<5=5=0 2@5<5==0O <5B:0 ?5@2>3> 8 ?>A;54=53> G0A0 A5AA88 FOREX.

"0:8< >1@07><, 5A;8 A5AA8O FOREX =0G8=05BAO 2 ?>=545;L=8: 2 00:00 (EET, 2@5<O MQ), >=0 4>;6=0

>A;5 MB>3> 87<5=5=8O 2@5<O 2 !( 1C45B =0G8=0BLAO =0 G0A @0=LH5, B.5. 2 2>A:@5A5=L5 2 23:00.

8 70:0=G8205BAO =0 G0A @0=LH5 2 ?OB=8FC, 2 23:00 (8;8 22:59:59).



>, : A>60;5=8N, <=5 ?@8H;>AL >A>7=0BL (8 A MB8< A:@8?B>< :064K9 <>65B A45;0BL MB> A0<>AB>OB5;L=>)

 59B8=3 1@>:5@>2), :>B>@K9 4>ABC?5= =0 45<>-AG5B5 MQ 8 =0 AG5B0E =5:>B>@KE @50;L=KE 1@>:5@>2

?5@2K9 G0A 2A5340(!) ?>O2;O5BAO 2 ?>=545;L=8: 2 00:00, => ?>A;54=89 G0A, :0: 8 >6840;>AL

2 ?OB=8FC 2 23:00 (8;8 22:59) 8;8 =0 G0A @0=LH5. B0:, ?5@2K9 G0A >BACBAB2C5B.

!5AA8O FOREX, =0 :>B>@>9 B@5945@ 8;8 :>=AC;LB0=B <>65B >B@5038@>20BL =0 A>1KB8O 2KE>4=>3> 4=O.

@><5 B>3>, >:>=G0=85 A5AA88 FOREX 1>;LH5 =5 <>65B 1KBL >?@545;5=> ?@>ABK< ?@8102;5=85< 120 :

?5@2K9 G0A A5AA88 FOREX, =0?@8<5@, GB>1K 70:@KBL 2A5 ?>78F88 ?5@54 2KE>4=K<8.



-B>B A:@8?B B5?5@L ?@>25@O5B, 87<5=8;>AL ;8 2@5<O 1@>:5@0 2 ?@>H;><, 8 @538AB@8@C5B 2A5

!5AA88 FOREX, :>B>@K5 O2=> AB@0==K5 8;8 =5 4;OBAO 120 G0A>2. A;8 <564C

A;8 <564C ?5@2K< 8 ?>A;54=8< G0A>< A5AA88 FOREX ?@>H;> 120 G0A>2, 70?8AL 2 6C@=0;5 =5 ?@>872>48BAO.



 :>=F5 A:@8?B >B>1@0605B ?>A;54=NN ?>;CG5==CN 2@5<5==CN <5B:C, :>;8G5AB2> =0945==KE

A>:@0I5==K5 ?5@8>4K A5AA89 8 ?@81;878B5;L=>5 :>;8G5AB2> ;5B, ?@8=OBKE 2> 2=8<0=85.





Unfortunately, I discovered that some brokers are a bit sloppy with the server time

change due to the daylight saving time (DST), which I did not expect and which surprised me a lot.



The FOREX session is exactly 120 hours:

from Sunday 5:00 p.m. Eastern Standard Time (North America) or EST

  to Friday 5:00 p.m. EST.



The problem arises from the time changes to summer time and winter time, which do not

take place on the same Sundays in the different regions of the world.



For example, the USA changes on the 2nd Sunday in March and the 1st Sunday in November,

and this also affects the start and end of the FOREX session.



The EU changes on the last Sunday in March i.e. after the USA and on the

last Sunday in October i.e. before the USA (see above Timeline).



This creates an interim period in which the USA and the EU have a different time differences

than the normal differences of 5 hours (London), 6 hours (Frankfurt, CET) or 7 hours (Cyprus, EET).



In this	interim period, this change of the time difference should be reflected in the changed

time stamps of the first and last hours of the FOREX session. So if the FOREX session starts

on Monday at 00:00 (EET, MQ time), after the USA has changed it should start an hour earlier,

i.e. Sunday at 23:00 and end an hour earlier on Friday, i.e. 23:00 (or 22:59:59).



But unfortunately I had to find out (and with this script anyone can check this with their broker)

that on a MQ demo account and on accounts of some real brokers the first hour always(!) appears

on Monday at 00:00, but the last hour, as expected,

on Friday at 23:00 (or 22:59) or one hour earlier. This means that the first hour of the

FOREX session, in which the trader or an EA could react to weekend events, is missing.

Also, the end of the FOREX session can no longer be determined by simply adding 120

to the first hour of the FOREX session, e.g. to close all positions before the weekend.



This script now checks the broker's time changes in the past and logs all FOREX sessions

that are obviously incorrect (odd) or not 120 hours. If there are 120 hours

between the first and last hour of a FOREX session, nothing is logged.



At the end the script prints the last retrieved timestamp, the number of odd sessions

found and the approximate number of years that have been checked.

//+------------------------------------------------------------------*/





#property copyright "Calli"

#property link      "https://www.mql5.com/de/users/gooly"

#property version   "1.01"



//+------------------------------------------------------------------+

//| needed #define to shorten code                                   |

//+------------------------------------------------------------------+

string  _WkDy[] = {"Su.","Mo.","Tu.","We.","Th.","Fr.","Sa."};

#define DoWs(t) (_WkDy[DoWi(t)])                               // Day of Week as string:  Sun, Mon, Tue, ...

#define DoWi(t) ((int)((t)/86400+4)%7)                         // Day of Week as integer:  Sun=0, Mon=1, Tue=2, ...

#define BoW(t) ((t)-((t)+345600)%604800)                       // Begin of Week 2017.08.03 11:30 => Sun, 2017.07.30 00:00 (fixed version)

#define WeekInSec    604800                                    // 60sec*60min*24h*7d = 604800 => 1 Week

#define _tSu(t)  DoWs(t)+" "+TimeToString(t,TIME_DATE)

#define _tWkD(t) DoWs(t)+" "+TimeToString(t,TIME_DATE|TIME_MINUTES)



MqlDateTime t¤;                                                // hidden auxiliary variable: the ¤ is a Greek character, so virtually no danger

int MoY(const datetime t) {TimeToStruct(t,t¤);return(t¤.mon);} // TimeMonthOfYear:  1,212





//+------------------------------------------------------------------+

//| 2 variables to control the printout                              |

//+------------------------------------------------------------------+

datetime tmeEndCheck   = D'1970.01.01 00:00'; //2022.01.01 00:00';   // stop if this date is triggered, '1970.01.01 00:00' means max.

int      maxOddSess    = 20;                    // max.number of odd lines found: either sessions (!=120h) or weekend (!=48h)





//+------------------------------------------------------------------+

//| Script program start function                                    |

//+------------------------------------------------------------------+

void OnStart()

   {

//---

    if(!TerminalInfoInteger(TERMINAL_CONNECTED))

       {

        Print("Not connected with ",AccountInfoString(ACCOUNT_COMPANY));

        return;

       }



//--- Get the earliest possible date to determin a meaninful period: earliest datetime, given datetime, or 1.5 years back form TimeCurrent()

    datetime first_server_date=0;

    if(!SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_SERVER_FIRSTDATE,first_server_date))

       {

        Print("Calling hist data failed: ",_LastError);

        return;

       }

    tmeEndCheck = fmin(fmin(TimeCurrent() - 47304000, tmeEndCheck),first_server_date);        // 47304000 = 1,5*365*24*3600 to look back at least 1.5 years.

//Print(tmeEndCheck," <=> ",first_server_date," <=> ",TimeCurrent() - 47304000); return;



//--- time vars.

    datetime dSu = DoWi(TimeCurrent()) > 1 ? BoW(TimeCurrent()) : BoW(TimeCurrent() - 345600),   // 345600 = 4*24*3600 4 days back in case it's Monday

             aTm1[], aTm9[],                                    // arrays for datetime values h1

             startCheck = BoW(TimeCurrent());                   // BoW => last Sunday



//--- aux. variables

    int      hD0,                                               // duration of the time gap of the weekend: Fr 17:00 NYt - So. 17:00 NYt = 48h + 1 (Fr. last full hour 16:00-17:00) = 49 h

             hWk,                                               // duration of Fx-Session from open So. 17:00 to Fr. 17:00 (120 h) - 1h (for Fr. 16:00) = 119 h

             b9,                                                // no. of many h1 bars

             b1 = CopyTime("EURUSD",PERIOD_H1,dSu,1,aTm1),      // no. of last h1 bar bfore weekend

             nOdd = 0;                                          // no. of odd weeks detected







//--- Test for MetaQuotes Ltd. starting week Su. 2025.01.12 - Su. 2025.01.19,  last hour before actual week: Fr. 2025.01.10 23:00

    if(b1>-1)

        Print("Weekend test for ",AccountInfoString(ACCOUNT_COMPANY)," on ",_Symbol," with starting at ", _tSu(startCheck)," - ", _tSu(startCheck+WeekInSec),", back into the past."); // Last theoretical timestamp before the actual week: ",_tWkD(aTm1[0]+(59*61)));

    else

        Print("Weekend test for ",AccountInfoString(ACCOUNT_COMPANY)," with start at ", _tSu(startCheck)," ",_tSu(dSu),"  b1: ",b1," err of CopyTime():",_LastError);

    Print("Weekend test will end either at tmeEndCheck: ",_tSu(tmeEndCheck)," or if MaxOddSess: ",maxOddSess," is triggered.");

    Print("Weekend test: an odd weekend gap (!= 48h) precedes a possibly odd FOREX session (!= 120)");

    Print("Timeline: Summer: AUS 1st Su.Mar, USA 2nd Su.Mar, EU last Su.Mar => Winter: AUS 1st Su.Oct, EU last Su.Oct, USA 1st Su.Nov");



    if((dSu - aTm1[0])/3600 > 4*24*3600)

        Print("Quote gap for ",AccountInfoString(ACCOUNT_COMPANY)," from ",_tWkD(dSu)," to ",_tWkD(aTm1[0])," = ", ((dSu - aTm1[0])/3600 > 4*24*3600),"h");



    bool isOdd=false, isOK=false;

    while(dSu>tmeEndCheck && !IsStopped() && maxOddSess >0)

       {





        //--- Skip Dec. and Jan. due to the many holidays and there is no change of DST

        while(MoY(dSu)<2 || MoY(dSu)>11)

            dSu -= WeekInSec;



        //--- get the last bar before the weekend gap

        b1 = CopyTime("EURUSD",PERIOD_H1,dSu,1,aTm1);

        if(b1<0)

           {

            Print(" FAILED  ",_tSu(dSu),"  b1: ",b1," e:",_LastError);

            continue;

           }



        //--- get the first bar after the weekend

        b9 = CopyTime("EURUSD",PERIOD_H1,aTm1[0],dSu+3*24*3600,aTm9);

        if(b9<3)

           {

            Print(" FAILED  ",_tWkD(dSu+WeekInSec),"  b9: ",b9," e:",_LastError);

            continue;

           }



        //--- get the last bar before the next weekend

        b1 = CopyTime("EURUSD",PERIOD_H1, dSu+WeekInSec,1,aTm1);

        if(b1<1)

           {

            Print(" FAILED  ",_tWkD(dSu+WeekInSec),"  b1: ",b1," e:",_LastError);

            continue;

           }



        //--- calc. the hours of the weekend gap and the following FX.-session

        hD0 = int((aTm9[1] - aTm9[0])/3600) - 1;  // -1 because th last h1 bar (e.g. 22:00) opens ~1h before the FX. session closes (e.g. 23:00)

        hWk = int((aTm1[0] - aTm9[1])/3600) + 1;  // +1 because th last h1 bar (e.g. 22:00) opens ~1h before the FX. session closes (e.g. 23:00)



        string sAdd = StringFormat("OK  48 / 120  Month:% 3d  USA DST == EU DST", MoY(aTm9[1]));

        //--- print only if the weekend gap != 48h (e.g. Fr. 23:00 - Su. 23:00) or the FGX session != 120h (Su. 23:00 - Fr. 23:00 = 5*24=120) and NOT the current week

        if((hD0!=48 || hWk!=120) && startCheck > aTm1[0])

           {

            sAdd = (hD0==48 && hWk==120)

                   ?                         StringFormat("OK  %2d / %3d  Month:% 3d  USA DST == EU DST",     hD0,hWk, MoY(aTm9[1]))

                   : (hD0!=48 && hWk!=120) ? StringFormat("odd %2d / %3d  Month:% 3d  USA DST != EU DST",     hD0,hWk, MoY(aTm9[1]))

                   : hD0!=48 ?               StringFormat("odd %2d / %3d  Month:% 3d  USA winter, EU summer", hD0,hWk, MoY(aTm9[1]))

                   :                         StringFormat("odd %2d / %3d  Month:% 3d  USA summer, EU winter", hD0,hWk, MoY(aTm9[1]));



            Print("odd  Last QTS: ",_tWkD(aTm9[0]+3540)," nxt. Sess: ",_tWkD(aTm9[1])," - ",_tWkD(aTm1[0]+3540),"  ",sAdd);

            isOdd=true;

            isOK=false;

            if(hWk!=120)

               {

                nOdd++;

                maxOddSess --;

               }

            isOK = false;

           }

        else

            //Print("Check ",_tSu(dSu)," Last H1: ",_tWkD(aTm9[0])," FX-Session(h1): ",_tWkD(aTm9[1])," - ",_tWkD(aTm1[0]+3600),"  Su.Gap:",hD0,"h   Fx.Sess:",hWk,"h  gap & sess. = OK");

            if(!isOK)

               {

                Print("OK   Last QTS: ",_tWkD(aTm9[0]+3540)," nxt. Sess: ",_tWkD(aTm9[1])," - ",_tWkD(aTm1[0]+3540)+"  "+sAdd);

                isOK = true;

               }



        //--- jump the next previous weekend

        dSu -= WeekInSec;



       }



    Print("Done - last date checked: ", _tWkD(aTm1[0]),", ",nOdd," odd FOREX sessions (weeks) detected within ~",(int)(startCheck-aTm1[0])/(3600*24*365)," years");

    return;

   }



Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---