Zeit-Enumeration über 0Uhr Problem optimieren (EA mit 2 Zeitfenstern (Signal&Trading) Wie zeiteffizient gestalten??

Einloggen oder registrieren, um einen Kommentar zu schreiben
Bayne
252
Bayne  

Folgender EA arbeitet mit dem Hoch und Tiefkurs eines bestimmten Tageszeitfensters. In einem zweiten TagesZeitfenster sollen dann mit die vorher genutzten Höchst und Tiefkurse als Signal mit PendingOrders getradet werden... (Ursprungscode stammt von @Otto Pauser)

Soweit sogut... Sofern alles am gleichen Tag geschieht funktioniert alles...

Nun habe ich aber das problem, dass ich keine Lösung finde, wenn ich dieses "Check"-Zeitfenster über die Nacht legen Möchte (bspw von 22Uhr bis 4Uhr).

Zumindest fällt mir kein zeiteffizienter Code ein, wie müsste ich also die DayChanged() (oder die OnInit() und OnTick()) Funktion abändern,

sodass ich die Checkphase (inp_CheckTimeBegin bis inp_CheckTimeEnd)  Über Nacht anlegen könnte?


enum ENUM_T30
{
   H00M00 =     0, // 00:00
   H00M30 =  1800, // 00:30
   H01M00 =  3600, // 01:00
   H01M30 =  5400, // 01:30
   H02M00 =  7200, // 02:00
   H02M30 =  9000, // 02:30
   H03M00 = 10800, // 03:00
   H03M30 = 12600, // 03:30
   H04M00 = 14400, // 04:00
   H04M30 = 16200, // 04:30
   H05M00 = 18000, // 05:00
   H05M30 = 19800, // 05:30
   H06M00 = 21600, // 06:00
   H06M30 = 23400, // 06:30
   H07M00 = 25200, // 07:00
   H07M30 = 27000, // 07:30
   H08M00 = 28800, // 08:00
   H08M30 = 30600, // 08:30
   H09M00 = 32400, // 09:00
   H09M30 = 34200, // 09:30
   H10M00 = 36000, // 10:00
   H10M30 = 37800, // 10:30
   H11M00 = 39600, // 11:00
   H11M30 = 41400, // 11:30
   H12M00 = 43200, // 12:00
   H12M30 = 45000, // 12:30
   H13M00 = 46800, // 13:00
   H13M30 = 48600, // 13:30
   H14M00 = 50400, // 14:00
   H14M30 = 52200, // 14:30
   H15M00 = 54000, // 15:00
   H15M30 = 55800, // 15:30
   H16M00 = 57600, // 16:00
   H16M30 = 59400, // 16:30
   H17M00 = 61200, // 17:00
   H17M30 = 63000, // 17:30
   H18M00 = 64800, // 18:00
   H18M30 = 66600, // 18:30
   H19M00 = 68400, // 19:00
   H19M30 = 70200, // 19:30
   H20M00 = 72000, // 20:00
   H20M30 = 73800, // 20:30
   H21M00 = 75600, // 21:00
   H21M30 = 77400, // 21:30
   H22M00 = 79200, // 22:00
   H22M30 = 81000, // 22:30
   H23M00 = 82800, // 23:00
   H23M30 = 84600  // 23:30
};

#ifdef __MQL5__

   int Hour()
   {
      MqlDateTime tm;
      TimeCurrent(tm);
      return(tm.hour);
   }

   int Day()
   {
      MqlDateTime tm;
      TimeCurrent(tm);
      return(tm.day);
   }

#endif

bool DayChanged()
{
   static int oldDay=Day();     ///Wie Kann ich diesen Part so ändern, dass die "CheckTimeBegin" 
         oldDay=newDay;         ///als Beginn für den neuen "Tag" gilt(wenn die Checkphase über die Nacht durchgeht(z.B. von 22Uhr bis 4Uhr))
   int newDay=Day();
   if(oldDay!=newDay)
      {         return(true);
      }
   return(false);
}

datetime EnumToDateTime(ENUM_T15 value)
{
   return(StringToTime(TimeToString(TimeCurrent(), TIME_DATE))+value);
}

datetime EnumToDateTime(ENUM_T30 value)
{
   return(StringToTime(TimeToString(TimeCurrent(), TIME_DATE))+value);
}

void NormalizeRange(datetime &rStart, datetime rEnd)
{
   if(rStart>rEnd)
      rStart-=86400;
}

bool InTimeRange(datetime aDateTime, datetime rStart, datetime rEnd)
{
   bool result=(aDateTime>=rStart) && (aDateTime<=rEnd);
   return(result);
}


//+------------------------------------------------------------------+
input ENUM_T30 inp_CheckTimeBegin = H00M00;  // Zeitspanne check High/Low Begin
input ENUM_T30 inp_CheckTimeEnd   = H08M00;  // Zeitspanne check High/Low Ende
input ENUM_T30 inp_TradeTimeBegin = H09M00;  // Handelszeit Begin
input ENUM_T30 inp_TradeTimeEnd   = H22M00;  // Handelszeit Ende
input ENUM_T30 inp_MinimaleCheckDauer =H05M00; //Minimale Zeitdauer des checkfensters
input int      inp_OffsetPending  =      3;  // Offset pending Orders (points)
input double   inp_Lotsize        =   0.01;  // Lots
input int      inp_SLLong             =    145;  // SL (points)
input int      inp_TPLong             =    250;  // TP (points)
input int      inp_SLShort             =    145;  // SL (points)
input int      inp_TPShort             =    250;  // TP (points)
input int      MagicNummer             =  77777;



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

int BuyStop,SellStop;
bool SL_Setzen,TP_Setzen,SL_Setzen2,TP_Setzen2;
double StopLossShort,StopLossLong,TakeProfitShort,TakeProfitLong,NewTP;
static bool siglong,sigshort;
static datetime lastOrderLong,lastOrderShort,lastSigLong,lastSigShort;

double   higestHI,
         lowestLO;

double   offset=inp_OffsetPending*_Point,
         slDistLong=inp_SLLong*_Point,
         tpDistLong=inp_TPLong*_Point,
         slDistShort=inp_SLShort*_Point,
         tpDistShort=inp_TPShort*_Point;

datetime checkTimeBegin,
         checkTimeEnd,
         tradeTimeBegin,
         tradeTimeEnd;

bool     calculated,
         setpending;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
{
// (nur für Optimierung) Richtige Reihenfolge Checken
//    if(!(inp_CheckTimeBegin<=inp_CheckTimeEnd && inp_CheckTimeEnd<=inp_TradeTimeBegin && (inp_TradeTimeEnd>=inp_TradeTimeBegin || inp_TradeTimeEnd<=inp_CheckTimeBegin)) || 
//       !(inp_CheckTimeEnd<=inp_TradeTimeBegin && inp_TradeTimeBegin<=inp_TradeTimeEnd && (inp_CheckTimeBegin>=inp_TradeTimeEnd || inp_CheckTimeBegin<=inp_CheckTimeEnd)) || 
//       !(inp_TradeTimeBegin<=inp_TradeTimeEnd && inp_TradeTimeEnd<=inp_CheckTimeBegin && (inp_CheckTimeEnd>=inp_CheckTimeBegin || inp_CheckTimeEnd<=inp_TradeTimeBegin)) || 
//       !(inp_TradeTimeEnd<=inp_CheckTimeBegin && inp_CheckTimeBegin<=inp_CheckTimeEnd && (inp_TradeTimeBegin>=inp_CheckTimeEnd || inp_TradeTimeBegin<=inp_TradeTimeEnd)))
//              {
//           Reihenfolge=true;}}else 
//              {
//               return(INIT_FAILED);}


   checkTimeBegin=EnumToDateTime(inp_CheckTimeBegin);
   checkTimeEnd  =EnumToDateTime(inp_CheckTimeEnd  );
   tradeTimeBegin=EnumToDateTime(inp_TradeTimeBegin);
   tradeTimeEnd  =EnumToDateTime(inp_TradeTimeEnd  );

   NormalizeRange(checkTimeBegin,checkTimeEnd);
   NormalizeRange(tradeTimeBegin,tradeTimeEnd);

   calculated=false;
   setpending=false;

   DeleteAllPendingOrders();

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
   if(DayChanged())
      OnInit();

   if(!InTimeRange(TimeCurrent(),checkTimeBegin,checkTimeEnd))
      if(!calculated)
         calculated=Calculate();

   if(InTimeRange(TimeCurrent(),tradeTimeBegin,tradeTimeEnd)){
      if(!setpending){
         setpending=SetPending();}
         }
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool Calculate()
{
   double values[];

   if(CopyHigh(_Symbol,_Period,checkTimeBegin,checkTimeEnd,values)==WRONG_VALUE) return(false);
   higestHI=values[ArrayMaximum(values)];

   if(CopyLow (_Symbol,_Period,checkTimeBegin,checkTimeEnd,values)==WRONG_VALUE) return(false);
   lowestLO=values[ArrayMinimum(values)];

   return(true);
}

Otto Pauser
1343
Otto Pauser  
Funktioniert die Funktion NormalizeRange(..) nicht? Die ist dafür gedacht den Zeitsprung über 0:00 zu korrigieren
Otto Pauser
1343
Otto Pauser  

Ich hab mir das nochmals angesehen. Ich denke das NOT passt nicht.

   if(!InTimeRange(TimeCurrent(),checkTimeBegin,checkTimeEnd))

so geht's

   if(InTimeRange(TimeCurrent(),checkTimeBegin,checkTimeEnd))
Carl Schreiber
Moderator
7642
Carl Schreiber  

Hmm - soweit ich Dich verstehe, beginnt Dein "Tag" mit checkTimeBegin und dann hast Du das Problem, dass die Tageszeit von checkTimeEnd kleiner ist als checkTimeBegin - richtig?

das ließe sich korrigieren leicht korrigieren, indem Du die datetime-Variablen in Stunde umrechnest:

#define  HoD(t) ((int)(((t)%86400)/3600))                // Hour of Day 2018.02.03 17:55:56 => (int) 17
...
checkTimeBegin = HoD(..)
checkTimeEnd = ( HoD(TimeCurrent() >= HoD(checkTimeBegin) ? HoD(TimeCurrent()) : HoD(TimeCurrent())+ 24) )

if (InTimeRange( HoD(TimeCurent(),checkTimeBegin, checkTimeEnd)

(UNGETESTET!)

Bayne
252
Bayne  

Dankeschön, hab ich leider übersehen...

aber warum minus 86400? (nur 23,5STd) statt 24Std?

 datetime EnumToDateTime(ENUM_T15 value)
     {
      return(StringToTime(TimeToString(TimeCurrent(), TIME_DATE))+value);
     }

   datetime EnumToDateTime(ENUM_T30 value)
     {
      return(StringToTime(TimeToString(TimeCurrent(), TIME_DATE))+value);
     }

   void NormalizeRange(datetime &rStart,datetime rEnd)
     {
      if(rStart>rEnd)
         rStart-=86400;
     }

   bool InTimeRange(datetime aDateTime,datetime rStart,datetime rEnd)
     {
      bool result=(aDateTime>=rStart) && (aDateTime<=rEnd);
      return(result);
     }

Verstehe weiterhin nicht, Warum die Daychanged() Funktion nur auf den Tag angepasst ist und nicht dann den nächsten Tag Zeigt,wenn checkTimeBegin ist.

Bayne
252
Bayne  
Bayne:

Dankeschön, hab ich leider übersehen...

aber warum minus 86400? (nur 23,5STd) statt 24Std?


Verstehe weiterhin nicht, Warum die Daychanged() Funktion nur auf den Tag angepasst ist und nicht dann den nächsten Tag Zeigt,wenn checkTimeBegin ist.

dann bleibt doch auch weiterhin dass Problem, dass nach Null Uhr alle Orders gelöscht werden oder? (falls das so ist, wäre blöd wenn die TradeTimeBegin um 23:30 beginnt)

Carl Schreiber
Moderator
7642
Carl Schreiber  
Bayne:

dann bleibt doch auch weiterhin dass Problem, dass nach Null Uhr alle Orders gelöscht werden oder? (falls das so ist, wäre blöd wenn die TradeTimeBegin um 23:30 beginnt)

Carl Schreiber:

Hmm - soweit ich Dich verstehe, beginnt Dein "Tag" mit checkTimeBegin und dann hast Du das Problem, dass die Tageszeit von checkTimeEnd kleiner ist als checkTimeBegin - richtig?

das ließe sich korrigieren leicht korrigieren, indem Du die datetime-Variablen in Stunde umrechnest:

(UNGETESTET!)

Ich hab einen kl. Denkfehler korrigiert: HoD( TC()+24*60*60) == HoD(TC()) - es muss natürlich heißen HoD(TC())+24!

Carl Schreiber
Moderator
7642
Carl Schreiber  
Bayne:

dann bleibt doch auch weiterhin dass Problem, dass nach Null Uhr alle Orders gelöscht werden oder? (falls das so ist, wäre blöd wenn die TradeTimeBegin um 23:30 beginnt)

Das Löschen muss halt passieren wenn:  !InTimeRange(..) :

if (InTimeRange(..)) { // trade
   ...
} else { // delete pending orders
  ...
}
Bayne
252
Bayne  
Carl Schreiber:

Das Löschen muss halt passieren wenn:  !InTimeRange(..) :

ich meine in der onInit(),

oder habe ich es Flasch verstanden, dass sobald sich der Tag ändert (also nicht die Range von checkTimeBegin zu checkTimeEnd, sondern das reale Tagesdatum), die OnInit() durchgeführt wird -> welche dann unabhängig von der InTimeRange() bools =false setzt & PendingOrders löscht

int OnInit()
{
   checkTimeBegin=EnumToDateTime(inp_CheckTimeBegin);
   checkTimeEnd  =EnumToDateTime(inp_CheckTimeEnd  );
   tradeTimeBegin=EnumToDateTime(inp_TradeTimeBegin);
   tradeTimeEnd  =EnumToDateTime(inp_TradeTimeEnd  );

   NormalizeRange(checkTimeBegin,checkTimeEnd);
   NormalizeRange(tradeTimeBegin,tradeTimeEnd);

   calculated=false;
   setpending=false;

   DeleteAllPendingOrders(); //Das hier meine Ich (und die beiden Bools), es gibt keine "Bedingung" die an die InTimeRange gebunden ist, 
                             //sondern für mich sieht das so aus als wäre es fest an das reale TagesDatum gebunden, liege ich falsch?
   return(INIT_SUCCEEDED);
}
Carl Schreiber
Moderator
7642
Carl Schreiber  

Meiner Meinung nach sollte ein EA 24/7 (oder 24-h/5-d) laufen oder willst Du ihn jeden Tag händisch anstellen?

Bayne
252
Bayne  
Da geb ich dir auf jeden Fall Recht
Carl Schreiber:

Hmm - soweit ich Dich verstehe, beginnt Dein "Tag" mit checkTimeBegin und dann hast Du das Problem, dass die Tageszeit von checkTimeEnd kleiner ist als checkTimeBegin - richtig?

das ließe sich korrigieren leicht korrigieren, indem Du die datetime-Variablen in Stunde umrechnest:

(UNGETESTET!)

Wenn das hiermit Klappen sollte und er 24/7 laufen kann ist alles super

Kannst du mir vielleicht zeigen wo im Code ich diese Änderungen (zur Umrechnung in Stunde)
Platzieren muss? (Sieht mir zu fortgeschritten aus für meine Kenntnisse)
Einloggen oder registrieren, um einen Kommentar zu schreiben