-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathTMA+CG+Martingale_EA.mq5
4376 lines (3861 loc) · 124 KB
/
TMA+CG+Martingale_EA.mq5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//+------------------------------------------------------------------+
//| Copyright © 2020, Gehtsoft USA LLC |
//| http://fxcodebase.com |
//+------------------------------------------------------------------+
//| Developed by : Mario Jemic |
//| [email protected] |
//| https://AppliedMachineLearning.systems |
//+------------------------------------------------------------------+
//| Support our efforts by donating |
//| Paypal : https://goo.gl/9Rj74e |
//| Patreon : https://goo.gl/GdXWeN |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Gehtsoft USA LLC"
#property link "http://fxcodebase.com"
#property version "1.0"
#property strict
input int HalfLength = 20;
input ENUM_APPLIED_PRICE Price=PRICE_WEIGHTED; //=0-6 PRICE_CLOSE,PRICE_OPEN,PRICE_HIGH,PRICE_LOW,PRICE_MEDIAN,PRICE_TYPICAL,PRICE_WEIGHTED
input double BandsDeviations = 2.3; //2.7; //1.618;
input bool use_TF1 = true; // Use timeframe 1
input ENUM_TIMEFRAMES TF1 = PERIOD_CURRENT; // Timeframe 1
input bool use_TF2 = true; // Use timeframe 2
input ENUM_TIMEFRAMES TF2 = PERIOD_CURRENT; // Timeframe 2
#define ACT_ON_SWITCH_CONDITION
#define TAKE_PROFIT_FEATURE
#define STOP_LOSS_FEATURE
#define USE_MARKET_ORDERS
// Order side v1.1
#ifndef OrderSide_IMP
#define OrderSide_IMP
enum OrderSide
{
BuySide,
SellSide
};
OrderSide GetOppositeSide(OrderSide side)
{
return side == BuySide ? SellSide : BuySide;
}
#endif
#ifndef tradeManager_INSTANCE
#define tradeManager_INSTANCE
#include <Trade\Trade.mqh>
CTrade tradeManager;
#endif
enum TradingMode
{
TradingModeOnBarClose, // Entry on candle close
TradingModeLive // Entry on tick
};
enum TradingDirection
{
LongSideOnly, // Long only
ShortSideOnly, // Short only
BothSides // Both
};
// Stop/limit type v1.0
#ifndef StopLimitType_IMP
#define StopLimitType_IMP
enum StopLimitType
{
StopLimitDoNotUse, // Do not use
StopLimitPercent, // Set in %
StopLimitPips, // Set in Pips
StopLimitDollar, // Set in $,
StopLimitRiskReward, // Set in % of stop loss (take profit only)
StopLimitAbsolute // Set in absolite value (rate)
};
#endif
// Position size type
#ifndef PositionSizeType_IMP
#define PositionSizeType_IMP
enum PositionSizeType
{
PositionSizeAmount, // $
PositionSizeContract, // In contracts
PositionSizeEquity, // % of equity
PositionSizeRisk, // Risk in % of equity
PositionSizeMoneyPerPip, // $ per pip
PositionSizeRiskCurrency // Risk in $
};
#endif
// Supported stop loss types v1.1
#ifndef StopLossType_IMP
#define StopLossType_IMP
enum StopLossType
{
SLDoNotUse, // Do not use
SLPercent, // Set in %
SLPips, // Set in Pips
SLDollar, // Set in $,
SLAbsolute, // Set in absolite value (rate),
SLAtr, // Set in ATR(value) * mult
SLRiskBalance // Set in % of risked balance
};
#endif
// Take profit type v1.0
#ifndef TakeProfitType_IMP
#define TakeProfitType_IMP
enum TakeProfitType
{
TPDoNotUse, // Do not use
TPPercent, // Set in %
TPPips, // Set in Pips
TPDollar, // Set in $,
TPRiskReward, // Set in % of stop loss
TPAbsolute, // Set in absolite value (rate),
TPAtr // Set in ATR(value) * mult
};
#endif
enum PositionDirection
{
DirectLogic, // Direct
ReversalLogic // Reversal
};
enum TrailingType
{
TrailingDontUse, // No trailing
TrailingPips, // Use trailing in pips
TrailingPercent // Use trailing in % of stop
};
input string GeneralSection = ""; // == General ==
input string symbols = ""; // Symbols to trade. Separated by ","
input bool allow_trading = true; // Allow trading
input bool BTCAccount = false; // Is BTC Account?
input TradingMode entry_logic = TradingModeOnBarClose; // Entry type
#ifdef WITH_EXIT_LOGIC
input TradingMode exit_logic = TradingModeOnBarClose; // Exit type
#endif
input TradingDirection trading_side = BothSides; // What trades should be taken
input double lots_value = 0.1; // Position size
input PositionSizeType lots_type = PositionSizeContract; // Position size type
input int slippage_points = 3; // Slippage, in points
input bool close_on_opposite = true; // Close on opposite
input string SLSection = ""; // == Stop loss/TakeProfit ==
input StopLossType stop_loss_type = SLPips; // Stop loss type
input double stop_loss_value = 10; // Stop loss value
input TrailingType trailing_type = TrailingDontUse; // Use trailing
input double trailing_start = 0; // Min distance to order to activate the trailing
input double trailing_step = 10; // Trailing step
input TakeProfitType take_profit_type = TPPips; // Take profit type
input double take_profit_value = 10; // Take profit value
input double take_profit_atr_multiplicator = 1.0; // Take profit ATR Multiplicator
// input StopLimitType breakeven_type = StopLimitPips; // Trigger type for the breakeven
// input double breakeven_value = 10; // Trigger for the breakeven
input string PositionCapSection = ""; // == Position cap ==
input bool use_position_cap = true; // Use position cap?
input int max_positions = 2; // Max positions
enum MartingaleType
{
MartingaleDoNotUse, // Do not use
MartingaleOnLoss // Open another position on loss
};
enum MartingaleLotSizingType
{
MartingaleLotSizingNo, // No lot sizing
MartingaleLotSizingMultiplicator, // Using miltiplicator
MartingaleLotSizingAdd // Addition
};
enum MartingaleStepSizeType
{
MartingaleStepSizePips, // Pips
MartingaleStepSizePercent, // %
};
#ifdef MARTINGALE_FEATURE
input string MartingaleSection = ""; // == Martingale type ==
input MartingaleType martingale_type = MartingaleDoNotUse; // Martingale type
input MartingaleLotSizingType martingale_lot_sizing_type = MartingaleLotSizingNo; // Martingale lot sizing type
input double martingale_lot_value = 1.5; // Matringale lot sizing value
MartingaleStepSizeType martingale_step_type = MartingaleStepSizePips; // Step unit
input double martingale_step = 50; // Open matringale position step
input int max_longs = 5; // Max long positions
input int max_shorts = 5; // Max short positions
#endif
enum DayOfWeek
{
DayOfWeekSunday = 0, // Sunday
DayOfWeekMonday = 1, // Monday
DayOfWeekTuesday = 2, // Tuesday
DayOfWeekWednesday = 3, // Wednesday
DayOfWeekThursday = 4, // Thursday
DayOfWeekFriday = 5, // Friday
DayOfWeekSaturday = 6 // Saturday
};
input string OtherSection = ""; // == Other ==
input int magic_number = 42; // Magic number
input PositionDirection logic_direction = DirectLogic; // Logic type
input string StartTime = "000000"; // Start time in hhmmss format
input string EndTime = "235959"; // End time in hhmmss format
input bool LimitWeeklyTime = false; // Weekly time
input DayOfWeek WeekStartDay = DayOfWeekSunday; // Start day
input string WeekStartTime = "000000"; // Start time in hhmmss format
input DayOfWeek WeekStopDay = DayOfWeekSaturday; // Stop day
input string WeekStopTime = "235959"; // Stop time in hhmmss format
input bool MandatoryClosing = false; // Mandatory closing for non-trading time
input bool print_log = false; // Print decisions into the log
input string log_file = "log.csv"; // Log file name
//Signaler v 1.4
input string AlertsSection = ""; // == Alerts ==
input bool Popup_Alert = true; // Popup message
input bool Notification_Alert = false; // Push notification
input bool Email_Alert = false; // Email
input bool Play_Sound = false; // Play sound on alert
input string Sound_File = ""; // Sound file
#ifdef ADVANCED_ALERTS
input bool Advanced_Alert = false; // Advanced alert
input string Advanced_Key = ""; // Advanced alert key
input string Comment2 = "- You can get a key via @profit_robots_bot Telegram Bot. Visit ProfitRobots.com for discord/other platform keys -";
input string Comment3 = "- Allow use of dll in the indicator parameters window -";
input string Comment4 = "- Install AdvancedNotificationsLib using ProfitRobots installer -";
// AdvancedNotificationsLib.dll could be downloaded here: http://profitrobots.com/Home/TelegramNotificationsMT4
#import "AdvancedNotificationsLib.dll"
void AdvancedAlert(string key, string text, string instrument, string timeframe);
#import
#endif
// Trading time condition v1.1
// Condition base v2.1
#ifndef ACondition_IMP
#define ACondition_IMP
// ICondition v3.0
#ifndef ICondition_IMP
#define ICondition_IMP
interface ICondition
{
public:
virtual void AddRef() = 0;
virtual void Release() = 0;
virtual bool IsPass(const int period, const datetime date) = 0;
virtual string GetLogMessage(const int period, const datetime date) = 0;
};
#endif
class AConditionBase : public ICondition
{
int _references;
string _conditionName;
public:
AConditionBase(string name = "")
{
_conditionName = name;
_references = 1;
}
virtual void AddRef()
{
++_references;
}
virtual void Release()
{
--_references;
if (_references == 0)
delete &this;
}
virtual string GetLogMessage(const int period, const datetime date)
{
if (_conditionName == "" || _conditionName == NULL)
{
return "";
}
return _conditionName + ": " + (IsPass(period, date) ? "true" : "false");
}
};
#endif
#ifndef TradingTimeCondition_IMP
#define TradingTimeCondition_IMP
class TradingTime
{
int _startTime;
int _endTime;
bool _useWeekTime;
int _weekStartTime;
int _weekStartDay;
int _weekStopTime;
int _weekStopDay;
public:
TradingTime()
{
_startTime = 0;
_endTime = 0;
_useWeekTime = false;
}
bool SetWeekTradingTime(const DayOfWeek startDay, const string startTime, const DayOfWeek stopDay,
const string stopTime, string &error)
{
_useWeekTime = true;
_weekStartTime = ParseTime(startTime, error);
if (_weekStartTime == -1)
return false;
_weekStopTime = ParseTime(stopTime, error);
if (_weekStopTime == -1)
return false;
_weekStartDay = (int)startDay;
_weekStopDay = (int)stopDay;
return true;
}
bool Init(const string startTime, const string endTime, string &error)
{
_startTime = ParseTime(startTime, error);
if (_startTime == -1)
return false;
_endTime = ParseTime(endTime, error);
if (_endTime == -1)
return false;
return true;
}
bool IsTradingTime(datetime dt)
{
if (_startTime == _endTime && !_useWeekTime)
return true;
MqlDateTime current_time;
if (!TimeToStruct(dt, current_time))
return false;
if (!IsIntradayTradingTime(current_time))
return false;
return IsWeeklyTradingTime(current_time);
}
private:
bool IsIntradayTradingTime(const MqlDateTime ¤t_time)
{
if (_startTime == _endTime)
return true;
int current_t = TimeToInt(current_time);
if (_startTime > _endTime)
return current_t >= _startTime || current_t <= _endTime;
return current_t >= _startTime && current_t <= _endTime;
}
int TimeToInt(const MqlDateTime ¤t_time)
{
return (current_time.hour * 60 + current_time.min) * 60 + current_time.sec;
}
bool IsWeeklyTradingTime(const MqlDateTime ¤t_time)
{
if (!_useWeekTime)
return true;
if (current_time.day_of_week < _weekStartDay || current_time.day_of_week > _weekStopDay)
return false;
if (current_time.day_of_week == _weekStartDay)
{
int current_t = TimeToInt(current_time);
return current_t >= _weekStartTime;
}
if (current_time.day_of_week == _weekStopDay)
{
int current_t = TimeToInt(current_time);
return current_t < _weekStopTime;
}
return true;
}
int ParseTime(const string time, string &error)
{
int time_parsed = (int)StringToInteger(time);
int seconds = time_parsed % 100;
if (seconds > 59)
{
error = "Incorrect number of seconds in " + time;
return -1;
}
time_parsed /= 100;
int minutes = time_parsed % 100;
if (minutes > 59)
{
error = "Incorrect number of minutes in " + time;
return -1;
}
time_parsed /= 100;
int hours = time_parsed % 100;
if (hours > 24 || (hours == 24 && (minutes > 0 || seconds > 0)))
{
error = "Incorrect number of hours in " + time;
return -1;
}
return (hours * 60 + minutes) * 60 + seconds;
}
};
class TradingTimeCondition : public AConditionBase
{
TradingTime *_tradingTime;
ENUM_TIMEFRAMES _timeframe;
public:
TradingTimeCondition(ENUM_TIMEFRAMES timeframe)
:AConditionBase("Trading time")
{
_timeframe = timeframe;
_tradingTime = new TradingTime();
}
~TradingTimeCondition()
{
delete _tradingTime;
}
bool Init(const string startTime, const string endTime, string &error)
{
return _tradingTime.Init(startTime, endTime, error);
}
virtual bool IsPass(const int period)
{
datetime time = iTime(_Symbol, _timeframe, period);
return _tradingTime.IsTradingTime(time);
}
};
#endif
// Disabled condition v1.1
#ifndef DisabledCondition_IMP
#define DisabledCondition_IMP
class DisabledCondition : public AConditionBase
{
public:
DisabledCondition()
:AConditionBase("Disabled")
{
}
virtual bool IsPass(const int period, const datetime date) { return false; }
};
#endif
// And condition v1.1
#ifndef AndCondition_IMP
#define AndCondition_IMP
class AndCondition : public AConditionBase
{
ICondition *_conditions[];
public:
~AndCondition()
{
int size = ArraySize(_conditions);
for (int i = 0; i < size; ++i)
{
_conditions[i].Release();
}
}
void Add(ICondition *condition, bool addRef)
{
int size = ArraySize(_conditions);
ArrayResize(_conditions, size + 1);
_conditions[size] = condition;
if (addRef)
{
condition.AddRef();
}
}
virtual bool IsPass(const int period, const datetime date)
{
int size = ArraySize(_conditions);
for (int i = 0; i < size; ++i)
{
if (!_conditions[i].IsPass(period, date))
return false;
}
return true;
}
virtual string GetLogMessage(const int period, const datetime date)
{
string messages = "";
int size = ArraySize(_conditions);
for (int i = 0; i < size; ++i)
{
string logMessage = _conditions[i].GetLogMessage(period, date);
if (messages != "")
messages = messages + " and (" + logMessage + ")";
else
messages = "(" + logMessage + ")";
}
return messages + (IsPass(period, date) ? "=true" : "=false");
}
};
#endif
// Base condition v1.1
#ifndef ABaseCondition_IMP
#define ABaseCondition_IMP
// Symbol info v1.3
#ifndef InstrumentInfo_IMP
#define InstrumentInfo_IMP
class InstrumentInfo
{
string _symbol;
double _mult;
double _point;
double _pipSize;
int _digit;
double _ticksize;
public:
InstrumentInfo(const string symbol)
{
_symbol = symbol;
_point = SymbolInfoDouble(symbol, SYMBOL_POINT);
_digit = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
_mult = _digit == 3 || _digit == 5 ? 10 : 1;
_pipSize = _point * _mult;
_ticksize = NormalizeDouble(SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE), _digit);
}
// Return < 0 when lot1 < lot2, > 0 when lot1 > lot2 and 0 owtherwise
int CompareLots(double lot1, double lot2)
{
double lotStep = SymbolInfoDouble(_symbol, SYMBOL_VOLUME_STEP);
if (lotStep == 0)
{
return lot1 < lot2 ? -1 : (lot1 > lot2 ? 1 : 0);
}
int lotSteps1 = (int)floor(lot1 / lotStep + 0.5);
int lotSteps2 = (int)floor(lot2 / lotStep + 0.5);
int res = lotSteps1 - lotSteps2;
return res;
}
static double GetPipSize(const string symbol)
{
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
double digit = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
double mult = digit == 3 || digit == 5 ? 10 : 1;
return point * mult;
}
double GetPointSize() { return _point; }
double GetPipSize() { return _pipSize; }
int GetDigits() { return _digit; }
string GetSymbol() { return _symbol; }
static double GetBid(const string symbol) { return SymbolInfoDouble(symbol, SYMBOL_BID); }
static double GetAsk(const string symbol) { return SymbolInfoDouble(symbol, SYMBOL_ASK); }
double GetBid() { return SymbolInfoDouble(_symbol, SYMBOL_BID); }
double GetAsk() { return SymbolInfoDouble(_symbol, SYMBOL_ASK); }
double GetMinLots() { return SymbolInfoDouble(_symbol, SYMBOL_VOLUME_MIN); };
double RoundRate(const double rate)
{
return NormalizeDouble(MathRound(rate / _ticksize) * _ticksize, _digit);
}
double RoundLots(const double lots)
{
double lotStep = SymbolInfoDouble(_symbol, SYMBOL_VOLUME_STEP);
if (lotStep == 0)
{
return 0.0;
}
return floor(lots / lotStep) * lotStep;
}
double LimitLots(const double lots)
{
double minVolume = GetMinLots();
if (minVolume > lots)
{
return 0.0;
}
double maxVolume = SymbolInfoDouble(_symbol, SYMBOL_VOLUME_MAX);
if (maxVolume < lots)
{
return maxVolume;
}
return lots;
}
double NormalizeLots(const double lots)
{
return LimitLots(RoundLots(lots));
}
};
#endif
class ACondition : public AConditionBase
{
protected:
ENUM_TIMEFRAMES _timeframe;
InstrumentInfo* _instrument;
string _symbol;
public:
ACondition(const string symbol, ENUM_TIMEFRAMES timeframe, string name = NULL)
:AConditionBase(name)
{
_instrument = new InstrumentInfo(symbol);
_timeframe = timeframe;
_symbol = symbol;
}
~ACondition()
{
delete _instrument;
}
};
#endif
// No condition v1.1
#ifndef NoCondition_IMP
#define NoCondition_IMP
class NoCondition : public AConditionBase
{
public:
NoCondition()
:AConditionBase("No condition")
{
}
bool IsPass(const int period, const datetime date) { return true; }
};
#endif
// Not condition v1.1
#ifndef NotCondition_IMP
#define NotCondition_IMP
class NotCondition : public AConditionBase
{
ICondition* _condition;
public:
NotCondition(ICondition* condition)
{
_condition = condition;
_condition.AddRef();
}
~NotCondition()
{
_condition.Release();
}
virtual bool IsPass(const int period, const datetime date)
{
return !_condition.IsPass(period, date);
}
virtual string GetLogMessage(const int period, const datetime date)
{
return "Not (" + _condition.GetLogMessage(period, date) + (IsPass(period, date) ? ")=true" : ")=false");
}
};
#endif
#ifdef ACT_ON_SWITCH_CONDITION
// Act on switch condition v1.1
#ifndef ActOnSwitchCondition_IMP
#define ActOnSwitchCondition_IMP
class ActOnSwitchCondition : public ACondition
{
ICondition* _condition;
bool _current;
datetime _currentDate;
bool _last;
public:
ActOnSwitchCondition(string symbol, ENUM_TIMEFRAMES timeframe, ICondition* condition)
:ACondition(symbol, timeframe)
{
_last = false;
_current = false;
_currentDate = 0;
_condition = condition;
_condition.AddRef();
}
~ActOnSwitchCondition()
{
_condition.Release();
}
virtual bool IsPass(const int period, const datetime date)
{
datetime time = iTime(_symbol, _timeframe, period);
if (time != _currentDate)
{
_last = _current;
_currentDate = time;
}
_current = _condition.IsPass(period, date);
return _current && !_last;
}
virtual string GetLogMessage(const int period, const datetime date)
{
return "Switch of (" + _condition.GetLogMessage(period, date) + (IsPass(period, date) ? ")=true" : ")=false");
}
};
#endif
#endif
// IStream v.2.0
interface IStream
{
public:
virtual void AddRef() = 0;
virtual void Release() = 0;
virtual bool GetValues(const int period, const int count, double &val[]) = 0;
virtual bool GetSeriesValues(const int period, const int count, double &val[]) = 0;
virtual int Size() = 0;
};
// Market entry strategy v1.1
// Entry strategy v1.1
// Money management strategy interface v1.0
#ifndef IMoneyManagementStrategy_IMP
#define IMoneyManagementStrategy_IMP
interface IMoneyManagementStrategy
{
public:
virtual void Get(const int period, const double entryPrice, double &amount, double &stopLoss, double &takeProfit) = 0;
};
#endif
#ifndef IEntryStrategy_IMP
#define IEntryStrategy_IMP
interface IEntryStrategy
{
public:
virtual void AddRef() = 0;
virtual void Release() = 0;
virtual ulong OpenPosition(const int period, OrderSide side, IMoneyManagementStrategy *moneyManagement, const string comment, bool ecnBroker) = 0;
virtual int Exit(const OrderSide side) = 0;
};
#endif
// Action on condition logic v2.0
// Action on condition v3.0
// Action v2.0
#ifndef IAction_IMP
interface IAction
{
public:
virtual void AddRef() = 0;
virtual void Release() = 0;
virtual bool DoAction(const int period, const datetime date) = 0;
};
#define IAction_IMP
#endif
#ifndef ActionOnConditionController_IMP
#define ActionOnConditionController_IMP
class ActionOnConditionController
{
bool _finished;
ICondition *_condition;
IAction* _action;
public:
ActionOnConditionController()
{
_action = NULL;
_condition = NULL;
_finished = true;
}
~ActionOnConditionController()
{
if (_action != NULL)
_action.Release();
if (_condition != NULL)
_condition.Release();
}
bool Set(IAction* action, ICondition *condition)
{
if (!_finished || action == NULL)
return false;
if (_action != NULL)
_action.Release();
_action = action;
_action.AddRef();
_finished = false;
if (_condition != NULL)
_condition.Release();
_condition = condition;
_condition.AddRef();
return true;
}
void DoLogic(const int period, const datetime date)
{
if (_finished)
return;
if ( _condition.IsPass(period, date))
{
if (_action.DoAction(period, date))
_finished = true;
}
}
};
#endif
#ifndef ActionOnConditionLogic_IMP
#define ActionOnConditionLogic_IMP
class ActionOnConditionLogic
{
ActionOnConditionController* _controllers[];
public:
~ActionOnConditionLogic()
{
int count = ArraySize(_controllers);
for (int i = 0; i < count; ++i)
{
delete _controllers[i];
}
}
void DoLogic(const int period, const datetime date)
{
int count = ArraySize(_controllers);
for (int i = 0; i < count; ++i)
{
_controllers[i].DoLogic(period, date);
}
}
bool AddActionOnCondition(IAction* action, ICondition* condition)
{
int count = ArraySize(_controllers);
for (int i = 0; i < count; ++i)
{
if (_controllers[i].Set(action, condition))
return true;
}
ArrayResize(_controllers, count + 1);
_controllers[count] = new ActionOnConditionController();
return _controllers[count].Set(action, condition);
}
};
#endif
#ifndef MarketEntryStrategy_IMP
#define MarketEntryStrategy_IMP
class MarketEntryStrategy : public IEntryStrategy
{
string _symbol;
int _magicNumber;
int _slippagePoints;
ActionOnConditionLogic* _actions;
int _references;
public:
MarketEntryStrategy(const string symbol,
const int magicMumber,
const int slippagePoints,
ActionOnConditionLogic* actions)
{
_actions = actions;
_magicNumber = magicMumber;
_slippagePoints = slippagePoints;
_symbol = symbol;
_references = 1;
}
virtual void AddRef()
{
++_references;
}
virtual void Release()
{
--_references;
if (_references == 0)
delete &this;
}
ulong OpenPosition(const int period, OrderSide side, IMoneyManagementStrategy *moneyManagement, const string comment, bool ecnBroker)
{
double entryPrice = side == BuySide ? InstrumentInfo::GetAsk(_symbol) : InstrumentInfo::GetBid(_symbol);
double amount;
double takeProfit;
double stopLoss;
moneyManagement.Get(period, entryPrice, amount, stopLoss, takeProfit);
if (amount == 0.0)
return -1;
string error = "";
MarketOrderBuilder *orderBuilder = new MarketOrderBuilder(_actions);
ulong order = orderBuilder
.SetSide(side)
.SetECNBroker(ecnBroker)
.SetInstrument(_symbol)
.SetAmount(amount)
.SetSlippage(_slippagePoints)
.SetMagicNumber(_magicNumber)
.SetStopLoss(stopLoss)
.SetTakeProfit(takeProfit)
.SetComment(comment)
.Execute(error);
delete orderBuilder;
if (error != "")
{
Print("Failed to open position: " + error);
}
return order;
}
int Exit(const OrderSide side)
{
TradesIterator toClose();
toClose.WhenSide(side);
toClose.WhenMagicNumber(_magicNumber);
return TradingCommands::CloseTrades(toClose);
}
};
#endif
// Trades iterator v 1.3
// Compare type v1.0
#ifndef CompareType_IMP
#define CompareType_IMP
enum CompareType
{
CompareLessThan
};
#endif
#ifndef TradesIterator_IMP