Skip to content

Commit 4f04e1a

Browse files
author
EarnForex
authored
1.02
1. Added an option to load the schedule via a text file. 2. Added a way to make the Scheduler to wait until there are no open positions or pending orders before switching AutoTrading off.
1 parent 03c6fe9 commit 4f04e1a

6 files changed

Lines changed: 384 additions & 34 deletions

File tree

MQL4/Experts/AutoTrading Scheduler/AutoTrading Scheduler.mq4

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#property copyright "EarnForex.com"
22
#property link "https://www.earnforex.com/metatrader-expert-advisors/AutoTrading-Scheduler/"
3-
#property version "1.01"
4-
string Version = "1.01";
3+
#property version "1.02"
4+
string Version = "1.02";
55
#property strict
66

77
#property description "Creates a weekly schedule when AutoTrading is enabled."
@@ -30,6 +30,9 @@ input bool DefaultClosePos = false; // Close all positions before turning AutoTr
3030
input bool DefaultEnforce = true; // Always enforce schedule?
3131
input string ____Miscellaneous = "================";
3232
input int Slippage = 2; // Slippage
33+
input string ScheduleFile = ""; // ScheduleFile (optional)
34+
input bool WaitForNoPositions = false; // Switch A/T off only when there are no open positions?
35+
input bool WaitForNoOrders = false; // Switch A/T off only when there are no pending orders?
3336

3437
CScheduler Panel;
3538

@@ -61,6 +64,8 @@ int OnInit()
6164
Panel.Run();
6265
Panel.IniFileLoad();
6366

67+
if (ScheduleFile != "") Panel.LoadScheduleFile();
68+
6469
// Brings panel on top of other objects without actual maximization of the panel.
6570
Panel.HideShowMaximize();
6671

MQL4/Experts/AutoTrading Scheduler/AutoTrading Scheduler.mqh

Lines changed: 197 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public:
3636
virtual bool SaveSettingsOnDisk();
3737
virtual bool LoadSettingsFromDisk();
3838
virtual bool DeleteSettingsFile();
39+
virtual bool LoadScheduleFile();
3940
virtual bool OnEvent(const int id, const long& lparam, const double& dparam, const string& sparam);
4041
virtual bool RefreshValues();
4142
virtual void RefreshPanelControls();
@@ -46,7 +47,6 @@ public:
4647
int remember_top, remember_left;
4748
private:
4849
virtual bool CreateObjects();
49-
virtual bool InitObjects();
5050
virtual bool ButtonCreate (CButton& Btn, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text);
5151
virtual bool CheckBoxCreate (CCheckBox& Chk, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text);
5252
virtual bool EditCreate (CEdit& Edt, const int X1, const int Y1, const int X2, const int Y2, const string Name, const string Text);
@@ -63,6 +63,8 @@ private:
6363
ENUM_TOGGLE CompareTime(int &_hours[], int &_minutes[], const int hour, const int minute, int &_hours_prev[], int &_minutes_prev[]);
6464
void Toggle_AutoTrading();
6565
void Notify(const int count, const bool enable_or_disable);
66+
bool ExistsPosition();
67+
bool ExistsOrder();
6668

6769
// Event handlers
6870
void OnChangeChkClosePos();
@@ -316,37 +318,37 @@ void CScheduler::RefreshPanelControls()
316318
// Refresh time type radio group.
317319
m_RgpTimeType.Value(sets.TimeType);
318320

319-
if (m_EdtMonday.Text() != sets.Monday)
321+
if ((m_EdtMonday.Text() != sets.Monday) && (m_EdtMonday.Text() != "<<FILE>>"))
320322
{
321323
m_EdtMonday.Text(sets.Monday);
322324
EditDay(Mon_Hours, Mon_Minutes, m_EdtMonday, sets.Monday);
323325
}
324-
if (m_EdtTuesday.Text() != sets.Tuesday)
326+
if ((m_EdtTuesday.Text() != sets.Tuesday) && (m_EdtTuesday.Text() != "<<FILE>>"))
325327
{
326328
m_EdtTuesday.Text(sets.Tuesday);
327329
EditDay(Tue_Hours, Tue_Minutes, m_EdtTuesday, sets.Tuesday);
328330
}
329-
if (m_EdtWednesday.Text() != sets.Wednesday)
331+
if ((m_EdtWednesday.Text() != sets.Wednesday) && (m_EdtWednesday.Text() != "<<FILE>>"))
330332
{
331333
m_EdtWednesday.Text(sets.Wednesday);
332334
EditDay(Wed_Hours, Wed_Minutes, m_EdtWednesday, sets.Wednesday);
333335
}
334-
if (m_EdtThursday.Text() != sets.Thursday)
336+
if ((m_EdtThursday.Text() != sets.Thursday) && (m_EdtThursday.Text() != "<<FILE>>"))
335337
{
336338
m_EdtThursday.Text(sets.Thursday);
337339
EditDay(Thu_Hours, Thu_Minutes, m_EdtThursday, sets.Thursday);
338340
}
339-
if (m_EdtFriday.Text() != sets.Friday)
341+
if ((m_EdtFriday.Text() != sets.Friday) && (m_EdtFriday.Text() != "<<FILE>>"))
340342
{
341343
m_EdtFriday.Text(sets.Friday);
342344
EditDay(Fri_Hours, Fri_Minutes, m_EdtFriday, sets.Friday);
343345
}
344-
if (m_EdtSaturday.Text() != sets.Saturday)
346+
if ((m_EdtSaturday.Text() != sets.Saturday) && (m_EdtSaturday.Text() != "<<FILE>>"))
345347
{
346348
m_EdtSaturday.Text(sets.Saturday);
347349
EditDay(Sat_Hours, Sat_Minutes, m_EdtSaturday, sets.Saturday);
348350
}
349-
if (m_EdtSunday.Text() != sets.Sunday)
351+
if ((m_EdtSunday.Text() != sets.Sunday) && (m_EdtSunday.Text() != "<<FILE>>"))
350352
{
351353
m_EdtSunday.Text(sets.Sunday);
352354
EditDay(Sun_Hours, Sun_Minutes, m_EdtSunday, sets.Sunday);
@@ -467,15 +469,20 @@ void CScheduler::OnClickBtnSetToAll()
467469
void CScheduler::EditDay(int &_hours[], int &_minutes[], CEdit &edt, string &sets_value)
468470
{
469471
string time = StringTrimRight(StringTrimLeft(edt.Text()));
472+
if (edt.ReadOnly()) time = sets_value; // It was read from file.
470473
int length = StringLen(time);
471474

472475
// For empty string, just clear everything.
473476
if (length == 0)
474477
{
475478
ArrayResize(_hours, 0);
476479
ArrayResize(_minutes, 0);
477-
sets_value = "";
478-
edt.Text("");
480+
if (!edt.ReadOnly()) // Otherwise it was read from the file.
481+
{
482+
sets_value = "";
483+
edt.Text("");
484+
}
485+
else sets_value = "<<FILE>>";
479486
return;
480487
}
481488

@@ -491,7 +498,11 @@ void CScheduler::EditDay(int &_hours[], int &_minutes[], CEdit &edt, string &set
491498
}
492499
}
493500

494-
edt.Text(time);
501+
if (!edt.ReadOnly()) edt.Text(time);
502+
else
503+
{
504+
edt.Text("<<FILE>>");
505+
}
495506

496507
// Divide.
497508
string times[];
@@ -560,9 +571,16 @@ void CScheduler::EditDay(int &_hours[], int &_minutes[], CEdit &edt, string &set
560571
ArrayResize(_hours, k);
561572
ArrayResize(_minutes, k);
562573

563-
sets_value = time;
564-
565-
SaveSettingsOnDisk();
574+
if (!edt.ReadOnly())
575+
{
576+
sets_value = time;
577+
SaveSettingsOnDisk();
578+
}
579+
else
580+
{
581+
sets_value = "<<FILE>>";
582+
// Settings are saved to disk via LoadScheduleFile().
583+
}
566584
}
567585

568586
void CScheduler::OnEndEditEdtMonday()
@@ -721,6 +739,57 @@ bool CScheduler::LoadSettingsFromDisk()
721739
else if (var_name == "Sunday")
722740
sets.Sunday = var_content;
723741

742+
// To avoid keeping the FILE schedule when we remove or change the Schedule File.
743+
if (sets.Monday == "<<FILE>>")
744+
{
745+
sets.Monday = "";
746+
m_EdtMonday.Text("");
747+
m_EdtMonday.ReadOnly(false);
748+
m_EdtMonday.ColorBackground(clrWhite);
749+
}
750+
if (sets.Tuesday == "<<FILE>>")
751+
{
752+
sets.Tuesday = "";
753+
m_EdtTuesday.Text("");
754+
m_EdtTuesday.ReadOnly(false);
755+
m_EdtTuesday.ColorBackground(clrWhite);
756+
}
757+
if (sets.Wednesday == "<<FILE>>")
758+
{
759+
sets.Wednesday = "";
760+
m_EdtWednesday.Text("");
761+
m_EdtWednesday.ReadOnly(false);
762+
m_EdtWednesday.ColorBackground(clrWhite);
763+
}
764+
if (sets.Thursday == "<<FILE>>")
765+
{
766+
sets.Thursday = "";
767+
m_EdtThursday.Text("");
768+
m_EdtThursday.ReadOnly(false);
769+
m_EdtThursday.ColorBackground(clrWhite);
770+
}
771+
if (sets.Friday == "<<FILE>>")
772+
{
773+
sets.Friday = "";
774+
m_EdtFriday.Text("");
775+
m_EdtFriday.ReadOnly(false);
776+
m_EdtFriday.ColorBackground(clrWhite);
777+
}
778+
if (sets.Saturday == "<<FILE>>")
779+
{
780+
sets.Saturday = "";
781+
m_EdtSaturday.Text("");
782+
m_EdtSaturday.ReadOnly(false);
783+
m_EdtSaturday.ColorBackground(clrWhite);
784+
}
785+
if (sets.Sunday == "<<FILE>>")
786+
{
787+
sets.Sunday = "";
788+
m_EdtSunday.Text("");
789+
m_EdtSunday.ReadOnly(false);
790+
m_EdtSunday.ColorBackground(clrWhite);
791+
}
792+
724793
// Is the expert advisor reloading due to the input parameters change?
725794
else if (GlobalVariableGet("ATS-" + IntegerToString(ChartID()) + "-Parameters") > 0)
726795
{
@@ -794,6 +863,87 @@ bool CScheduler::DeleteSettingsFile()
794863
return true;
795864
}
796865

866+
bool CScheduler::LoadScheduleFile()
867+
{
868+
if (!FileIsExist(ScheduleFile))
869+
{
870+
Print("Schedule file not found: ", ScheduleFile, ".");
871+
return false;
872+
}
873+
int fh = FileOpen(ScheduleFile, FILE_TXT | FILE_READ);
874+
if (fh == INVALID_HANDLE)
875+
{
876+
Print("Failed to open file for reading: " + ScheduleFile + ". Error: " + IntegerToString(GetLastError()));
877+
return false;
878+
}
879+
880+
Print("Reading schedule from file: ", ScheduleFile, ".");
881+
882+
while (!FileIsEnding(fh))
883+
{
884+
string weekday = FileReadString(fh);
885+
string schedule = FileReadString(fh);
886+
887+
if ((weekday == "Monday") || (weekday == "Mon"))
888+
{
889+
sets.Monday = schedule;
890+
m_EdtMonday.ReadOnly(true);
891+
m_EdtMonday.ColorBackground(CONTROLS_EDIT_COLOR_DISABLE);
892+
EditDay(Mon_Hours, Mon_Minutes, m_EdtMonday, sets.Monday);
893+
}
894+
else if ((weekday == "Tuesday") || (weekday == "Tue"))
895+
{
896+
sets.Tuesday = schedule;
897+
m_EdtTuesday.ReadOnly(true);
898+
m_EdtTuesday.ColorBackground(CONTROLS_EDIT_COLOR_DISABLE);
899+
EditDay(Tue_Hours, Tue_Minutes, m_EdtTuesday, sets.Tuesday);
900+
}
901+
else if ((weekday == "Wednesday") || (weekday == "Wed"))
902+
{
903+
sets.Wednesday = schedule;
904+
m_EdtWednesday.ReadOnly(true);
905+
m_EdtWednesday.ColorBackground(CONTROLS_EDIT_COLOR_DISABLE);
906+
EditDay(Wed_Hours, Wed_Minutes, m_EdtWednesday, sets.Wednesday);
907+
}
908+
else if ((weekday == "Thursday") || (weekday == "Thu"))
909+
{
910+
sets.Thursday = schedule;
911+
m_EdtThursday.ReadOnly(true);
912+
m_EdtThursday.ColorBackground(CONTROLS_EDIT_COLOR_DISABLE);
913+
EditDay(Thu_Hours, Thu_Minutes, m_EdtThursday, sets.Thursday);
914+
}
915+
else if ((weekday == "Friday") || (weekday == "Fri"))
916+
{
917+
sets.Friday = schedule;
918+
m_EdtFriday.ReadOnly(true);
919+
m_EdtFriday.ColorBackground(CONTROLS_EDIT_COLOR_DISABLE);
920+
EditDay(Fri_Hours, Fri_Minutes, m_EdtFriday, sets.Friday);
921+
}
922+
else if ((weekday == "Saturday") || (weekday == "Sat"))
923+
{
924+
sets.Saturday = schedule;
925+
m_EdtSaturday.ReadOnly(true);
926+
m_EdtSaturday.ColorBackground(CONTROLS_EDIT_COLOR_DISABLE);
927+
EditDay(Sat_Hours, Sat_Minutes, m_EdtSaturday, sets.Saturday);
928+
}
929+
else if ((weekday == "Sunday") || (weekday == "Sun"))
930+
{
931+
sets.Sunday = schedule;
932+
m_EdtSunday.ReadOnly(true);
933+
m_EdtSunday.ColorBackground(CONTROLS_EDIT_COLOR_DISABLE);
934+
EditDay(Sun_Hours, Sun_Minutes, m_EdtSunday, sets.Sunday);
935+
}
936+
Print(weekday);
937+
Print(schedule);
938+
}
939+
940+
FileClose(fh);
941+
942+
SaveSettingsOnDisk();
943+
944+
return true;
945+
}
946+
797947
void CScheduler::HideShowMaximize()
798948
{
799949
// Remember the panel's location.
@@ -827,7 +977,6 @@ void CScheduler::CheckTimer()
827977
int hour = TimeHour(time);
828978
int minute = TimeMinute(time);
829979
int weekday = TimeDayOfWeek(time);
830-
831980
switch(weekday)
832981
{
833982
// Monday
@@ -863,6 +1012,11 @@ void CScheduler::CheckTimer()
8631012
{
8641013
if (StartedToggling) return;
8651014
StartedToggling = true;
1015+
if (((WaitForNoPositions) && (ExistsPosition())) || ((WaitForNoOrders) && (ExistsOrder())))
1016+
{
1017+
StartedToggling = false;
1018+
return;
1019+
}
8661020
int n_closed = 0;
8671021
if (sets.ClosePos)
8681022
{
@@ -1134,4 +1288,32 @@ void CScheduler::Notify(const int count, const bool enable_or_disable)
11341288
if (!SendNotification(AppText)) Print("Error sending notification: " + IntegerToString(GetLastError()));
11351289
}
11361290
}
1291+
1292+
// Returns true if at least one position is open.
1293+
bool CScheduler::ExistsPosition()
1294+
{
1295+
int total = OrdersTotal();
1296+
for (int i = 0; i < total; i++)
1297+
{
1298+
if (OrderSelect(i, SELECT_BY_POS))
1299+
{
1300+
if ((OrderType() == OP_BUY) || (OrderType() == OP_SELL)) return true;
1301+
}
1302+
}
1303+
return false;
1304+
}
1305+
1306+
// Returns true if there is at least one pending order.
1307+
bool CScheduler::ExistsOrder()
1308+
{
1309+
int total = OrdersTotal();
1310+
for (int i = 0; i < total; i++)
1311+
{
1312+
if (OrderSelect(i, SELECT_BY_POS))
1313+
{
1314+
if ((OrderType() != OP_BUY) && (OrderType() != OP_SELL)) return true;
1315+
}
1316+
}
1317+
return false;
1318+
}
11371319
//+------------------------------------------------------------------+

MQL4/Experts/AutoTrading Scheduler/Defines.mqh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <Controls\Label.mqh>
55
#include <Controls\RadioGroup.mqh>
66

7+
color CONTROLS_EDIT_COLOR_DISABLE = C'221,221,211';
8+
79
enum ENUM_TIME_TYPE
810
{
911
Local,

MQL5/Experts/AutoTrading Scheduler/AutoTrading Scheduler.mq5

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#property copyright "EarnForex.com"
22
#property link "https://www.earnforex.com/metatrader-expert-advisors/AutoTrading-Scheduler/"
3-
#property version "1.01"
4-
string Version = "1.01";
3+
#property version "1.02"
4+
string Version = "1.02";
55
#property strict
66

77
#property description "Creates a weekly schedule when AutoTrading is enabled."
@@ -31,6 +31,9 @@ input bool DefaultClosePos = false; // Close all positions before turning AutoTr
3131
input bool DefaultEnforce = true; // Always enforce schedule?
3232
input group "Miscellaneous"
3333
input int Slippage = 2; // Slippage
34+
input string ScheduleFile = ""; // ScheduleFile (optional)
35+
input bool WaitForNoPositions = false; // Switch A/T off only when there are no open positions?
36+
input bool WaitForNoOrders = false; // Switch A/T off only when there are no pending orders?
3437

3538
CScheduler Panel;
3639

@@ -57,11 +60,13 @@ int OnInit()
5760
sets.Enforce = DefaultEnforce;
5861
sets.ClosePos = DefaultClosePos;
5962
}
60-
63+
6164
if (!Panel.Create(0, "AutoTrading Scheduler (ver. " + Version + ")", 0, 20, 20)) return(-1);
6265
Panel.Run();
6366
Panel.IniFileLoad();
6467

68+
if (ScheduleFile != "") Panel.LoadScheduleFile();
69+
6570
// Brings panel on top of other objects without actual maximization of the panel.
6671
Panel.HideShowMaximize();
6772

0 commit comments

Comments
 (0)