Mql5 Language Reference: For The Metatrader 5 Client Terminal
Mql5 Language Reference: For The Metatrader 5 Client Terminal
Mql5 Language Reference: For The Metatrader 5 Client Terminal
Content
MQL5 Reference 67
1 Language Basics................................................................................................. 69
Syntax ............................................................................................................................70
Comments......................................................................................................................... 71
I dentifiers......................................................................................................................... 72
Reserved Words
......................................................................................................................... 73
Data Types ............................................................................................................................75
I nteger Types
......................................................................................................................... 76
Char, Short, I................................................................................................................
nt and Long Types 77
Character Constants
................................................................................................................ 81
Datetime Type
................................................................................................................ 84
Color Type ................................................................................................................ 85
Bool Type ................................................................................................................ 86
Enumerations................................................................................................................ 87
Real Types.........................................................................................................................
(double, float) 89
String Type
......................................................................................................................... 94
Structures,
.........................................................................................................................
Classes and I nterfaces 95
Dynamic .........................................................................................................................
Array Object 120
Typecasting
......................................................................................................................... 121
Void Type
.........................................................................................................................
and NULL Constant 126
User-defined
.........................................................................................................................
Types 127
Object Pointers
......................................................................................................................... 137
References:
.........................................................................................................................
Modifier & and Keyword this 140
Operations............................................................................................................................142
and Expressions
Expressions
......................................................................................................................... 143
Arithmetic
.........................................................................................................................
Operations 144
Assignment
.........................................................................................................................
Operations 145
Operations
.........................................................................................................................
of Relation 146
Boolean Operations
......................................................................................................................... 147
Bitwise Operations
......................................................................................................................... 149
Other Operations
......................................................................................................................... 152
Precedence
.........................................................................................................................
Rules 156
Operators ............................................................................................................................158
Compound
.........................................................................................................................
Operator 160
Expression
.........................................................................................................................
Operator 161
Return Operator
......................................................................................................................... 162
Conditional
.........................................................................................................................
Operator if-else 163
Ternary Operator
.........................................................................................................................
?: 164
Switch Operator
......................................................................................................................... 166
Loop Operator
.........................................................................................................................
while 168
Loop Operator
.........................................................................................................................
for 169
Loop Operator
.........................................................................................................................
do while 170
Break Operator
......................................................................................................................... 171
Continue.........................................................................................................................
Operator 172
Object Create
.........................................................................................................................
Operator new 173
Object Delete
.........................................................................................................................
Operator delete 174
Functions ............................................................................................................................175
Function.........................................................................................................................
Call 177
Passing Parameters
......................................................................................................................... 178
Function.........................................................................................................................
Overloading 181
Operation
.........................................................................................................................
Overloading 184
Description
.........................................................................................................................
of External Functions 197
Exporting
.........................................................................................................................
Functions 199
Event Handling
.........................................................................................................................
Functions 200
Variables ............................................................................................................................211
Local Variables
......................................................................................................................... 213
Formal Parameters
......................................................................................................................... 215
Static Variables
......................................................................................................................... 217
Global Variables
......................................................................................................................... 219
I nput Variables
......................................................................................................................... 220
Extern Variables
......................................................................................................................... 224
I nitializ ation
.........................................................................................................................
of Variables 225
Visibility .........................................................................................................................
Scope and Lifetime of Variables 227
Creating.........................................................................................................................
and Deleting Objects 229
............................................................................................................................232
Preprocessor
Macro substitution (#define)
......................................................................................................................... 234
Properties (#property)
Program......................................................................................................................... 237
Files (#include)
I ncluding......................................................................................................................... 243
I mporting Functions (#import)
......................................................................................................................... 244
Conditional Compilation (#ifdef, #ifndef, #else, #endif)
......................................................................................................................... 246
............................................................................................................................248
Object-Oriented Programming
Encapsulation
.........................................................................................................................
and Extensibility of Types 250
I nheritance
......................................................................................................................... 253
Polymorphism
......................................................................................................................... 258
Overload......................................................................................................................... 262
Virtual Functions
......................................................................................................................... 263
Static Members
.........................................................................................................................
of a Class 267
Function.........................................................................................................................
templates 271
Class templates
......................................................................................................................... 275
Abstract.........................................................................................................................
Classes 280
2 Constants, Enumerations
.................................................................................................
and Structures 282
............................................................................................................................283
Chart Constants
Types of .........................................................................................................................
Chart Events 284
Chart Timeframes
......................................................................................................................... 291
Chart Properties
......................................................................................................................... 293
Positioning
.........................................................................................................................
Constants 301
Chart Representation
......................................................................................................................... 302
Examples.........................................................................................................................
of Working with the Chart 304
............................................................................................................................362
Objects Constants
Object Types
......................................................................................................................... 363
OBJ_VLI NE ................................................................................................................ 365
OBJ_HLI NE ................................................................................................................ 370
OBJ_TREND ................................................................................................................ 375
OBJ_TRENDB................................................................................................................
Y ANGLE 382
OBJ_C Y CLES................................................................................................................ 388
OBJ_ARROWED _LI NE
................................................................................................................ 394
OBJ_CHANNEL
................................................................................................................ 400
OBJ_STDDEVCHANNEL
................................................................................................................ 407
OBJ_REGRESSI
................................................................................................................
ON 414
OBJ_PI TCHFORK
................................................................................................................ 420
OBJ_GANNLI................................................................................................................
NE 428
OBJ_GANNFAN
................................................................................................................ 435
OBJ_GANNGRI
................................................................................................................
D 442
OBJ_FI BO ................................................................................................................ 449
OBJ_FI BOTI MES
................................................................................................................ 456
OBJ_FI BOFAN
................................................................................................................ 463
OBJ_FI BOARC
................................................................................................................ 470
OBJ_FI BOCHANNEL
................................................................................................................ 477
OBJ_EX PANSI
................................................................................................................
ON 485
OBJ_ELLI OTWAVE5
................................................................................................................ 493
OBJ_ELLI OTWAVE3
................................................................................................................ 501
OBJ_RECTANGLE
................................................................................................................ 508
OBJ_TRI ANGLE
................................................................................................................ 514
OBJ_ELLI PSE................................................................................................................ 521
OBJ_ARROW................................................................................................................
_THUMB_UP 527
OBJ_ARROW................................................................................................................
_THUMB_DOWN 533
OBJ_ARROW................................................................................................................
_UP 539
OBJ_ARROW................................................................................................................
_DOWN 545
OBJ_ARROW................................................................................................................
_STOP 551
OBJ_ARROW................................................................................................................
_CHECK 557
OBJ_ARROW................................................................................................................
_LEFT_PRI CE 563
OBJ_ARROW................................................................................................................
_RI GHT_PRI CE 568
OBJ_ARROW................................................................................................................
_BUY 573
OBJ_ARROW................................................................................................................
_SELL 578
OBJ_ARROW................................................................................................................ 583
OBJ_TEX T ................................................................................................................ 589
OBJ_LABEL ................................................................................................................ 595
OBJ_BUTTON
................................................................................................................ 603
OBJ_CHART ................................................................................................................ 610
OBJ_BI TMAP................................................................................................................ 617
OBJ_BI TMAP................................................................................................................
_LABEL 624
OBJ_EDI T ................................................................................................................ 631
OBJ_EVENT ................................................................................................................ 638
OBJ_RECTANGLE _LABEL
................................................................................................................ 643
Object Properties
......................................................................................................................... 649
Methods .........................................................................................................................
of Object Binding 657
Chart Corner
......................................................................................................................... 662
Visibility .........................................................................................................................
of Objects 665
Levels of.........................................................................................................................
Elliott Wave 668
Gann Objects
......................................................................................................................... 669
Web Colors
......................................................................................................................... 671
Wingdings
......................................................................................................................... 673
............................................................................................................................674
Indicator Constants
Price Constants
......................................................................................................................... 675
Smoothing
.........................................................................................................................
Methods 678
I ndicators
.........................................................................................................................
Lines 679
Drawing .........................................................................................................................
Styles 681
Custom I.........................................................................................................................
ndicator Properties 685
I ndicator.........................................................................................................................
Types 688
Data Type
.........................................................................................................................
I dentifiers 690
............................................................................................................................691
Environment State
Client Terminal
.........................................................................................................................
Properties 692
Running MQL5
.........................................................................................................................
Program Properties 698
Symbol Properties
......................................................................................................................... 701
Account .........................................................................................................................
Properties 718
Testing Statistics
......................................................................................................................... 723
............................................................................................................................727
Trade Constants
History Database
.........................................................................................................................
Properties 728
Order Properties
......................................................................................................................... 729
Position Properties
......................................................................................................................... 734
Deal Properties
......................................................................................................................... 737
Trade Operation
.........................................................................................................................
Types 741
Trade Transaction
.........................................................................................................................
Types 753
Trade Orders
.........................................................................................................................
in DOM 756
Signal Properties
......................................................................................................................... 757
............................................................................................................................759
Named Constants
Predefined
.........................................................................................................................
Macro Substitutions 760
Mathematical
.........................................................................................................................
Constants 762
Numerical
.........................................................................................................................
Type Constants 764
PlaySound ............................................................................................................................942
Print ............................................................................................................................943
PrintFormat............................................................................................................................945
............................................................................................................................951
ResetLastError
............................................................................................................................952
ResourceCreate
............................................................................................................................954
ResourceFree
............................................................................................................................955
ResourceReadImage
............................................................................................................................956
ResourceSave
............................................................................................................................957
SetReturnError
............................................................................................................................958
SetUserError
Sleep ............................................................................................................................959
............................................................................................................................960
TerminalClose
............................................................................................................................962
TesterHideIndicators
............................................................................................................................964
TesterStatistics
TesterStop ............................................................................................................................965
............................................................................................................................966
TesterDeposit
............................................................................................................................967
TesterWithdrawal
............................................................................................................................968
TranslateKey
ZeroMemory ............................................................................................................................969
6 Array Functions
................................................................................................. 970
ArrayBsearch............................................................................................................................972
ArrayCopy ............................................................................................................................976
ArrayCompare............................................................................................................................981
ArrayFree ............................................................................................................................982
............................................................................................................................991
ArrayGetAsSeries
ArrayInitiali............................................................................................................................994
ze
ArrayFill ............................................................................................................................996
............................................................................................................................998
ArrayIsDynamic
............................................................................................................................1000
ArrayIsSeries
............................................................................................................................1002
ArrayMaximum
............................................................................................................................1013
ArrayMinimum
ArrayPrint............................................................................................................................1024
ArrayRange............................................................................................................................1027
ArrayResiz............................................................................................................................1028
e
............................................................................................................................1031
ArrayInsert
............................................................................................................................1034
ArrayRemove
............................................................................................................................1036
ArrayReverse
............................................................................................................................1038
ArraySetAsSeries
ArraySize ............................................................................................................................1041
ArraySort............................................................................................................................1043
ArraySwap............................................................................................................................1048
7 Conversion Functions
................................................................................................. 1050
............................................................................................................................1052
CharToString
............................................................................................................................1053
CharArrayToString
............................................................................................................................1054
CharArrayToStruct
............................................................................................................................1055
StructToCharArray
............................................................................................................................1056
ColorToARGB
............................................................................................................................1058
ColorToString
............................................................................................................................1059
DoubleToString
............................................................................................................................1060
EnumToString
............................................................................................................................1062
IntegerToString
............................................................................................................................1063
ShortToString
............................................................................................................................1064
ShortArrayToString
............................................................................................................................1065
TimeToString
............................................................................................................................1066
NormalizeDouble
............................................................................................................................1068
StringToCharArray
............................................................................................................................1069
StringToColor
............................................................................................................................1070
StringToDouble
© 2000-2019, MetaQuotes Software Corp.
7 Content
............................................................................................................................1071
StringToInteger
............................................................................................................................1072
StringToShortArray
............................................................................................................................1073
StringToTime
............................................................................................................................1074
StringFormat
8 Math Functions
................................................................................................. 1078
MathAbs ............................................................................................................................1080
MathArccos............................................................................................................................1081
MathArcsin............................................................................................................................1082
MathArctan............................................................................................................................1083
MathCeil ............................................................................................................................1084
MathCos ............................................................................................................................1085
MathExp ............................................................................................................................1086
MathFloor............................................................................................................................1087
MathLog ............................................................................................................................1088
MathLog10............................................................................................................................1089
MathMax ............................................................................................................................1090
MathMin ............................................................................................................................1091
MathMod ............................................................................................................................1092
MathPow ............................................................................................................................1093
MathRand ............................................................................................................................1094
MathRound............................................................................................................................1095
MathSin ............................................................................................................................1096
MathSq rt ............................................................................................................................1097
MathSrand............................................................................................................................1098
MathTan ............................................................................................................................1101
............................................................................................................................1102
MathIsValidNumber
MathExpm1............................................................................................................................1103
MathLog1p............................................................................................................................1104
............................................................................................................................1105
MathArccosh
............................................................................................................................1106
MathArcsinh
............................................................................................................................1107
MathArctanh
MathCosh ............................................................................................................................1108
MathSinh ............................................................................................................................1109
MathTanh ............................................................................................................................1110
MathSwap............................................................................................................................1111
9 String Functions
................................................................................................. 1112
StringAdd ............................................................................................................................1114
............................................................................................................................1116
StringBufferLen
............................................................................................................................1117
StringCompare
............................................................................................................................1119
StringConcatenate
StringFill ............................................................................................................................1120
StringFind............................................................................................................................1121
............................................................................................................................1122
StringGetCharacter
StringInit ............................................................................................................................1123
StringLen ............................................................................................................................1124
............................................................................................................................1125
StringSetLength
............................................................................................................................1126
StringReplace
............................................................................................................................1127
StringReserve
............................................................................................................................1129
StringSetCharacter
StringSplit............................................................................................................................1131
............................................................................................................................1133
StringSubstr
............................................................................................................................1134
StringToLower
............................................................................................................................1135
StringToUpper
............................................................................................................................1136
StringTrimLeft
............................................................................................................................1137
StringTrimRight
10 Date and Time
................................................................................................. 1138
............................................................................................................................1139
TimeCurrent
............................................................................................................................1140
TimeTradeServer
TimeLocal............................................................................................................................1141
TimeGMT ............................................................................................................................1142
............................................................................................................................1143
TimeDaylightSavings
............................................................................................................................1144
TimeGMTOffset
............................................................................................................................1145
TimeToStruct
............................................................................................................................1146
StructToTime
11 Account Information
................................................................................................. 1147
............................................................................................................................1148
AccountInfoDouble
............................................................................................................................1149
AccountInfoInteger
............................................................................................................................1151
AccountInfoString
12 Checkup ................................................................................................. 1152
............................................................................................................................1153
GetLastError
IsStopped ............................................................................................................................1154
............................................................................................................................1155
UninitializeReason
............................................................................................................................1156
TerminalInfoInteger
............................................................................................................................1157
TerminalInfoDouble
............................................................................................................................1158
TerminalInfoString
............................................................................................................................1159
MQLInfoInteger
............................................................................................................................1160
MQLInfoString
Symbol ............................................................................................................................1161
Period ............................................................................................................................1162
Digits ............................................................................................................................1163
Point ............................................................................................................................1164
13 Event Handling
................................................................................................. 1165
OnStart ............................................................................................................................1167
OnInit ............................................................................................................................1170
OnDeinit ............................................................................................................................1173
OnTick ............................................................................................................................1176
............................................................................................................................1182
OnCalculate
OnTimer ............................................................................................................................1186
OnTrade ............................................................................................................................1189
............................................................................................................................1194
OnTradeTransaction
............................................................................................................................1200
OnBookEvent
............................................................................................................................1203
OnChartEvent
OnTester ............................................................................................................................1210
............................................................................................................................1217
OnTesterInit
............................................................................................................................1224
OnTesterDeinit
............................................................................................................................1225
OnTesterPass
14 Market Info ................................................................................................. 1226
............................................................................................................................1227
SymbolsTotal
............................................................................................................................1228
SymbolExist
............................................................................................................................1229
SymbolName
............................................................................................................................1230
SymbolSelect
............................................................................................................................1231
SymbolIsSynchroni zed
............................................................................................................................1232
SymbolInfoDouble
............................................................................................................................1234
SymbolInfoInteger
............................................................................................................................1236
SymbolInfoString
............................................................................................................................1237
SymbolInfoMarginRate
............................................................................................................................1238
SymbolInfoTick
............................................................................................................................1239
SymbolInfoSessionQuote
............................................................................................................................1240
SymbolInfoSessionTrade
............................................................................................................................1241
MarketBookAdd
............................................................................................................................1242
MarketBookRelease
............................................................................................................................1243
MarketBookGet
15 Economic Calendar
................................................................................................. 1244
............................................................................................................................1245
CalendarCountryById
............................................................................................................................1247
CalendarEventById
............................................................................................................................1250
CalendarValueById
............................................................................................................................1253
CalendarCountries
............................................................................................................................1255
CalendarEventByCountry
............................................................................................................................1257
CalendarEventByCurrency
............................................................................................................................1259
CalendarValueHistoryByEvent
............................................................................................................................1262
CalendarValueHistory
............................................................................................................................1265
CalendarValueLastByEvent
............................................................................................................................1270
CalendarValueLast
16 Timeseries and
.................................................................................................
Indicators Access 1275
............................................................................................................................1280
Indexing Direction in Arrays, Buffers and Timeseries
Organizing............................................................................................................................1283
Data Access
............................................................................................................................1292
SeriesInfoInteger
Bars ............................................................................................................................1294
............................................................................................................................1297
BarsCalculated
............................................................................................................................1299
IndicatorCreate
............................................................................................................................1301
IndicatorParameters
............................................................................................................................1303
IndicatorRelease
CopyBuffer............................................................................................................................1305
CopyRates............................................................................................................................1310
CopyTime............................................................................................................................1314
CopyOpen............................................................................................................................1317
CopyHigh ............................................................................................................................1320
CopyLow ............................................................................................................................1324
CopyClose............................................................................................................................1327
............................................................................................................................1330
CopyTickVolume
............................................................................................................................1334
CopyRealVolume
CopySpread............................................................................................................................1337
CopyTicks............................................................................................................................1341
............................................................................................................................1347
CopyTicksRange
iBars ............................................................................................................................1349
iBarShift ............................................................................................................................1350
iClose ............................................................................................................................1353
iHigh ............................................................................................................................1355
iHighest ............................................................................................................................1357
iLow ............................................................................................................................1358
iLowest ............................................................................................................................1360
iOpen ............................................................................................................................1361
iTime ............................................................................................................................1363
............................................................................................................................1365
iTickVolume
............................................................................................................................1367
iRealVolume
iVolume ............................................................................................................................1369
iSpread ............................................................................................................................1371
17 Custom Symbols
................................................................................................. 1373
............................................................................................................................1375
CustomSymbolCreate
............................................................................................................................1377
CustomSymbolDelete
............................................................................................................................1378
CustomSymbolSetInteger
............................................................................................................................1379
CustomSymbolSetDouble
............................................................................................................................1380
CustomSymbolSetString
............................................................................................................................1381
CustomSymbolSetMarginRate
............................................................................................................................1382
CustomSymbolSetSessionQuote
............................................................................................................................1383
CustomSymbolSetSessionTrade
............................................................................................................................1384
CustomRatesDelete
............................................................................................................................1385
CustomRatesReplace
............................................................................................................................1386
CustomRatesUpdate
............................................................................................................................1387
CustomTicksAdd
............................................................................................................................1389
CustomTicksDelete
© 2000-2019, MetaQuotes Software Corp.
10 Content
............................................................................................................................1390
CustomTicksReplace
............................................................................................................................1392
CustomBookAdd
18 Chart Operations
................................................................................................. 1395
............................................................................................................................1397
ChartApplyTemplate
............................................................................................................................1400
ChartSaveTemplate
............................................................................................................................1405
ChartWindowFind
............................................................................................................................1407
ChartTimePriceToXY
............................................................................................................................1408
ChartXYToTimePrice
ChartOpen............................................................................................................................1410
ChartFirst ............................................................................................................................1411
ChartNext............................................................................................................................1412
ChartClose............................................................................................................................1413
ChartSymbol............................................................................................................................1414
ChartPeriod............................................................................................................................1415
ChartRedraw............................................................................................................................1416
............................................................................................................................1417
ChartSetDouble
............................................................................................................................1418
ChartSetInteger
............................................................................................................................1420
ChartSetString
............................................................................................................................1422
ChartGetDouble
............................................................................................................................1424
ChartGetInteger
............................................................................................................................1426
ChartGetString
............................................................................................................................1428
ChartNavigate
ChartID ............................................................................................................................1431
............................................................................................................................1432
ChartIndicatorAdd
............................................................................................................................1436
ChartIndicatorDelete
............................................................................................................................1439
ChartIndicatorGet
............................................................................................................................1441
ChartIndicatorName
............................................................................................................................1442
ChartIndicatorsTotal
............................................................................................................................1443
ChartWindowOnDropped
............................................................................................................................1444
ChartPriceOnDropped
............................................................................................................................1445
ChartTimeOnDropped
............................................................................................................................1446
ChartXOnDropped
............................................................................................................................1447
ChartYOnDropped
............................................................................................................................1448
ChartSetSymbolPeriod
............................................................................................................................1449
ChartScreenShot
19 Trade Functions
................................................................................................. 1452
............................................................................................................................1455
OrderCalcMargin
............................................................................................................................1456
OrderCalcProfit
OrderCheck............................................................................................................................1457
OrderSend............................................................................................................................1458
............................................................................................................................1463
OrderSendAsync
............................................................................................................................1474
PositionsTotal
............................................................................................................................1475
PositionGetSymbol
............................................................................................................................1476
PositionSelect
............................................................................................................................1477
PositionSelectByTicket
............................................................................................................................1478
PositionGetDouble
............................................................................................................................1479
PositionGetInteger
............................................................................................................................1481
PositionGetString
............................................................................................................................1482
PositionGetTicket
............................................................................................................................1483
OrdersTotal
............................................................................................................................1484
OrderGetTicket
............................................................................................................................1486
OrderSelect
............................................................................................................................1487
OrderGetDouble
............................................................................................................................1488
OrderGetInteger
............................................................................................................................1489
OrderGetString
............................................................................................................................1490
HistorySelect
............................................................................................................................1492
HistorySelectByPosition
............................................................................................................................1493
HistoryOrderSelect
© 2000-2019, MetaQuotes Software Corp.
11 Content
............................................................................................................................1494
HistoryOrdersTotal
............................................................................................................................1495
HistoryOrderGetTicket
............................................................................................................................1497
HistoryOrderGetDouble
............................................................................................................................1498
HistoryOrderGetInteger
............................................................................................................................1501
HistoryOrderGetString
............................................................................................................................1502
HistoryDealSelect
............................................................................................................................1503
HistoryDealsTotal
............................................................................................................................1504
HistoryDealGetTicket
............................................................................................................................1506
HistoryDealGetDouble
............................................................................................................................1507
HistoryDealGetInteger
............................................................................................................................1510
HistoryDealGetString
20 Trade Signals................................................................................................. 1511
............................................................................................................................1512
SignalBaseGetDouble
............................................................................................................................1513
SignalBaseGetInteger
............................................................................................................................1514
SignalBaseGetString
............................................................................................................................1515
SignalBaseSelect
............................................................................................................................1516
SignalBaseTotal
............................................................................................................................1517
SignalInfoGetDouble
............................................................................................................................1518
SignalInfoGetInteger
............................................................................................................................1519
SignalInfoGetString
............................................................................................................................1520
SignalInfoSetDouble
............................................................................................................................1521
SignalInfoSetInteger
............................................................................................................................1522
SignalSubscribe
............................................................................................................................1523
SignalUnSubscribe
21 Network Functions
................................................................................................. 1524
............................................................................................................................1526
SocketCreate
............................................................................................................................1529
SocketClose
............................................................................................................................1532
SocketConnect
............................................................................................................................1536
SocketIsConnected
............................................................................................................................1537
SocketIsReadable
............................................................................................................................1540
SocketIsWritable
............................................................................................................................1541
SocketTimeouts
............................................................................................................................1542
SocketRead
............................................................................................................................1546
SocketSend
............................................................................................................................1550
SocketTlsHandshake
............................................................................................................................1551
SocketTlsCertificate
............................................................................................................................1555
SocketTlsRead
............................................................................................................................1559
SocketTlsReadAvailable
............................................................................................................................1560
SocketTlsSend
............................................................................................................................1561
WebRe q uest
SendFTP ............................................................................................................................1564
SendMail ............................................................................................................................1565
............................................................................................................................1566
SendNotification
22 Global Variables
.................................................................................................
of the Terminal 1567
............................................................................................................................1568
GlobalVariableCheck
............................................................................................................................1569
GlobalVariableTime
............................................................................................................................1570
GlobalVariableDel
............................................................................................................................1571
GlobalVariableGet
............................................................................................................................1572
GlobalVariableName
............................................................................................................................1573
GlobalVariableSet
............................................................................................................................1574
GlobalVariablesFlush
............................................................................................................................1575
GlobalVariableTemp
............................................................................................................................1576
GlobalVariableSetOnCondition
............................................................................................................................1577
GlobalVariablesDeleteAll
............................................................................................................................1578
GlobalVariablesTotal
23 File Functions................................................................................................. 1579
............................................................................................................................1582
FileFindFirst
© 2000-2019, MetaQuotes Software Corp.
12 Content
FileFindNext............................................................................................................................1584
............................................................................................................................1586
FileFindClose
FileIsExist ............................................................................................................................1588
FileOpen ............................................................................................................................1591
FileClose ............................................................................................................................1594
FileCopy ............................................................................................................................1595
FileDelete............................................................................................................................1598
FileMove ............................................................................................................................1600
FileFlush ............................................................................................................................1602
............................................................................................................................1604
FileGetInteger
FileIsEnding............................................................................................................................1607
............................................................................................................................1609
FileIsLineEnding
............................................................................................................................1614
FileReadArray
FileReadBool............................................................................................................................1616
............................................................................................................................1619
FileReadDatetime
............................................................................................................................1622
FileReadDouble
............................................................................................................................1625
FileReadFloat
............................................................................................................................1628
FileReadInteger
FileReadLong............................................................................................................................1632
............................................................................................................................1635
FileReadNumber
............................................................................................................................1640
FileReadString
............................................................................................................................1642
FileReadStruct
FileSeek ............................................................................................................................1646
FileSize ............................................................................................................................1649
FileTell ............................................................................................................................1651
FileWrite ............................................................................................................................1654
............................................................................................................................1657
FileWriteArray
............................................................................................................................1660
FileWriteDouble
............................................................................................................................1663
FileWriteFloat
............................................................................................................................1665
FileWriteInteger
............................................................................................................................1668
FileWriteLong
............................................................................................................................1670
FileWriteString
............................................................................................................................1673
FileWriteStruct
FileLoad ............................................................................................................................1676
FileSave ............................................................................................................................1678
FolderCreate............................................................................................................................1680
FolderDelete............................................................................................................................1683
FolderClean ............................................................................................................................1686
24 Custom Indicators
................................................................................................. 1689
............................................................................................................................1693
Indicator Styles in Examples
DRAW _NONE
......................................................................................................................... 1700
DRAW _LI
.........................................................................................................................
NE 1703
DRAW _SECTI
.........................................................................................................................
ON 1707
DRAW _HI
.........................................................................................................................
STOGRAM 1711
DRAW _HI
.........................................................................................................................
STOGRAM2 1715
DRAW _ARROW
......................................................................................................................... 1719
DRAW _Z.........................................................................................................................
I GZAG 1724
DRAW _FI
.........................................................................................................................
LLI NG 1729
DRAW _BARS
......................................................................................................................... 1734
DRAW _CANDLES
......................................................................................................................... 1740
DRAW _COLOR _LI NE
......................................................................................................................... 1746
DRAW _COLOR _SECTI ON
......................................................................................................................... 1751
DRAW _COLOR _HI STOGRAM
......................................................................................................................... 1757
DRAW _COLOR _HI STOGRAM2
......................................................................................................................... 1762
DRAW _COLOR _ARROW
......................................................................................................................... 1767
DRAW _COLOR _ZI GZAG
......................................................................................................................... 1773
DRAW _COLOR _BARS
......................................................................................................................... 1778
DRAW _COLOR _CANDLES
......................................................................................................................... 1785
Connection............................................................................................................................1792
between Indicator Properties and Functions
............................................................................................................................1795
SetIndexBuffer
............................................................................................................................1798
IndicatorSetDouble
............................................................................................................................1802
IndicatorSetInteger
............................................................................................................................1806
IndicatorSetString
............................................................................................................................1809
PlotIndexSetDouble
............................................................................................................................1810
PlotIndexSetInteger
............................................................................................................................1814
PlotIndexSetString
............................................................................................................................1815
PlotIndexGetInteger
25 Object Functions
................................................................................................. 1818
............................................................................................................................1820
ObjectCreate
ObjectName............................................................................................................................1824
............................................................................................................................1825
ObjectDelete
............................................................................................................................1826
ObjectsDeleteAll
ObjectFind............................................................................................................................1827
............................................................................................................................1828
ObjectGetTimeByValue
............................................................................................................................1829
ObjectGetValueByTime
ObjectMove............................................................................................................................1830
............................................................................................................................1831
ObjectsTotal
............................................................................................................................1832
ObjectSetDouble
............................................................................................................................1836
ObjectSetInteger
............................................................................................................................1839
ObjectSetString
............................................................................................................................1841
ObjectGetDouble
............................................................................................................................1843
ObjectGetInteger
............................................................................................................................1845
ObjectGetString
............................................................................................................................1847
TextSetFont
TextOut ............................................................................................................................1849
TextGetSiz............................................................................................................................1853
e
26 Technical Indicators
................................................................................................. 1854
iAC ............................................................................................................................1857
iAD ............................................................................................................................1862
iADX ............................................................................................................................1867
iADXWilder ............................................................................................................................1872
iAlligator ............................................................................................................................1877
iAMA ............................................................................................................................1884
iAO ............................................................................................................................1889
iATR ............................................................................................................................1894
iBearsPower............................................................................................................................1899
iBands ............................................................................................................................1904
iBullsPower............................................................................................................................1910
iCCI ............................................................................................................................1915
iChaikin ............................................................................................................................1920
iCustom ............................................................................................................................1925
iDEMA ............................................................................................................................1928
iDeMarker............................................................................................................................1933
iEnvelopes............................................................................................................................1938
iForce ............................................................................................................................1944
iFractals ............................................................................................................................1949
iFrAMA ............................................................................................................................1954
iGator ............................................................................................................................1959
iIchimoku ............................................................................................................................1966
iBWMFI ............................................................................................................................1973
iMomentum ............................................................................................................................1978
iMFI ............................................................................................................................1983
iMA ............................................................................................................................1988
iOsMA ............................................................................................................................1993
iMACD ............................................................................................................................1998
iOBV ............................................................................................................................2004
© 2000-2019, MetaQuotes Software Corp.
14 Content
iSAR ............................................................................................................................2009
iRSI ............................................................................................................................2014
iRVI ............................................................................................................................2019
iStdDev ............................................................................................................................2024
iStochastic............................................................................................................................2029
iTEMA ............................................................................................................................2035
iTriX ............................................................................................................................2040
iWPR ............................................................................................................................2045
iVIDyA ............................................................................................................................2050
iVolumes ............................................................................................................................2055
27 Working with.................................................................................................
Optimization Results 2060
FrameFirst............................................................................................................................2061
FrameFilter............................................................................................................................2062
FrameNext............................................................................................................................2063
............................................................................................................................2064
FrameInputs
FrameAdd............................................................................................................................2065
............................................................................................................................2066
ParameterGetRange
............................................................................................................................2069
ParameterSetRange
28 Working with.................................................................................................
Events 2071
............................................................................................................................2072
EventSetMillisecondTimer
............................................................................................................................2073
EventSetTimer
............................................................................................................................2074
EventKillTimer
............................................................................................................................2075
EventChartCustom
29 Working with.................................................................................................
OpenCL 2081
............................................................................................................................2083
CLHandleType
............................................................................................................................2084
CLGetInfoInteger
............................................................................................................................2087
CLGetInfoString
............................................................................................................................2090
CLContextCreate
............................................................................................................................2091
CLContextFree
............................................................................................................................2092
CLGetDeviceInfo
............................................................................................................................2096
CLProgramCreate
............................................................................................................................2101
CLProgramFree
............................................................................................................................2102
CLKernelCreate
............................................................................................................................2103
CLKernelFree
............................................................................................................................2104
CLSetKernelArg
............................................................................................................................2105
CLSetKernelArgMem
............................................................................................................................2106
CLSetKernelArgMemLocal
............................................................................................................................2107
CLBufferCreate
............................................................................................................................2108
CLBufferFree
............................................................................................................................2109
CLBufferWrite
............................................................................................................................2110
CLBufferRead
CLExecute............................................................................................................................2111
............................................................................................................................2113
CLExecutionStatus
30 Integration ................................................................................................. 2114
............................................................................................................................2115
MetaTrader for Python
MT5I nitialize
......................................................................................................................... 2119
MT5Shutdown
......................................................................................................................... 2120
MT5TerminalI
.........................................................................................................................
nfo 2121
MT5Version
......................................................................................................................... 2123
MT5WaitForTerminal
......................................................................................................................... 2125
MT5CopyRatesFrom
......................................................................................................................... 2126
MT5CopyRatesFromPos
......................................................................................................................... 2130
MT5CopyRatesRange
......................................................................................................................... 2133
MT5CopyTicksFrom
......................................................................................................................... 2136
MT5CopyTicksRange
......................................................................................................................... 2140
31 Standard Library
................................................................................................. 2143
............................................................................................................................2144
Mathematics
Statistics
......................................................................................................................... 2145
Statistical Characteristics
................................................................................................................ 2148
MathMean ........................................................................................................... 2149
MathVariance
........................................................................................................... 2150
MathSkewness
........................................................................................................... 2151
MathKurtosis
........................................................................................................... 2152
MathMoments
........................................................................................................... 2153
MathMedian
........................................................................................................... 2154
MathStandardDeviation
........................................................................................................... 2155
MathAverageDeviation
........................................................................................................... 2156
Normal Distribution
................................................................................................................ 2157
MathProbabilityDensityNormal
........................................................................................................... 2161
MathCumulativeDistributionNormal
........................................................................................................... 2163
MathQuantileNormal
........................................................................................................... 2165
MathRandomNormal
........................................................................................................... 2167
MathMomentsNormal
........................................................................................................... 2168
Log-normal................................................................................................................
distribution 2169
MathProbabilityDensityLognormal
........................................................................................................... 2173
MathCumulativeDistributionLognormal
........................................................................................................... 2175
MathQuantileLognormal
........................................................................................................... 2177
MathRandomLognormal
........................................................................................................... 2179
MathMomentsLognormal
........................................................................................................... 2180
Beta distribution
................................................................................................................ 2181
MathProbabilityDensityBeta
........................................................................................................... 2185
MathCumulativeDistributionBeta
........................................................................................................... 2187
MathQuantileBeta
........................................................................................................... 2189
MathRandomBeta
........................................................................................................... 2191
MathMomentsBeta
........................................................................................................... 2192
Noncentral................................................................................................................
beta distribution 2193
MathProbabilityDensityNoncentralBeta
........................................................................................................... 2197
MathCumulativeDistributionNoncentralBeta
........................................................................................................... 2199
MathQuantileNoncentralBeta
........................................................................................................... 2201
MathRandomNoncentralBeta
........................................................................................................... 2203
MathMomentsNoncentralBeta
........................................................................................................... 2204
Gamma distribution
................................................................................................................ 2205
MathProbabilityDensityGamma
........................................................................................................... 2209
MathCumulativeDistributionGamma
........................................................................................................... 2211
MathQuantileGamma
........................................................................................................... 2213
MathRandomGamma
........................................................................................................... 2215
MathMomentsGamma
........................................................................................................... 2216
Chi-s quared
................................................................................................................
distribution 2217
MathProbabilityDensityChiS quare
........................................................................................................... 2221
MathCumulativeDistributionChiS quare
........................................................................................................... 2223
MathQuantileChiS quare
........................................................................................................... 2225
MathRandomChiS quare
........................................................................................................... 2227
MathMomentsChiS quare
........................................................................................................... 2228
chi-s quared distribution
Noncentral................................................................................................................ 2229
MathProbabilityDensityNoncentralChiS quare
........................................................................................................... 2233
MathCumulativeDistributionNoncentralChiS quare
........................................................................................................... 2235
MathQuantileNoncentralChiS quare
........................................................................................................... 2237
MathRandomNoncentralChiS quare
........................................................................................................... 2239
MathMomentsNoncentralChiS quare
........................................................................................................... 2240
Exponential
................................................................................................................
distribution 2241
MathProbabilityDensityExponential
........................................................................................................... 2245
MathCumulativeDistributionExponential
........................................................................................................... 2247
MathQuantileExponential
........................................................................................................... 2249
MathRandomExponential
........................................................................................................... 2251
MathMomentsExponential
........................................................................................................... 2252
F-distribution
................................................................................................................ 2253
MathProbabilityDensityF
........................................................................................................... 2257
MathCumulativeDistributionF
........................................................................................................... 2259
MathQuantileF
........................................................................................................... 2261
MathRandomF
........................................................................................................... 2263
MathMomentsF
........................................................................................................... 2264
Noncentral................................................................................................................
F-distribution 2265
MathProbabilityDensityNoncentralF
........................................................................................................... 2269
MathCumulativeDistributionNoncentralF
........................................................................................................... 2271
MathQuantileNoncentralF
........................................................................................................... 2273
MathRandomNoncentralF
........................................................................................................... 2275
MathMomentsNoncentralF
........................................................................................................... 2276
T-distribution
................................................................................................................ 2277
MathProbabilityDensityT
........................................................................................................... 2281
MathCumulativeDistributionT
........................................................................................................... 2283
MathQuantileT
........................................................................................................... 2285
MathRandomT
........................................................................................................... 2287
MathMomentsT
........................................................................................................... 2288
Noncentral................................................................................................................
t-distribution 2289
MathProbabilityDensityNoncentralT
........................................................................................................... 2293
MathCumulativeDistributionNoncentralT
........................................................................................................... 2295
MathQuantileNoncentralT
........................................................................................................... 2297
MathRandomNoncentralT
........................................................................................................... 2299
MathMomentsNoncentralT
........................................................................................................... 2300
Logistic distribution
................................................................................................................ 2301
MathProbabilityDensityLogistic
........................................................................................................... 2305
MathCumulativeDistributionLogistic
........................................................................................................... 2307
MathQuantileLogistic
........................................................................................................... 2309
MathRandomLogistic
........................................................................................................... 2311
MathMomentsLogistic
........................................................................................................... 2312
Cauchy distribution
................................................................................................................ 2313
MathProbabilityDensityCauchy
........................................................................................................... 2317
MathCumulativeDistributionCauchy
........................................................................................................... 2319
MathQuantileCauchy
........................................................................................................... 2321
MathRandomCauchy
........................................................................................................... 2323
MathMomentsCauchy
........................................................................................................... 2324
Uniform distribution
................................................................................................................ 2325
MathProbabilityDensityUniform
........................................................................................................... 2329
MathCumulativeDistributionUniform
........................................................................................................... 2331
MathQuantileUniform
........................................................................................................... 2333
MathRandomUniform
........................................................................................................... 2335
MathMomentsUniform
........................................................................................................... 2336
Weibull distribution
................................................................................................................ 2337
MathProbabilityDensityWeibull
........................................................................................................... 2341
MathCumulativeDistributionWeibull
........................................................................................................... 2343
MathQuantileWeibull
........................................................................................................... 2345
MathRandomWeibull
........................................................................................................... 2347
MathMomentsWeibull
........................................................................................................... 2348
Binomial distribution
................................................................................................................ 2349
MathProbabilityDensityBinomial
........................................................................................................... 2352
MathCumulativeDistributionBinomial
........................................................................................................... 2354
MathQuantileBinomial
........................................................................................................... 2356
MathRandomBinomial
........................................................................................................... 2358
MathMomentsBinomial
........................................................................................................... 2359
Negative binomial
................................................................................................................
distribution 2360
MathProbabilityDensityNegativeBinomial
........................................................................................................... 2363
MathCumulativeDistributionNegativeBinomial
........................................................................................................... 2365
MathQuantileNegativeBinomial
........................................................................................................... 2367
MathRandomNegativeBinomial
........................................................................................................... 2369
MathMomentsNegativeBinomial
........................................................................................................... 2370
Geometric ................................................................................................................
distribution 2371
MathProbabilityDensityGeometric
........................................................................................................... 2375
MathCumulativeDistributionGeometric
........................................................................................................... 2377
MathQuantileGeometric
........................................................................................................... 2379
MathRandomGeometric
........................................................................................................... 2381
MathMomentsGeometric
........................................................................................................... 2382
Hypergeometric
................................................................................................................
distribution 2383
MathProbabilityDensityHypergeometric
........................................................................................................... 2387
MathCumulativeDistributionHypergeometric
........................................................................................................... 2389
MathQuantileHypergeometric
........................................................................................................... 2391
MathRandomHypergeometric
........................................................................................................... 2393
MathMomentsHypergeometric
........................................................................................................... 2394
Poisson distribution
................................................................................................................ 2395
MathProbabilityDensityPoisson
........................................................................................................... 2399
MathCumulativeDistributionPoisson
........................................................................................................... 2401
MathQuantilePoisson
........................................................................................................... 2403
MathRandomPoisson
........................................................................................................... 2405
MathMomentsPoisson
........................................................................................................... 2406
Subfunctions
................................................................................................................ 2407
MathRandomNon Zero
........................................................................................................... 2412
MathMoments
........................................................................................................... 2413
MathPowI nt
........................................................................................................... 2414
MathFactorial
........................................................................................................... 2415
MathTrunc........................................................................................................... 2416
MathRound........................................................................................................... 2417
MathArctan2
........................................................................................................... 2419
MathGamma
........................................................................................................... 2421
MathGammaLog
........................................................................................................... 2422
MathBeta ........................................................................................................... 2423
MathBetaLog
........................................................................................................... 2424
MathBetaI ncomplete
........................................................................................................... 2425
MathGammaI
...........................................................................................................
ncomplete 2426
MathBinomialCoefficient
........................................................................................................... 2427
MathBinomialCoefficientLog
........................................................................................................... 2428
MathHypergeometric2F2
........................................................................................................... 2429
MathSequence
........................................................................................................... 2430
MathSequenceByCount
........................................................................................................... 2431
MathReplicate
........................................................................................................... 2432
MathReverse
........................................................................................................... 2433
MathI dentical
........................................................................................................... 2434
MathUnique
........................................................................................................... 2435
MathQuickSortAscending
........................................................................................................... 2436
MathQuickSortDescending
........................................................................................................... 2437
MathQuickSort
........................................................................................................... 2438
MathOrder........................................................................................................... 2439
MathBitwiseNot
........................................................................................................... 2440
MathBitwiseAnd
........................................................................................................... 2441
MathBitwiseOr
........................................................................................................... 2442
MathBitwise X or
........................................................................................................... 2443
MathBitwiseShiftL
........................................................................................................... 2444
MathBitwiseShiftR
........................................................................................................... 2445
MathCumulativeSum
........................................................................................................... 2446
MathCumulativeProduct
........................................................................................................... 2447
MathCumulativeMin
........................................................................................................... 2448
MathCumulativeMax
........................................................................................................... 2449
A1 ........................................................................................................... 2515
A2 ........................................................................................................... 2515
C1 ........................................................................................................... 2516
C2 ........................................................................................................... 2516
GetValue ........................................................................................................... 2517
CGeneraliz...........................................................................................................
edBellShapedMembershipFunction 2518
A ........................................................................................................... 2520
B ........................................................................................................... 2520
C ........................................................................................................... 2521
GetValue ........................................................................................................... 2521
CNormalCombinationMembershipFunction
........................................................................................................... 2522
B1 ........................................................................................................... 2524
B2 ........................................................................................................... 2524
Sigma1 ........................................................................................................... 2525
Sigma2 ........................................................................................................... 2525
GetValue ........................................................................................................... 2526
CNormalMembershipFunction
........................................................................................................... 2527
B ........................................................................................................... 2529
Sigma ........................................................................................................... 2529
GetValue ........................................................................................................... 2530
CP_ShapedMembershipFunction
........................................................................................................... 2531
A ........................................................................................................... 2533
B ........................................................................................................... 2533
C ........................................................................................................... 2534
D ........................................................................................................... 2534
GetValue ........................................................................................................... 2534
CProductTwoSigmoidalMembershipFunctions
........................................................................................................... 2536
A1 ........................................................................................................... 2538
A2 ........................................................................................................... 2538
C1 ........................................................................................................... 2539
C2 ........................................................................................................... 2539
GetValue ........................................................................................................... 2540
CS_ShapedMembershipFunction
........................................................................................................... 2541
A ........................................................................................................... 2543
B ........................................................................................................... 2543
GetValue ........................................................................................................... 2544
CSigmoidalMembershipFunction
........................................................................................................... 2545
A ........................................................................................................... 2547
C ........................................................................................................... 2547
GetValue ........................................................................................................... 2548
CTrapez oidMembershipFunction
........................................................................................................... 2549
X1 ........................................................................................................... 2551
X2 ........................................................................................................... 2551
X3 ........................................................................................................... 2552
X4 ........................................................................................................... 2552
GetValue ........................................................................................................... 2553
CTriangularMembershipFunction
........................................................................................................... 2554
X1 ........................................................................................................... 2556
X2 ........................................................................................................... 2556
X3 ........................................................................................................... 2557
ToNormalMF
........................................................................................................... 2557
GetValue ........................................................................................................... 2557
C Z_ShapedMembershipFunction
........................................................................................................... 2559
A ........................................................................................................... 2561
B ........................................................................................................... 2561
GetValue ........................................................................................................... 2562
I MembershipFunction
........................................................................................................... 2563
GetValue ........................................................................................................... 2563
Fuzz y systems
................................................................................................................
rules 2564
CMamdaniFu zz yRule
........................................................................................................... 2565
Conclusion........................................................................................................... 2566
Weight ........................................................................................................... 2566
zz yRule
CSugenoFu........................................................................................................... 2567
Conclusion........................................................................................................... 2567
CSingleCondition
........................................................................................................... 2569
Not ........................................................................................................... 2569
Term ........................................................................................................... 2570
Var ........................................................................................................... 2570
CConditions
........................................................................................................... 2572
ConditionsList
........................................................................................................... 2572
Not ........................................................................................................... 2573
Op ........................................................................................................... 2573
CGenericFuzz yRule
........................................................................................................... 2574
Conclusion........................................................................................................... 2574
Condition ........................................................................................................... 2575
CreateCondition
........................................................................................................... 2575
Fuzz y systems
................................................................................................................
variables 2577
CFuzz yVariable
........................................................................................................... 2578
AddTerm ........................................................................................................... 2579
GetTermByName
........................................................................................................... 2579
Max ........................................................................................................... 2579
Min ........................................................................................................... 2580
Terms ........................................................................................................... 2580
Values ........................................................................................................... 2580
CSugenoVariable
........................................................................................................... 2582
Functions ........................................................................................................... 2582
GetFuncByName
........................................................................................................... 2583
Values ........................................................................................................... 2583
Fuzz y terms
................................................................................................................ 2584
MembershipFunction
........................................................................................................... 2585
Fuzz y systems
................................................................................................................ 2586
Mamdani system
........................................................................................................... 2587
AggregationMethod
........................................................................................................... 2587
Calculate ........................................................................................................... 2588
Defuzz ificationMethod
........................................................................................................... 2588
EmptyRule ........................................................................................................... 2588
I mplicationMethod
........................................................................................................... 2588
Output ........................................................................................................... 2589
OutputByName
........................................................................................................... 2589
ParseRule ........................................................................................................... 2589
Rules ........................................................................................................... 2589
Sugeno system
........................................................................................................... 2591
Calculate ........................................................................................................... 2591
CreateSugenoFunction
........................................................................................................... 2592
EmptyRule ........................................................................................................... 2593
Output ........................................................................................................... 2593
OutputByName
........................................................................................................... 2593
ParseRule ........................................................................................................... 2593
Rules ........................................................................................................... 2594
OpenCL ............................................................................................................................2595
BufferCreate
......................................................................................................................... 2597
BufferFree
......................................................................................................................... 2598
BufferFromArray
......................................................................................................................... 2599
BufferRead
......................................................................................................................... 2600
BufferWrite
......................................................................................................................... 2601
Execute......................................................................................................................... 2602
GetContext
......................................................................................................................... 2603
GetKernel
......................................................................................................................... 2604
GetKernelName
......................................................................................................................... 2605
GetProgram
......................................................................................................................... 2606
I nitializ.........................................................................................................................
e 2607
KernelCreate
......................................................................................................................... 2608
KernelFree
......................................................................................................................... 2609
SetArgument
......................................................................................................................... 2610
SetArgumentBuffer
......................................................................................................................... 2611
SetArgumentLocalMemory
......................................................................................................................... 2612
SetBuffersCount
......................................................................................................................... 2613
SetKernelsCount
......................................................................................................................... 2614
Shutdown
......................................................................................................................... 2615
SupportDouble
......................................................................................................................... 2616
Basic Class............................................................................................................................2617
CObject
Prev ......................................................................................................................... 2618
Prev ......................................................................................................................... 2619
Next ......................................................................................................................... 2620
Next ......................................................................................................................... 2621
Compare
......................................................................................................................... 2622
Save ......................................................................................................................... 2624
Load ......................................................................................................................... 2626
Type ......................................................................................................................... 2628
............................................................................................................................2629
Data Collections
CArray ......................................................................................................................... 2630
Step ................................................................................................................ 2632
Step ................................................................................................................ 2633
Total ................................................................................................................ 2634
Available ................................................................................................................ 2635
Max ................................................................................................................ 2636
I sSorted ................................................................................................................ 2637
SortMode ................................................................................................................ 2638
Clear ................................................................................................................ 2639
Sort ................................................................................................................ 2640
Save ................................................................................................................ 2641
Load ................................................................................................................ 2642
CArrayChar
......................................................................................................................... 2643
Reserve ................................................................................................................ 2646
Resiz e ................................................................................................................ 2647
Shutdown ................................................................................................................ 2648
Add ................................................................................................................ 2649
AddArray ................................................................................................................ 2650
AddArray ................................................................................................................ 2651
I nsert ................................................................................................................ 2653
I nsertArray
................................................................................................................ 2654
I nsertArray
................................................................................................................ 2655
AssignArray
................................................................................................................ 2657
AssignArray
................................................................................................................ 2658
Update ................................................................................................................ 2660
Shift ................................................................................................................ 2661
Delete ................................................................................................................ 2662
DeleteRange
................................................................................................................ 2663
At ................................................................................................................ 2664
CompareArray
................................................................................................................ 2666
CompareArray
................................................................................................................ 2667
I nsertSort ................................................................................................................ 2668
Search ................................................................................................................ 2669
SearchGreat
................................................................................................................ 2670
SearchLess................................................................................................................ 2671
SearchGreatOrE qual
................................................................................................................ 2672
SearchLessOrE qual
................................................................................................................ 2673
SearchFirst................................................................................................................ 2674
SearchLast................................................................................................................ 2675
SearchLinear
................................................................................................................ 2676
Save ................................................................................................................ 2677
Load ................................................................................................................ 2678
Type ................................................................................................................ 2680
CArrayShort
......................................................................................................................... 2681
Reserve ................................................................................................................ 2684
Resiz e ................................................................................................................ 2685
Shutdown ................................................................................................................ 2686
Add ................................................................................................................ 2687
AddArray ................................................................................................................ 2688
AddArray ................................................................................................................ 2689
I nsert ................................................................................................................ 2691
I nsertArray
................................................................................................................ 2692
I nsertArray
................................................................................................................ 2693
AssignArray
................................................................................................................ 2695
AssignArray
................................................................................................................ 2696
Update ................................................................................................................ 2698
Shift ................................................................................................................ 2699
Delete ................................................................................................................ 2700
DeleteRange
................................................................................................................ 2701
At ................................................................................................................ 2702
CompareArray
................................................................................................................ 2704
CompareArray
................................................................................................................ 2705
I nsertSort ................................................................................................................ 2706
Search ................................................................................................................ 2707
SearchGreat
................................................................................................................ 2708
SearchLess................................................................................................................ 2709
SearchGreatOrE qual
................................................................................................................ 2710
SearchLessOrE qual
................................................................................................................ 2711
SearchFirst................................................................................................................ 2712
SearchLast................................................................................................................ 2713
SearchLinear
................................................................................................................ 2714
Save ................................................................................................................ 2715
Load ................................................................................................................ 2717
Type ................................................................................................................ 2719
CArrayI.........................................................................................................................
nt 2720
Reserve ................................................................................................................ 2723
Resiz e ................................................................................................................ 2724
Shutdown ................................................................................................................ 2725
Add ................................................................................................................ 2726
AddArray ................................................................................................................ 2727
AddArray ................................................................................................................ 2728
I nsert ................................................................................................................ 2730
I nsertArray
................................................................................................................ 2731
I nsertArray
................................................................................................................ 2732
AssignArray
................................................................................................................ 2734
AssignArray
................................................................................................................ 2735
Update ................................................................................................................ 2737
Shift ................................................................................................................ 2738
Delete ................................................................................................................ 2739
DeleteRange
................................................................................................................ 2740
At ................................................................................................................ 2741
CompareArray
................................................................................................................ 2743
CompareArray
................................................................................................................ 2744
I nsertSort ................................................................................................................ 2745
Search ................................................................................................................ 2746
SearchGreat
................................................................................................................ 2747
SearchLess................................................................................................................ 2748
SearchGreatOrE qual
................................................................................................................ 2749
SearchLessOrE qual
................................................................................................................ 2750
SearchFirst................................................................................................................ 2751
SearchLast................................................................................................................ 2752
SearchLinear
................................................................................................................ 2753
Save ................................................................................................................ 2754
Load ................................................................................................................ 2756
Type ................................................................................................................ 2758
CArrayLong
......................................................................................................................... 2759
Reserve ................................................................................................................ 2762
Resiz e ................................................................................................................ 2763
Shutdown ................................................................................................................ 2764
Add ................................................................................................................ 2765
AddArray ................................................................................................................ 2766
AddArray ................................................................................................................ 2767
I nsert ................................................................................................................ 2769
I nsertArray
................................................................................................................ 2770
I nsertArray
................................................................................................................ 2771
AssignArray
................................................................................................................ 2773
AssignArray
................................................................................................................ 2774
Update ................................................................................................................ 2776
Shift ................................................................................................................ 2777
Delete ................................................................................................................ 2778
DeleteRange
................................................................................................................ 2779
At ................................................................................................................ 2780
CompareArray
................................................................................................................ 2782
CompareArray
................................................................................................................ 2783
I nsertSort ................................................................................................................ 2784
Search ................................................................................................................ 2785
SearchGreat
................................................................................................................ 2786
SearchLess................................................................................................................ 2787
SearchGreatOrE qual
................................................................................................................ 2788
SearchLessOrE qual
................................................................................................................ 2789
SearchFirst................................................................................................................ 2790
SearchLast................................................................................................................ 2791
SearchLinear
................................................................................................................ 2792
Save ................................................................................................................ 2793
Load ................................................................................................................ 2795
Type ................................................................................................................ 2797
CArrayFloat
......................................................................................................................... 2798
Delta ................................................................................................................ 2801
Reserve ................................................................................................................ 2802
Resiz e ................................................................................................................ 2803
Shutdown ................................................................................................................ 2804
Add ................................................................................................................ 2805
AddArray ................................................................................................................ 2806
AddArray ................................................................................................................ 2807
I nsert ................................................................................................................ 2809
I nsertArray
................................................................................................................ 2810
I nsertArray
................................................................................................................ 2811
AssignArray
................................................................................................................ 2813
AssignArray
................................................................................................................ 2814
Update ................................................................................................................ 2816
I EqualityComparable <T>
......................................................................................................................... 3039
Equals ................................................................................................................ 3040
HashCode ................................................................................................................ 3041
I Comparable <T>
......................................................................................................................... 3042
Compare ................................................................................................................ 3043
I Comparer <T>
......................................................................................................................... 3044
Compare ................................................................................................................ 3045
I EqualityComparer <T>
......................................................................................................................... 3046
Equals ................................................................................................................ 3047
HashCode ................................................................................................................ 3048
I List <T>......................................................................................................................... 3049
TryGetValue
................................................................................................................ 3050
TrySetValue
................................................................................................................ 3051
I nsert ................................................................................................................ 3052
I ndexOf ................................................................................................................ 3053
LastI ndexOf
................................................................................................................ 3054
RemoveAt ................................................................................................................ 3055
I Map<TKey,TValue >
......................................................................................................................... 3056
Add ................................................................................................................ 3057
Contains ................................................................................................................ 3058
Remove ................................................................................................................ 3059
TryGetValue
................................................................................................................ 3060
TrySetValue
................................................................................................................ 3061
CopyTo ................................................................................................................ 3062
I Set <T>......................................................................................................................... 3063
ExceptWith
................................................................................................................ 3065
I ntersectWith
................................................................................................................ 3066
SymmetricExceptWith
................................................................................................................ 3067
UnionWith ................................................................................................................ 3068
I sProperSubsetOf
................................................................................................................ 3069
I sProperSupersetOf
................................................................................................................ 3070
I sSubsetOf................................................................................................................ 3071
I sSupersetOf
................................................................................................................ 3072
Overlaps ................................................................................................................ 3073
SetEquals ................................................................................................................ 3074
CDefaultComparer <T>
......................................................................................................................... 3075
Compare ................................................................................................................ 3076
CDefaultE qualityComparer <T>
......................................................................................................................... 3077
Equals ................................................................................................................ 3078
HashCode ................................................................................................................ 3079
CRedBlackTreeNode <T>
......................................................................................................................... 3080
Value ................................................................................................................ 3081
Parent ................................................................................................................ 3082
Left ................................................................................................................ 3083
Right ................................................................................................................ 3084
Color ................................................................................................................ 3085
I sLeaf ................................................................................................................ 3086
CreateEmptyNode
................................................................................................................ 3087
CLinkedListNode <T>
......................................................................................................................... 3088
List ................................................................................................................ 3089
Next ................................................................................................................ 3090
Previous ................................................................................................................ 3091
Value ................................................................................................................ 3092
CKeyValuePair <TKey,TValue>
......................................................................................................................... 3093
Key ................................................................................................................ 3094
Value ................................................................................................................ 3095
Clone ................................................................................................................ 3096
Compare ................................................................................................................ 3097
FileFindNext
................................................................................................................ 3284
FileFindClose
................................................................................................................ 3285
CFileBin......................................................................................................................... 3286
Open ................................................................................................................ 3288
WriteChar ................................................................................................................ 3289
WriteShort................................................................................................................ 3290
WriteI nteger
................................................................................................................ 3291
WriteLong ................................................................................................................ 3292
WriteFloat ................................................................................................................ 3293
WriteDouble
................................................................................................................ 3294
WriteString
................................................................................................................ 3295
WriteCharArray
................................................................................................................ 3296
WriteShortArray
................................................................................................................ 3297
WriteI ntegerArray
................................................................................................................ 3298
WriteLongArray
................................................................................................................ 3299
WriteFloatArray
................................................................................................................ 3300
WriteDoubleArray
................................................................................................................ 3301
WriteObject
................................................................................................................ 3302
ReadChar ................................................................................................................ 3303
ReadShort ................................................................................................................ 3304
ReadI nteger
................................................................................................................ 3305
ReadLong ................................................................................................................ 3306
ReadFloat ................................................................................................................ 3307
ReadDouble................................................................................................................ 3308
ReadString ................................................................................................................ 3309
ReadCharArray
................................................................................................................ 3310
ReadShortArray
................................................................................................................ 3311
ReadI ntegerArray
................................................................................................................ 3312
ReadLongArray
................................................................................................................ 3313
ReadFloatArray
................................................................................................................ 3314
ReadDoubleArray
................................................................................................................ 3315
ReadObject
................................................................................................................ 3316
CFileTxt......................................................................................................................... 3317
Open ................................................................................................................ 3318
WriteString
................................................................................................................ 3319
ReadString ................................................................................................................ 3320
Strings ............................................................................................................................3321
CString ......................................................................................................................... 3322
Str ................................................................................................................ 3324
Len ................................................................................................................ 3325
Copy ................................................................................................................ 3326
Fill ................................................................................................................ 3327
Assign ................................................................................................................ 3328
Append ................................................................................................................ 3329
I nsert ................................................................................................................ 3330
Compare ................................................................................................................ 3331
CompareNoCase
................................................................................................................ 3332
Left ................................................................................................................ 3333
Right ................................................................................................................ 3334
Mid ................................................................................................................ 3335
Trim ................................................................................................................ 3336
TrimLeft ................................................................................................................ 3337
TrimRight ................................................................................................................ 3338
Clear ................................................................................................................ 3339
ToUpper ................................................................................................................ 3340
ToLower ................................................................................................................ 3341
Reverse ................................................................................................................ 3342
Find ................................................................................................................ 3343
LineThickVertical
................................................................................................................ 3690
LineThickHori z ontal
................................................................................................................ 3691
LoadFromFile
................................................................................................................ 3692
PixelGet ................................................................................................................ 3693
PixelSet ................................................................................................................ 3694
PixelSetAA ................................................................................................................ 3695
Polygon ................................................................................................................ 3696
PolygonAA ................................................................................................................ 3697
PolygonWu................................................................................................................ 3698
PolygonThick
................................................................................................................ 3699
PolygonSmooth
................................................................................................................ 3700
Polyline ................................................................................................................ 3701
PolylineSmooth
................................................................................................................ 3702
PolylineThick
................................................................................................................ 3703
PolylineWu ................................................................................................................ 3704
PolylineAA ................................................................................................................ 3705
Rectangle ................................................................................................................ 3706
Resiz e ................................................................................................................ 3707
ResourceName
................................................................................................................ 3708
TextHeight................................................................................................................ 3709
TextOut ................................................................................................................ 3710
TextSiz e ................................................................................................................ 3711
TextWidth ................................................................................................................ 3712
TransparentLevelSet
................................................................................................................ 3713
Triangle ................................................................................................................ 3714
TriangleAA ................................................................................................................ 3715
TriangleWu................................................................................................................ 3716
Update ................................................................................................................ 3717
Width ................................................................................................................ 3718
CChartCanvas
......................................................................................................................... 3719
ColorBackground
................................................................................................................ 3722
ColorBorder
................................................................................................................ 3723
ColorText ................................................................................................................ 3724
ColorGrid ................................................................................................................ 3725
MaxData ................................................................................................................ 3726
MaxDescrLen
................................................................................................................ 3727
ShowFlags ................................................................................................................ 3728
I sShowLegend
................................................................................................................ 3729
I sShowScaleLeft
................................................................................................................ 3730
I sShowScaleRight
................................................................................................................ 3731
I sShowScaleTop
................................................................................................................ 3732
I sShowScaleBottom
................................................................................................................ 3733
I sShowGrid................................................................................................................ 3734
I sShowDescriptors
................................................................................................................ 3735
I sShowPercent
................................................................................................................ 3736
VScaleMin ................................................................................................................ 3737
VScaleMax ................................................................................................................ 3738
NumGrid ................................................................................................................ 3739
DataOffset................................................................................................................ 3740
DataTotal ................................................................................................................ 3741
DrawDescriptors
................................................................................................................ 3742
DrawData ................................................................................................................ 3743
Create ................................................................................................................ 3744
AllowedShowFlags
................................................................................................................ 3745
ShowLegend
................................................................................................................ 3746
ShowScaleLeft
................................................................................................................ 3747
ShowScaleRight
................................................................................................................ 3748
ShowScaleTop
................................................................................................................ 3749
ShowScaleBottom
................................................................................................................ 3750
ShowGrid ................................................................................................................ 3751
ShowDescriptors
................................................................................................................ 3752
ShowValue ................................................................................................................ 3753
ShowPercent
................................................................................................................ 3754
LegendAlignment
................................................................................................................ 3755
Accumulative
................................................................................................................ 3756
VScaleParams
................................................................................................................ 3757
DescriptorUpdate
................................................................................................................ 3758
ColorUpdate
................................................................................................................ 3759
ValuesCheck
................................................................................................................ 3760
Redraw ................................................................................................................ 3761
DrawBackground
................................................................................................................ 3762
DrawLegend
................................................................................................................ 3763
DrawLegendVertical
................................................................................................................ 3764
DrawLegendHori z ontal
................................................................................................................ 3765
CalcScales ................................................................................................................ 3766
DrawScales................................................................................................................ 3767
DrawScaleLeft
................................................................................................................ 3768
DrawScaleRight
................................................................................................................ 3769
DrawScaleTop
................................................................................................................ 3770
DrawScaleBottom
................................................................................................................ 3771
DrawGrid ................................................................................................................ 3772
DrawChart................................................................................................................ 3773
CHistogramChart
......................................................................................................................... 3774
Gradient ................................................................................................................ 3779
BarGap ................................................................................................................ 3780
BarMinSiz e................................................................................................................ 3781
BarBorder ................................................................................................................ 3782
Create ................................................................................................................ 3783
SeriesAdd ................................................................................................................ 3784
SeriesI nsert
................................................................................................................ 3785
SeriesUpdate
................................................................................................................ 3786
SeriesDelete
................................................................................................................ 3787
ValueUpdate
................................................................................................................ 3788
DrawData ................................................................................................................ 3789
DrawBar ................................................................................................................ 3790
GradientBrush
................................................................................................................ 3791
CLineChart
......................................................................................................................... 3792
Filled ................................................................................................................ 3796
Create ................................................................................................................ 3797
SeriesAdd ................................................................................................................ 3798
SeriesI nsert
................................................................................................................ 3799
SeriesUpdate
................................................................................................................ 3800
SeriesDelete
................................................................................................................ 3801
ValueUpdate
................................................................................................................ 3802
DrawChart................................................................................................................ 3803
DrawData ................................................................................................................ 3804
CalcArea ................................................................................................................ 3805
CPieChart
......................................................................................................................... 3806
Create ................................................................................................................ 3810
SeriesSet ................................................................................................................ 3811
ValueAdd ................................................................................................................ 3812
ValueI nsert................................................................................................................ 3813
ValueUpdate
................................................................................................................ 3814
ValueDelete
................................................................................................................ 3815
DrawChart................................................................................................................ 3816
DrawPie ................................................................................................................ 3817
I ndicatorDelete
......................................................................................................................... 3880
I ndicatorsTotal
......................................................................................................................... 3881
I ndicatorName
......................................................................................................................... 3882
Navigate
......................................................................................................................... 3883
Symbol ......................................................................................................................... 3884
Period ......................................................................................................................... 3885
Redraw......................................................................................................................... 3886
GetI nteger
......................................................................................................................... 3887
SetI nteger
......................................................................................................................... 3888
GetDouble
......................................................................................................................... 3889
SetDouble
......................................................................................................................... 3890
GetString
......................................................................................................................... 3891
SetString
......................................................................................................................... 3892
SetSymbolPeriod
......................................................................................................................... 3893
ApplyTemplate
......................................................................................................................... 3894
ScreenShot
......................................................................................................................... 3895
WindowOnDropped
......................................................................................................................... 3896
PriceOnDropped
......................................................................................................................... 3897
TimeOnDropped
......................................................................................................................... 3898
X OnDropped
......................................................................................................................... 3899
Y OnDropped
......................................................................................................................... 3900
Save ......................................................................................................................... 3901
Load ......................................................................................................................... 3902
Type ......................................................................................................................... 3903
Scientific ............................................................................................................................3904
Charts
GraphPlot
......................................................................................................................... 3905
CAxis ......................................................................................................................... 3909
AutoScale ................................................................................................................ 3911
Min ................................................................................................................ 3912
Max ................................................................................................................ 3913
Step ................................................................................................................ 3914
Name ................................................................................................................ 3915
Color ................................................................................................................ 3916
ValuesSiz e ................................................................................................................ 3917
ValuesWidth
................................................................................................................ 3918
ValuesFormat
................................................................................................................ 3919
ValuesDateTimeMode
................................................................................................................ 3920
ValuesFunctionFormat
................................................................................................................ 3921
ValuesFunctionFormatCBData
................................................................................................................ 3923
NameSiz e ................................................................................................................ 3924
ZeroLever ................................................................................................................ 3925
DefaultStep
................................................................................................................ 3926
MaxLabels ................................................................................................................ 3927
MinGrace ................................................................................................................ 3928
MaxGrace ................................................................................................................ 3929
SelectAxisScale
................................................................................................................ 3930
CColorGenerator
......................................................................................................................... 3931
Next ................................................................................................................ 3932
Reset ................................................................................................................ 3933
CCurve......................................................................................................................... 3934
Type ................................................................................................................ 3936
Name ................................................................................................................ 3937
Color ................................................................................................................ 3938
X Max ................................................................................................................ 3939
X Min ................................................................................................................ 3940
Y Max ................................................................................................................ 3941
Y Min ................................................................................................................ 3942
Siz e ................................................................................................................ 3943
MajorMarkSize
................................................................................................................ 4012
FontSet ................................................................................................................ 4013
FontGet ................................................................................................................ 4014
Attach ................................................................................................................ 4015
CalculateMaxMinValues
................................................................................................................ 4016
Height ................................................................................................................ 4017
I ndentDown
................................................................................................................ 4018
I ndentLeft ................................................................................................................ 4019
I ndentRight
................................................................................................................ 4020
I ndentUp ................................................................................................................ 4021
Redraw ................................................................................................................ 4022
ResetParameters
................................................................................................................ 4023
ScaleX ................................................................................................................ 4024
ScaleY ................................................................................................................ 4025
SetDefaultParameters
................................................................................................................ 4026
Width ................................................................................................................ 4027
Indicators............................................................................................................................4028
Base classes
......................................................................................................................... 4029
CSpreadBuffer
................................................................................................................ 4030
Siz e ........................................................................................................... 4032
SetSymbolPeriod
........................................................................................................... 4033
At ........................................................................................................... 4034
Refresh ........................................................................................................... 4035
RefreshCurrent
........................................................................................................... 4036
CTimeBuffer
................................................................................................................ 4037
Siz e ........................................................................................................... 4039
SetSymbolPeriod
........................................................................................................... 4040
At ........................................................................................................... 4041
Refresh ........................................................................................................... 4042
RefreshCurrent
........................................................................................................... 4043
CTickVolumeBuffer
................................................................................................................ 4044
Siz e ........................................................................................................... 4046
SetSymbolPeriod
........................................................................................................... 4047
At ........................................................................................................... 4048
Refresh ........................................................................................................... 4049
RefreshCurrent
........................................................................................................... 4050
CRealVolumeBuffer
................................................................................................................ 4051
Siz e ........................................................................................................... 4053
SetSymbolPeriod
........................................................................................................... 4054
At ........................................................................................................... 4055
Refresh ........................................................................................................... 4056
RefreshCurrent
........................................................................................................... 4057
CDoubleBuffer
................................................................................................................ 4058
Siz e ........................................................................................................... 4060
SetSymbolPeriod
........................................................................................................... 4061
At ........................................................................................................... 4062
Refresh ........................................................................................................... 4063
RefreshCurrent
........................................................................................................... 4064
COpenBuffer
................................................................................................................ 4065
Refresh ........................................................................................................... 4066
RefreshCurrent
........................................................................................................... 4067
CHighBuffer
................................................................................................................ 4068
Refresh ........................................................................................................... 4069
RefreshCurrent
........................................................................................................... 4070
CLowBuffer................................................................................................................ 4071
Refresh ........................................................................................................... 4072
RefreshCurrent
........................................................................................................... 4073
CCloseBuffer
................................................................................................................ 4074
SignalPeriod
........................................................................................................... 4350
Applied ........................................................................................................... 4351
Create ........................................................................................................... 4352
Main ........................................................................................................... 4353
Signal ........................................................................................................... 4354
Type ........................................................................................................... 4355
CiMomentum
................................................................................................................ 4356
MaPeriod ........................................................................................................... 4358
Applied ........................................................................................................... 4359
Create ........................................................................................................... 4360
Main ........................................................................................................... 4361
Type ........................................................................................................... 4362
CiOsMA ................................................................................................................ 4363
FastEmaPeriod
........................................................................................................... 4365
SlowEmaPeriod
........................................................................................................... 4366
SignalPeriod
........................................................................................................... 4367
Applied ........................................................................................................... 4368
Create ........................................................................................................... 4369
Main ........................................................................................................... 4370
Type ........................................................................................................... 4371
CiRSI ................................................................................................................ 4372
MaPeriod ........................................................................................................... 4374
Applied ........................................................................................................... 4375
Create ........................................................................................................... 4376
Main ........................................................................................................... 4377
Type ........................................................................................................... 4378
CiRVI ................................................................................................................ 4379
MaPeriod ........................................................................................................... 4381
Create ........................................................................................................... 4382
Main ........................................................................................................... 4383
Signal ........................................................................................................... 4384
Type ........................................................................................................... 4385
CiStochastic
................................................................................................................ 4386
Kperiod ........................................................................................................... 4388
Dperiod ........................................................................................................... 4389
Slowing ........................................................................................................... 4390
MaMethod ........................................................................................................... 4391
PriceField ........................................................................................................... 4392
Create ........................................................................................................... 4393
Main ........................................................................................................... 4394
Signal ........................................................................................................... 4395
Type ........................................................................................................... 4396
CiTriX ................................................................................................................ 4397
MaPeriod ........................................................................................................... 4399
Applied ........................................................................................................... 4400
Create ........................................................................................................... 4401
Main ........................................................................................................... 4402
Type ........................................................................................................... 4403
CiWPR ................................................................................................................ 4404
CalcPeriod........................................................................................................... 4406
Create ........................................................................................................... 4407
Main ........................................................................................................... 4408
Type ........................................................................................................... 4409
Volume .........................................................................................................................
I ndicators 4410
CiAD ................................................................................................................ 4411
Applied ........................................................................................................... 4413
Create ........................................................................................................... 4414
Main ........................................................................................................... 4415
TicksBookDepth
................................................................................................................ 4545
StopsLevel................................................................................................................ 4546
Freez eLevel
................................................................................................................ 4547
Bid ................................................................................................................ 4548
BidHigh ................................................................................................................ 4549
BidLow ................................................................................................................ 4550
Ask ................................................................................................................ 4551
AskHigh ................................................................................................................ 4552
AskLow ................................................................................................................ 4553
Last ................................................................................................................ 4554
LastHigh ................................................................................................................ 4555
LastLow ................................................................................................................ 4556
TradeCalcMode
................................................................................................................ 4557
TradeCalcModeDescription
................................................................................................................ 4558
TradeMode................................................................................................................ 4559
TradeModeDescription
................................................................................................................ 4560
TradeExecution
................................................................................................................ 4561
TradeExecutionDescription
................................................................................................................ 4562
SwapMode ................................................................................................................ 4563
SwapModeDescription
................................................................................................................ 4564
SwapRollover3days
................................................................................................................ 4565
SwapRollover3daysDescription
................................................................................................................ 4566
MarginI nitial
................................................................................................................ 4567
MarginMaintenance
................................................................................................................ 4568
MarginLong................................................................................................................ 4569
MarginShort
................................................................................................................ 4570
MarginLimit
................................................................................................................ 4571
MarginStop................................................................................................................ 4572
MarginStopLimit
................................................................................................................ 4573
TradeTimeFlags
................................................................................................................ 4574
TradeFillFlags
................................................................................................................ 4575
Digits ................................................................................................................ 4576
Point ................................................................................................................ 4577
TickValue ................................................................................................................ 4578
TickValueProfit
................................................................................................................ 4579
TickValueLoss
................................................................................................................ 4580
TickSiz e ................................................................................................................ 4581
ContractSiz
................................................................................................................
e 4582
LotsMin ................................................................................................................ 4583
LotsMax ................................................................................................................ 4584
LotsStep ................................................................................................................ 4585
LotsLimit ................................................................................................................ 4586
SwapLong ................................................................................................................ 4587
SwapShort ................................................................................................................ 4588
CurrencyBase
................................................................................................................ 4589
CurrencyProfit
................................................................................................................ 4590
CurrencyMargin
................................................................................................................ 4591
Bank ................................................................................................................ 4592
Description................................................................................................................ 4593
Path ................................................................................................................ 4594
SessionDeals
................................................................................................................ 4595
SessionBuyOrders
................................................................................................................ 4596
SessionSellOrders
................................................................................................................ 4597
SessionTurnover
................................................................................................................ 4598
SessionI nterest
................................................................................................................ 4599
SessionBuyOrdersVolume
................................................................................................................ 4600
SessionSellOrdersVolume
................................................................................................................ 4601
SessionOpen
................................................................................................................ 4602
SessionClose
................................................................................................................ 4603
SessionAW ................................................................................................................ 4604
SessionPriceSettlement
................................................................................................................ 4605
SessionPriceLimitMin
................................................................................................................ 4606
SessionPriceLimitMax
................................................................................................................ 4607
I nfoI nteger................................................................................................................ 4608
I nfoDouble ................................................................................................................ 4609
I nfoString ................................................................................................................ 4610
Normaliz ePrice
................................................................................................................ 4611
COrderI.........................................................................................................................
nfo 4612
Ticket ................................................................................................................ 4614
TimeSetup ................................................................................................................ 4615
TimeSetupMsc
................................................................................................................ 4616
OrderType................................................................................................................ 4617
TypeDescription
................................................................................................................ 4618
State ................................................................................................................ 4619
StateDescription
................................................................................................................ 4620
TimeExpiration
................................................................................................................ 4621
TimeDone ................................................................................................................ 4622
TimeDoneMsc
................................................................................................................ 4623
TypeFilling ................................................................................................................ 4624
TypeFillingDescription
................................................................................................................ 4625
TypeTime ................................................................................................................ 4626
TypeTimeDescription
................................................................................................................ 4627
Magic ................................................................................................................ 4628
PositionI d ................................................................................................................ 4629
VolumeI nitial
................................................................................................................ 4630
VolumeCurrent
................................................................................................................ 4631
PriceOpen ................................................................................................................ 4632
StopLoss ................................................................................................................ 4633
TakeProfit ................................................................................................................ 4634
PriceCurrent
................................................................................................................ 4635
PriceStopLimit
................................................................................................................ 4636
Symbol ................................................................................................................ 4637
Comment ................................................................................................................ 4638
I nfoI nteger................................................................................................................ 4639
I nfoDouble ................................................................................................................ 4640
I nfoString ................................................................................................................ 4641
StoreState................................................................................................................ 4642
CheckState................................................................................................................ 4643
Select ................................................................................................................ 4644
SelectByI ndex
................................................................................................................ 4645
CHistoryOrderI
.........................................................................................................................
nfo 4646
TimeSetup ................................................................................................................ 4648
TimeSetupMsc
................................................................................................................ 4649
OrderType................................................................................................................ 4650
TypeDescription
................................................................................................................ 4651
State ................................................................................................................ 4652
StateDescription
................................................................................................................ 4653
TimeExpiration
................................................................................................................ 4654
TimeDone ................................................................................................................ 4655
TimeDoneMsc
................................................................................................................ 4656
TypeFilling ................................................................................................................ 4657
TypeFillingDescription
................................................................................................................ 4658
TypeTime ................................................................................................................ 4659
TypeTimeDescription
................................................................................................................ 4660
Magic ................................................................................................................ 4661
PositionI d ................................................................................................................ 4662
VolumeI nitial
................................................................................................................ 4663
VolumeCurrent
................................................................................................................ 4664
PriceOpen ................................................................................................................ 4665
StopLoss ................................................................................................................ 4666
TakeProfit ................................................................................................................ 4667
PriceCurrent
................................................................................................................ 4668
PriceStopLimit
................................................................................................................ 4669
Symbol ................................................................................................................ 4670
Comment ................................................................................................................ 4671
I nfoI nteger................................................................................................................ 4672
I nfoDouble ................................................................................................................ 4673
I nfoString ................................................................................................................ 4674
Ticket ................................................................................................................ 4675
SelectByI ndex
................................................................................................................ 4676
CPositionI
.........................................................................................................................
nfo 4677
Time ................................................................................................................ 4679
TimeMsc ................................................................................................................ 4680
TimeUpdate
................................................................................................................ 4681
TimeUpdateMsc
................................................................................................................ 4682
PositionType
................................................................................................................ 4683
TypeDescription
................................................................................................................ 4684
Magic ................................................................................................................ 4685
I dentifier ................................................................................................................ 4686
Volume ................................................................................................................ 4687
PriceOpen ................................................................................................................ 4688
StopLoss ................................................................................................................ 4689
TakeProfit ................................................................................................................ 4690
PriceCurrent
................................................................................................................ 4691
Commission................................................................................................................ 4692
Swap ................................................................................................................ 4693
Profit ................................................................................................................ 4694
Symbol ................................................................................................................ 4695
Comment ................................................................................................................ 4696
I nfoI nteger................................................................................................................ 4697
I nfoDouble ................................................................................................................ 4698
I nfoString ................................................................................................................ 4699
Select ................................................................................................................ 4700
SelectByI ndex
................................................................................................................ 4701
SelectByMagic
................................................................................................................ 4702
SelectByTicket
................................................................................................................ 4703
StoreState................................................................................................................ 4704
CheckState................................................................................................................ 4705
CDealI nfo
......................................................................................................................... 4706
Order ................................................................................................................ 4708
Time ................................................................................................................ 4709
TimeMsc ................................................................................................................ 4710
DealType ................................................................................................................ 4711
TypeDescription
................................................................................................................ 4712
Entry ................................................................................................................ 4713
EntryDescription
................................................................................................................ 4714
Magic ................................................................................................................ 4715
PositionI d ................................................................................................................ 4716
Volume ................................................................................................................ 4717
Price ................................................................................................................ 4718
Commision ................................................................................................................ 4719
Swap ................................................................................................................ 4720
Profit ................................................................................................................ 4721
Symbol ................................................................................................................ 4722
CheckClose........................................................................................................... 4914
CheckCloseLong
........................................................................................................... 4915
CheckCloseShort
........................................................................................................... 4916
CloseAll ........................................................................................................... 4917
Close ........................................................................................................... 4918
CloseLong ........................................................................................................... 4919
CloseShort ........................................................................................................... 4920
CheckTrailingStop
........................................................................................................... 4921
CheckTrailingStopLong
........................................................................................................... 4922
CheckTrailingStopShort
........................................................................................................... 4923
TrailingStopLong
........................................................................................................... 4924
TrailingStopShort
........................................................................................................... 4925
CheckTrailingOrderLong
........................................................................................................... 4926
CheckTrailingOrderShort
........................................................................................................... 4927
TrailingOrderLong
........................................................................................................... 4928
TrailingOrderShort
........................................................................................................... 4929
CheckDeleteOrderLong
........................................................................................................... 4930
CheckDeleteOrderShort
........................................................................................................... 4931
DeleteOrders
........................................................................................................... 4932
DeleteOrder
........................................................................................................... 4933
DeleteOrderLong
........................................................................................................... 4934
DeleteOrderShort
........................................................................................................... 4935
LotOpenLong
........................................................................................................... 4936
LotOpenShort
........................................................................................................... 4937
LotReverse........................................................................................................... 4938
PrepareHistoryDate
........................................................................................................... 4939
HistoryPoint
........................................................................................................... 4940
CheckTradeState
........................................................................................................... 4941
WaitEvent ........................................................................................................... 4942
NoWaitEvent
........................................................................................................... 4943
TradeEventPositionStopTake
........................................................................................................... 4944
TradeEventOrderTriggered
........................................................................................................... 4945
TradeEventPositionOpened
........................................................................................................... 4946
TradeEventPositionVolumeChanged
........................................................................................................... 4947
TradeEventPositionModified
........................................................................................................... 4948
TradeEventPositionClosed
........................................................................................................... 4949
TradeEventOrderPlaced
........................................................................................................... 4950
TradeEventOrderModified
........................................................................................................... 4951
TradeEventOrderDeleted
........................................................................................................... 4952
TradeEventNotI
...........................................................................................................
dentified 4953
TimeframeAdd
........................................................................................................... 4954
TimeframesFlags
........................................................................................................... 4955
CExpertSignal
................................................................................................................ 4956
BasePrice ........................................................................................................... 4959
UsedSeries........................................................................................................... 4960
Weight ........................................................................................................... 4961
PatternsUsage
........................................................................................................... 4962
General ........................................................................................................... 4963
I gnore ........................................................................................................... 4964
I nvert ........................................................................................................... 4965
ThresholdOpen
........................................................................................................... 4966
ThresholdClose
........................................................................................................... 4967
PriceLevel........................................................................................................... 4968
StopLevel ........................................................................................................... 4969
TakeLevel ........................................................................................................... 4970
Expiration ........................................................................................................... 4971
Magic ........................................................................................................... 4972
ValidationSettings
........................................................................................................... 4973
I nitI ndicators
........................................................................................................... 4974
AddFilter ........................................................................................................... 4975
CheckOpenLong
........................................................................................................... 4976
CheckOpenShort
........................................................................................................... 4977
OpenLongParams
........................................................................................................... 4978
OpenShortParams
........................................................................................................... 4979
CheckCloseLong
........................................................................................................... 4980
CheckCloseShort
........................................................................................................... 4981
CloseLongParams
........................................................................................................... 4982
CloseShortParams
........................................................................................................... 4983
CheckReverseLong
........................................................................................................... 4984
CheckReverseShort
........................................................................................................... 4985
CheckTrailingOrderLong
........................................................................................................... 4986
CheckTrailingOrderShort
........................................................................................................... 4987
LongCondition
........................................................................................................... 4988
ShortCondition
........................................................................................................... 4989
Direction ........................................................................................................... 4990
CExpertTrailing
................................................................................................................ 4991
CheckTrailingStopLong
........................................................................................................... 4993
CheckTrailingStopShort
........................................................................................................... 4994
CExpertMoney
................................................................................................................ 4995
Percent ........................................................................................................... 4996
ValidationSettings
........................................................................................................... 4997
CheckOpenLong
........................................................................................................... 4998
CheckOpenShort
........................................................................................................... 4999
CheckReverse
........................................................................................................... 5000
CheckClose........................................................................................................... 5001
Modules.........................................................................................................................
of Trade Signals 5002
Signals of the
................................................................................................................
I ndicator Accelerator Oscillator 5005
Signals of the
................................................................................................................
I ndicator Adaptive Moving Average 5008
Signals of the
................................................................................................................
I ndicator Awesome Oscillator 5012
Signals of the
................................................................................................................
Oscillator Bears Power 5016
Signals of the
................................................................................................................
Oscillator Bulls Power 5018
Signals of the
................................................................................................................
Oscillator Commodity Channel I ndex 5020
Signals of the
................................................................................................................
Oscillator DeMarker 5024
Signals of the
................................................................................................................
I ndicator Double Exponential Moving Average 5028
Signals of the
................................................................................................................
I ndicator Envelopes 5032
Signals of the
................................................................................................................
I ndicator Fractal Adaptive Moving Average 5035
Signals of the
................................................................................................................
I ntraday Time Filter 5039
Signals of the
................................................................................................................
Oscillator MACD 5041
Signals of the
................................................................................................................
I ndicator Moving Average 5047
Signals of the
................................................................................................................
I ndicator Parabolic SAR 5051
Signals of the
................................................................................................................
Oscillator Relative Strength I ndex 5053
Signals of the
................................................................................................................
Oscillator Relative Vigor I ndex 5059
Signals of the
................................................................................................................
Oscillator Stochastic 5061
Signals of the
................................................................................................................
Oscillator Triple Exponential Average 5066
Signals of the
................................................................................................................
I ndicator Triple Exponential Moving Average 5070
Signals of the
................................................................................................................
Oscillator Williams Percent Range 5074
Trailing .........................................................................................................................
Stop Classes 5077
CTrailingFixedPips
................................................................................................................ 5078
StopLevel ........................................................................................................... 5080
ProfitLevel........................................................................................................... 5081
ValidationSettings
........................................................................................................... 5082
CheckTrailingStopLong
........................................................................................................... 5083
CheckTrailingStopShort
........................................................................................................... 5084
CTrailingMA
................................................................................................................ 5085
Period ........................................................................................................... 5087
Shift ........................................................................................................... 5088
OnObjectEndEdit
................................................................................................................ 5348
OnSetText ................................................................................................................ 5349
OnSetColor................................................................................................................ 5350
OnSetColorBackground
................................................................................................................ 5351
OnSetColorBorder
................................................................................................................ 5352
OnSetFont ................................................................................................................ 5353
OnSetFontSize
................................................................................................................ 5354
OnSet ZOrder
................................................................................................................ 5355
OnCreate ................................................................................................................ 5356
OnShow ................................................................................................................ 5357
OnHide ................................................................................................................ 5358
OnMove ................................................................................................................ 5359
OnResiz e ................................................................................................................ 5360
OnChange ................................................................................................................ 5361
OnClick ................................................................................................................ 5362
CPanel ......................................................................................................................... 5363
Create ................................................................................................................ 5368
BorderType................................................................................................................ 5369
OnSetText ................................................................................................................ 5370
OnSetColorBackground
................................................................................................................ 5371
OnSetColorBorder
................................................................................................................ 5372
OnCreate ................................................................................................................ 5373
OnShow ................................................................................................................ 5374
OnHide ................................................................................................................ 5375
OnMove ................................................................................................................ 5376
OnResiz e ................................................................................................................ 5377
OnChange ................................................................................................................ 5378
CPicture
......................................................................................................................... 5379
Create ................................................................................................................ 5384
Border ................................................................................................................ 5385
BmpName ................................................................................................................ 5386
OnCreate ................................................................................................................ 5387
OnShow ................................................................................................................ 5388
OnHide ................................................................................................................ 5389
OnMove ................................................................................................................ 5390
OnChange ................................................................................................................ 5391
CScroll ......................................................................................................................... 5392
Create ................................................................................................................ 5394
OnEvent ................................................................................................................ 5395
MinPos ................................................................................................................ 5396
MaxPos ................................................................................................................ 5397
CurrPos ................................................................................................................ 5398
CreateBack
................................................................................................................ 5399
CreateI nc ................................................................................................................ 5400
CreateDec ................................................................................................................ 5401
CreateThumb
................................................................................................................ 5402
OnClickI nc ................................................................................................................ 5403
OnClickDec................................................................................................................ 5404
OnShow ................................................................................................................ 5405
OnHide ................................................................................................................ 5406
OnChangePos
................................................................................................................ 5407
OnThumbDragStart
................................................................................................................ 5408
OnThumbDragProcess
................................................................................................................ 5409
OnThumbDragEnd
................................................................................................................ 5410
CalcPos ................................................................................................................ 5411
CScrollV......................................................................................................................... 5412
CreateI nc ................................................................................................................ 5418
CreateDec ................................................................................................................ 5419
CreateThumb
................................................................................................................ 5420
OnResiz e ................................................................................................................ 5421
OnChangePos
................................................................................................................ 5422
OnThumbDragStart
................................................................................................................ 5423
OnThumbDragProcess
................................................................................................................ 5424
OnThumbDragEnd
................................................................................................................ 5425
CalcPos ................................................................................................................ 5426
CScrollH......................................................................................................................... 5427
CreateI nc ................................................................................................................ 5433
CreateDec ................................................................................................................ 5434
CreateThumb
................................................................................................................ 5435
OnResiz e ................................................................................................................ 5436
OnChangePos
................................................................................................................ 5437
OnThumbDragStart
................................................................................................................ 5438
OnThumbDragProcess
................................................................................................................ 5439
OnThumbDragEnd
................................................................................................................ 5440
CalcPos ................................................................................................................ 5441
CWndClient
......................................................................................................................... 5442
Create ................................................................................................................ 5445
OnEvent ................................................................................................................ 5446
ColorBackground
................................................................................................................ 5447
ColorBorder
................................................................................................................ 5448
BorderType................................................................................................................ 5449
VScrolled ................................................................................................................ 5450
HScrolled ................................................................................................................ 5451
CreateBack
................................................................................................................ 5452
CreateScrollV
................................................................................................................ 5453
CreateScrollH
................................................................................................................ 5454
OnResiz e ................................................................................................................ 5455
OnVScrollShow
................................................................................................................ 5456
OnVScrollHide
................................................................................................................ 5457
OnHScrollShow
................................................................................................................ 5458
OnHScrollHide
................................................................................................................ 5459
OnScrollLineDown
................................................................................................................ 5460
OnScrollLineUp
................................................................................................................ 5461
OnScrollLineLeft
................................................................................................................ 5462
OnScrollLineRight
................................................................................................................ 5463
Rebound ................................................................................................................ 5464
CListView
......................................................................................................................... 5465
Create ................................................................................................................ 5471
OnEvent ................................................................................................................ 5472
TotalView ................................................................................................................ 5473
AddI tem ................................................................................................................ 5474
Select ................................................................................................................ 5475
SelectByText
................................................................................................................ 5476
SelectByValue
................................................................................................................ 5477
Value ................................................................................................................ 5478
CreateRow................................................................................................................ 5479
OnResiz e ................................................................................................................ 5480
OnVScrollShow
................................................................................................................ 5481
OnVScrollHide
................................................................................................................ 5482
OnScrollLineDown
................................................................................................................ 5483
OnScrollLineUp
................................................................................................................ 5484
OnI temClick
................................................................................................................ 5485
Redraw ................................................................................................................ 5486
RowState ................................................................................................................ 5487
CheckView................................................................................................................ 5488
CComboBox
......................................................................................................................... 5489
OnScrollLineDown
................................................................................................................ 5569
OnScrollLineUp
................................................................................................................ 5570
OnChangeI................................................................................................................
tem 5571
Redraw ................................................................................................................ 5572
RowState ................................................................................................................ 5573
Select ................................................................................................................ 5574
CSpinEdit
......................................................................................................................... 5575
Create ................................................................................................................ 5580
OnEvent ................................................................................................................ 5581
MinValue ................................................................................................................ 5582
MaxValue ................................................................................................................ 5583
Value ................................................................................................................ 5584
CreateEdit................................................................................................................ 5585
CreateI nc ................................................................................................................ 5586
CreateDec ................................................................................................................ 5587
OnClickI nc ................................................................................................................ 5588
OnClickDec................................................................................................................ 5589
OnChangeValue
................................................................................................................ 5590
CDialog ......................................................................................................................... 5591
Create ................................................................................................................ 5593
OnEvent ................................................................................................................ 5594
Caption ................................................................................................................ 5595
Add ................................................................................................................ 5596
CreateWhiteBorder
................................................................................................................ 5597
CreateBackground
................................................................................................................ 5598
CreateCaption
................................................................................................................ 5599
CreateButtonClose
................................................................................................................ 5600
CreateClientArea
................................................................................................................ 5601
OnClickCaption
................................................................................................................ 5602
OnClickButtonClose
................................................................................................................ 5603
ClientAreaVisible
................................................................................................................ 5604
ClientAreaLeft
................................................................................................................ 5605
ClientAreaTop
................................................................................................................ 5606
ClientAreaRight
................................................................................................................ 5607
ClientAreaBottom
................................................................................................................ 5608
ClientAreaWidth
................................................................................................................ 5609
ClientAreaHeight
................................................................................................................ 5610
OnDialogDragStart
................................................................................................................ 5611
OnDialogDragProcess
................................................................................................................ 5612
OnDialogDragEnd
................................................................................................................ 5613
CAppDialog
......................................................................................................................... 5614
Create ................................................................................................................ 5617
Destroy ................................................................................................................ 5618
OnEvent ................................................................................................................ 5619
Run ................................................................................................................ 5620
ChartEvent................................................................................................................ 5621
Minimiz ed ................................................................................................................ 5622
I niFileSave ................................................................................................................ 5623
I niFileLoad................................................................................................................ 5624
I niFileName................................................................................................................ 5625
I niFileExt ................................................................................................................ 5626
CreateCommon
................................................................................................................ 5627
CreateExpert
................................................................................................................ 5628
CreateI ndicator
................................................................................................................ 5629
CreateButtonMinMax
................................................................................................................ 5630
OnClickButtonClose
................................................................................................................ 5631
OnClickButtonMinMax
................................................................................................................ 5632
OnAnotherApplicationClose
................................................................................................................ 5633
MQL5 Reference
MetaQuotes Language 5 (MQL5) is a high-level language designed for developing technical indicators,
trading robots and utility applications, which automate financial trading. MQL5 has been developed by
MetaQuotes Software Corp. for their trading platform. The language syntax is very close to C++
enabling programmers to develop applications in the object-oriented programming (OOP) style.
In addition to the MQL5 language, the trading platform pack age also includes the MetaEditor I DE with
highly advanced code writing tools, such as templates, snippets, debugging, profiling and auto
completion tools, as well as built-in MQL5 Storage enabling file versioning.
The language support is available on the MQL5.community website, which contains a huge free
CodeBase and a plethora of articles. These articles cover all the aspects of the modern trading,
including neural network s, statistics and analysis, high-frequency trading, arbitrage, testing and
optimization of trading strategies, use of trading automation robots, and more.
Traders and MQL5 program developers can communicate on the forum, order and develop applications
using the Freelance service, as well as buy and sell protected programs in the Mark et of automated
trading applications.
The MQL5 language provides specialized trading functions and predefined event handlers to help
programmers develop Expert Advisors (EAs), which automatically control trading processes following
specific trading rules. In addition to EAs, MQL5 allows developing custom technical indicators, scripts
and libraries.
This MQL5 language reference contains functions, operations, reserved words and other language
constructions divided into categories. The reference also provides descriptions of Standard Library
classes used for developing trading strategies, control panels, custom graphics and enabling file
access.
Additionally, the CodeBase contains the AL GLIB numerical analysis library, which can be used for
solving various mathematical problems.
· Expert Advisor is an automated trading system link ed to a chart. An Expert Advisor contains event
handlers to manage predefined events which activate execution of appropriate trading strategy
elements. For example, an event of program initialization and deinitializtion, new tick s, timer
events, changes in the Depth of Mark et, chart and custom events.
In addition to calculating trading signals based on the implemented rules, Expert Advisors can also
automatically execute trades and send them directly to a trading server. Expert Advisors are stored
in <Terminal_Directory>\MQL5\Experts .
· Custom Indicator s is a technical indicator developed by a user in addition to standard indicators
integrated into the trading platform. Custom indicators, as well as standard ones, cannot trade
automatically, but only implement analytical functions. Custom indicators can utilize values of other
indicators for calculations, and can be called from Expert Advisors.
Custom indicators are stored in <Terminal_Directory>\MQL5\Indicators .
· Script is a program for a single execution of an action. Unlik e Expert Advisors, scripts do not handle
any event except for trigger. A script code must contain the OnStart handler function.
Scripts are stored in <Terminal_DIrectory>\MQL5\Scripts.
· Service is a program that, unlik e indicators, Expert Advisors and scripts, does not require to be
bound to a chart to work . Lik e scripts, services do not handle any event except for trigger. To
launch a service, its code should contain the OnStart handler function. Services do not accept any
other events except Start, but they are able to send custom events to charts using
EventChartCustom. Services are stored in <terminal_directory>\MQL5\Services.
· Library is a set of custom functions. Libraries are intended to store and distribute commonly used
algorithms of custom programs.
Libraries are stored in <Terminal_Directory>\MQL5\Libraries .
· Include File is a source text of the most frequently used block s of custom programs. Such files can
be included into the source texts of Expert Advisors, scripts, custom indicators, and libraries at the
compiling stage. The use of included files is more preferable than the use of libraries because of
additional burden occurring at calling library functions.
Include files can be stored in the same directory where the original file is located. In this case the
#include directive with double quotes is used. Another option is to store include files in
<Terminal_Directory>\MQL5\Include. In this case #include with angle brack ets should be used.
Language Basics
The MetaQuotes Language 5 (MQL5) is an object-oriented high-level programming language intended
for writing automated trading strategies, custom technical indicators for the analysis of various
financial mark ets. It allows not only to write a variety of expert systems, designed to operate in real
time, but also create their own graphical tools to help you mak e trade decisions.
MQL5 is based on the concept of the popular programming language C++. As compared to MQL 4, the
new language now has enumerations, structures, classes and event handling. By increasing the number
of embedded main types, the interaction of executable programs in MQL5 with other applications
through dll is now as easy as possible. MQL5 syntax is similar to the syntax of C++, and this mak es it
easy to translate into it programs from modern programming languages.
To help you study the MQL5 language, all topics are grouped into the following sections :
· Syntax
· Data Types
· Operators
· Functions
· Variables
· Preprocessor
· Object-Oriented Programming
Syntax
As to the syntax, T HE MQL5 language for programming trading strategies is very much similar to the
C++ programming language, except for some features :
· no address arithmetic;
· no goto operator;
· no multiple inheritance.
See also
Enumerations, Structures and Classes, Inheritance
Comments
Multi-line comments start with the /* pair of symbols and end with the */ one. Such k ind of comments
cannot be nested. Single-line comments begin with the // pair of symbols and end with the newline
character, they can be nested in other multi-line comments. Comments are allowed everywhere where
the spaces are allowed, they can have any number of spaces in them.
Examples:
Identifiers
Identifiers are used as names of variables and functions. The length of the identifier can not exceed
63 characters.
Characters allowed to be written in an identifier: figures 0-9, the Latin uppercase and lowercase
letters a-z and A-Z, recognized as different characters, the underscore character (_).The first
character can not be a digit.
Examples:
See also
Variables, Functions
Reserved Words
The following identifiers are recorded as reserved words, each of them corresponds to a certain
action, and cannot be used in another meaning :
Data Types
Access Specificators
public virtual
Memory Classes
Operators
default if while
delete new
do operator
Other
Data Types
Any program operates with data. Data can be of different types depending on their purposes. For
example, integer data are used to access to array components. Price data belong to those of double
precision with floating point. This is related to the fact that no special data type for price data is
provided in MQL5.
Data of different types are processed with different rates. Integer data are processed at the fastest.
To process the double precision data, a special co-processor is used. H owever, because of complexity
of internal representation of data with floating point, they are processed slower than the integer ones.
String data are processed at the longest because of dynamic computer memory allocation/reallocation.
· logical (bool);
· literals (ushort);
· strings (string);
· color (color);
· enumerations (enum).
· structures ;
· classes.
In terms of OOP complex data types are called abstract data types.
The color and datetime types mak e sense only to facilitate visualization and input of parameters
defined from outside - from the table of Expert Advisor or custom indicator properties (the Inputs
tab). Data of color and datetime types are represented as integers. Integer types and floating-point
types are called arithmetic (numeric) types.
Only implicit type casting is used in expressions, unless the explicit casting is specified.
See also
Typecasting
Integer Types
In MQL5 integers are represented by eleven types. Some types can be used together with other ones,
if required by the program logic, but in this case it's necessary to remember the rules of typecasting.
The table below lists the characteristics of each type. Besides, the last column features a type in C++
corresponding to each type.
Integer type values can also be presented as numeric constants, color literals, date-time literals,
character constants and enumerations.
See also
Conversion Functions, Numerical Type Constants
uchar
The uchar integer type also occupies 1 byte of memory, as well as the char type, but unlik e it uchar is
intended only for positive values. The minimum value is zero, the maximum value is 255. The first
letter u in the name of the uchar type is the abbreviation for unsigned.
short
The size of the short type is 2 bytes (16 bits) and, accordingly, it allows expressing the range of values
equal to 2 to the power 16: 2^16 = 65 536.Since the short type is a signed one, and contains both
positive and negative values, the range of values is between -32 768 and 32 767.
ushort
The unsigned short type is the type ushort, which also has a size of 2 bytes. The minimum value is 0,
the maximum value is 65 535.
int
The size of the int type is 4 bytes (32 bits). The minimal value is -2 147 483 648, the maximal one is 2
147 483 647.
uint
The unsigned integer type is uint. It tak es 4 bytes of memory and allows expressing integers from 0 to
4 294 967 295.
long
The size of the long type is 8 bytes (64 bits). The minimum value is -9 223 372 036 854 775 808, the
maximum value is 9 223 372 036 854 775 807.
ulong
The ulong type also occupies 8 bytes and can store values from 0 to 18 446 744 073 709 551 615.
Examples:
char ch=12;
short sh=-5000;
int in=2445777;
Since the unsigned integer types are not designed for storing negative values, the attempt to set a
negative value can lead to unexpected consequences. Such a simple script will lead to an infinite loop:
for(char ch=-128;ch<128;ch++)
{
u_ch=ch;
Print("ch = ",ch," u_ch = ",u_ch);
}
}
for(char ch=-128;ch<=127;ch++)
{
u_ch=ch;
Print("ch = ",ch," u_ch = ",u_ch);
if(ch==127) break;
}
}
Result:
...
Examples:
H exadecimal: numbers 0-9, the letters a-f or A-F for the values of 10-15; start with 0x or 0X.
Examples:
For integer variables, the values can be set in binary form using B prefix. For example, you can encode
the work ing hours of a trading session into int type variable and use information about them according
to the required algorithm:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- set 1 for working hours and 0 for nonworking ones
int AsianSession =B'111111111'; // Asian session from 0:00 to 9:00
int EuropeanSession=B'111111111000000000'; // European session 9:00 - 18:00
int AmericanSession =B'111111110000000000000011'; // American session 16:00 - 02:00
//--- derive numerical values of the sessions
PrintFormat("Asian session hours as value =%d",AsianSession);
PrintFormat("European session hours as value is %d",EuropeanSession);
PrintFormat("American session hours as value is %d",AmericanSession);
//--- and now let's display string representations of the sessions' working hours
Print("Asian session ",GetHoursForSession(AsianSession));
Print("European session ",GetHoursForSession(EuropeanSession));
Print("American session ",GetHoursForSession(AmericanSession));
//---
}
//+------------------------------------------------------------------+
//| return the session's working hours as a string |
//+------------------------------------------------------------------+
string GetHoursForSession(int session)
{
//--- in order to check, use AND bit operations and left shift by 1 bit <<=1
//--- start checking from the lowest bit
int bit=1;
string out="working hours: ";
//--- check all 24 bits starting from the zero and up to 23 inclusively
for(int i=0;i<24;i++)
{
//--- receive bit state in number
bool workinghour=(session&bit)==bit;
//--- add the hour's number to the message
if(workinghour )out=out+StringFormat("%d ",i);
//--- shift by one bit to the left to check the value of the next one
bit<<=1;
}
//--- result string
return out;
}
See also
Typecasting
Character Constants
Characters as elements of a string in MQL5 are indexes in the Unicode character set. They are
hexadecimal values that can be cast into integers, and that can be manipulated by integer operations
lik e addition and subtraction.
Any single character in quotation mark s or a hexadecimal ASCII code of a character as '\x 10' is a
character constant and is of ushort type. For example, a record of '0' type is a numerical value 30, that
corresponds to the index of zero in the table of characters.
Example:
void OnStart()
{
//--- define character constants
int symbol_0='0';
int symbol_9=symbol_0+9; // get symbol '9'
//--- output values of constants
printf("In a decimal form: symbol_0 = %d, symbol_9 = %d",symbol_0,symbol_9);
printf("In a hexadecimal form: symbol_0 = 0x%x, symbol_9 = 0x%x",symbol_0,symbol_9);
//--- enter constants into a string
string test="";
StringSetCharacter(test,0,symbol_0);
StringSetCharacter(test,1,symbol_9);
//--- this is what they look like in a string
Print(test);
}
A back slash is a control character for a compiler when dealing with constant strings and character
constants in a source text of a program. Some symbols, for example a single quote ('), double quotes
(" ), back slash (\ ) and control characters can be represented as a combination of symbols that start
with a back slash (\ ), according to the below table:
If a back slash is followed by a character other than those described above, result is undefined.
Example
void OnStart()
{
//--- declare character constants
int a='A';
int b='$';
int c='©'; // code 0xA9
int d='\xAE'; // code of the symbol ®
//--- output print constants
Print(a,b,c,d);
//--- add a character to the string
string test="";
StringSetCharacter(test,0,a);
Print(test);
//--- replace a character in a string
StringSetCharacter(test,0,b);
Print(test);
//--- replace a character in a string
StringSetCharacter(test,0,c);
Print(test);
//--- replace a character in a string
StringSetCharacter(test,0,d);
Print(test);
//--- represent characters as a number
int a1=65;
int b1=36;
int c1=169;
int d1=174;
//--- add a character to the string
StringSetCharacter(test,1,a1);
Print(test);
//--- add a character to the string
StringSetCharacter(test,1,b1);
Print(test);
//--- add a character to the string
StringSetCharacter(test,1,c1);
Print(test);
//--- add a character to the string
StringSetCharacter(test,1,d1);
Print(test);
}
As it was mentioned above, the value of a character constant (or variable) is an index in the table of
characters. Index being an integer, it can be written in different ways.
void OnStart()
{
//---
int a=0xAE; // the code of ® corresponds to the '\xAE' literal
int b=0x24; // the code of $ corresponds to the '\x24' literal
int c=0xA9; // the code of © corresponds to the '\xA9' literal
int d=0x263A; // the code of ☺ corresponds to the '\x263A' literal
//--- show values
Print(a,b,c,d);
//--- add a character to the string
string test="";
StringSetCharacter(test,0,a);
Print(test);
//--- replace a character in a string
StringSetCharacter(test,0,b);
Print(test);
//--- replace a character in a string
StringSetCharacter(test,0,c);
Print(test);
//--- replace a character in a string
StringSetCharacter(test,0,d);
Print(test);
//--- codes of suits
int a1=0x2660;
int b1=0x2661;
int c1=0x2662;
int d1=0x2663;
//--- add a character of spades
StringSetCharacter(test,1,a1);
Print(test);
//--- add a character of hearts
StringSetCharacter(test,2,b1);
Print(test);
//--- add a character of diamonds
StringSetCharacter(test,3,c1);
Print(test);
//--- add a character of clubs
StringSetCharacter(test,4,d1);
Print(test);
//--- Example of character literals in a string
test="Queen\x2660Ace\x2662";
printf("%s",test);
}
The internal representation of a character literal is the ushort type. Character constants can accept
values from 0 to 65535.
See also
StringSetCharacter(), String GetCharacter(), ShortToString(), ShortArrayToString(),
StringToShortArray()
Datetime Type
The datetime type is intended for storing the date and time as the number of seconds elapsed since
January 01, 1970. This type occupies 8 bytes of memory.
Constants of the date and time can be represented as a literal string, which consists of 6 parts
showing the numerical value of the year, month, day (or day, month, year), hours, minutes and
seconds. The constant is enclosed in single quotation mark s and starts with the D character.
Values range from 1 January, 1970 to 31 December, 3000. Either date (year , month, day) or time
(hours, minutes, seconds), or all together can be omitted.
W ith literal date specification, it is desirable that you specify year, month and day. Otherwise the
compiler returns a warning about an incomplete entry.
Examples:
See also
Structure of the Date Type, Date and Time, TimeToString, StringToTime
Color Type
The color type is intended for storing information about color and occupies 4 bytes in memory. The
first byte is ignored, the remaining 3 bytes contain the RGB-components.
Color constants can be represented in three ways : literally, by integers, or by name (for named W eb-
colors only).
Literal representation consists of three parts representing numerical rate values of the three main
color components : red, green, blue. The constant starts with C and is enclosed in single quotes.
Numerical rate values of a color component lie in the range from 0 to 255.
Examples:
//--- Literals
C'128,128,128' // Gray
C'0x00,0x00,0xFF' // Blue
//color names
clrRed // Red
clrYellow // Yellow
clrBlack // Black
//--- Integral representations
0xFFFFFF // White
16777215 // White
0x008000 // Green
32768 // Green
See also
W eb Colors, ColorToString, StringToColor, Typecasting
Bool Type
The bool type is intended to store the logical values of true or false, numeric representation of them is
1 or 0, respectively.
Examples:
bool a = true;
bool b = false;
bool c = 1;
The internal representation is a whole number 1 byte large. It should be noted that in logical
expressions you can use other integer or real types or expressions of these types - the compiler will
not generate any error. In this case, the zero value will be interpreted as false, and all other values -
as true.
Examples:
int i=5;
double d=-2.5;
if(i) Print("i = ",i," and is set to true");
else Print("i = ",i," and is set to false");
i=0;
if(i) Print("i = ",i," and has the true value");
else Print("i = ",i," and has the false value");
d=0.0;
if(d) Print("d = ",d," and has the true value");
else Print("d = ",d," and has the false value");
See also
Boolean Operations, Precedence R ules
Enumerations
Data of the enum type belong to a certain limited set of data. Defining the enumeration type:
Example:
After the enumeration is declared, a new integer-valued 4-byte data type appears. Declaration of the
new data type allows the compiler to strictly control types of passed parameters, because enumeration
introduces new named constants. In the above example, the January named constant has the value of
0, February - 1, December - 11.
Rule: If a certain value is not assigned to a named constant that is a member of the enumeration, its
new value will be formed automatically. If it is the first member of the enumeration, the 0 value will
be assigned to it. For all subsequent members, values will be calculated based on the value of the
previous members by adding one.
Example:
Notes
· Unlik e C++, the size of the internal representation of the enumerated type in MQL5 is always equal
to 4 bytes. That is, sizeof (months) returns the value 4.
· Unlik e C++, an anonymous enumeration can't be declared in MQL5. That is, a unique name must be
always specified after the enum k eyword.
See also
Typecasting
The double name means that the accuracy of these numbers is twice the accuracy of the float type
numbers. In most cases, the double type is the most convenient one. In many cases the limited
precision of float numbers is not enough. The reason why the float type is still used is saving the
memory (this is important for large arrays of real numbers).
Floating-point constants consist of an integer part, a point (.) and the fractional part. The integer and
fractional parts are sequences of decimal digits.
Examples:
double a=12.111;
double b=-956.1007;
float c =0.0001;
float d =16;
There is a scientific way of writing real constants, often this method of recording is more compact
than the traditional one.
Example:
double c1=1.12123515e-25;
double c2=0.000000000000000000000000112123515; // 24 zero after the decimal point
Print("1. c1 =",DoubleToString(c1,16));
// Result: 1. c1 = 0.0000000000000000
Print("2. c1 =",DoubleToString(c1,-16));
// Result: 2. c1 = 1.1212351499999999e-025
Print("3. c2 =",DoubleToString(c2,-16));
// Result: 3. c2 = 1.1212351499999999e-025
It should be remembered that real numbers are stored in memory with some limited accuracy in the
binary system, while generally the decimal notation is used. That's why many numbers that are
precisely represented in the decimal system can be written only as an infinite fraction in the binary
system.
For example, numbers 0.3 and 0.7 are represented in the computer as infinite fractions, while the
number of 0.25 is stored exactly, because it represents the power of two.
In this regard, it is strongly recommended not to compare two real numbers for equality, because such
a comparison is not correct.
Example:
void OnStart()
{
//---
double three=3.0;
double x,y,z;
x=1/three;
y=4/three;
z=5/three;
if(x+y==z)
Print("1/3 + 4/3 == 5/3");
else
Print("1/3 + 4/3 != 5/3");
// Result: 1/3 + 4/3 != 5/3
}
If you still need to compare the equality of two real numbers, then you can do this in two different
ways. The first way is to compare the difference between two numbers with some small quantity that
specifies the accuracy of comparison.
Example:
Note that the value of epsilon in the above example can not be less than the predefined constant
DBL _EPSILON. The value of this constant is 2.2204460492503131e-016. The constant corresponding to
the float type is FLT _EPSILON = 1.192092896e-07. The meaning of these values is the following : it is
the lowest value that satisfies the condition 1.0 + DBL _EPSILON! = 1.0 (for numbers of float type 1.0
+ FLT _EPSILON! = 1.0).
The second way offers comparing the normalized difference of two real numbers with zero. It's
meaningless to compare the difference of normalized numbers with a zero, because any mathematical
operation with normalized numbers gives a non-normalized result.
Example:
Some operations of the mathematical co-processor can result in the invalid real number, which can't be
used in mathematical operations and operations of comparison, because the result of operations with
invalid real numbers is undefined. For example, when trying to calculate the arcsine of 2, the result is
the negative infinity.
Example:
Besides the minus infinity there is the plus infinity and NaN (not a number). To determine that this
number is invalid, you can use MathIs ValidNumber(). According to the I EEE standard, they have a
special machine representation. For example, plus infinity for the double type has the bit
representation of 0x 7FF0 0000 0000 0000.
Examples:
struct str1
{
double d;
};
struct str2
{
long l;
};
//--- Start
str1 s1;
str2 s2;
//---
s1.d=MathArcsin(2.0); // Get the invalid number -1.#IND
s2=s1;
printf("1. %f %I64X",s1.d,s2.l);
//---
s2.l=0xFFFF000000000000; // invalid number -1.#QNAN
s1=s2;
printf("2. %f %I64X",s1.d,s2.l);
//---
s2.l=0x7FF7000000000000; // greatest non-number SNaN
s1=s2;
printf("3. %f %I64X",s1.d,s2.l);
//---
s2.l=0x7FF8000000000000; // smallest non-number QNaN
s1=s2;
printf("4. %f %I64X",s1.d,s2.l);
//---
s2.l=0x7FFF000000000000; // greatest non-number QNaN
s1=s2;
printf("5. %f %I64X",s1.d,s2.l);
//---
s2.l=0x7FF0000000000000; // Positive infinity 1.#INF and smallest non-number SNaN
s1=s2;
printf("6. %f %I64X",s1.d,s2.l);
//---
s2.l=0xFFF0000000000000; // Negative infinity -1.#INF
s1=s2;
printf("7. %f %I64X",s1.d,s2.l);
//---
s2.l=0x8000000000000000; // Negative zero -0.0
s1=s2;
printf("8. %f %I64X",s1.d,s2.l);
//---
s2.l=0x3FE0000000000000; // 0.5
s1=s2;
printf("9. %f %I64X",s1.d,s2.l);
//---
s2.l=0x3FF0000000000000; // 1.0
s1=s2;
printf("10. %f %I64X",s1.d,s2.l);
//---
See also
DoubleToString, NormalizeDouble, Numeric Type Constants
String Type
The string type is used for storing text strings. A text string is a sequence of characters in the
Unicode format with the final zero at the end of it. A string constant can be assigned to a string
variable. A string constant is a sequence of Unicode characters enclosed in double quotes : " This is a
string constant" .
If you need to include a double quote (" ) into a string, the back slash character (\ ) must be put before
it. Any special character constants can be written in a string, if the back slash character (\ ) is typed
before them.
Examples:
To mak e the source code readable, long constant strings can be split into parts without addition
operation. During compilation, these parts will be combined into one long string :
See also
Conversion Functions, String Functions, FileOpen, FileR eadString, FileW riteString
Structure Declaration
struct structure_name
{
elements_description
};
The structure name can't be used as an identifier (name of a variable or function). It should be noted
that in MQL5 structure elements follow one another directly, without alignment. In C++ such an order
is made to the compiler using the following instruction:
#pragma pack(1)
If you want to do another alignment in the structure, use auxiliary members, " fillers " to the right size.
Example:
struct trade_settings
{
uchar slippage; // value of the permissible slippage-size 1 byte
char reserved1; // skip 1 byte
short reserved2; // skip 2 bytes
int reserved4; // another 4 bytes are skipped. ensure alignment of the boundary 8 bytes
double take; // values of the price of profit fixing
double stop; // price value of the protective stop
};
Such a description of aligned structures is necessary only for transferring to imported dll-functions.
Attention: This example illustrates incorrectly designed data. It would be better first to declare the
take and stop large data of the double type, and then declare the slippage member of the uchar type.
In this case, the internal representation of data will always be the same regardless of the value
specified in #pragma pack().
If a structure contains variables of the string type and/or object of a dynamic array, the compiler
assigns an implicit constructor to such a structure. This constructor resets all the structure members
of string type and correctly initializes objects of the dynamic array.
Simple Structures
Structures that do not contain strings, class objects, pointers and objects of dynamic arrays are called
simple structures. Variables of simple structures, as well as their arrays can be passed as parameters
to functions imported from DLL.
· if the objects are connected by the lineage meaning that one structure is a descendant of another.
To provide an example, let's develop the CustomM qlTick custom structure with its contents identical to
the built-in M qlTick one. The compiler does not allow copying the M qlTick object value to the
CustomM qlTick type object. Direct typecasting to the necessary type also causes the compilation error:
Therefore, only one option is left – copying the values of the structure elements one by one. It is still
allowed to copy the values of the same type of CustomM qlTick .
CustomMqlTick my_tick1,my_tick2;
//--- it is allowed to copy the objects of the same type of CustomMqlTick the following way
my_tick2=my_tick1;
//--- create an array out of the objects of the simple CustomMqlTick structure and write valu
CustomMqlTick arr[2];
arr[0]=my_tick1;
arr[1]=my_tick2;
The ArrayPrint() function is called for a check to display the arr[] array value in the journal.
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- develop the structure similar to the built-in MqlTick
struct CustomMqlTick
{
datetime time; // Last price update time
double bid; // Current Bid price
double ask; // Current Ask price
double last; // Current price of the last trade (Last)
ulong volume; // Volume for the current Last price
long time_msc; // Last price update time in milliseconds
uint flags; // Tick flags
};
//--- get the last tick value
MqlTick last_tick;
CustomMqlTick my_tick1,my_tick2;
//--- attempt to copy data from MqlTick to CustomMqlTick
if(SymbolInfoTick(Symbol(),last_tick))
{
//--- it is allowed to copy the objects of the same type of CustomMqlTick the following way
my_tick2=my_tick1;
//--- create an array out of the objects of the simple CustomMqlTick structure and write valu
CustomMqlTick arr[2];
arr[0]=my_tick1;
arr[1]=my_tick2;
ArrayPrint(arr);
//--- example of displaying values of the array containing the objects of CustomMqlTick type
/*
[time] [bid] [ask] [last] [volume] [time_msc] [flags]
[0] 2017.05.29 15:04:37 1.11854 1.11863 +0.00000 1450000 1496070277157 2
[1] 2017.05.29 15:04:37 1.11854 1.11863 +0.00000 1450000 1496070277157 2
*/
}
else
Print("SymbolInfoTick() failed, error = ",GetLastError());
}
The second example shows the features of copying simple structures by the lineage. Suppose that we
have the Animal basic structure, from which the Cat and Dog structures are derived. W e can copy the
Animal and Cat objects, as well as the Animal and Dog objects to each other but we cannot copy Cat
and Dog to each other, although both are descendants of the Animal structure.
Dog dog;
Cat cat;
//--- can be copied from ancestor to descendant (Animal ==> Dog)
dog=some_animal;
dog.swim=true; // dogs can swim
//--- you cannot copy objects of child structures (Dog != Cat)
cat=dog; // compiler returns an error
dog=some_animal;
dog.swim=true; // dogs can swim
//--- you cannot copy objects of child structures (Dog != Cat)
//cat=dog; // compiler returns an error here
//--- therefore, it is possible to copy elements one by one only
cat.head=dog.head;
cat.legs=dog.legs;
cat.wings=dog.wings;
cat.tail=dog.tail;
cat.fly=dog.fly;
cat.swim=false; // cats cannot swim
//--- it is possible to copy the values from descendant to ancestor
Animal elephant;
elephant=cat;
elephant.run=false;// elephants cannot run
elephant.swim=true;// elephants can swim
//--- create an array
Animal animals[4];
animals[0]=some_animal;
animals[1]=dog;
animals[2]=cat;
animals[3]=elephant;
//--- print out
ArrayPrint(animals);
//--- execution result
/*
[head] [legs] [wings] [tail] [fly] [swim] [run]
[0] 1 4 0 true false false true
[1] 1 4 0 true false true true
[2] 1 4 0 true false false false
[3] 1 4 0 true false true false
*/
}
Another way to copy simple types is using a union. The objects of the structures should be members of
the same union – see the example in union.
The name of a structure becomes a new data type, so you can declare variables of this type. The
structure can be declared only once within a project. The structure members are accessed using the
point operation (.).
Example:
struct trade_settings
{
double take; // values of the profit fixing price
double stop; // value of the protective stop price
uchar slippage; // value of the acceptable slippage
};
//--- create up and initialize a variable of the trade_settings type
trade_settings my_set={0.0,0.0,5};
if (input_TP>0) my_set.take=input_TP;
The special pack attribute allows setting the alignment of structure or class fields.
pack([n])
Example:
'pack (1)' is applied by default for structures. This means that the structure members are located one
after another in memory, and the structure size is equal to the sum of its members ' size.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- simple structure with no alignment
struct Simple_Structure
{
char c; // sizeof(char)=1
short s; // sizeof(short)=2
int i; // sizeof(int)=4
double d; // sizeof(double)=8
};
//--- declare a simple structure instance
Simple_Structure s;
//--- display the size of each structure member
Print("sizeof(s.c)=",sizeof(s.c));
Print("sizeof(s.s)=",sizeof(s.s));
Print("sizeof(s.i)=",sizeof(s.i));
Print("sizeof(s.d)=",sizeof(s.d));
//--- make sure the size of POD structure is equal to the sum of its members' size
Print("sizeof(simple_structure)=",sizeof(simple_structure));
/*
Result:
sizeof(s.c)=1
sizeof(s.s)=2
sizeof(s.i)=4
sizeof(s.d)=8
sizeof(simple_structure)=15
*/
}
Alignment of the structure fields may be needed when exchanging data with third-party libraries
(*.DLL) where such alignment is applied.
Let's use some examples to show how alignment work s. W e will apply a structure consisting of four
members with no alignment.
Structure fields are to be located in memory one after another according to the declaration order and
type size. The structure size is 15, while an offset to the structure fields in the arrays is undefined.
Now declare the same structure with the alignment of 4 bytes and run the code.
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- simple structure with the 4-byte alignment
struct Simple_Structure pack(4)
{
char c; // sizeof(char)=1
short s; // sizeof(short)=2
int i; // sizeof(int)=4
double d; // sizeof(double)=8
};
The structure size has changed so that all members of 4 bytes and more has an offset from the
beginning of the structure multiple of 4 bytes. Smaller members are to be aligned to their own size
boundary (for example, 2 for 'short'). This is how it look s (the added byte is shown in gray).
In this case, 1 byte is added after the s.c member, so that the s.s (sizeof(short)==2) field has the
boundary of 2 bytes (alignment for 'short' type).
The offset to the beginning of the structure in the array is also aligned to the 4-byte boundary, i.e. the
addresses of the a[0], a[1] and a[n] elements are to be multiple of 4 bytes for Simple_Structure arr[].
Let's consider two more structures consisting of similar types with 4-bytes alignment but different
member order. In the first structure, the members are located in type size ascending order.
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- simple structure aligned to the 4-byte boundary
struct CharShortInt pack(4)
{
char c; // sizeof(char)=1
short s; // sizeof(short)=2
int i; // sizeof(double)=4
};
//--- make sure the size of POD structure is equal to the sum of its members' size
Print("sizeof(CharShortInt)=",sizeof(CharShortInt));
/*
Result:
sizeof(ch_sh_in.c)=1
sizeof(ch_sh_in.s)=2
sizeof(ch_sh_in.i)=4
sizeof(CharShortInt)=8
*/
}
As we can see, the structure size is 8 and consists of the two 4-byte block s. The first block contains
the fields with 'char' and 'short' types, while the second one contains the field with 'int' type.
Now let's turn the first structure into the second one, which differs only in the field order, by moving
the 'short' type member to the end.
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- simple structure aligned to the 4-byte boundary
struct CharIntShort pack(4)
{
char c; // sizeof(char)=1
int i; // sizeof(double)=4
short s; // sizeof(short)=2
};
//--- declare a simple structure instance
CharIntShort ch_in_sh;
//--- display the size of each structure member
Print("sizeof(ch_in_sh.c)=",sizeof(ch_in_sh.c));
Print("sizeof(ch_in_sh.i)=",sizeof(ch_in_sh.i));
Print("sizeof(ch_in_sh.s)=",sizeof(ch_in_sh.s));
//--- make sure the size of POD structure is equal to the sum of its members' size
Print("sizeof(CharIntShort)=",sizeof(CharIntShort));
/*
Result:
sizeof(ch_in_sh.c)=1
sizeof(ch_in_sh.i)=4
sizeof(ch_in_sh.s)=2
sizeof(CharIntShort)=12
*/
}
Although the structure content has not changed, altering the member sequence has increased its size.
Alignment should also be considered when inheriting. Let's demonstrate this using the simple Parent
structure having a single 'char' type member. The structure size without alignment is 1.
struct Parent
{
char c; // sizeof(char)=1
};
Let's create the Children child class featuring the 'short' (sizeof(short)=2) type member.
As a result, when setting alignment to 2 bytes, the structure size is equal to 4, although the size of its
members is 3. In this example, 2 bytes are to be allocated to the Parent class, so that the access to
the 'short' field of the child class is aligned to 2 bytes.
The k nowledge of how memory is allocated for the structure members is necessary if an MQL5
application interacts with third-party data by writing /reading on the files or streams level.
The MQL5\ Include\W inAPI directory of the Standard Library contains the functions for work ing with the
W inAPI functions. These functions apply the structures with a specified alignment for the cases when
it is required for work ing with W inAPI.
offsetof is a special command directly related to the pack attribute. It allows us to obtain a member
offset from the beginning of the structure.
Modifier 'final'
The use of the 'final' modifier during structure declaration prohibits further inheritance from this
structure. If a structure requires no further modifications, or modifications are not allowed for
security reasons, declare this structure with the 'final' modifier. In addition, all the members of the
structure will also be implicitly considered final.
If you try to inherit from a structure with the 'final' modifier as shown in the above example, the
compiler will return an error:
Classes
Classes differ from structures in the following :
· by default, all class members have access specifier private, unless otherwise indicated. Data-
members of the structure have the default type of access as public, unless otherwise indicated;
· class objects always have a table of virtual functions, even if there are no virtual functions declared
in the class. Structures can't have virtual functions ;
· the new operator can be applied to class objects ; this operator cannot be applied to structures ;
· classes can be inherited only from classes, structures can be inherited only from structures.
Classes and structures can have an explicit constructor and destructor. If your constructor is explicitly
defined, the initialization of a structure or class variable using the initializing sequence is impossible.
Example:
struct trade_settings
{
double take; // values of the profit fixing price
double stop; // value of the protective stop price
uchar slippage; // value of the acceptable slippage
//--- Constructor
trade_settings() { take=0.0; stop=0.0; slippage=5; }
//--- Destructor
~trade_settings() { Print("This is the end"); }
};
//--- Compiler will generate an error message that initialization is impossible
trade_settings my_set={0.0,0.0,5};
A constructor is a special function, which is called automatically when creating an object of a structure
or class and is usually used to initialize class members. Further we will talk only about classes, while
the same applies to structures, unless otherwise indicated. The name of a constructor must match the
class name. The constructor has no return type (you can specify the void type).
Defined class members – strings, dynamic arrays and objects that require initialization – will be in any
case initialized, regardless of whether there is a constructor.
Each class can have multiple constructors, differing by the number of parameters and the initialization
list. A constructor that requires specifying parameters is called a parametric constructor.
//+------------------------------------------------------------------+
//| A class for working with a date |
//+------------------------------------------------------------------+
class MyDateClass
{
private:
int m_year; // Year
int m_month; // Month
int m_day; // Day of the month
int m_hour; // Hour in a day
int m_minute; // Minutes
int m_second; // Seconds
public:
//--- Default constructor
MyDateClass(void);
//--- Parametric constructor
MyDateClass(int h,int m,int s);
};
A constructor can be declared in the class description and then its body can be defined. For example,
two constructors of MyDateClass can be defined the following way:
//+------------------------------------------------------------------+
//| Default constructor |
//+------------------------------------------------------------------+
MyDateClass::MyDateClass(void)
{
//---
MqlDateTime mdt;
datetime t=TimeCurrent(mdt);
m_year=mdt.year;
m_month=mdt.mon;
m_day=mdt.day;
m_hour=mdt.hour;
m_minute=mdt.min;
m_second=mdt.sec;
Print(__FUNCTION__);
}
//+------------------------------------------------------------------+
//| Parametric constructor |
//+------------------------------------------------------------------+
MyDateClass::MyDateClass(int h,int m,int s)
{
MqlDateTime mdt;
datetime t=TimeCurrent(mdt);
m_year=mdt.year;
m_month=mdt.mon;
m_day=mdt.day;
m_hour=h;
m_minute=m;
m_second=s;
Print(__FUNCTION__);
}
In the default constructor, all members of the class are filled using the TimeCurrent() function. In the
parametric constructor only hour values are filled in. Other members of the class (m_year, m_month
and m_day) will be automatically initialized with the current date.
The default constructor has a special purpose when initializing an array of objects of its class. The
constructor, all parameters of which have default values, is not a default constructor. H ere is an
example:
//+------------------------------------------------------------------+
//| A class with a default constructor |
//+------------------------------------------------------------------+
class CFoo
{
datetime m_call_time; // Time of the last object call
public:
//--- Constructor with a parameter that has a default value is not a default constructor
CFoo(const datetime t=0){m_call_time=t;};
//--- Copy constructor
CFoo(const CFoo &foo){m_call_time=foo.m_call_time;};
string ToString(){return(TimeToString(m_call_time,TIME_DATE|TIME_SECONDS));};
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
// CFoo foo; // This variant cannot be used - a default constructor is not set
//--- Possible options to create the CFoo object
//CFoo foo_array[3]; // This variant cannot be used - a default constructor is not set
or
//CFoo foo_dyn_array[]; // This variant cannot be used - a default constructor is not set
then the compiler will return an error for them " default constructor is not defined" .
If a class has a user-defined constructor, the default constructor is not generated by the compiler. This
means that if a parametric constructor is declared in a class, but a default constructor is not declared,
you can not declare the arrays of objects of this class. The compiler will return an error for this script:
//+------------------------------------------------------------------+
//| A class without a default constructor |
//+------------------------------------------------------------------+
class CFoo
{
string m_name;
public:
In this example, the CFoo class has a declared parametric constructor - in such cases, the compiler
does not create a default constructor automatically during compilation. At the same time when you
declare an array of objects, it is assumed that all objects should be created and initialized
automatically. During auto-initialization of an object, it is necessary to call a default constructor, but
since the default constructor is not explicitly declared and not automatically generated by the compiler,
it is impossible to create such an object. For this reason, the compiler generates an error at the
compilation stage.
There is a special syntax to initialize an object using a constructor. Constructor initializers (special
constructions for initialization) for the members of a struct or class can be specified in the
initialization list.
An initialization list is a list of initializers separated by commas, which comes after the colon after the
list of parameters of a constructor and precedes the body (goes before an opening brace). There are
several requirements :
//+------------------------------------------------------------------+
//| A class for storing the name of a character |
//+------------------------------------------------------------------+
class CPerson
{
string m_first_name; // First name
string m_second_name; // Second name
public:
//--- An empty default constructor
CPerson() {Print(__FUNCTION__);};
//--- A parametric constructor
CPerson(string full_name);
//--- A constructor with an initialization list
CPerson(string surname,string name): m_second_name(surname), m_first_name(name
void PrintName(){PrintFormat("Name=%s Surname=%s",m_first_name,m_second_name);};
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
CPerson::CPerson(string full_name)
{
int pos=StringFind(full_name," ");
if(pos>=0)
{
m_first_name=StringSubstr(full_name,0,pos);
m_second_name=StringSubstr(full_name,pos+1);
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Get an error "default constructor is not defined"
CPerson people[5];
CPerson Tom="Tom Sawyer"; // Tom Sawyer
CPerson Huck("Huckleberry","Finn"); // Huckleberry Finn
CPerson *Pooh = new CPerson("Winnie","Pooh"); // Winnie the Pooh
//--- Output values
Tom.PrintName();
Huck.PrintName();
Pooh.PrintName();
1. An explicit default constructor, which allows creating an array of objects of this class ;
2. A constructor with one parameter, which gets a full name as a parameter and divides it to the
name and second name according to the found space;
3. A constructor with two parameters that contains an initialization list. Initializers -
m_second_name(surname) and m_first_name(name).
Note that the initialization using a list has replaced an assignment. Individual members must be
initialized as :
In the initialization list, members can go in any order, but all members of the class will be initialized
according to the order of their announcement. This means that in the third constructor, first the
m_first_name member will be initialized, as it is announced first, and only after it m_second_name is
initialized. This should be tak en into account in cases where the initialization of some members of the
class depends on the values in other class members.
If a default constructor is not declared in the base class, and at the same time one or more
constructors with parameters are declared, you should always call one of the base class constructors in
the initialization list. It goes through the comma as ordinary members of the list and will be called first
during object initialization, no matter where in the initialization list it is located.
//+------------------------------------------------------------------+
//| Base class |
//+------------------------------------------------------------------+
class CFoo
{
string m_name;
public:
//--- A constructor with an initialization list
CFoo(string name) : m_name(name) { Print(m_name);}
};
//+------------------------------------------------------------------+
//| Class derived from CFoo |
//+------------------------------------------------------------------+
class CBar : CFoo
{
CFoo m_member; // A class member is an object of the parent
public:
//--- A default constructor in the initialization list calls the constructor of a parent
CBar(): m_member(_Symbol), CFoo("CBAR") {Print(__FUNCTION__);}
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CBar bar;
}
In this example, when creating the bar object, a default constructor CBar() will be called, in which first
a constructor for the parent CFoo is called, and then comes a constructor for the m_member class
member.
A destructor is a special function that is called automatically when a class object is destroyed. The
name of the destructor is written as a class name with a tilde (~). Strings, dynamic arrays and objects,
requiring deinitialization, will be de-initialized anyway, regardless of the destructor presence or
absence. If there is a destructor, these actions will be performed after calling the destructor.
Destructors are always virtual, regardless of whether they are declared with the virtual k eyword or not.
Class function-methods can be defined both inside the class and outside the class declaration. If the
method is defined within a class, then its body comes right after the method declaration.
Example:
class CTetrisShape
{
protected:
int m_type;
int m_xpos;
int m_ypos;
int m_xsize;
int m_ysize;
int m_prev_turn;
int m_turn;
int m_right_border;
public:
void CTetrisShape();
void SetRightBorder(int border) { m_right_border=border; }
void SetYPos(int ypos) { m_ypos=ypos; }
void SetXPos(int xpos) { m_xpos=xpos; }
int GetYPos() { return(m_ypos); }
int GetXPos() { return(m_xpos); }
int GetYSize() { return(m_ysize); }
int GetXSize() { return(m_xsize); }
int GetType() { return(m_type); }
void Left() { m_xpos-=SHAPE_SIZE; }
void Right() { m_xpos+=SHAPE_SIZE; }
void Rotate() { m_prev_turn=m_turn; if(++m_turn>3) m_turn=0; }
virtual void Draw() { return; }
virtual bool CheckDown(int& pad_array[]);
virtual bool CheckLeft(int& side_row[]);
virtual bool CheckRight(int& side_row[]);
};
Functions from SetR ightBorder(int border) to Draw() are declared and defined directly inside the
CTetrisShape class.
Example:
//+------------------------------------------------------------------+
//| Constructor of the basic class |
//+------------------------------------------------------------------+
void CTetrisShape::CTetrisShape()
{
m_type=0;
m_ypos=0;
m_xpos=0;
m_xsize=SHAPE_SIZE;
m_ysize=SHAPE_SIZE;
m_prev_turn=0;
m_turn=0;
m_right_border=0;
}
//+------------------------------------------------------------------+
//| Checking ability to move down (for the stick and cube) |
//+------------------------------------------------------------------+
bool CTetrisShape::CheckDown(int& pad_array[])
{
int i,xsize=m_xsize/SHAPE_SIZE;
//---
for(i=0; i<xsize; i++)
{
if(m_ypos+m_ysize>=pad_array[i]) return(false);
}
//---
return(true);
}
W hen developing a new class, it is recommended to restrict access to the members from the outside.
For this purpose k eywords private or protected are used. In this case, hidden data can be accessed
only from function-methods of the same class. If the protected k eyword is used, hidden data can be
accessed also from methods of classes - inheritors of this class. The same method can be used to
restrict the access to functions-methods of a class.
If you need to completely open access to members and/or methods of a class, use the k eyword public.
Example:
class CTetrisField
{
private:
int m_score; // Score
int m_ypos; // Current position of the figures
int m_field[FIELD_HEIGHT][FIELD_WIDTH]; // Matrix of the well
int m_rows[FIELD_HEIGHT]; // Numbering of the well rows
int m_last_row; // Last free row
CTetrisShape *m_shape; // Tetris figure
bool m_bover; // Game over
public:
void CTetrisField() { m_shape=NULL; m_bover=false; }
void Init();
void Deinit();
void Down();
void Left();
void Right();
void Rotate();
void Drop();
private:
void NewShape();
void CheckAndDeleteRows();
void LabelOver();
};
Any class members and methods declared after the specifier public: (and before the next access
specifier) are available in any reference to the class object by the program. In this example these are
the following members : functions CTetris Field(), Init(), Deinit(), Down(), Left(), R ight(), R otate() and
Drop().
Any members that are declared after the access specifier to the elements private: (and before the
next access specifier) are available only to members-functions of this class. Specifiers of access to
elements always end with a colon (:) and can appear in the class definition many times.
Access to the members of the basis class can be redefined during inheritance in derived classes.
Modifier 'final'
The use of the 'final' modifier during class declaration prohibits further inheritance from this class. If
the class interface requires no further modifications, or modifications are not allowed for security
reasons, declare this class with the 'final' modifier. In addition, all the members of the class will also
be implicitly considered final.
If you try to inherit form a class with the 'final' modifier as shown in the above example, the compiler
will return an error:
Unions (union)
Union is a special data type consisting of several variables sharing the same memory area. Therefore,
the union provides the ability to interpret the same bit sequence in two (or more) different ways.
Union declaration is similar to structure declaration and starts with the union k eyword.
union LongDouble
{
long long_value;
double double_value;
};
Unlik e the structure, various union members belong to the same memory area. In this example, the
union of Long Double is declared with long and double type values sharing the same memory area.
Please note that it is impossible to mak e the union store a long integer value and a double real value
simultaneously (unlik e a structure), since long _value and double_value variables overlap (in memory).
On the other hand, an MQL5 program is able to process data containing in the union as an integer
(long) or real (double) value at any time. Therefore, the union allows receiving two (or more) options
for representing the same data sequence.
During the union declaration, the compiler automatically allocates the memory area sufficient to store
the largest type (by volume) in the variable union. The same syntax is used for accessing the union
element as for the structures – point operator.
union LongDouble
{
long long_value;
double double_value;
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
LongDouble lb;
//--- get and display the invalid -nan(ind) number
lb.double_value=MathArcsin(2.0);
printf("1. double=%f integer=%I64X",lb.double_value,lb.long_value);
//--- largest normalized value (DBL_MAX)
lb.long_value=0x7FEFFFFFFFFFFFFF;
printf("2. double=%.16e integer=%I64X",lb.double_value,lb.long_value);
//--- smallest positive normalized (DBL_MIN)
lb.long_value=0x0010000000000000;
printf("3. double=%.16e integer=%.16I64X",lb.double_value,lb.long_value);
}
/* Execution result
1. double=-nan(ind) integer=FFF8000000000000
2. double=1.7976931348623157e+308 integer=7FEFFFFFFFFFFFFF
3. double=2.2250738585072014e-308 integer=0010000000000000
*/
Since the unions allow the program to interpret the same memory data in different ways, they are
often used when an unusual type conversion is required.
The unions cannot be involved in the inheritance, and they also cannot have static members due to
their very nature. In all other aspects, the union behaves lik e a structure with all its members having a
zero offset. The following types cannot be the union members :
· dynamic arrays
· strings
· class objects
Similar to classes, the union is capable of having constructors and destructors, as well as methods. By
default, the union members are of public access type. In order to create private elements, use the
private k eyword. All these possibilities are displayed in the example illustrating how to convert a color
of the color type to ARGB as does the ColorToARGB() function.
//+------------------------------------------------------------------+
//| Union for color(BGR) conversion to ARGB |
//+------------------------------------------------------------------+
union ARGB
{
uchar argb[4];
color clr;
//--- constructors
ARGB(color col,uchar a=0){Color(col,a);};
~ARGB(){};
//--- public methods
public:
uchar Alpha(){return(argb[3]);};
void Alpha(const uchar alpha){argb[3]=alpha;};
color Color(){ return(color(clr));};
//--- private methods
private:
//+------------------------------------------------------------------+
//| set the alpha channel value and color |
//+------------------------------------------------------------------+
void Color(color col,uchar alpha)
{
//--- set color to clr member
clr=col;
//--- set the Alpha component value - opacity level
argb[3]=alpha;
//--- interchange the bytes of R and B components (Red and Blue)
uchar t=argb[0];argb[0]=argb[2];argb[2]=t;
};
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 0x55 means 55/255=21.6 % (0% - fully transparent)
uchar alpha=0x55;
//--- color type is represented as 0x00BBGGRR
color test_color=clrDarkOrange;
//--- values of bytes from the ARGB union are accepted here
uchar argb[];
PrintFormat("0x%.8X - here is how the 'color' type look like for %s, BGR=(%s)",
test_color,ColorToString(test_color,true),ColorToString(test_color));
//--- ARGB type is represented as 0x00RRGGBB, RR and BB components are swapped
ARGB argb_color(test_color);
//--- copy the bytes array
ArrayCopy(argb,argb_color.argb);
//--- here is how it looks in ARGB representation
PrintFormat("0x%.8X - ARGB representation with the alpha channel=0x%.2x, ARGB=(%d,%d,%d,%d)",
argb_color.clr,argb_color.Alpha(),argb[3],argb[2],argb[1],argb[0]);
//--- add opacity level
argb_color.Alpha(alpha);
//--- try defining ARGB as 'color' type
Print("ARGB as color=(",argb_color.clr,") alpha channel=",argb_color.Alpha());
//--- copy the bytes array
ArrayCopy(argb,argb_color.argb);
//--- here is how it looks in ARGB representation
PrintFormat("0x%.8X - ARGB representation with the alpha channel=0x%.2x, ARGB=(%d,%d,%d,%d)",
argb_color.clr,argb_color.Alpha(),argb[3],argb[2],argb[1],argb[0]);
//--- check with the ColorToARGB() function results
PrintFormat("0x%.8X - result of ColorToARGB(%s,0x%.2x)",ColorToARGB(test_color,alpha),
ColorToString(test_color,true),alpha);
}
/* Execution result
0x00008CFF - here is how the color type looks for clrDarkOrange, BGR=(255,140,0)
0x00FF8C00 - ARGB representation with the alpha channel=0x00, ARGB=(0,255,140,0)
ARGB as color=(0,140,255) alpha channel=85
0x55FF8C00 - ARGB representation with the alpha channel=0x55, ARGB=(85,255,140,0)
0x55FF8C00 - result of ColorToARGB(clrDarkOrange,0x55)
*/
Interfaces
An interface allows determining specific functionality, which a class can then implement. In fact, an
interface is a class that cannot contain any members, and may not have a constructor and/or a
destructor. All methods declared in an interface are purely virtual, even without an explicit definition.
Lik e with abstract classes, an interface object cannot be created without inheritance. An interface can
only be inherited from other interfaces and can be a parent for a class. An interface is always publicly
visible.
An interface cannot be declared within a class or structure declaration, but a pointer to the interface
can be saved in a variable of type void *. Generally speak ing, a pointer to an object of any class can be
saved into a variable of type void *. In order to convert a void * pointer to a pointer to an object of a
particular class, use the dynamic_cast operator. If conversion is not possible, the result of the
dynamic_cast operation will be NULL.
See also
Object-Oriented Programming
Maximum 4-dimension array can be declared. W hen declaring a dynamic array (an array of unspecified
value in the first pair of s quare brack ets), the compiler automatically creates a variable of the above
structure (a dynamic array object) and provides a code for the correct initialization.
Dynamic arrays are automatically freed when going beyond the visibility area of the block they are
declared in.
Example:
Static Arrays
W hen all significant array dimensions are explicitly specified, the compiler pre-allocates the necessary
memory size. Such an array is called static. Nevertheless, the compiler allocates additional memory for
the object of a dynamic array, which (object) is associated with the pre-allocated static buffer
(memory part for storing the array).
Creating a dynamic array object is due to the possible need to pass this static array as a parameter to
some function.
Examples:
Arrays in Structures
W hen a static array is declared as a member of a structure, a dynamic array object is not created.
This is done to ensure compatibility of data structures used in the W indows API.
H owever, static arrays that are declared as members of structures can also be passed to MQL5
functions. In this case, when passing the parameter, a temporary object of a dynamic array will be
created. Such an object is link ed with the static array - member of structure.
See also
Array Functions, Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and
Deleting Objects
Typecasting
Casting Numeric Types
Often a necessity occurs to convert one numeric type into another. Not all numeric types can be
converted into another. H ere is the scheme of allowed casting :
Solid lines with arrows indicate changes that are performed almost without any loss of information.
Instead of the char type, the bool type can be used (both tak e 1 byte of memory), instead of type int,
the color type can be used (4 bytes), instead of the long type, datetime can be used (tak e 8 bytes).
The four dashed grey lines, also arrowed, denote conversions, when the loss of precision can occur.
For example, the number of digits in an integer equal to 123456789 (int) is higher than the number of
digits that can be represented by float.
int n=123456789;
float f=n; // the content of f is equal to 1.234567892E8
Print("n = ",n," f = ",f);
// result n= 123456789 f= 123456792.00000
A number converted into float has the same order, but is less accurate. Conversions, contrary to black
arrows, can be performed with possible data loss. Conversions between char and uchar, short and
ushort, int and uint, long and ulong (conversions to both sides), may lead to the loss of data.
As a result of converting floating point values to integer type, the fractional part is always deleted. If
you want to round off a float to the nearest whole number (which in many cases is more useful), you
should use MathR ound().
Example:
If two values are combined by a binary operator, before the operation execution the operand of a
lower type is converted to the higher type in accordance with the priority given in the below scheme:
The data types char, uchar, short, and ushort unconditionally are converted to the int type.
Examples:
char c1=3;
//--- First example
double d2=c1/2+0.3;
Print("c1/2 + 0.3 = ",d2);
// Result: c1/2+0.3 = 1.3
The calculated expression consists of two operations. In the first example, the variable c1 of the char
type is converted to a temporary variable of the int type, because the second operand in the division
operation, the constant 2, is of the higher type int. As a result of the integer division 3/2 we get the
value 1, which is of the int type.
In the second operation of the first example, the second operand is the constant 0.3, which is of the
double type, so the result of the first operation is converted into a temporary variable of the double
type with a value of 1.0.
In the second example the variable of the char type c1 is converted to a temporary variable of the
double type, because the second operand in the division operation, the constant 2.0, is of the double
type; no further conversions are made.
In the expressions of the MQL5 language both explicit and implicit typecasting can be used. The
explicit typecasting is written as follows :
var_1 = (type)var_2;
An expression or function execution result can be used as the var_2 variable. The function style
notation of the explicit typecasting is also possible:
var_1 = type(var_2);
Before the division operation is performed, the c1 variable is explicitly cast to the double type. Now
the integer constant 2 is cast to the value 2.0 of the double type, because as a result of converting the
first operand has tak en the double type. In fact, the explicit typecasting is a unary operation.
Besides, when trying to cast types, the result may go beyond the permissible range. In this case, the
truncation occurs. For example:
char c;
uchar u;
c=400;
u=400;
Print("c = ",c); // Result c=-112
Print("u = ",u); // Result u=144
Before operations (except for the assignment ones) are performed, the data are converted into the
maximum priority type. Before assignment operations are performed, the data are cast into the target
type.
Examples:
double x=1/2; // the expression of the int type is cast to the double target typr,
Print("x = 1/2; ",x); // the result is 0.0
W hen converting long /ulong type into double, precision may be lost in case the integer value is
greater than 9223372036854774784 or less than -9223372036854774784.
void OnStart()
{
long l_max=LONG_MAX;
long l_min=LONG_MIN+1;
//--- define the highest integer value, which does not lose accuracy when being cast to double
while(l_max!=long((double)l_max))
l_max--;
//--- define the lowest integer value, which does not lose accuracy when being cast to double
while(l_min!=long((double)l_min))
l_min++;
//--- derive the found interval for integer values
The string type has the highest priority among simple types. Therefore, if one of operands of an
operation is of the string type, the second operand will be cast to a string automatically. Note that for
a string, a single dyadic two-place operation of addition is possible. The explicit casting of string to
any numeric type is allowed.
Examples:
string str1="true";
string str2="0,255,0";
string str3="2009.06.01";
string str4="1.2345e2";
Print(bool(str1));
Print(color(str2));
Print(datetime(str3));
Print(double(str4));
Objects of the open generated class can also be viewed as objects of the corresponding base class.
This leads to some interesting consequences. For example, despite the fact that objects of different
classes, generated by a single base class, may differ significantly from each other, we can create a
link ed list (List) of them, as we view them as objects of the base type. But the converse is not true:
the base class objects are not automatically objects of a derived class.
You can use the explicit casting to convert the base class pointers to the pointers of a derived class.
But you must be fully confident in the admissibility of such a transformation, because otherwise a
critical runtime error will occur and the mql5 program will be stopped.
Dynamic typecasting is performed using dynamic_cast operator that can be applied only to pointers to
classes. Type validation is performed at runtime. This means that the compiler does not check the
data type applied for typecasting when dynamic_cast operator is used. If a pointer is converted to a
data type which is not the actual type of an object, the result is NULL.
The type-id parameter in angle brack ets should point to a previously defined class type. Unlik e C++,
expression operand type can be of any value except for void.
Example:
class CBar { };
class CFoo : public CBar { };
void OnStart()
{
CBar bar;
//--- dynamic casting of *bar pointer type to *foo pointer is allowed
CFoo *foo = dynamic_cast<CFoo *>(&bar); // no critical error
Print(foo); // foo=NULL
//--- an attempt to explicitly cast a Bar type object reference to a Foo type object is forbidden
foo=(CFoo *)&bar; // critical runtime error
Print(foo); // this string is not executed
}
See also
Data Types
The predefined constant variable NULL is of the void type. It can be assigned to variables of any other
fundamental types without conversion. The comparison of fundamental type variables with the NULL
value is allowed.
Example:
//--- If the string is not initialized, then assign our predefined value to it
if(some_string==NULL) some_string="empty";
Also NULL can be compared to pointers to objects created with the new operator.
See also
Variables, Functions
User-defined types
The typedef k eyword in C++ allows creating user-defined data types. To do this, simply specify a new
data type name for an already existing data type. The new data type is not created. A new name for
the existing type is defined instead. User-defined types mak e applications more flexible: sometimes,
it is enough to change typedef instructions using substitution macros (#define). User-defined types
also improve code readability since it is possible to apply custom names to standard data types using
typedef. The general format of the entry for creating a user-defined type:
H ere,type means any acceptable data type, while new_name is a new name of the type. A new name
is set only as an addition (not as a replacement) to an existing type name. MQL5 allows creating
pointers to functions using typedef.
where after typedef, the function signature (number and type of input parameters, as well as a type of
a result returned by the function) is set. Below is a simple example of creating and applying a pointer
to a function:
In this example, the func_ptr variable may receive the sub and add functions since they have two
inputs each of int type as defined in the TFunc pointer to the function. On the contrary, the neg
function cannot be assigned to the func_ptr pointer since its signature is different.
Pointers to functions allow you to easily create processing of events when creating a user interface.
Let's use an example from the CButton section to show how to create buttons and add the functions for
handling pressing to them. First, define a pointer to the TAction function to be called by pressing the
button and create three functions according to the TAction description.
Then, create the MyButton class from CButton, where we should add the TAction pointer to the
function.
//+------------------------------------------------------------------+
//| Create the button class with the events processing function |
//+------------------------------------------------------------------+
class MyButton: public CButton
{
private:
TAction m_action; // chart events handler
public:
MyButton(void){}
~MyButton(void){}
//--- constructor specifying the button text and the pointer to the events handling function
MyButton(string text, TAction act)
{
Text(text);
m_action=act;
}
//--- set the custom function called from the OnEvent() events handler
void SetAction(TAction act){m_action=act;}
Create the CControls Dialog derivative class from CAppDialog, add the m_buttons array to it for storing
the buttons of the MyButton type, as well as the AddButton(MyButton &button) and CreateButtons()
methods.
//+------------------------------------------------------------------+
//| CControlsDialog class |
//| Objective: graphical panel for managing the application |
//+------------------------------------------------------------------+
class CControlsDialog : public CAppDialog
{
private:
CArrayObj m_buttons; // button array
public:
CControlsDialog(void){};
~CControlsDialog(void){};
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const
//--- add the button
bool AddButton(MyButton &button){return(m_buttons.Add(GetPointer(button)));m_button
protected:
//--- create the buttons
bool CreateButtons(void);
};
//+------------------------------------------------------------------+
//| Create the CControlsDialog object on the chart |
//+------------------------------------------------------------------+
bool CControlsDialog::Create(const long chart,const string name,const int subwin,const int x1,const
{
if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
return(CreateButtons());
//---
}
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
//--- indents and gaps
#define INDENT_LEFT (11) // indent from left (with allowance for borde
#define INDENT_TOP (11) // indent from top (with allowance for border
#define CONTROLS_GAP_X (5) // gap by X coordinate
#define CONTROLS_GAP_Y (5) // gap by Y coordinate
//--- for buttons
#define BUTTON_WIDTH (100) // size by X coordinate
#define BUTTON_HEIGHT (20) // size by Y coordinate
//--- for the indication area
#define EDIT_HEIGHT (20) // size by Y coordinate
//+------------------------------------------------------------------+
//| Create and add buttons to the CControlsDialog panel |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButtons(void)
{
//--- calculate buttons coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2;
int y2=y1+BUTTON_HEIGHT;
//--- add buttons objects together with pointers to functions
AddButton(new MyButton("Open",Open));
AddButton(new MyButton("Save",Save));
AddButton(new MyButton("Close",Close));
//--- create the buttons graphically
for(int i=0;i<m_buttons.Total();i++)
{
MyButton *b=(MyButton*)m_buttons.At(i);
x1=INDENT_LEFT+i*(BUTTON_WIDTH+CONTROLS_GAP_X);
x2=x1+BUTTON_WIDTH;
if(!b.Create(m_chart_id,m_name+"bt"+b.Text(),m_subwin,x1,y1,x2,y2))
{
PrintFormat("Failed to create button %s %d",b.Text(),i);
return(false);
}
//--- add each button to the CControlsDialog container
if(!Add(b))
return(false);
}
//--- succeed
return(true);
}
Now, we can develop the program using the CControls Dialog control panel having 3 buttons : Open,
Save and Close. W hen click ing a button, the appropriate function in the form of the TAction pointer is
called.
//--- declare the object on the global level to automatically create it when launching the program
CControlsDialog MyDialog;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- now, create the object on the chart
if(!MyDialog.Create(0,"Controls",0,40,40,380,344))
return(INIT_FAILED);
//--- launch the application
MyDialog.Run();
//--- application successfully initialized
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy dialog
MyDialog.Destroy(reason);
}
//+------------------------------------------------------------------+
//| Expert chart event function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, // event ID
const long& lparam, // event parameter of the long type
const double& dparam, // event parameter of the double type
const string& sparam) // event parameter of the string type
{
//--- call the handler from the parent class (here it is CAppDialog) for the chart events
MyDialog.ChartEvent(id,lparam,dparam,sparam);
}
The launched application's appearance and button click ing results are provided on the screenshot.
//+------------------------------------------------------------------+
//| Panel_Buttons.mq5 |
//| Copyright 2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
}
//+------------------------------------------------------------------+
//| Expert chart event function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, // event ID
const long& lparam, // event parameter of the long type
const double& dparam, // event parameter of the double type
const string& sparam) // event parameter of the string type
{
//--- call the handler from the parent class (here it is CAppDialog) for the chart events
MyDialog.ChartEvent(id,lparam,dparam,sparam);
}
See also
Variables, Functions
Object Pointers
In MQL5, there is a possibility to dynamically create objects of complex type. This is done by the new
operator, which returns a descriptor of the created object. Descriptor is 8 bytes large. Syntactically,
object descriptors in MQL5 are similar to pointers in C++.
Examples:
In contrast to C++, the hobject variable from example above is not a pointer to memory, but rather an
object descriptor. Furthermore, in MQL5 all objects in function parameters must be passed by
reference. Below are examples of passing objects as function parameters :
class Foo
{
public:
string m_name;
int m_id;
static int s_counter;
//--- constructors and desctructors
Foo(void){Setup("noname");};
Foo(string name){Setup(name);};
~Foo(void){};
//--- initializes object of type Foo
void Setup(string name)
{
m_name=name;
s_counter++;
m_id=s_counter;
}
};
int Foo::s_counter=0;
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare an object as variable with its automatic creation
Foo foo1;
//--- variant of passing an object by reference
PrintObject(foo1);
//--- declare a pointer to an object and create it using the 'new' operator
Foo *foo2=new Foo("foo2");
//--- variant of passing a pointer to an object by reference
PrintObject(foo2); // pointer to an object is converted automatically by compiler
//+------------------------------------------------------------------+
See also
Variables, Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and
Deleting Objects
Passing a parameter by reference means passing the address of the variable, that's why all changes in
the parameter that is passed by reference will be immediately reflected in the source variable. Using
parameter passing by reference, you can implement return of several results of a function at the same
time. In order to prevent changing of a parameter passed by reference, use the const modifier.
Thus, if the input parameter of a function is an array, a structure or class object, symbol '&' is placed
in the function header after the variable type and before its name.
Example
class CDemoClass
{
private:
double m_array[];
public:
void setArray(double &array[]);
};
//+------------------------------------------------------------------+
//| filling the array |
//+------------------------------------------------------------------+
void CDemoClass::setArray(double &array[])
{
if(ArraySize(array)>0)
{
ArrayResize(m_array,ArraySize(array));
ArrayCopy(m_array, array);
}
}
In the above example class CDemoClass is declared, which contains the private member - array
m_array[] of double type. Function setArray() is declared, to which array[] is passed by reference. If
the function header doesn't contain the indication about passing by reference, i.e. doesn't contain the
ampersand character, an error message will be generated at the attempt to compile such a code.
Despite the fact that the array is passed by reference, we can't assign one array to another. W e need
to perform the element-wise copying of contents of the source array to the recipient array. The
presence of & in the function description is the obligatory condition for arrays and structures when
passed as the function parameter.
Keyword this
A variable of class type (object) can be passed both by reference and by pointer. As well as reference,
the pointer allows having access to an object. After the object pointer is declared, the new operator
should be applied to it to create and initialize it.
The reserved word this is intended for obtaining the reference of the object to itself, which is
available inside class or structure methods. this always references to the object, in the method of
which it is used, and the expression GetPointer(this) gives the pointer of the object, whose member is
the function, in which call of GetPointer() is performed. In MQL5 functions can't return objects, but
they can return the object pointer.
Thus, if we need a function to return an object, we can return the pointer of this object in the form of
GetPointer(this). Let's add function getDemoClass() that returns pointer of the object of this class,
into the description of CDemoClass.
class CDemoClass
{
private:
double m_array[];
public:
void setArray(double &array[]);
CDemoClass *getDemoClass();
};
//+------------------------------------------------------------------+
//| filling the array |
//+------------------------------------------------------------------+
void CDemoClass::setArray(double &array[])
{
if(ArraySize(array)>0)
{
ArrayResize(m_array,ArraySize(array));
ArrayCopy(m_array,array);
}
}
//+------------------------------------------------------------------+
//| returns its own pointer |
//+------------------------------------------------------------------+
CDemoClass *CDemoClass::getDemoClass(void)
{
return(GetPointer(this));
}
Structures don't have pointers, operators new and delete can't be applied to them, GetPointer(this)
can't be used.
See also
Object Pointers, Creating and Deleting Objects, Visibility Scope and Lifetime of Variables
Operation symbols are used in expressions and have sense when appropriate operands are given to
them. Punctuation mark s are emphasized, as well. These are parentheses, braces, comma, colon, and
semicolon.
Operation symbols, punctuation mark s, and spaces are used to separate language elements from each
other.
· Expressions
· Arithmetic Operations
· Assignment Operations
· Operations of R elation
· Boolean Operations
· Bitwise Operations
· Other Operations
Expressions
An expression consists of one or more operands and operation symbols. An expression can be written
in several lines.
Examples:
See also
Precedence R ules
Arithmetic Operations
Arithmetic operations include additive and multiplicative operations :
Sum of variables i = j + 2;
Difference of variables i = j - 3;
Changing the sign x = - x;
Product of variables z = 3 * x;
Division quotient i = j / 5;
Remainder of division minutes = time % 60;
Adding 1 to the variable value i++;
Adding 1 to the variable value ++i;
Subtracting 1 from the variable value k--;
Subtracting 1 from the variable value --k;
Increment and decrement operations are applied only to variables, they can't be applied to constants.
The prefix increment (++i) and decrement (--k ) are applied to the variable right before this variable is
used in an expression.
Post-increment (i++) and post-decrement (k --) are applied to the variable right after this variable is
used in an expression.
Important Notice
int i=5;
int k = i++ + ++i;
Computational problems may occur while moving the above expression from one programming
environment to another one (for example, from Borland C++ to MQL5). In general, the order of
computations depends on the compiler implementation. In practice, there are two ways to implement
the post-decrement (post-increment):
1. The post-decrement (post-increment) is applied to the variable after calculating the whole
expression.
2. The post-decrement (post-increment) is applied to the variable immediately at the operation.
Currently the first way of post-decrement (post-increment) calculation is implemented in MQL5. But
even k nowing this peculiarity, it is not recommended to experiment with its use.
Examples:
int a=3;
a++; // valid expression
int b=(a++)*3; // invalid expression
See also
Precedence R ules
Assignment Operations
The value of the expression that includes the given operation is the value of the left operand after
assignment:
The following operations unite arithmetic or bitwise operations with operation of assignment:
Bitwise operations can be applied to integers only. W hen performing the operation of the logical shift
of the y representation to the right/left by x bits, the 5 smallest binary digits of the x value are used,
the highest ones are dropped, i.e. the shift is made to 0-31 bits.
By %= operation (y value by module of x), the result sign is equal to the sign of divided number.
The assignment operator can be used several times in an expression . In this case the processing of
the expression is performed from left to right:
y=x=3;
First, the variable x will be assigned the value 3, then the y variable will be assigned the value of x,
i.e. also 3.
See also
Precedence R ules
Operations of Relation
Boolean FALS E is represented with an integer zero value, while the boolean T RUE is represented by any
non-zero value.
The value of expressions containing operations of relation or logical operations is FALS E (0) or T RUE
(1).
True if a is equal to b a == b;
True if a is not equal to b a != b;
True if a is less than b a < b;
True if a is greater than b a > b;
True if a is less than or equal to b a <= b;
True if a is greater than or equal to b a >= b;
The equality of two real numbers can't be compared. In most cases, two seemingly identical numbers
can be unequal because of different values in the 15th decimal place. In order to correctly compare two
real numbers, compare the normalized difference of these numbers with zero.
Example:
See also
Precedence R ules
Boolean Operations
Logical Negation NOT (!)
Operand of the logical negation (!) must be of arithmetic type. The result is T RUE (1), if the operand
value is FALS E (0); and it is equal to FALS E (0), if the operand differs from FALS E (0).
Logical OR operation (||) of x and y values. The expression value is T RUE (1), if x or y value is true
(not null). Otherwise - FALS E (0).
Logical operation AND (&&) of x and y values. The expression value is T RUE (1), if the values of x and
y are true (not null). Otherwise - FALS E (0).
The scheme of the so called " brief estimate" is applied to boolean operations, i.e. the calculation of
the expression is terminated when the result of the expression can be precisely estimated.
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- the first example of the brief estimate
if(func_false() && func_true())
{
Print("Operation &&: You will never see this expression");
}
else
{
Print("Operation &&: Result of the first expression is false, so the second wasn't calculated
}
//--- the second example of the brief estimate
if(!func_false() || !func_true())
{
Print("Operation ||: Result of the first expression is true, so the second wasn't calculated"
}
else
{
Print("Operation ||: You will never see this expression");
}
}
//+------------------------------------------------------------------+
See also
Precedence R ules
Bitwise Operations
Complement to One
Complement of the variable value up to one. The value of the expression contains 1 in all digits where
the variable value contains 0, and 0 in all digits where the variable contains 1.
b = ~n;
Example:
char a='a',b;
b=~a;
Print("a = ",a, " b = ",b);
// The result will be:
// a = 97 b = -98
Right Shift
The binary representation of x is shifted to the right by y digits. If the value to shift is of the unsigned
type, the logical right shift is made, i.e. the freed left-side bits will be filled with zeroes.
If the value to shift is of a sign type, the arithmetic right shift is made, i.e. the freed left-side digits
will be filled with the value of a sign bit (if the number is positive, the value of the sign bit is 0; if the
number is negative, the value of the sign bit is 1).
x = x >> y;
Example:
char a='a',b='b';
Print("Before: a = ",a, " b = ",b);
//--- shift to the right
b=a>>1;
Print("After: a = ",a, " b = ",b);
// The result will be:
// Before: a = 97 b = 98
// After: a = 97 b = 48
Left Shift
The binary representation of x is shifted to the left by y digits, the freed right-side digits are filled
with zeros.
x = x << y;
Example:
char a='a',b='b';
Print("Before: a = ",a, " b = ",b);
//--- shift to the left
b=a<<1;
Print("After: a = ",a, " b = ",b);
It is not recommended to shift by the number of bits larger or equal to the length of the variable
shifted, because the result of such an operation is undefined.
The bitwise AND operation of binary-coded x and y representations. The value of the expression
contains a 1 (T RUE) in all digits where both x and y contain non-zero, and it contains 0 (FALS E) in all
other digits.
Example:
char a='a',b='b';
//--- AND operation
char c=a&b;
Print("a = ",a," b = ",b);
Print("a & b = ",c);
// The result will be:
// a = 97 b = 98
// a & b = 96
Bitwise OR Operation
The bitwise OR operation of binary representations of x and y. The value of the expression contains 1
in all digits where x or y does not contain 0, and it contains 0 in all other digits.
b = x | y;
Example:
char a='a',b='b';
//--- OR operation
char c=a|b;
Print("a = ",a," b = ",b);
Print("a | b = ",c);
// The result will be:
// a = 97 b = 98
// a | b = 99
The bitwise exclusive OR (eXclusive OR ) operation of binary representations of x and y. The value of
the expression contains a 1 in all digits where x and y have different binary values, and it contains 0 in
all other digits.
b = x ^ y;
Example:
See also
Precedence R ules
Other operations
Indexing ( [] )
W hen addressing the i-th element of the array, the expression value is the value of a variable with the
serial number i.
Example:
Only an integer can be index of an array. Four-dimensional and below arrays are allowed. Each
dimension is indexed from 0 to dimension size-1. In particular case, for a one-dimensional array
consisting of 50 elements, the reference to the first element will look lik e array [0], that to the last
element will be array [49].
W hen addressing beyond the array, the executing subsystem will generate a critical error, and the
program will be stopped.
The expression value is the value returned by the function. If the return value is of void type, such
function call cannot be placed to the right in the assignment operation. Note that the expressions
x 1,..., xn are executed exactly in this order.
Example:
int length=1000000;
string a="a",b="b",c;
//---Other Operations
int start=GetTickCount(),stop;
long i;
for(i=0;i<length;i++)
{
c=a+b;
}
stop=GetTickCount();
Print("time for 'c = a + b' = ",(stop-start)," milliseconds, i = ",i);
Comma Operation ( , )
Expressions separated by commas are executed from left to right. All side effects of the left
expression calculation can appear before the right expression is calculated. The result type and value
coincide with those of the right expression. The list of parameters to be passed (see above) can be
considered as an example.
Example:
Dot Operator ( . )
For the direct access to the public members of structures and classes the dot operation is used.
Syntax :
Variable_name_of_structure_type.Member_name
Example:
struct SessionTime
{
string sessionName;
int startHour;
int startMinutes;
int endHour;
int endMinutes;
} st;
st.sessionName="Asian";
st.startHour=0;
st.startMinutes=0;
st.endHour=9;
st.endMinutes=0;
[Scope_name]::Function_name(parameters)
If there is no scope name, this is the explicit direction to use the global scope. If there is no scope
resolution operation, the function is sought in the nearest scope. If there is no function in the local
scope, the search is conducted in the global scope.
type Class_name::Function_name(parameters_description)
{
// function body
}
Use of several functions of the same name from different execution contexts in a program may cause
ambiguity. The priority order of function calls without explicit scope specification is the following :
1. Class methods. If no function with the specified name is set in the class, move to the next level.
2. MQL5 functions. If the language does not have such a function, move to the next level.
3. User defined global functions. If no function with the specified name is found, move to the next
level.
4. Imported functions. If no function with the specified name is found, the compiler returns an error.
To avoid the ambiguity of function calls, always explicitly specify the function scope using the scope
resolution operation.
Example:
#property script_show_inputs
#import "kernel32.dll"
int GetLastError(void);
#import
class CCheckContext
{
int m_id;
public:
CCheckContext() { m_id=1234; }
protected:
int GetLastError() { return(m_id); }
};
class CCheckContext2 : public CCheckContext
{
int m_id2;
public:
CCheckContext2() { m_id2=5678; }
void Print();
protected:
int GetLastError() { return(m_id2); }
};
void CCheckContext2::Print()
{
::Print("Terminal GetLastError",::GetLastError());
::Print("kernel32 GetLastError",kernel32::GetLastError());
::Print("parent GetLastError",CCheckContext::GetLastError());
::Print("our GetLastError",GetLastError());
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
CCheckContext2 test;
test.Print();
}
//+------------------------------------------------------------------+
Example:
sizeof(expression)
Any identifier, or type name enclosed in brack ets can be used as an expression. Note that the void
type name can't be used, and the identifier cannot belong to the field of bits, or be a function name.
If the expression is the name of a static array (i.e. the first dimension is given), then the result is the
size of the whole array (i.e. the product of the number of elements and the length of the type). If the
expression is the name of a dynamic array (the first dimension is not specified), the result will be the
size of the object of the dynamic array.
W hen sizeof is applied to the name of structure or class type, or to the identifier of the structure or
class type, the result is the actual size of the structure or class.
Example:
struct myStruct
{
char h;
int b;
double f;
} str;
Print("sizeof(str) = ",sizeof(str));
Print("sizeof(myStruct) = ",sizeof(myStruct));
See also
Precedence R ules
Precedence Rules
Each group of operations in the table has the same priority. The higher the priority of operations is,
the higher it is position of the group in the table. The precedence rules determine the grouping of
operations and operands.
Attention: Precedence of operations in the MQL5 language corresponds to the priority adopted in C++,
and differs from the priority given in the MQL 4 language.
To change the operation execution order, parenthesis that are of higher priority are used.
Operators
Language operators describe some algorithmic operations that must be executed to accomplish a tas k .
The program body is a sequence of such operators. Operators following one by one are separated by
semicolons.
Operator Description
Expression operator (;) Any expression that ends with a semicolon (;)
One operator can occupy one or more lines. Two or more operators can be located in the same line.
Operators that control over the execution order (if, if-else, switch, while and for), can be nested into
each other.
Example:
if(Month() == 12)
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Compound Operator
A compound operator (a block ) consists of one or more operators of any type, enclosed in braces {}.
The closing brace must not be followed by a semicolon (;).
Example:
if(x==0)
{
Print("invalid position x = ",x);
return;
}
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Expression Operator
Any expression followed by a semicolon (;) is the operator. H ere are some examples of expression
operators.
Assignment Operator
Identifier = expression;
x=3;
y=x=3;
bool equal=(x==y);
Assignment operator can be used many times in an expression. In this case, the expression is
processed from right to left.
FileClose(file);
Empty Operator
Consists only of a semicolon (;) and is used to denote an empty body of a control operator.
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Return Operator
The return operator terminates the current function execution and returns control to the calling
program. The expression calculation result is returned to the calling function. The expression can
contain an assignment operator.
Example:
In functions with the void return type, the return operator without expression must be used:
void SomeFunction()
{
Print("Hello!");
return; // this operator can be removed
}
The right brace of the function means implicit execution of the return operator without expression.
W hat can be returned: simple types, simple structures, object pointers. W ith the return operator you
can't return any arrays, class objects, variables of compound structure type.
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
if (expression)
operator1
else
operator2
If the expression is true, operator1 is executed and control is given to the operator that follows
operator2 (operator2 is not executed). If the expression is false, operator2 is executed.
The else part of the if operator can be omitted. Thus, a divergence may appear in nested if operators
with omitted else part. In this case, else addresses to the nearest previous if operator in the same
block that has no else part.
Examples:
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Ternary Operator ?:
The general form of the ternary operator is as follows :
For the first operand - " expression1" - any expression that results in a bool type value can be used. If
the result is true, then the operator set by the second operand, i.e. " expression2" is executed.
If the first operand is false, the third operand - " expression3" is performed. The second and third
operands, i.e. " expression2" and " expression3" should return values of one type and should not be of
void type. The result of the conditional operator execution is the result of expression2 or result of the
expression3, depending on the result of expression1.
//--- normalize difference between open and close prices for a day range
double true_range = (High==Low)?0:(Close-Open)/(High-Low);
double true_range;
if(High==Low)true_range=0; // if High and Low are equal
else true_range=(Close-Open)/(High-Low); // if the range is not null
1. Do not mix user-defined type with simple type or enumeration. NULL can be used for the pointer.
2. If types of values are simple, the operator will be of the maximum type (see Type casting).
3. If one of the values is an enumeration and the second one is of a numeric type, the enumeration is
replaced by int and the second rule is applied.
4. If both values are enumerations, their types must be identical, and the operator will be of type
enumeration.
a) Types must be identical or one should be derived from the other one.
b) If types are not identical (inheritance), then the child is implicitly cast to the parent, i.e. the
operator will be of the parent type.
c) Do not mix object and the pointer – both expressions must be either objects or pointers. NULL can
be used for the pointer.
Note
Be careful when using the conditional operator as an argument of an overloaded function, because the
type of the result of a conditional operator is defined at the time of program compilation. And this
type is determined as the larger of the types " expression2" and " expression3" .
Example:
bool Expression1=true;
double Expression2=M_PI;
string Expression3="3.1415926";
void OnStart()
{
func(Expression2);
func(Expression3);
// Result:
// double argument: 3.141592653589793
// string argument: 3.1415926
// string argument: 3.141592653589793
// string argument: 3.1415926
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Switch Operator
Compares the expression value with constants in all the case variants and passes control to the
operator that corresponds to the expression value. Each variant of case can be mark ed with an integer
constant, a literal constant or a constant expression. The constant expression can't contain variables
or function calls. Expression of the switch operator must be of integer type – int or uint.
switch(expression)
{
case constant: operators
case constant: operators
...
default: operators
}
Operators mark ed by the default label are executed if none of the constants in case operators is equal
to the expression value. The default variant should not be necessarily declared and should not be
necessarily the last one. If none of the constants corresponds to the expression value and the default
variant is not available, no actions are executed.
The case k eyword with a constant are just labels, and if operators are executed for some case variant,
the program will further execute the operators of all subsequent variants until the break operator
occurs. It allows to bind a sequence of operators with several variants.
A constant expression is calculated during compilation. No two constants in one switch operator can
have the same value.
Examples:
default:
res="default";break;
case 2:
res=i;break;
case 3:
res=i;break;
}
Print(res);
/*
Result
default
*/
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
while(expression)
operator;
If the expression is true, the operator is executed until the expression becomes false. If the
expression is false, the control is passed to the next operator. The expression value is defined before
the operator is executed. Therefore, if the expression is false from the very beginning, the operator
will not be executed at all.
Note
If it is expected that a large number of iterations will be handled in a loop, it is advisable that you
check the fact of forced program termination using the IsStopped() function.
Example:
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Expression1 describes the loop initialization. Expression2 check s the conditions of the loop
termination. If it is true, the loop body for is executed. The loop repeats expression2 until it becomes
false. If it is false, the loop is terminated, and control is given to the next operator. Expression3 is
calculated after each iteration.
expression1;
while(expression2)
{
operator;
expression3;
};
Any of the three or all three expressions can be absent in the for operator, but the semicolons (;) that
separate them must not be omitted. If expression2 is omitted, it is considered constantly true. The
for(;;) operator is a continuous loop, equivalent to the while(1) operator. Each expression 1 or 3 can
consist of several expressions combined by a comma operator ','.
Note
If it is expected that a large number of iterations will be handled in a loop, it is advisable that you
check the fact of forced program termination using the IsStopped() function.
Examples:
for(x=1;x<=7000; x++)
{
if(IsStopped())
break;
Print(MathPower(x,2));
}
//--- Another example
for(;!IsStopped();)
{
Print(MathPower(x,2));
x++;
if(x>10) break;
}
//--- Third example
for(i=0,j=n-l;i<n && !IsStopped();i++,j--) a[i]=a[j];
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
do
operator;
while(expression);
First the operator is executed, then the expression is calculated. If it is true, then the operator is
executed again, and so on. If the expression becomes false, the loop terminates.
Note
If it is expected that a large number of iterations will be handled in a loop, it is advisable that you
check the fact of forced program termination using the IsStopped() function.
Example:
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Break Operator
The break operator terminates the execution of the nearest nested outward switch, while, do-while or
for operator. The control is passed to the operator that follows the terminated one. One of the
purposes of this operator is to finish the looping execution when a certain value is assigned to a
variable.
Example:
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Continue Operator
The continue operator passes control to the beginning of the nearest outward loop while, do-while or
for operator, the next iteration being called. The purpose of this operator is opposite to that of break
operator.
Example:
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
The new operator can be applied only to class objects. It can't be applied to structures.
The operator shall not be used to create arrays of objects. To do this, use the ArrayR esize() function.
Example:
//+------------------------------------------------------------------+
//| Figure creation |
//+------------------------------------------------------------------+
void CTetrisField::NewShape()
{
m_ypos=HORZ_BORDER;
//--- randomly create one of the 7 possible shapes
int nshape=rand()%7;
switch(nshape)
{
case 0: m_shape=new CTetrisShape1; break;
case 1: m_shape=new CTetrisShape2; break;
case 2: m_shape=new CTetrisShape3; break;
case 3: m_shape=new CTetrisShape4; break;
case 4: m_shape=new CTetrisShape5; break;
case 5: m_shape=new CTetrisShape6; break;
case 6: m_shape=new CTetrisShape7; break;
}
//--- draw
if(m_shape!=NULL)
{
//--- pre-settings
m_shape.SetRightBorder(WIDTH_IN_PIXELS+VERT_BORDER);
m_shape.SetYPos(m_ypos);
m_shape.SetXPos(VERT_BORDER+SHAPE_SIZE*8);
//--- draw
m_shape.Draw();
}
//---
}
An object created with the new operator must be explicitly removed using the delete operator.
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Example:
See also
Initialization of Variables, Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Functions
Every tas k can be divided into subtas k s, each of which can either be directly represented in the form
of a code, or divided into smaller sub-tas k s. This method is called stepwise refinement. Functions are
used for writing the code of sub-tas k s to be solved. The code that describes what a function does is
called function definition:
function_header
{
instructions
}
All that is before the first brace is the header of the function definition, and what is between braces is
the body of the function definition. The function header includes a description of the return value
type, name (identifier) and formal parameters. The number of parameters passed to the function is
limited and cannot exceed 64.
The function can be called from other parts of the program as many times as necessary. In fact, the
return type, function identifier and parameter types constitute the function prototype.
Function prototype is the function declaration, but not its definition. Due to the explicit declaration of
the return type and a list of argument types, the strict type check ing and implicit typecasting are
possible during function calls. Very often function declarations are used in classes to improve the code
readability.
The function definition must exactly match its declaration. Each declared function must be defined.
Example:
The return operator can return the value of an expression located in this operator. If necessary, the
expression value is converted to the function result type. W hat can be returned: simple types, simple
structures, object pointers. W ith the return operator you can't return any arrays, class objects,
variables of compound structure type.
Example:
void errmesg(string s)
{
Print("error: "+s);
}
Parameters passed to the function can have default values, which are defined by constants of that
type.
Example:
int somefunc(double a,
double d=0.0001,
int n=5,
bool b=true,
string s="passed string")
{
Print("Required parameter a = ",a);
Print("Pass the following parameters: d = ",d," n = ",n," b = ",b," s = ",s);
return(0);
}
If any of parameters has a default value, all subsequent parameters must also have default values.
int somefunc(double a,
double d=0.0001, // default value 0.0001 declared
int n, // default value is not specified !
bool b, // default value is not specified !
string s="passed string")
{
}
See also
Overload, Virtual Functions, Polymorphism
Function Call
If a name that has not been described before, appears in the expression and is followed by the left
parenthesis, it is contextually considered as the name of a function.
Arguments (formal parameters) are passed by value, i.e. each expression x 1,..., xn is calculated, and
the value is passed to the function. The order of expressions calculation and the order of values
loading are not guaranteed. During the execution, the system check s the number and type of
arguments passed to the function. Such way of addressing to the function is called a value call.
Function call is an expression, the value of which is the value returned by the function. The function
type described above must correspond with the type of the return value. The function can be declared
or described in any part of the program on the global scope, i.e., outside other functions. The function
cannot be declared or described inside of another function.
Examples:
int start()
{
double some_array[4]={0.3, 1.4, 2.5, 3.6};
double a=linfunc(some_array, 10.5, 8);
//...
}
double linfunc(double x[], double a, double b)
{
return (a*x[0] + b);
}
At calling of a function with default parameters, the list of parameters to be passed can be limited,
but not before the first default parameter.
Examples:
W hen calling a function, one may not s k ip parameters, even those having default values :
somefunc(3.14, , 10); // Wrong call -> the second parameter was skipped.
See also
Overload, Virtual Functions, Polymorphism
Passing Parameters
There are two methods, by which the machine language can pass arguments to a subprogram
(function). The first method is to send a parameter by value. This method copies the argument value
into a formal function parameter. Therefore, any changes in this parameter within the function have
no influence on the corresponding call argument.
//+------------------------------------------------------------------+
//| Passing parameters by value |
//+------------------------------------------------------------------+
double FirstMethod(int i,int j)
{
double res;
//---
i*=2;
j/=2;
res=i+j;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int a=14,b=8;
Print("a and b before call:",a," ",b);
double d=FirstMethod(a,b);
Print("a and b after call:",a," ",b);
}
//--- Result of script execution
// a and b before call: 14 8
// a and b after call: 14 8
The second method is to pass by reference. In this case, reference to a parameter (not its value) is
passed to a function parameter. Inside the function, it is used to refer to the actual parameter
specified in the call. This means that the parameter changes will affect the argument used to call the
function.
//+------------------------------------------------------------------+
//| Passing parameters by reference |
//+------------------------------------------------------------------+
double SecondMethod(int &i,int &j)
{
double res;
//---
i*=2;
j/=2;
res=i+j;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int a=14,b=8;
Print("a and b before call:",a," ",b);
double d=SecondMethod(a,b);
Print("a and b after call:",a," ",b);
}
//+------------------------------------------------------------------+
//--- result of script execution
// a and b before call: 14 8
// a and b after call: 28 4
MQL5 uses both methods, with one exception: arrays, structure type variables and class objects are
always passed by reference. In order to avoid changes in actual parameters (arguments passed at
function call) use the access specifier const. W hen trying to change the contents of a variable declared
with the const specifier, the compiler will generate an error.
Note
It should be noted that parameters are passed to a function in reversed order, i.e., first the last
parameter is calculated and passed, and then the last but one, etc. The last calculated and passed
parameter is the one that stands first after opening parenthesis.
Example:
void OnStart()
{
//---
int a[]={0,1,2};
int i=0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void func(int par1,int par2,string comment)
{
In first call (see example above) the i variable is first used in strings concatenation:
H ere its value doesn't change. Then the i variable is used in calculation of thea[i++] array element,
i.e. when array element with index i is accessed, the i variable is incremented. And only after that the
first parameter with changed value of i variable is calculated.
In the second call the same value of i (calculated on the first phase of function calling) is used when
calculating all three parameters. Only after the first parameters is calculated the i variable is changed
again.
See also
Visibility Scope and Lifetime of Variables, Overload, Virtual Functions, Polymorphism
Function Overloading
Usually the function name tends to reflect its main purpose. As a rule, readable programs contain
various well selected identifiers. Sometimes different functions are used for the same purposes. Let's
consider, for example, a function that calculates the average value of an array of double precision
numbers and the same function, but operating with an array of integers. Both are convenient to be
called AverageFromArray:
//+------------------------------------------------------------------+
//| The calculation of average for an array of double type |
//+------------------------------------------------------------------+
double AverageFromArray(const double & array[],int size)
{
if(size<=0) return 0.0;
double sum=0.0;
double aver;
//---
for(int i=0;i<size;i++)
{
sum+=array[i]; // Summation for the double
}
aver=sum/size; // Just divide the sum by the number
//---
Print("Calculation of the average for an array of double type");
return aver;
}
//+------------------------------------------------------------------+
//| The calculation of average for an array of int type |
//+------------------------------------------------------------------+
double AverageFromArray(const int & array[],int size)
{
if(size<=0) return 0.0;
double aver=0.0;
int sum=0;
//---
for(int i=0;i<size;i++)
{
sum+=array[i]; // Summation for the int
}
aver=(double)sum/size;// Give the amount of type double, and divide
//---
Print("Calculation of the average for an array of int type");
return aver;
}
Each function contains the message output via the Print() function;
The compiler selects a necessary function in accordance with the types of arguments and their
quantity. The rule, according to which the choice is made, is called the signature matching algorithm.
A signature is a list of types used in the function declaration.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int a[5]={1,2,3,4,5};
double b[5]={1.1,2.2,3.3,4.4,5.5};
double int_aver=AverageFromArray(a,5);
double double_aver=AverageFromArray(b,5);
Print("int_aver = ",int_aver," double_aver = ",double_aver);
}
//--- Result of the script
// Calculate the average for an array of int type
// Calculate the average for an array of double type
// int_aver= 3.00000000 double_aver= 3.30000000
Function overloading is a process of creating several functions with the same name, but different
parameters. This means that in overloaded variants of a function, the number of arguments and/or
their type must be different. A specific function variant is selected based on the correspondence of
the list of arguments when calling the function, to the list of parameters in the function declaration.
W hen an overloaded function is called, the compiler must have an algorithm to select the appropriate
function. The algorithm that performs this choice depends on castings of what types are present. The
best correspondence must be unique. An overloaded function must be the best match among all the
other variants for at least one argument. At the same time it must match for all other arguments not
worse than other variants.
The standard type increase is better than other standard conversions. Increase is the conversion of
float to double, of bool, char, short or enum to int. Typecasting of arrays of similar integer types also
belongs to typecasting. Similar types are: bool, char, uchar, since all the three types are single-byte
integers ; double-byte integers short and ushort; 4-byte integers int, uint, and color; long, ulong, and
datetime.
Of course, the strict matching is the best. To achieve such a consistency typecasting can be used. The
compiler cannot cope with ambiguous situations. Therefore you should not rely on subtle differences of
types and implicit conversions that mak e the overloaded function unclear.
Examples of overloaded functions in MQL5 can be seen in the example of ArrayInitialize() functions.
Overloading of system functions is allowed, but it should be observed that the compiler is able to
accurately select the necessary function. For example, we can overload the system function MathMax()
in 4 different ways, but only two variants are correct.
Example:
// 1. overload is allowed - function differs from built-in MathMax() function in the number of para
double MathMax(double a,double b,double c);
See also
Overload, Virtual Functions, Polymorphism
Operation Overloading
For ease of code reading and writing, overloading of some operations is allowed. Overloading operator
is written using the k eyword operator. The following operators can be overloaded:
· binary +,-,/,*,%,<<,>>,==,!=,<,>,<=,>=,=,+=,-=,/=,*=,%=,&=,|=,^=,<<=,>>=,&&,||,&,|,^
· unary +,-,++,--,!,~
· assignment operator =
· indexing operator []
Operation overloading allows the use of the operating notation (written in the form of simple
expressions) for complex objects - structures and classes. W riting expressions using overloaded
operations simplifies the view of the source code, because a more complex implementation is hidden.
For example, consider complex numbers, which consist of real and imaginary parts. They are widely
used in mathematics. The MQL5 language has no data type to represent complex numbers, but it is
possible to create a new data type in the form of a structure or class. Declare the complex structure
and define four methods that implement four arithmetic operations :
//+------------------------------------------------------------------+
//| A structure for operations with complex numbers |
//+------------------------------------------------------------------+
struct complex
{
double re; // Real part
double im; // Imaginary part
//--- Constructors
complex():re(0.0),im(0.0) { }
complex(const double r):re(r),im(0.0) { }
complex(const double r,const double i):re(r),im(i) { }
complex(const complex &o):re(o.re),im(o.im) { }
//--- Arithmetic operations
complex Add(const complex &l,const complex &r) const; // Addition
complex Sub(const complex &l,const complex &r) const; // Subtraction
complex Mul(const complex &l,const complex &r) const; // Multiplication
complex Div(const complex &l,const complex &r) const; // Division
};
Now, in our code we can declare variables representing complex numbers, and work with them.
For example:
void OnStart()
{
//--- Declare and initialize variables of a complex type
complex a(2,4),b(-4,-2);
PrintFormat("a=%.2f+i*%.2f, b=%.2f+i*%.2f",a.re,a.im,b.re,b.im);
//--- Sum up two numbers
complex z;
z=a.Add(a,b);
PrintFormat("a+b=%.2f+i*%.2f",z.re,z.im);
//--- Multiply two numbers
z=a.Mul(a,b);
PrintFormat("a*b=%.2f+i*%.2f",z.re,z.im);
//--- Divide two numbers
z=a.Div(a,b);
PrintFormat("a/b=%.2f+i*%.2f",z.re,z.im);
//---
}
But it would be more convenient to use usual operators " +" , " -" , "*" and "/" for ordinary arithmetic
operations with complex numbers.
Keyword operator is used for defining a member function that performs type conversion. Unary and
binary operations for class object variables can be overloaded as non-static member functions. They
implicitly act on the class object.
Most binary operations can be overloaded lik e regular functions that tak e one or both arguments as a
class variable or a pointer to an object of this class. For our type complex, overloading in the
declaration will look lik e this :
//--- Operators
complex operator+(const complex &r) const { return(Add(this,r)); }
complex operator-(const complex &r) const { return(Sub(this,r)); }
complex operator*(const complex &r) const { return(Mul(this,r)); }
complex operator/(const complex &r) const { return(Div(this,r)); }
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Declare and initialize variables of type complex
complex a(2,4),b(-4,-2);
PrintFormat("a=%.2f+i*%.2f, b=%.2f+i*%.2f",a.re,a.im,b.re,b.im);
//a.re=5;
//a.im=1;
//b.re=-1;
//b.im=-5;
//--- Sum up two numbers
complex z=a+b;
PrintFormat("a+b=%.2f+i*%.2f",z.re,z.im);
//--- Multiply two numbers
z=a*b;
PrintFormat("a*b=%.2f+i*%.2f",z.re,z.im);
//--- Divide two numbers
z=a/b;
PrintFormat("a/b=%.2f+i*%.2f",z.re,z.im);
//---
}
//+------------------------------------------------------------------+
//| A structure for operations with complex numbers |
//+------------------------------------------------------------------+
struct complex
{
double re; // Real part
double im; // Imaginary part
//--- Constructors
complex():re(0.0),im(0.0) { }
complex(const double r):re(r),im(0.0) { }
complex(const double r,const double i):re(r),im(i) { }
complex(const complex &o):re(o.re),im(o.im) { }
//--- Arithmetic operations
complex Add(const complex &l,const complex &r) const; // Addition
complex Sub(const complex &l,const complex &r) const; // Subtraction
complex Mul(const complex &l,const complex &r) const; // Multiplication
complex Div(const complex &l,const complex &r) const; // Division
//--- Binary operators
complex operator+(const complex &r) const { return(Add(this,r)); }
complex operator-(const complex &r) const { return(Sub(this,r)); }
complex operator*(const complex &r) const { return(Mul(this,r)); }
complex operator/(const complex &r) const { return(Div(this,r)); }
};
//+------------------------------------------------------------------+
//| Addition |
//+------------------------------------------------------------------+
complex complex::Add(const complex &l,const complex &r) const
{
complex res;
//---
res.re=l.re+r.re;
res.im=l.im+r.im;
//--- Result
return res;
}
//+------------------------------------------------------------------+
//| Subtraction |
//+------------------------------------------------------------------+
complex complex::Sub(const complex &l,const complex &r) const
{
complex res;
//---
res.re=l.re-r.re;
res.im=l.im-r.im;
//--- Result
return res;
}
//+------------------------------------------------------------------+
//| Multiplication |
//+------------------------------------------------------------------+
complex complex::Mul(const complex &l,const complex &r) const
{
complex res;
//---
res.re=l.re*r.re-l.im*r.im;
res.im=l.re*r.im+l.im*r.re;
//--- Result
return res;
}
//+------------------------------------------------------------------+
//| Division |
//+------------------------------------------------------------------+
complex complex::Div(const complex &l,const complex &r) const
{
//--- Empty complex number
complex res(EMPTY_VALUE,EMPTY_VALUE);
//--- Check for zero
if(r.re==0 && r.im==0)
{
Print(__FUNCTION__+": number is zero");
return(res);
}
//--- Auxiliary variables
double e;
double f;
//--- Selecting calculation variant
if(MathAbs(r.im)<MathAbs(r.re))
{
e = r.im/r.re;
f = r.re+r.im*e;
res.re=(l.re+l.im*e)/f;
res.im=(l.im-l.re*e)/f;
}
else
{
e = r.re/r.im;
f = r.im+r.re*e;
res.re=(l.im+l.re*e)/f;
res.im=(-l.re+l.im*e)/f;
}
//--- Result
return res;
}
Most unary operations for classes can be overloaded as ordinary functions that accept a single class
object argument or a pointer to it. Add overloading of unary operations " -" and "!" .
//+------------------------------------------------------------------+
//| A structure for operations with complex numbers |
//+------------------------------------------------------------------+
struct complex
{
double re; // Real part
double im; // Imaginary part
...
//--- Unary operators
complex operator-() const; // Unary minus
bool operator!() const; // Negation
};
...
//+------------------------------------------------------------------+
//| Overloading the "unary minus" operator |
//+------------------------------------------------------------------+
complex complex::operator-() const
{
complex res;
//---
res.re=-re;
res.im=-im;
//--- Result
return res;
}
//+------------------------------------------------------------------+
//| Overloading the "logical negation" operator |
//+------------------------------------------------------------------+
bool complex::operator!() const
{
//--- Are the real and imaginary parts of the complex number equal to zero?
return (re!=0 && im!=0);
}
Now we can check the value of a complex number for zero and get a negative value:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Declare and initialize variables of type complex
complex a(2,4),b(-4,-2);
PrintFormat("a=%.2f+i*%.2f, b=%.2f+i*%.2f",a.re,a.im,b.re,b.im);
//--- Divide the two numbers
complex z=a/b;
PrintFormat("a/b=%.2f+i*%.2f",z.re,z.im);
//--- A complex number is equal to zero by default (in the default constructor re==0 and im==0)
complex zero;
Print("!zero=",!zero);
//--- Assign a negative value
zero=-z;
PrintFormat("z=%.2f+i*%.2f, zero=%.2f+i*%.2f",z.re,z.im, zero.re,zero.im);
PrintFormat("-zero=%.2f+i*%.2f",-zero.re,-zero.im);
//--- Check for zero once again
Print("!zero=",!zero);
//---
}
Note that we did not have to overload the assignment operator "=" , as structures of simple types can
be directly copied one into each other. Thus, we can now write a code for calculations involving
complex numbers in the usual manner.
Overloading of the indexing operator allows to obtain the values of the arrays enclosed in an object, in
a simple and familiar way, and it also contributes to a better readability of the source code. For
example, we need to provide access to a symbol in the string at the specified position. A string in
MQL5 is a separate type string, which is not an array of symbols, but with the help of an overloaded
indexing operation we can provide a simple and transparent work in the generated CString class :
//+------------------------------------------------------------------+
//| Class to access symbols in string as in array of symbols |
//+------------------------------------------------------------------+
class CString
{
string m_string;
public:
CString(string str=NULL):m_string(str) { }
ushort operator[] (int x) { return(StringGetCharacter(m_string,x)); }
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- An array for receiving symbols from a string
int x[]={ 19,4,18,19,27,14,15,4,17,0,19,14,17,27,26,28,27,5,14,
17,27,2,11,0,18,18,27,29,30,19,17,8,13,6 };
CString str("abcdefghijklmnopqrstuvwxyz[ ]CS");
string res;
//--- Make up a phrase using symbols from the str variable
for(int i=0,n=ArraySize(x);i<n;i++)
{
res+=ShortToString(str[x[i]]);
}
Another example of overloading of the indexing operation is operations with matrices. The matrix
represents a two-dimensional dynamic array, the array size is not defined in advance. Therefore, you
cannot declare an array of form array[][] without specifying the size of the second dimension, and
then pass this array as a parameter. A possible solution is a special class CMatrix, which contains an
array of CR ow class objects.
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Operations of addition and multiplication of matrices
CMatrix A(3),B(3),C();
//--- Prepare an array for rows
double a1[3]={1,2,3}, a2[3]={2,3,1}, a3[3]={3,1,2};
double b1[3]={3,2,1}, b2[3]={1,3,2}, b3[3]={2,1,3};
//--- Fill the matrices
A[0]=a1; A[1]=a2; A[2]=a3;
B[0]=b1; B[1]=b2; B[2]=b3;
//--- Output the matrices in the Experts log
Print("---- Elements of matrix A");
Print(A.String());
Print("---- Elements of matrix B");
Print(B.String());
//--- Now we show how to get values in the style of dynamic arrays matrix[i][j]
Print("Output the values of matrix C elementwise");
//--- Go through the matrix rows - CRow objects - in a loop
for(int i=0;i<3;i++)
{
string com="| ";
//--- Form rows from the matrix for the value
for(int j=0;j<3;j++)
{
//--- Get the matrix element by the number of the row and column
double element=C[i][j];// [i] - Access to CRow in the array m_rows[] ,
// [j] - Overloaded operator of indexing in CRow
com=com+StringFormat("a(%d,%d)=%G ; ",i,j,element);
}
com+="|";
//--- Output the values of the row
Print(com);
}
}
//+------------------------------------------------------------------+
//| Class "Row" |
//+------------------------------------------------------------------+
class CRow
{
private:
double m_array[];
public:
//--- Constructors and a destructor
CRow(void) { ArrayResize(m_array,0); }
CRow(const CRow &r) { this=r; }
CRow(const double &array[]);
~CRow(void){};
//--- Number of elements in the row
int Size(void) const { return(ArraySize(m_array));}
//--- Returns a string with values
string String(void) const;
//--- Indexing operator
double operator[](int i) const { return(m_array[i]); }
//--- Assignment operators
void operator=(const double &array[]); // An array
void operator=(const CRow & r); // Another CRow object
double operator*(const CRow &o); // CRow object for multiplication
};
//+------------------------------------------------------------------+
//| Constructor for initializing a row with an array |
//+------------------------------------------------------------------+
void CRow::CRow(const double &array[])
{
int size=ArraySize(array);
//--- If the array is not empty
if(size>0)
{
ArrayResize(m_array,size);
//--- Fill with values
for(int i=0;i<size;i++)
m_array[i]=array[i];
}
//---
}
//+------------------------------------------------------------------+
//| Assignment operation for the array |
//+------------------------------------------------------------------+
void CRow::operator=(const double &array[])
{
int size=ArraySize(array);
if(size==0) return;
//--- Fill the array with values
ArrayResize(m_array,size);
for(int i=0;i<size;i++) m_array[i]=array[i];
//---
}
//+------------------------------------------------------------------+
//| Assignment operation for CRow |
//+------------------------------------------------------------------+
void CRow::operator=(const CRow &r)
{
int size=r.Size();
if(size==0) return;
//--- Fill the array with values
ArrayResize(m_array,size);
for(int i=0;i<size;i++) m_array[i]=r[i];
//---
}
//+------------------------------------------------------------------+
//| Operator of multiplication by another row |
//+------------------------------------------------------------------+
double CRow::operator*(const CRow &o)
{
double res=0;
//--- Verifications
int size=Size();
if(size!=o.Size() || size==0)
{
Print(__FUNCSIG__,": Failed to multiply two matrices, their sizes are different");
return(res);
}
//--- Multiply arrays elementwise and add the products
for(int i=0;i<size;i++)
res+=m_array[i]*o[i];
//--- Result
return(res);
}
//+------------------------------------------------------------------+
//| Returns a formatted string representation |
//+------------------------------------------------------------------+
string CRow::String(void) const
{
string out="";
//--- If the size of the array is greater than zero
int size=ArraySize(m_array);
//--- We work only with a non-zero number of array elements
if(size>0)
{
out="{";
for(int i=0;i<size;i++)
{
//--- Collect the values to a string
out+=StringFormat(" %G;",m_array[i]);
}
out+=" }";
}
//--- Result
return(out);
}
//+------------------------------------------------------------------+
//| Class "Matrix" |
//+------------------------------------------------------------------+
class CMatrix
{
private:
CRow m_rows[];
public:
//--- Constructors and a destructor
CMatrix(void);
CMatrix(int rows) { ArrayResize(m_rows,rows); }
~CMatrix(void){};
//--- Get the matrix sizes
int Rows() const { return(ArraySize(m_rows)); }
int Cols() const { return(Rows()>0? m_rows[0].Size():0); }
//--- Returns the value of the column in the form of a CRow row
CRow GetColumnAsRow(const int col_index) const;
//--- Returns a string with the matrix values
string String(void) const;
//--- The indexing operator returns a string by its number
CRow *operator[](int i) const { return(GetPointer(m_rows[i])); }
//--- Addition operator
CMatrix operator+(const CMatrix &m);
//--- Multiplication operator
CMatrix operator*(const CMatrix &m);
//--- Assignment operator
CMatrix *operator=(const CMatrix &m);
};
//+------------------------------------------------------------------+
//| A default constructor, create an array of rows of zero size |
//+------------------------------------------------------------------+
CMatrix::CMatrix(void)
{
//--- The zero number of rows in the matrix
ArrayResize(m_rows,0);
//---
}
//+------------------------------------------------------------------+
//| Returns the column value in the form of CRow |
//+------------------------------------------------------------------+
CRow CMatrix::GetColumnAsRow(const int col_index) const
{
//--- A variable to get the values from the column
CRow row();
//--- The number of rows in the matrix
int rows=Rows();
//--- If the number of rows is greater than zero, execute the operation
if(rows>0)
{
//--- An array to receive the values of the column with index col_index
double array[];
ArrayResize(array,rows);
//--- Filling the array
for(int i=0;i<rows;i++)
{
//--- Check the number of the column for row i - it may exceed the boundaries of the array
if(col_index>=this[i].Size())
{
Print(__FUNCSIG__,": Error! Column number ",col_index,"> row size ",i);
break; // row will be uninitialized object
}
array[i]=this[i][col_index];
}
//--- Create a CRow row based on the array values
row=array;
}
//--- Result
return(row);
}
//+------------------------------------------------------------------+
//| Addition of two matrices |
//+------------------------------------------------------------------+
CMatrix CMatrix::operator+(const CMatrix &m)
{
//--- The number of rows and columns in the passed matrix
int cols=m.Cols();
int rows=m.Rows();
//--- The matrix to receive the addition results
CMatrix res(rows);
//--- The sizes of the matrix must match
if(cols!=Cols() || rows!=Rows())
{
//--- Addition impossible
Print(__FUNCSIG__,": Failed to add two matrices, their sizes are different");
return(res);
}
//--- Auxiliary array
double arr[];
ArrayResize(arr,cols);
//--- Go through rows to add
for(int i=0;i<rows;i++)
{
//--- Write the results of addition of matrix strings in the array
for(int k=0;k<cols;k++)
{
arr[k]=this[i][k]+m[i][k];
}
//--- Place the array to the matrix row
res[i]=arr;
}
//--- return the result of addition of matrices
return(res);
}
//+------------------------------------------------------------------+
//| Multiplication of two matrices |
//+------------------------------------------------------------------+
CMatrix CMatrix::operator*(const CMatrix &m)
{
//--- Number of columns of the first matrix, number of rows passed in the matrix
int cols1=Cols();
int rows2=m.Rows();
int rows1=Rows();
int cols2=m.Cols();
//--- Matrix to receive the addition result
CMatrix res(rows1);
//--- Matrices should be coordinated
if(cols1!=rows2)
{
//--- Multiplication impossible
Print(__FUNCSIG__,": Failed to multiply two matrices, format is not compatible "
"- number of columns in the first factor should be equal to the number of rows in the s
return(res);
}
//--- Auxiliary array
double arr[];
ArrayResize(arr,cols1);
//--- Fill the rows in the multiplication matrix
for(int i=0;i<rows1;i++)// Go through rows
{
See also
Overloading, Arithmetic Operations, Function Overloading, Precedence R ules
Examples:
#import "user32.dll"
int MessageBoxW(int hWnd ,string szText,string szCaption,int nType);
int SendMessageW(int hWnd,int Msg,int wParam,int lParam);
#import "lib.ex5"
double round(double value);
#import
W ith the help of import, it is easy to describe functions that are called from external DLL or compiled
EX5 libraries. EX5 libraries are compiled ex5 files, which have the library property. Only function
described with the export modifier can be imported from EX5 libraries.
Please k eep in mind that DLL and EX5 libraries should have different names (regardless of the
directories they are located in) if they are imported together. All imported functions have the scope
resolution corresponding to the library's " file name" .
Example:
#import "kernel32.dll"
int GetLastError();
#import "lib.ex5"
int GetLastError();
#import
class CFoo
{
public:
int GetLastError() { return(12345); }
void func()
{
Print(GetLastError()); // call of the class method
Print(::GetLastError()); // call of the MQL5 function
Print(kernel32::GetLastError()); // call of the DLL library function from kernel32.dll
Print(lib::GetLastError()); // call of the EX5 library function from lib.ex5
}
};
void OnStart()
{
CFoo foo;
foo.func();
}
See also
Overload, Virtual Functions, Polymorphism
Exporting Functions
A function declared in a mql5 program with the export postmodifier can be used in another mql5
program. Such a function is called exportable, and it can be called from other programs after
compilation.
This modifier orders the compiler to add the function into the table of EX5 functions exported by this
ex5 file. Only function with such a modifier are accessible (" visible" ) from other mql5 programs.
The library property tells the compiler that the EX5-file will be a library, and the compiler will show it in
the header of EX5.
All functions that are planned as exportable ones must be mark ed with the export modifier.
See also
Overload, Virtual Functions, Polymorphism
The event handler of the client terminal identifies functions, handling this or that event, by the type
of return value and type of parameters. If other parameters, not corresponding to below descriptions,
are specified for a corresponding function, or another return type is indicated for it, such a function
will not be used as an event handler.
OnStart
The OnStart() function is the Start event handler, which is automatically generated only for running
scripts. It must be of void type, with no parameters :
void OnStart();
For the OnStart() function, the int return type can be specified.
OnInit
The OnInit() function is the Init event handler. It must be of void or int type, with no parameters :
void OnInit();
The Init event is generated immediately after an Expert Advisor or an indicator is downloaded; this
event is not generated for scripts. The OnInit() function is used for initialization. If OnInit() has the
int type of the return value, the non-zero return code means unsuccessful initialization, and it
generates the Deinit event with the code of deinitialization reason REASON_I NIT FAIL ED.
ENUM_INIT_RETCODE
Identifier Description
I NIT _PARAM ET ER S _I NCORRECT This value means the incorrect set of input
parameters. The result string containing this
return code is highlighted in red in the general
optimization table.
Testing for the given set of parameters of the
Expert Advisor will not be executed, the agent is
free to receive a new tas k .
Upon receiving this value, the strategy tester
will reliably not pass this tas k to other agents
for retry.
I NIT _AGENT _NOT _S UIT ABL E No errors during initialization, but for some
reason the agent is not suitable for testing. For
example, not enough memory, no OpenCL
support, etc.
After the return of this code, the agent will not
receive tas k s until the end of this optimization.
The OnInit() function of the void type always denotes successful initialization.
OnDeinit
The OnDeinit() function is called during deinitialization and is the Deinit event handler. It must be
declared as the void type and should have one parameter of the const int type, which contains the
code of deinitialization reason. If a different type is declared, the compiler will generate a warning,
but the function will not be called. For scripts the Deinit event is not generated and therefore the
OnDeinit() function can't be used in scripts.
The Deinit event is generated for Expert Advisors and indicators in the following cases :
· before reinitialization due to the change of a symbol or chart period, to which the mql5 program is
attached;
· before reinitialization due to the change of input parameters ;
OnTick
The NewTick event is generated for Expert Advisors only when a new tick for a symbol is received, to
the chart of which the Expert Advisor is attached. It's useless to define the OnTick () function in a
custom indicator or script, because the NewTick event is not generated for them.
The Tick event is generated only for Expert Advisors, but this does not mean that Expert Advisors
required the OnTick () function, since not only NewTick events are generated for Expert Advisors, but
also events of Timer, BookEvent and ChartEvent are generated. It must be declared as the void type,
with no parameters :
void OnTick();
OnTimer
The OnTimer() function is called when the Timer event occurs, which is generated by the system timer
only for Expert Advisors and indicators - it can't be used in scripts. The frequency of the event
occurrence is set when subscribing to notifications about this event to be received by the
EventSetTimer() function.
You can unsubscribe from receiving timer events for a particular Expert Advisor using the
EventKillTimer() function. The function must be defined with the void type, with no parameters :
void OnTimer();
It is recommended to call the EventSetTimer() function once in the OnInit() function, and the
EventKillTimer() function should be called once in OnDeinit().
Every Expert Advisor, as well as every indicator work s with its own timer and receives events only
from it. As soon as the mql5 program stops operating, the timer is destroyed forcibly, if it was created
but hasn't been disabled by the EventKillTimer() function.
OnTrade
The function is called when the Trade event occurs, which appears when you change the list of placed
orders and open positions, the history of orders and history of deals. W hen a trade activity is
performed (pending order opening, position opening /closing, stops setting, pending order triggering,
etc.) the history of orders and deals and/or list of positions and current orders is changed accordingly.
void OnTrade();
Users must independently implement in the code the verification of a trade account state when such
an event is received (if this is required by the trade strategy conditions). If the OrderSend() function
call has been completed successfully and returned a value of true, this means that the trading server
has put the order into the queue for execution and assigned a tick et number to it. As soon as the
server processes this order, the Trade event will be generated. And if a user remembers the tick et
value, he/she will be able to find out what happened to the order using this value during OnTrade()
event handling.
OnTradeTransaction
W hen performing some definite actions on a trade account, its state changes. Such actions include:
· Sending a trade request from any MQL5 application in the client terminal using OrderSend and
OrderSendAsync functions and its further execution;
· Sending a trade request via the terminal graphical interface and its further execution;
· changing positions.
For example, when sending a mark et buy order, it is handled, an appropriate buy order is created for
the account, the order is then executed and removed from the list of the open ones, then it is added
to the orders history, an appropriate deal is added to the history and a new position is created. All
these actions are trade transactions. Arrival of such a transaction at the terminal is a
TradeTransaction event. It calls OnTradeTransaction handler
void OnTradeTransaction(
const MqlTradeTransaction& trans, // trade transaction structure
const MqlTradeRequest& request, // request structure
const MqlTradeResult& result // result structure
);
· trans - this parameter gets M qlTradeTransaction structure describing a trade transaction applied to
a trade account;
· request - this parameter gets M qlTradeR equest structure describing a trade request;
· result - this parameter gets M qlTradeR esult structure describing a trade request execution result.
The last two request and result parameters are filled by values only for
T RADE_T RANS ACTION_REQUEST type transaction, data on transaction can be received from type
parameter of trans variable. Note that in this case, request_id field in result variable contains I D of
request trade request, after the execution of which the trade transaction described in trans variable
has been performed. R equest I D allows to associate the performed action (OrderSend or
OrderSendAsync functions call) with the result of this action sent to OnTradeTransaction().
One trade request manually sent from the terminal or via OrderSend()/OrderSendAsync() functions can
generate several consecutive transactions on the trade server. Priority of these transactions ' arrival at
the terminal is not guaranteed. Thus, you should not expect that one group of transactions will arrive
after another one when developing your trading algorithm.
· All types of trade transactions are described in ENUM _T RADE_T RANS ACTION_T YPE enumeration.
· M qlTradeTransaction structure describing a trade transaction is filled in different ways
depending on a transaction type. For example, only type field (trade transaction type) must be
analyzed for T RADE_T RANS ACTION_REQUEST type transactions. The second and third
parameters of OnTradeTransaction function (request and result) must be analyzed for additional
data. For more information, see " Structure of a Trade Transaction" .
· A trade transaction description does not deliver all available information concerning orders,
deals and positions (e.g., comments). OrderGet*, H istoryOrderGet*, H istoryDealGet* and
PositionGet* functions should be used to get extended information.
After applying trade transactions for a client account, they are consistently placed to the terminal
trade transactions queue, from which they consistently sent to OnTradeTransaction entry point in
order of arrival at the terminal.
W hen handling trade transactions by an Expert Advisor using OnTradeTransaction handler, the
terminal continues handling newly arrived trade transactions. Therefore, the state of a trade account
can change during OnTradeTransaction operation already. For example, while an MQL5 program
handles an event of adding a new order, it may be executed, deleted from the list of the open ones
and moved to the history. Further on, the application will be notified of these events.
Transactions queue length comprises 1024 elements. If OnTradeTransaction handles a new transaction
for too long, the old ones in the queue may be superseded by the newer ones.
· Generally, there is no accurate ratio of the number of OnTrade and OnTradeTransaction calls.
One OnTrade call corresponds to one or several OnTradeTransaction calls.
· OnTrade is called after appropriate OnTradeTransaction calls.
OnTester
The OnTester() function is the handler of the Tester event that is automatically generated after a
history testing of an Expert Advisor on the chosen interval is over. The function must be defined with
the double type, with no parameters :
double OnTester();
The function is called right before the call of OnDeinit() and has the same type of the return value -
double. OnTester() can be used only in the testing of Expert Advisors. Its main purpose is to calculate
a certain value that is used as the Custom max criterion in the genetic optimization of input
parameters.
In the genetic optimization descending sorting is applied to results within one generation. I.e. from
the point of view of the optimization criterion, the best results are those with largest values (for the
Custom max optimization criterion values returned by the OnTester function are tak en into account).
In such a sorting, the worst values are positioned at the end and further thrown off and do not
participate in the forming of the next generation.
OnTesterInit
The OnTesterInit() function is the handler of the TesterInit event, which is automatically generated
before the start of Expert Advisor optimization in the strategy tester. The function must be defined
with the void type. It has no parameters :
void OnTesterInit();
W ith the start of optimization, an Expert Advisor with the OnTesterDeinit() or OnTesterPass() handler
is automatically loaded in a separate terminal chart with the symbol and period specified in the tester,
and receives the TesterInit event. The function is used for Expert Advisor initialization before the
start of optimization for further processing of optimization results.
OnTesterPass
The OnTesterPass() function is the handler of the TesterPass event, which is automatically generated
when a frame is received during Expert Advisor optimization in the strategy tester. The function must
be defined with the void type. It has no parameters :
void OnTesterPass();
An Expert Advisor with the OnTesterPass() handler is automatically loaded in a separate terminal chart
with the symbol/period specified for testing, and gets TesterPass events when a frame is received
during optimization. The function is used for dynamic handling of optimization results " on the spot"
without waiting for its completion. Frames are added using the FrameAdd() function, which can be
called after the end of a single pass in the OnTester() handler.
OnTesterDeinit
OnTesterDeinit() is the handler of the TesterDeinit event, which is automatically generated after the
end of Expert Advisor optimization in the strategy tester. The function must be defined with the void
type. It has no parameters :
void OnTesterDeinit();
An Expert Advisor with the TesterDeinit() handler is automatically loaded on a chart at the start of
optimization, and receives TesterDeinit after its completion. The function is used for final processing
of all optimization results.
OnBookEvent
The OnBookEvent() function is the BookEvent handler. BookEvent is generated for Expert Advisors and
indicators when Depth of Mark et changes. It must be of the void type and have one parameter of the
string type:
To receive BookEvent events for any symbol, you just need to pre-subscribe to receive these events
for this symbol using the Mark etBookAdd() function. In order to unsubscribe from receiving the
BookEvent events for a particular symbol, call Mark etBookR elease().
Unlik e other events, the BookEvent event is broadcast. This means that if one Expert Advisor
subscribes to receiving BookEvent events using Mark etBookAdd, all the other Experts Advisors that
have the OnBookEvent() handler will receive this event. It is therefore necessary to analyze the name
of the symbol, which is passed to the handler as the const string& symbol parameter.
OnChartEvent
· CHAR T EVENT _KEYDOWN — event of a k eystrok e, when the chart window is focused;
· CHAR T EVENT _MOUS E_MOVE — mouse move events and mouse click events (if
CHAR T _EVENT _MOUS E_MOVE=true is set for the chart);
· CHAR T EVENT _OBJECT _CREAT E — event of graphical object creation (if
CHAR T _EVENT _OBJECT _CREAT E=true is set for the chart);
· CHAR T EVENT _OBJECT _CHANGE — event of change of an object property via the properties dialog ;
· CHAR T EVENT _OBJECT _CLICK — event of a mouse click in a graphical object belonging to the chart;
· CHAR T EVENT _OBJECT _DRAG — event of a graphical object move using the mouse;
· CHAR T EVENT _OBJECT _ENDEDIT — event of the finished text editing in the entry box of the
LabelEdit graphical object;
· CHAR T EVENT _CHAR T _CHANGE — event of chart changes ;
· CHAR T EVENT _CUSTOM+n — I D of the user event, where n is in the range from 0 to 65535.
· CHAR T EVENT _CUSTOM _L AST — the last acceptable I D of a custom event (CHAR T EVENT _CUSTOM
+65535).
The function can be called only in Expert Advisors and indicators. The function should be of void type
with 4 parameters :
For each type of event, the input parameters of the OnChartEvent() function have definite values that
are required for the processing of this event. The events and values passed through these parameters
are listed in the table below.
Event of a CHAR T EVENT _KE code of a R epeat count The string value
k eystrok e YDOWN pressed k ey (the number of of a bit mas k
times the describing the
k eystrok e is status of
repeated as a k eyboard buttons
result of the user
holding down the
k ey)
Mouse events (if CHAR T EVENT _MO the X coordinate the Y coordinate The string value
property US E_MOVE of a bit mas k
CHAR T _EVENT _ describing the
MOUS E_MOVE=tr status of mouse
ue is set for the buttons
chart)
Event of a CHAR T EVENT _OB the X coordinate the Y coordinate Name of the
mouse click in a JECT _CLICK graphical object,
graphical object on which the
belonging to the event occurred
chart
I D of the user CHAR T EVENT _CU Value set by the Value set by the Value set by the
event under the STOM+N EventChartCusto EventChartCusto EventChartCusto
N number m() function m() function m() function
OnCalculate
The OnCalculate() function is called only in custom indicators when it's necessary to calculate the
indicator values by the Calculate event. This usually happens when a new tick is received for the
symbol, for which the indicator is calculated. This indicator is not required to be attached to any price
chart of this symbol.
The OnCalculate() function must have a return type int. There are two possible definitions. W ithin one
indicator you cannot use both versions of the function.
The first form is intended for those indicators that can be calculated on a single data buffer. An
example of such an indicator is Custom Moving Average.
As the price[] array, one of timeseries or a calculated buffer of some indicator can be passed. To
determine the direction of indexing in the price[] array, call ArrayGetAsSeries(). In order not to
depend on the default values, you must unconditionally call the ArraySetAsSeries() function for those
arrays, that are expected to work with.
Necessary time series or an indicator to be used as the price[] array can be selected by the user in the
" Parameters " tab when starting the indicator. To do this, you should specify the necessary item in the
drop-down list of "Apply to" field.
To receive values of a custom indicator from other mql5 programs, the iCustom() function is used,
which returns the indicator handle for subsequent operations. You can also specify the appropriate
price[] array or the handle of another indicator. This parameter should be transmitted last in the list
of input variables of the custom indicator.
Example:
void OnStart()
{
//---
string terminal_path=TerminalInfoString(STATUS_TERMINAL_PATH);
int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRIC
if(handle_customMA>0)
Print("handle_customMA = ",handle_customMA);
else
Print("Cannot open or not EX5 file '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Ave
}
In this example, the last parameter passed is the PR ICE_T YPICAL value (from the
ENUM _APPLIED_PR ICE enumeration), which indicates that the custom indicator will be built on typical
prices obtained as (H igh+Low+Close)/3. If this parameter is not specified, the indicator is built based
on PR ICE_CLOS E values, i.e. closing prices of each bar.
Another example that shows passing of the indicator handler as the last parameter to specify the
price[] array, is given in the description of the iCustom() function.
The second form is intended for all other indicators, in which more than one time series is used for
calculations.
Parameters of open[], high[], low[] and close[] contain arrays with open prices, high and low prices
and close prices of the current time frame. The time[] parameter contains an array with open time
values, the spread[] parameter has an array containing the history of spreads (if any spread is
provided for the traded security). The parameters of volume[] and tick_volume[] contain the history of
trade and tick volume, respectively.
To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[]
and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should
unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
The first rates _total parameter contains the number of bars, available to the indicator for calculation,
and corresponds to the number of bars available in the chart.
W e should note the connection between the return value of OnCalculate() and the second input
parameter prev _calculated. During the function call, the prev _calculated parameter contains a value
returned by OnCalculate() during previous call. This allows for economical algorithms for calculating
the custom indicator in order to avoid repeated calculations for those bars that haven't changed since
the previous run of this function.
For this, it is usually enough to return the value of the rates _total parameter, which contains the
number of bars in the current function call. If since the last call of OnCalculate() price data has
changed (a deeper history downloaded or history blank s filled), the value of the input parameter
prev _calculated will be set to zero by the terminal.
Note: if OnCalculate returns zero, then the indicator values are not shown in the DataW indow of the
client terminal.
To understand it better, it would be useful to start the indicator, which code is attached below.
Indicator Example:
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
See also
R unning Programs, Client Terminal Events, W ork ing with Events
Variables
Declaring Variables
Variables must be declared before they are used. Unique names are used to identify variables. To
declare a variable, you must specify its type and a unique name. Declaration of variable is not an
operator.
· datetime – the date and time, an unsigned integer containing the number of seconds since 0 hour
January 1, 1970;
· bool – boolean values true and false ;
· double – double-precision floating point number;
Examples:
string szInfoBox;
int nOrders;
double dSymbolPrice;
bool bLog;
datetime tBegin_Data = D'2004.01.01 00:00';
color cModify_Color = C'0x44,0xB9,0xE6';
struct MyTime
{
int hour; // 0-23
int minute; // 0-59
int second; // 0-59
};
...
MyTime strTime; // Variable of the previously declared structure MyTime
You can't declare variables of the structure type until you declare the structure.
Arrays
Only an integer can be an array index. No more than four-dimensional arrays are allowed. Numbering
of array elements starts with 0. The last element of a one-dimensional array has the number which is 1
less than the array size. This means that call for the last element of an array consisting of 50 integers
will appear as a[49]. The same concerns multidimensional arrays : A dimension is indexed from 0 to
the dimension size-1. The last element of a two-dimensional array from the example will appear as
m[6][49].
Static arrays can't be represented as timeseries, i.e., the ArraySetAsSeries() function, which sets
access to array elements from the end to beginning, can't be applied to them. If you want to provide
access to an array the same as in timeseries, use the dynamic array object.
If there is an attempt to access out of the array range, the executing subsystem will generate a critical
error and the program will be stopped.
Access Specifiers
Access specifiers define how the compiler can access variables, members of structures or classes.
The const specifier declares a variable as a constant, and does not allow to change this variable during
runtime. A single initialization of a variable is allowed when declaring it.
Example:
· protected – allows access from methods of this class, as well as from methods of publicly inherited
classes. Other access is impossible;
· private – allows access to variables and class methods only from methods of the same class.
· virtual – applies only to class methods (but not to methods of structures) and tells the compiler that
this method should be placed in the table of virtual functions of the class.
Storage Classes
There are three storage classes : static, input and extern. These modifiers of a storage class explicitly
indicate to the compiler that corresponding variables are distributed in a pre-allocated area of
memory, which is called the global pool. Besides, these modifiers indicate the special processing of
variable data. If a variable declared on a local level is not a static one, memory for such a variable is
allocated automatically at a program stack . Freeing of memory allocated for a non-static array is also
performed automatically when going beyond the visibility area of the block , in which the array is
declared.
See also
Data Types, Encapsulation and Extensibility of Types,Initialization of Variables, Visibility Scope and
Lifetime of Variables, Creating and Deleting Objects, Static Members of a Class
Local Variables
A variable declared inside a function is local. The scope of a local variable is limited to the function
range inside which it is declared. Local variable can be initialized by outcome of any expression. Every
call of the function initializes a local variable. Local variables are stored in memory area of the
corresponding function.
Example:
int somefunc()
{
int ret_code=0;
...
return(ret_code);
}
Scope of a variable is a program part, in which a variable can be referred to. Variables declared inside
a block (at the internal level), have the block as their scope. The block scope start with the variable
declaration and ends with the final right brace.
Local variables declared in the beginning of a function also have the scope of block , as well as function
parameters that are local variables. Any block can contain variable declarations. If block s are nested
and the identifier in the external block has the same name as the identifier in the internal block , the
external block identifier is hidden, until the operation of the internal block is over.
Example:
void OnStart()
{
//---
int i=5; // local variable of the function
{
int i=10; // function variable
Print("Inside block i = ",i); // result is i=10;
}
Print("Outside block i = ",i); // result is i=5;
}
This means that while the internal block is running, it sees values of its own local identifiers, not the
values of identifiers with identical names in the external block .
Example:
void OnStart()
{
//---
int i=5; // local variable of the function
for(int i=0;i<3;i++)
Print("Inside for i = ",i);
Print("Outside the block i = ",i);
}
/* Execution result
Inside for i = 0
Inside for i = 1
Inside for i = 2
Outside block i = 5
*/
Local variables declared as static have the scope of the block , despite the fact that they exist since
the program start.
Stack
In every MQL5 program, a special memory area called stack is allocated for storing local function
variables that are created automatically. One stack is allocated for all functions, its default size for
indicators is equal to 1Mb. In Expert Advisors and scripts, stack size can be managed using the
#property stack size compiler directive (which sets the stack size in bytes), a memory of 8Mb is
allocated by default for the stack .
Static local variables are stored in the same place where other static and global variables are stored -
in a special memory area, which exists separately from the stack . Dynamically created variables also
use a memory area separate from the stack .
W ith each function call, a place on the stack is allocated for internal non-static variables. After exiting
the function, the memory is available for use again.
If from the first function the second one is called, then the second function occupies the required size
from the remaining stack memory for its variables. Thus, when using included functions, stack
memory will be sequentially occupied for each function. This may lead to a shortage of memory during
one of the function calls, such a situation is called stack overflow.
Therefore, for large local data you should better use dynamic memory - when entering a function,
allocate the memory, which is required for local needs, in the system (new, ArrayR esize()), and when
exiting the function, release the memory (delete, ArrayFree()).
See also
Data Types, Encapsulation and Extensibility of Types,Initialization of Variables, Visibility Scope and
Lifetime of Variables, Creating and Deleting Objects
Formal Parameters
Parameters passed to the function are local. The scope is the function block . Formal parameters must
have names differing from those of external variables and local variables defined within one function.
Some values can be assigned to formal parameters in the function block . If a formal parameter is
declared with the const modifier, its value can't be changed within the function.
Example:
Formal parameters can be initialized by constants. In this case, the initializing value is considered as
the default value. Parameters, next to the initialized one, must also be initialized.
Example:
W hen calling such a function, the initialized parameters can be omitted, the defaults being substituted
instead of them.
Example:
func(123, 0.5);
Parameters of simple types are passed by value, i.e., modifications of the corresponding local variable
of this type inside the called function will not be reflected in the calling function. Arrays of any type
and data of the structure type are always passed by reference. If it is necessary to prohibit modifying
the array or structure contents, the parameters of these types must be declared with the const
k eyword.
There is an opportunity to pass parameters of simple types by reference. In this case, modification of
such parameters inside the calling function will affect the corresponding variables passed by reference.
In order to indicate that a parameter is passed by reference, put the & modifier after the data type.
Example:
z[i]=OrderOpenPrice();
}
x=i;
y=calculated_tp;
}
See also
Input Variables, Data Types, Encapsulation and Extensibility of Types,Initialization of Variables,
Visibility Scope and Lifetime of Variables, Creating and Deleting Objects
Static Variables
The storage class of static defines a static variable. The static modifier is indicated before the data
type.
Example:
int somefunc()
{
static int flag=10;
...
return(flag);
}
A static variable can be initialized by a constant or constant expression corresponding to its type,
unlik e a simple local variable, which can be initialized by any expression.
Static variables exist from the moment of program execution and are initialized only once before the
specialized functions OnInit() is called. If the initial values are not specified, variables of the static
storage class are tak ing zero initial values.
Local variables declared with the static k eyword retain their values throughout the function lifetime.
W ith each next function call, such local variables contain the values that they had during the previous
call.
Any variables in a block , except formal parameters of a function, can be defined as static. If a
variable declared on a local level is not a static one, memory for such a variable is allocated
automatically at a program stack .
Example:
int Counter()
{
static int count;
count++;
if(count%100==0) Print("Function Counter has been called ",count," times");
return count;
}
void OnStart()
{
//---
int c=345;
for(int i=0;i<1000;i++)
{
int c=Counter();
}
Print("c =",c);
}
See also
Data Types, Encapsulation and Extensibility of Types, Initialization of Variables, Visibility Scope and
Lifetime of Variables, Creating and Deleting Objects, Static Class Members
Global Variables
Global variables are created by placing their declarations outside function descriptions. Global
variables are defined at the same level as functions, i.e., they are not local in any block .
Example:
The scope of global variables is the entire program. Global variables are accessible from all functions
defined in the program. They are initialized to zero unless another initial value is explicitly defined. A
global variable can be initialized only by a constant or constant expression that corresponds to its type.
Global variables are initialized only once after the program is loaded into the client terminal memory
and before the first handling of the Init event. For global variables representing class objects, during
their initialization the corresponding constructors are called. In scripts global variables are initialized
before handling the Start event.
Note: Variables declared at global level must not be mixed up with the client terminal global variables
that can be accessed using the GlobalVariable...() functions.
See also
Data Types, Encapsulation and Extensibility of Types,Initialization of Variables, Visibility Scope and
Lifetime of Variables, Creating and Deleting Objects
Input Variables
The input storage class defines the external variable. The input modifier is indicated before the data
type. A variable with the input modifier can't be changed inside mql5-programs, such variables can be
accessed for reading only. Values of input variables can be changed only by a user from the program
properties window. External variables are always reinitialized immediately before the OnInit() is
called.
Example:
Input variables determine the input parameters of a program. They are available from the Properties
window of a program.
There is another way to set how your input parameter will look lik e in the Inputs tab. For this, place a
string comment after the description of an input parameter in the same line. In this way you can mak e
names of input parameters more understandable for users.
Example:
Note: Arrays and variables of complex types can't act as input variables.
Note: The length of a string comment for Input variables cannot exceed 63 characters.
Custom Indicators are called using the iCustom() function. After the name of the custom indicator,
parameters should go in a strict accordance with the declaration of input variables of this custom
indicator. If indicated parameters are less than input variables declared in the called custom indicator,
the missing parameters are filled with values specified during the declaration of variables.
If the custom indicator uses the OnCalculate function of the first type (i.e., the indicator is calculated
using the same array of data), then one of ENUM _APPLI ED_PR ICE values or handle of another indicator
should be used as the last parameter when calling such a custom indicator. All parameters
corresponding to input variables must be clearly indicated.
Not only built-in enumerations provided in MQL5, but also user defined variables can be used as input
variables (input parameters for mql5 programs). For example, we can create the dayOfW eek
enumeration, describing days of the week , and use the input variable to specify a particular day of the
week , not as a number, but in a more common way.
Example:
#property script_show_inputs
//--- day of week
enum dayOfWeek
{
S=0, // Sunday
M=1, // Monday
T=2, // Tuesday
W=3, // Wednesday
Th=4, // Thursday
Fr=5, // Friday,
St=6, // Saturday
};
//--- input parameters
input dayOfWeek swapday=W;
In order to enable a user to select a necessary value from the properties window during the script
startup, we use the preprocessor command #property script_show_inputs. W e start the script and can
choose one of values of the dayOfW eek enumeration from the list. W e start the EnumInInput script
and go to the Inputs tab. By default, the value of swapday (day of triple swap charge) is W ednesday (W
= 3), but we can specify any other value, and use this value to change the program operation.
Number of possible values of an enumeration is limited. In order to select an input value the drop-
down list is used. Mnemonic names of enumeration members are used for values displayed in the list.
If a comment is associated with a mnemonic name, as shown in this example, the comment content is
used instead of the mnemonic name.
Each value of the dayOfW eek enumeration has its value from 0 to 6, but in the list of parameters,
comments specified for each value will be shown. This provides additional flexibility for writing
programs with clear descriptions of input parameters.
Sometimes, it is necessary to exclude some external program parameters from the area of all passes
in the tester. sinput memory modifier has been introduced for such cases. sinput stands for static
external variable declaration (sinput = static input). It means that the following declaration in an
Expert Advisor code
The variable declared with sinput modifier is an input parameter of MQL5 program. The value of this
parameter can be changed when launching the program. H owever, this variable is not used in the
optimization of input parameters. In other words, its values are not enumerated when searching for
the best set of parameters fitting a specified condition.
The Expert Advisor shown above has 5 external parameters. "Number of layers " is declared to be
sinput and equal to 6. This parameter cannot be changed during a trading strategy optimization. W e
can specify the necessary value for it to be used further on. Start, Step and Stop fields are not
available for such a variable.
Therefore, users will not be able to optimize this parameter after we specify sinput modifier for the
variable. In other words, the terminal users will not be able to set initial and final values for it in the
Strategy Tester for automatic enumeration in the specified range during optimization.
H owever, there is one exception to this rule: sinput variables can be varied in optimization tas k s
using ParameterSetR ange() function. This function has been introduced specifically for the program
control of available values sets for any input variable including the ones declared as static input
(sinput). The ParameterGetR ange() function allows to receive input variables values when
optimization is launched (in OnTesterInit() handler) and to reset a change step value and a range,
within which an optimized parameter values will be enumerated.
In this way, combining the sinput modifier and two functions that work with input parameters, allows
to create a flexible rules for setting optimization intervals of input parameters that depend on values
of another input parameters.
See also
iCustom, Enumerations, Properties of Programs
Extern Variables
The extern k eyword is used for declaring variable identifiers as identifiers of the static storage class
with global lifetime. These variables exist from the start of the program and memory for them is
allocated and initialized immediately after the start of the program.
You can create programs that consist of multiple source files ; in this case a directive to the
preprocessor #include is used. Variables declared as an extern with the same type and identifier can
exist in different source files of one project.
W hen compiling the whole project, all the extern variables with the same type and an identifier are
associated with one part of memory of the global variable pool. Extern variables are useful for
separate compilation of source files. Extern variables can be initialized, but only once - existence of
several initialized extern variables of the same type and with the same identifier is prohibited.
See also
Data Types, Encapsulation and Extensibility of Types,Initialization of Variables, Visibility Scope and
Lifetime of Variables, Creating and Deleting Objects
Initialization of Variables
Any variable can be initialized during definition. If a variable is not initialized explicitly, the value
stored in this variable can be any. Implicit initialization is not used.
Global and static variables can be initialized only by a constant of the corresponding type or a constant
expression. Local variables can be initialized by any expression, not just a constant.
Initialization of global and static variables is performed only once. Initialization of local variables is
made every time you call the corresponding functions.
Examples:
int n = 1;
string s = "hello";
double f[] = { 0.0, 0.236, 0.382, 0.5, 0.618, 1.0 };
int a[4][4] = { {1, 1, 1, 1}, {2, 2, 2, 2}, {3, 3, 3, 3}, {4, 4, 4, 4 } };
//--- from tetris
int right[4]={WIDTH_IN_PIXELS+VERT_BORDER,WIDTH_IN_PIXELS+VERT_BORDER,
WIDTH_IN_PIXELS+VERT_BORDER,WIDTH_IN_PIXELS+VERT_BORDER};
//--- initialization of all fields of the structure with zero values
MqlTradeRequest request={0};
List of values of the array elements must be enclosed in curly brack ets. Missed initializing sequences
are considered equal to 0. The initializing sequence must have at least one value: this value is
initialized to the first element of the corresponding structure or array, missing elements are
considered equal to zero.
If the size of the initialized array is not specified, it is determined by a compiler, based on the size of
the initialization sequence. Multi-dimensional arrays cannot be initialized by a one-dimensional
sequence (a sequence without additional curly brack ets), except for the case, when only one
initializing element is specified (zero, as a rule).
Arrays (including those announced at the local level) can be initialized only by constants.
Examples:
struct str3
{
int low_part;
int high_part;
};
struct str10
{
str3 s3;
double d1[10];
int i3;
};
void OnStart()
{
str10 s10_1={{1,0},{1.0,2.1,3.2,4.4,5.3,6.1,7.8,8.7,9.2,10.0},100};
str10 s10_2={{1,0},{0},100};
str10 s10_3={{1,0},{1.0}};
//---
Print("1. s10_1.d1[5] = ",s10_1.d1[5]);
Print("2. s10_2.d1[5] = ",s10_2.d1[5]);
Print("3. s10_3.d1[5] = ",s10_3.d1[5]);
Print("4. s10_3.d1[0] = ",s10_3.d1[0]);
}
For structure type variable partial initialization is allowed, as well as for static arrays (with an
implicitly set size). You can initialize one or more first elements of a structure or array, the other
elements will be initialized with zeroes in this case.
See also
Data Types, Encapsulation and Extensibility of Types, Visibility Scope and Lifetime of Variables,
Creating and Deleting Objects
A variable declared outside all functions is located into the global scope. Access to such variables can
be done from anywhere in the program.These variables are located in the global pool of memory, so
their lifetime coincides with the lifetime of the program.
A variable declared inside a block (part of code enclosed in curly brack ets) belongs to the local scope.
Such a variable is not visible (and therefore not available) outside the block , in which it is declared.
The most common case of local declaration is a variable declared within a function. A variable declared
locally, is located on the stack , and the lifetime of such a variable is equal to the lifetime of the
function.
Since the scope of a local variable is the block in which it is declared, it is possible to declare variables
with the same name, as those of variables declared in other block s ; as well as of those declared at
upper levels, up to the global level.
Example:
for(i=limit;i<rates_total;i++)
{
sum=0;
Its scope is only the for loop; outside of this loop there is another variable with the same name,
declared at the beginning of the function. In addition, the k variable is declared in the loop body, its
scope is the loop body.
Local variables can be declared with the access specifier static. In this case, the compiler has a
variable in the global pool of memory. Therefore, the lifetime of a static variable is equal to the
lifetime of the program. H ere the scope of such a variable is limited to the block in which it is
declared.
See also
Data Types, Encapsulation and Extensibility of Types,Initialization of Variables, Creating and
Deleting Objects
Despite the fact that static variables are usually declared at a local level, the memory for these
variables is pre-allocated, and initialization is performed right after a program is loaded, the same as
for global variables.
The initialization order corresponds to the variable declaration order in the program. Deinitialization is
performed in the reverse order. This rule is true only for the variables that were not created by the
new operator. Such variables are created and initialized automatically right after loading, and are
deinitialized before the program unloading.
Local variables are deinitialized at the end of the program block , in which they were declared, and in
the order opposite to their declaration. A program block is a compound operator that can be a part of
selection operator switch, loop operator (for, while, do-while), a function body or a part of the if-else
operator.
Local variables are initialized only at the moment when the program execution meets the variable
declaration. If during the program execution the block , in which the variable is declared, was not
executed, such a variable is not initialized.
Pointers can be declared on a local or global level; and they can be initialized by the empty value of
NULL or by the value of the pointer of the same or inherited type. If the new operator is called for a
pointer declared on a local level, the delete operator for this pointer must be performed before exiting
the level. Otherwise the pointer will be lost and the explicit deletion of the object will fail.
All objects created by the expression ofobject_pointer=new Class_name, must be then deleted by the
delete(object_pointer) operator. If for some reasons such a variable is not deleted by the delete
operator when the program is completed, the corresponding entry will appear in the "Experts " journal.
One can declare several variables and assign a pointer of one object to all of them.
If a dynamically created object has a constructor, this constructor will be called at the moment of the
new operator execution. If an object has a destructor, it will be called during the execution of the
delete operator.
Thus dynamically placed objects are created only at the moment when the corresponding new operator
is invok ed, and are assuredly deleted either by the delete operator or automatically by the executing
system of MQL5 during the program unloading. The order of declaration of pointers of dynamically
created object doesn't influence the order of their initialization. The order of initialization and
deinitialization is fully controlled by the programmer.
W hen work ing with dynamic class objects using the new operator, first memory is requested from the
class memory pool the memory manager is work ing with. If there is not enough memory in the pool,
memory is requested from the operating system. W hen deleting the dynamic object using the delete
operator, released memory is immediately returned back to the class memory pool.
Memory manager releases memory back to the operating system immediately after exiting the
following event handling functions : OnInit(), OnDeinit(), OnStart(), OnTick (), OnCalculate(),
OnTimer(), OnTrade(), OnTester(), OnTesterInit(), OnTesterPass(), OnTesterDeinit(),
OnChartEvent(), OnBookEvent().
Initialization right after a mql5 when the code line at the execution of
program is loaded where it is declared is the new operator
reached during
execution
Deinitialization before a mql5 program when execution exits when the delete
is unloaded the declaration block operator is executed
or before a mql5
program is unloaded
Destructor call at mql5 program when exiting the block at the execution of
unloading where the variable the delete operator
was initialized
Error logs log message in the log message in the log message in the
"Experts " journal "Experts " journal "Experts " journal
about the attempt to about the attempt to about undeleted
delete an delete an dynamically created
automatically created automatically created objects at the unload
object object of a mql5 program
See also
Data Types, Encapsulation and Extensibility of Types,Initialization of Variables, Visibility Scope and
Lifetime of Variables
Preprocessor
Preprocessor is a special subsystem of the MQL5 compiler that is intended for preparation of the
program source code immediately before the program is compiled.
Preprocessor allows enhancement of the source code readability. The code can be structured by
including of specific files containing source codes of mql5-programs. The possibility to assign
mnemonic names to specific constants contributes to enhancement of the code readability.
· Declare constants
· Import functions
· Conditional Compilation
The preprocessor directives are used by the compiler to preprocess the source code before compiling
it. The directive always begins with #, therefore the compiler prohibits using the symbol in names of
variables, functions etc.
Each directive is described by a separate entry and is valid until the line break . You cannot use several
directives in one entry. If the directive entry is too big, it can be brok en into several lines using the '\'
symbol. In this case, the next line is considered a continuation of the directive entry.
//+------------------------------------------------------------------+
//| foreach pseudo-operator |
//+------------------------------------------------------------------+
#define ForEach(index, array) for (int index = 0, \
max_##index=ArraySize((array)); \
index<max_##index; index++)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string array[]={"12","23","34","45"};
//--- bypass the array using ForEach
ForEach(i,array)
{
PrintFormat("%d: array[%d]=%s",i,i,array[i]);
}
}
//+------------------------------------------------------------------+
/* Output result
0: array[0]=12
1: array[1]=23
2: array[2]=34
3: array[3]=45
*/
For the compiler, all these three #define directive lines look lik e a single long line. The example above
also applies ## character which is a merge operator used in the #define macros to merge the two
macro tok ens into one. The tok ens merge operator cannot be the first or last one in a macro
definition.
Each directive is described by a separate entry and is valid until the line break . You cannot use several
directives in one entry. If the directive entry is too big, it can be brok en into several lines using the '\'
symbol. In this case, the next line is considered a continuation of the directive entry.
The #define directive can be used to assign mnemonic names to constants. There are two forms :
The #define directive substitutes expression for all further found entries of identifier in the source
text. The identifier is replaced only if it is a separate tok en. The identifier is not replaced if it is part
of a comment, part of a string, or part of another longer identifier.
The constant identifier is governed by the same rules as variable names. The value can be of any type:
expression can consist of several tok ens, such as k eywords, constants, constant and non-constant
expressions. expression ends with the end of the line and can't be transferred to the next line.
Example:
#define TWO 2
#define THREE 3
#define INCOMPLETE TWO+THREE
#define COMPLETE (TWO+THREE)
void OnStart()
{
Print("2 + 3*2 = ",INCOMPLETE*2);
Print("(2 + 3)*2 = ",COMPLETE*2);
}
// Result
// 2 + 3*2 = 8
// (2 + 3)*2 = 10
W ith the parametric form, all the subsequent found entries of identifier will be replaced by expression
tak ing into account the actual parameters. For example:
double c=MUL(A,B);
Print("c=",c);
/*
expression double c=MUL(A,B);
is equivalent to double c=((2+3)*(5-1));
*/
// Result
// c=20
Be sure to enclose parameters in parentheses when using the parameters in expression, as this will
help avoid non-obvious errors that are hard to find. If we rewrite the code without using the brack ets,
the result will be different:
double c=MUL(A,B);
Print("c=",c);
/*
expression double c=MUL(A,B);
is equivalent to double c=2+3*5-1;
*/
// Result
// c=16
The #undef directive cancels declaration of the macro substitution, defined before.
Example:
#define MACRO
void func1()
{
#ifdef MACRO
Print("MACRO is defined in ",__FUNCTION__);
#else
Print("MACRO is not defined in ",__FUNCTION__);
#endif
}
#undef MACRO
void func2()
{
#ifdef MACRO
Print("MACRO is defined in ",__FUNCTION__);
#else
Print("MACRO is not defined in ",__FUNCTION__);
#endif
}
void OnStart()
{
func1();
func2();
}
/* Result:
MACRO is defined in func1
MACRO is not defined in func2
*/
See also
Identifiers, Character Constants
The compiler will write declared values in the configuration of the module executed.
By specifying the
tester_everytick_calculate
Examples of Specifying a Separate Label for Each Indicator Buffer ( " C open; C high; C low; C
close" )
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 1
#property indicator_type1 DRAW_CANDLES
#property indicator_width1 3
#property indicator_label1 "C open;C high;C low;C close"
#include <file_name>
#include "file_name"
Examples:
#include <WinUser32.mqh>
#include "mylib.mqh"
The preprocessor replaces the line #include <file_name> with the content of the file W inUser32.mqh.
Angle brack ets indicate that the W inUser32.mqh file will be tak en from the standard directory (usually
it is terminal_installation_directory\MQL5\Include). The current directory is not included in the
search.
If the file name is enclosed in quotation mark s, the search is made in the current directory (which
contains the main source file). The standard directory is not included in the search.
See also
Standard Library, Importing Functions
#import "file_name"
func1 define;
func2 define;
...
funcN define;
#import
Imported functions can have any names. Functions having the same names but from different modules
can be imported at the same time. Imported functions can have names that coincide with the names
of built-in functions. Operation of scope resolution defines which of the functions should be called.
The order of searching for a file specified after the #import k eyword is described in Call of Imported
Functions.
Since the imported functions are outside the compiled module, the compiler can not verify the validity
of passed parameters. Therefore, to avoid run-time errors, one must accurately describe the
composition and order of parameters passed to imported functions. Parameters passed to imported
functions (both from EX5, and from the DLL-module) can have default values.
· pointers (*);
Classes, string arrays or complex objects that contain strings and/or dynamic arrays of any types
cannot be passed as a parameter to functions imported from DLL.
Examples:
#import "stdlib.ex5"
string ErrorDescription(int error_code);
int RGB(int red_value,int green_value,int blue_value);
bool CompareDoubles(double number1,double number2);
string DoubleToStrMorePrecision(double number,int precision);
string IntegerToHexString(int integer_number);
#import "ExpertSample.dll"
int GetIntValue(int);
double GetDoubleValue(double);
string GetStringValue(string);
double GetArrayItemValue(double &arr[],int,int);
bool SetArrayItemValue(double &arr[],int,int,double);
double GetRatesItemValue(double &rates[][6],int,int,int);
#import
To import functions during execution of a mql5 program, early binding is used. This means that the
library is loaded during the loading of a program using its ex5 program.
It's not recommended to use a fully qualified name of the loadable module of type Drive:
\Directory\FileName.Ext. MQL5 libraries are loaded from the terminal_dir\MQL5\Libraries folder.
If the imported function has different call versions for 32- and 64-bit W indows versions, both of them
should be imported, and the right function version should be called explicitly using the _Is X64
variable.
Example:
#import "user32.dll"
//--- For the 32-bit system
int MessageBoxW(uint hWnd,string lpText,string lpCaption,uint uType);
//--- For the 64-bit system
int MessageBoxW(ulong hWnd,string lpText,string lpCaption,uint uType);
#import
//+------------------------------------------------------------------+
//| MessageBox_32_64_bit uses the proper version of MessageBoxW() |
//+------------------------------------------------------------------+
int MessageBox_32_64_bit()
{
int res=-1;
//--- If we are using the 64-bit Windows
if(_IsX64)
{
ulong hwnd=0;
res=MessageBoxW(hwnd,"64-bit MessageBoxW call example","MessageBoxW 64 bit",MB_OK|MB_ICONINFO
}
else // We are using the 32-bit Windows
{
uint hwnd=0;
res=MessageBoxW(hwnd,"32-bit MessageBoxW call example","MessageBoxW 32 bit",MB_OK|MB_ICONINFO
}
return (res);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int ans=MessageBox_32_64_bit();
PrintFormat("MessageBox_32_64_bit returned %d",ans);
}
See also
Including Files
Each directive is described by a separate entry and is valid until the line break . You cannot use several
directives in one entry. If the directive entry is too big, it can be brok en into several lines using the '\'
symbol. In this case, the next line is considered a continuation of the directive entry.
Preprocessor conditional compilation directives allow compiling or s k ipping a part of the program
depending on the fulfillment of a certain condition.
#ifdef identifier
// the code located here is compiled if the identifier has already been defined for the preproce
#endif
#ifndef identifier
// the code located here is compiled if the identifier is not currently defined by #define prepr
#endif
Any of the conditional compilation directives can be followed by any number of lines possibly
containing #else directive and ending with #endif. If the verified condition is true, the lines between
#else and #endif are ignored. If the verified condition is not fulfilled, all lines between check ing and
#else directive (or #endif directive if the former is absent) are ignored.
Example:
#ifndef TestMode
#define TestMode
#endif
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
#ifdef TestMode
Print("Test mode");
#else
Print("Normal mode");
#endif
}
Depending on the program type and compilation mode, the standard macros are defined the following
way:
__MQL5__ macro is defined when compiling *.mq5 file, __MQL 4__ macro is defined when compiling
*.mq4 one.
_DEBUG macro is defined when compiling in debug mode.
_REL EAS E macro is defined when compiling in release mode.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
#ifdef __MQL5__
#ifdef _DEBUG
Print("Hello from MQL5 compiler [DEBUG]");
#else
#ifdef _RELEASE
Print("Hello from MQL5 compiler [RELEASE]");
#endif
#endif
#else
#ifdef __MQL4__
#ifdef _DEBUG
Print("Hello from MQL4 compiler [DEBUG]");
#else
#ifdef _RELEASE
Print("Hello from MQL4 compiler [RELEASE]");
#endif
#endif
#endif
#endif
}
Object-Oriented Programming
Object-oriented programming (OOP) is programming primarily focused on data, while data and
behavior are being inseparably link ed. Data and behavior together constitute a class, while objects are
class instances.
· Inheritance
· Polymorphism
· Overloading
· Virtual functions
OOP considers computation as modeling of behavior. The modeled item is the object represented by
computational abstractions. Suppose we want to write a well k nown game " Tetris " . To do this, we
must learn how to model the appearance of random shapes composed of four s quares joined together
by edges. Also we need to regulate the falling speed of shapes, define operations of rotation and shift
of shapes. Moving of shapes on the screen is limited by the well's boundaries, this requirement must
also be modeled. Besides that, filled rows of cubes must be destroyed and achieved points must be
counted.
Thus, this easy-to-understand game requires the creation of several models - shape model, well
model, shape movement model and so on. All these models are abstractions, represented by
calculations in the computer. To describe these models, the concept of Abstract Data Type, ADT (or
complex data type) is used. Strictly speak ing, the model of the " shapes " motion in the DOM is not a
data type, but it is a set of operations on the " shape" data type, using the restrictions of the " well"
data type.
Objects are class variables. Object-oriented programming allows you to easily create and use ADT.
Object-oriented programming uses the inheritance mechanism. The benefit of inheritance is in the
fact that it allows obtaining derivative types from data types already defined by a user.
For example, to create Tetris shapes, it's convenient to create a base class Shape first. The other
classes representing all seven possible shape types can be derived on its basis. Behavior of shapes is
defined in the base class, while implementation of behavior of each separate shape is defined in
derivative classes.
In OOP objects are responsible for their behavior. ADT developer should include a code to describe any
behavior that would normally be expected from the corresponding objects. The fact that the object
itself is responsible for its behavior, greatly simplifies the tas k of programming for the user of this
object.
If we want to draw a shape on the screen, we need to k now where the center will be and how to draw
it. If a separate shape k nows how to draw itself, the programmer should send a " draw" message when
using such a shape.
The MQL5 Language is a C++ lik e, and it also has the encapsulation mechanism for the implementation
of ADT. On the one hand encapsulation combines the internal details of the implementation of a
particular type, and on the other hand it combines externally accessible functions that can influence
objects of this type. Implementation details may be inaccessible for a program that uses this type.
The concept of OOP has a set of related concepts, including the following :
Some of these concepts are rather vague, some are abstract, others are general.
An abstract data type, for example, a string, is a description of the ideal, well k nown behavior type.
The string user k nows that the string operations, such as concatenation or print, have a certain
behavior. Concatenation and print operations are called methods.
A certain implementation of ADT may have some restrictions, for example, strings can be limited in
length. These limitations affect the behavior opened to all. At the same time, internal or private
implementation details do not affect directly the way the user sees the object. For example, the string
is often implemented as an array, while the internal base address of this array and its name are not
essential for the user.
Encapsulation is the ability to hide the implementation details when the open interfaces to user-
defined type is provided. In MQL5, as well as in C++, class and structure definitions (class and struct)
are used for the encapsulation provisions in combination with access k eywords private, protected and
public.
The public k eyword shows that access to the members that stand behind it is open without
restrictions. W ithout this k eyword, class members are lock ed by default. Private members are
accessible only by member functions only of its class.
Protected class functions are available to class functions not only in its class, but also in its inheritor
classes. Public class functions are available for any function within the scope of the class declaration.
The protection mak es possible to hide part of the class implementation, thus preventing unexpected
changes in the structure of data. Access restriction or data hiding is a feature of the object-oriented
programming.
Usually, class functions are protected and declared with the protected modifier, the reading and
writing of the values are performed by using special so-called set-and get-methods that are defined by
the public access modifier.
Example:
class CPerson
{
protected:
string m_name; // name
public:
void SetName(string n){m_name=n;}// sets name
string GetName(){return (m_name);} // returns name
};
This approach offers several advantages. First, by function name we can understand what it does -
sets or gets the value of a class member. Secondly, perhaps in the future we will need to change the
type of the m_name variable in the CPerson class or in any of its derivative classes.
In this case, we'll need just to change the implementation of functions SetName() and GetName(),
while objects of the CPerson class will be available for using in a program without any code changes
because the user will not even k now that the data type of m_name has changed.
Example:
struct Name
{
string first_name; // name
string last_name; // last name
};
class CPerson
{
protected:
Name m_name; // name
public:
void SetName(string n);
string GetName(){return(m_name.first_name+" "+m_name.last_name);}
private:
string GetFirstName(string full_name);
string GetLastName(string full_name);
};
void CPerson::SetName(string n)
{
m_name.first_name=GetFirstName(n);
m_name.last_name=GetLastName(n);
}
See also
Data Types
Inheritance
The characteristic feature of OOP is the encouragement of code reuse through inheritance. A new
class is made from the existing, which is called the base class. The derived class uses the members of
the base class, but can also modify and supplement them.
Many types are variations of the existing types. It is often tedious to develop a new code for each of
them. In addition, the new code implies new errors. The derived class inherits the description of the
base class, thus any re-development and re-testing of code is unnecessary. The inheritance
relationships are hierarchical.
H ierarchy is a method that allows to copy the elements in all their diversity and complexity. It
introduces the objects classification. For example, the periodic table of elements has gases. They
possess to properties inherent to all periodic elements.
Inert gases constitute the next important subclass. The hierarchy is that the inert gas, such as argon
is a gas, and gas, in its turn, is part of the system. Such a hierarchy allows to interpret behaviour of
inert gases easily. W e k now that their atoms contain protons and electrons, that is true for all other
elements.
W e k now that they are in a gaseous state at room temperature, lik e all the gases. W e k now that no
gas from inert gas subclass enters usual chemical reaction with other elements, and it is a property of
all inert gases.
Consider an example of the inheritance of geometric shapes. To describe the whole variety of simple
shapes (circle, triangle, rectangle, s quare etc.), the best way is to create a base class (ADT), which is
the ancestor of all the derived classes.
Let's create a base class CShape, which contains just the most common members describing the
shape. These members describe properties that are characteristic of any shape - the type of the shape
and main anchor point coordinates.
Example:
Next, create new classes derived from the base class, in which we will add necessary fields, each
specifying a certain class. For the Circle shape it is necessary to add a member that contains the
radius value. The S quare shape is characterized by the side value. Therefore, derived classes,
inherited from the base class CShape will be declared as follows :
public:
CCircle(){m_type=1;}// constructor, type 1
};
public:
CSquare(){m_type=2;} // constructor, type 2
};
It should be noted that while object is created the base class constructor is called first, and then the
constructor of the derived class is called. W hen an object is destroyed first the destructor of the
derived class is called, and then a base class destructor is called.
Thus, by declaring the most general members in the base class, we can add an additional members in
derived classes, which specify a particular class. Inheritance allows creating powerful code libraries
that can be reused many times.
The syntax for creating a derived class from an already existing one is as follows :
class class_name :
(public | protected | private) opt base_class_name
{
class members declaration
};
One of aspects of the derived class is the visibility (openness) of its members successors (heirs). The
public, protected and private k eywords are used to indicate the extent, to which members of the base
class will be available for the derived one. The public k eyword after a colon in the header of a derived
class indicates that the protected and public members of the base class CShape should be inherited as
protected and public members of the derived class CCircle.
The private class members of the base class are not available for the derived class. The public
inheritance also means that derived classes (CCircle and CS quare) are CShapes. That is, the S quare
(CS quare) is a shape (CShape), but the shape does not necessarily have to be a s quare.
The derived class is a modification of the base class, it inherits the protected and public members of
the base class. The constructors and destructors of the base class cannot be inherited. In addition to
members of the base class, new members are added in a derivative class.
The derived class may include the implementation of member functions, different from the base class.
It has nothing common with an overload, when the meaning of the same function name may be
different for different signatures.
In protected inheritance, public and protected members of base class become protected members of
derived class. In private inheritance, the public and protected members of base class become private
members of the derived class.
In protected and private inheritance, the relation that " the object of a derivative class is object of a
base class " is not true. The protected and private inheritance types are rare, and each of them needs
to be used carefully.
It should be understood that the type of inheritance (public, protected or private) does not affect the
ways of accessing the members of base classes in the hierarchy of inheritance from a derived
class. W ith any type of inheritance, only base class members declared with public and protected access
specifiers will be available out of the derived classes. Let's consider it in the following example:
};
//+------------------------------------------------------------------+
//| Derived class with errors |
//+------------------------------------------------------------------+
class CDerived: public CBaseClass // specification of public inheritance can be omitted, since it i
{
public:
void Func() // In the derived class, define a function with calls to base class members
{
//--- An attempt to modify a private member of the base class
m_member=0; // Error, the private member of the base class is not available
Member(0); // Error, the private method of the base class is not available in derived
In the above example, CBaseClass has only a public method – the constructor. Constructors are called
automatically when creating a class object. Therefore, the private member m_member and the
protected methods Member() cannot be called from the outside. But in case of public inheritance, the
Member() method of the base class will be available from the derived classes.
In case of protected inheritance, all the members of the base class with public and protected access
become protected. It means that if public data members and methods of the base class were
accessible from the outside, with protected inheritance they are available only from the classes of the
derived class and its further derivatives.
//+------------------------------------------------------------------+
//| Example class with a few access types |
//+------------------------------------------------------------------+
class CBaseMathClass
{
private: //--- The private member is not available from derived classes
double m_Pi;
public: //--- Getting and setting a value for m_Pi
void SetPI(double v){m_Pi=v;return;};
double GetPI(){return m_Pi;};
public: // The class constructor is available to all members
CBaseMathClass() {SetPI(3.14); PrintFormat("%s",__FUNCTION__);};
};
//+------------------------------------------------------------------+
//| Derived class, in which m_Pi cannot be modified |
//+------------------------------------------------------------------+
class CProtectedChildClass: protected CBaseMathClass // Protected inheritance
{
private:
double m_radius;
public: //--- Public methods in the derived class
void SetRadius(double r){m_radius=r; return;};
double GetCircleLength(){return GetPI()*m_radius;};
};
//+------------------------------------------------------------------+
//| Script starting function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- When creating a derived class, the constructor of the base class will be called automatically
CProtectedChildClass pt;
//--- Specify radius
pt.SetRadius(10);
PrintFormat("Length=%G",pt.GetCircleLength());
//--- If we uncomment the line below, we will get an error at the stage of compilation, since SetPI
// pt.SetPI(3);
//--- Now declare a variable of the base class and try to set the Pi constant equal to 10
CBaseMathClass bc;
bc.SetPI(10);
//--- Here is the result
PrintFormat("bc.GetPI()=%G",bc.GetPI());
}
The example shows that methods SetPI() and GetPi() in the base class CBaseMathClass are open and
available for calling from any place of the program. But at the same time, for CProtectedChildClass
which is derived from it these methods can be called only from the methods of the
CProtectedChildClass class or its derived classes.
In case of private inheritance, all the members of the basic class with the public and protected access
become private, and calling them becomes impossible in further inheritance.
See also
Structures and Classes
Polymorphism
Polymorphism is an opportunity for different classes of objects, related through inheritance, to
respond in various ways when calling the same function element. It helps to create a universal
mechanism describing the behavior of not only the base class, but also descendant classes.
Let's continue to develop a base class CShape, and define a member function GetArea(), designed to
calculate the area of a shape. In all the descendant classes, produced by inheritance from the base
class, we redefine this function in accordance with rules of calculating the area of a particular shape.
For a s quare (class CS quare), the area is calculated through its sides, for a circle (class CCircle), area
is expressed through its radius etc. W e can create an array to store objects of CShape type, in which
both objects of a base class and those of all descendant classes can be stored. Further we can call the
same function for each element of the array.
Example:
Now, all of the derived classes have a member function getArea(), which returns a zero value. The
implementation of this function in each descendant will vary.
public:
void CCircle(){m_type=1;}; // constructor, type=1
void SetRadius(double r){m_radius=r;};
virtual double GetArea(){return (3.14*m_radius*m_radius);}// circle area
};
private:
double m_square_side; // square side
public:
void CSquare(){m_type=2;}; // constructor, type=1
void SetSide(double s){m_square_side=s;};
virtual double GetArea(){return (m_square_side*m_square_side);}// square area
};
For calculating the area of the s quare and circle, we need the corresponding values of m_radius and
m_s quare_side, so we have added the functions SetR adius() and SetSide() in the declaration of the
corresponding class.
It is assumed that object of different types (CCircle and CS quare) derived from one base type CShape
are used in our program. Polymorphism allows creating an array of objects of the base CShape class,
but when declaring this array, these objects are yet unk nown and their type is undefined.
The decision on what type of object will be contained in each element of the array will be tak en
directly during program execution. This involves the dynamic creation of objects of the appropriate
classes, and hence the necessity to use object pointers instead of objects.
The new operator is used for dynamic creation of objects. Each such object must be individually and
explicitly deleted using the delete operator. Therefore we will declare an array of pointers of CShape
type, and create an object of a proper type for each element (new Class_Name), as shown in the
following script example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Declare an array of object pointers of the base type
CShape *shapes[5]; // An array of pointers to CShape object
//--- Create another CCircle object and write down its pointer in shapes[1]
circle=new CCircle();
shapes[1]=circle;
circle.SetRadius(5);
//--- Create a CSquare object and write down its pointer to shapes[3]
CSquare *square=new CSquare();
square.SetSide(5);
shapes[3]=square;
//--- Create a CSquare object and write down its pointer to shapes[4]
square=new CSquare();
square.SetSide(10);
shapes[4]=square;
Please note that when deleting an object using the delete operator, the type of its pointer must be
check ed. Only objects with the POI NT ER_DYNAMIC pointer can be deleted using delete. For pointers of
other type, an error will be returned.
But besides the redefining of functions during inheritance, polymorphism also includes the
implementation of one and the same functions with different sets of parameters within a class. This
means that the class may have several functions with the same name but with a different type and/or
set of parameters. In this case, polymorphism is implemented through the function overload.
See also
Standard Library
Overload
W ithin one class it is possible to define two or more methods that use the same name, but have
different numbers of parameters. W hen this occurs, methods are called overloaded and such a process
is referred to as method overloading.
If the called function has no exact match, the compiler searches for a suitable function on three levels
sequentially:
If there is no exact correspondence at all levels, but several suitable functions at different levels have
been found, the function found at the least level is used. W ithin one level, there can't be more than
one suitable function.
See also
Function Overloading
Virtual Functions
The virtual k eyword is the function specifier, which provides a mechanism to select dynamically at
runtime an appropriate function-member among the functions of basic and derived classes. Structures
cannot have virtual functions. It can be used to change the declarations for function-members only.
The virtual function, lik e an ordinary function, must have an executable body. W hen called, its
semantic is the same as that of other functions.
A virtual function may be overridden in a derived class. The choice of what function definition should
be called for a virtual function is made dynamically (at runtime). A typical case is when a base class
contains a virtual function, and derived classes have their own versions of this function.
The pointer to the base class can indicate either a base class object or the object of a derived class.
The choice of the member-function to call will be performed at runtime and will depend on the type of
the object, not the type of the pointer. If there is no member of a derived type, the virtual function of
the base class is used by default.
Destructors are always virtual, regardless of whether they are declared with the virtual k eyword or not.
Let's consider the use of virtual functions on the example of MT5_Tetris.mq5. The base class
CTetrisShape with the virtual function Draw is defined in the included file MT5_TetrisShape.mqh.
//+------------------------------------------------------------------+
class CTetrisShape
{
protected:
int m_type;
int m_xpos;
int m_ypos;
int m_xsize;
int m_ysize;
int m_prev_turn;
int m_turn;
int m_right_border;
public:
void CTetrisShape();
void SetRightBorder(int border) { m_right_border=border; }
void SetYPos(int ypos) { m_ypos=ypos; }
void SetXPos(int xpos) { m_xpos=xpos; }
int GetYPos() { return(m_ypos); }
int GetXPos() { return(m_xpos); }
int GetYSize() { return(m_ysize); }
int GetXSize() { return(m_xsize); }
int GetType() { return(m_type); }
void Left() { m_xpos-=SHAPE_SIZE; }
void Right() { m_xpos+=SHAPE_SIZE; }
void Rotate() { m_prev_turn=m_turn; if(++m_turn>3) m_turn=0; }
virtual void Draw() { return; }
virtual bool CheckDown(int& pad_array[]);
virtual bool CheckLeft(int& side_row[]);
Further, for each derived class, this function is implemented in accordance with characteristics of a
descendant class. For example, the first shape CTetrisShape1 has its own implementation of the
Draw() function:
The S quare shape is described by class CTetrisShape6 and has its own implementation of the Draw()
method:
//---
for(i=0; i<2; i++)
{
name=SHAPE_NAME+(string)i;
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,m_xpos+i*SHAPE_SIZE);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,m_ypos);
}
for(i=2; i<4; i++)
{
name=SHAPE_NAME+(string)i;
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,m_xpos+(i-2)*SHAPE_SIZE);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,m_ypos+SHAPE_SIZE);
}
}
};
Depending on the class, to which the created object belongs, it calls the virtual function of this or that
derived class.
void CTetrisField::NewShape()
{
//--- creating one of the 7 possible shapes randomly
int nshape=rand()%7;
switch(nshape)
{
case 0: m_shape=new CTetrisShape1; break;
case 1: m_shape=new CTetrisShape2; break;
case 2: m_shape=new CTetrisShape3; break;
case 3: m_shape=new CTetrisShape4; break;
case 4: m_shape=new CTetrisShape5; break;
case 5: m_shape=new CTetrisShape6; break;
case 6: m_shape=new CTetrisShape7; break;
}
//--- draw
m_shape.Draw();
//---
}
Modifier 'override'
The 'override' modifier means that the declared function must override the method of a parent class.
Use of this method allows you to avoid overriding errors, for example it allows you to avoid accidental
modification of the method signature. Suppose, the 'func' method is defined in the base class. The
method accepts an int variable as an argument:
class CFoo
{
void virtual func(int x) const { }
};
H owever, the argument type is mistak enly changed from int to short. In fact, this is not method
overriding, but it is method overloading. Acting in accordance with the overloaded function defining
algorithm, the compiler can in certain situations choose a method defined in the base class instead of
the overridden method.
In order to avoid such errors, you should explicitly add the 'override' modifier to the method you want
to override.
If the method signature is changed during overriding, the compiler will not be able to find a method
with the same signature in the parent class, and it will return a compilation error:
'CBar::func' method is declared with 'override' specifier but does not override any base class meth
Modifier 'final'
The 'final' modifier does the opposite — it prohibits method overriding in child classes. If a method
implementation is sufficient and fully complete, declare this method with the 'final' modifier so as to
mak e sure that it will not be modified later.
class CFoo
{
void virtual func(int x) final { }
};
If you try to override a method with the 'final' modifier as shown in the above example, the compiler
will return an error:
See also
Standard Library
The inability to declare static members of a class would have led to the need to declare these data on
the the global level of the program. It would break the relationship between the data and their class,
and is not consistent with the basic paradigm of the OOP - joining data and methods for handling them
in a class. The static member allows class data that are not specific to a particular instance to exist in
the class scope.
Since a static class member does not depend on the particular instance, the reference to it is as
follows :
class_name::variable
where class_name is the name of the class, and variable is the name of the class member.
As you see, to access the static member of a class, context resolution operator :: is used. W hen you
access a static member within class methods, the context operator is optional.
Static member of a class has to be explicitly initialized with desired value. For this it must be declared
and initialized in global scope. The sequence of static members initialization will correspond to the
sequence of their declaration in global scope.
For example, we have a class CParser used for parsing the text, and we need to count the total
number of processed words and characters. W e only need to declare the necessary class members as
static and initialize them at the global level. Then all instances of the class will use common counters
of words and characters.
//+------------------------------------------------------------------+
//| Class "Text analyzer" |
//+------------------------------------------------------------------+
class CParser
{
public:
static int s_words;
static int s_symbols;
//--- Constructor and destructor
CParser(void);
~CParser(void){};
};
...
//--- Initialization of static members of the Parser class at the global level
int CParser::s_words=0;
int CParser::s_symbols=0;
A static class member can be declared with the const k eyword. Such static constants must be
initialized at the global level with the const k eyword:
//+------------------------------------------------------------------+
//| Class "Stack" for storing processed data |
//+------------------------------------------------------------------+
class CStack
{
public:
CStack(void);
~CStack(void){};
...
private:
static const int s_max_length; // Maximum stack capacity
};
Pointer this
The k eyword this denotes an implicitly declared pointer to itself – to a specific instance of the class, in
the context of which the method is executed. It can be used only in non-static methods of the class.
Pointer this is an implicit non-static member of any class.
In static functions you can access only static members /methods of a class.
Static Methods
In MQL5 member functions of type static can be used. The static modifier must precede the return
type of a function in the declaration inside a class.
class CStack
{
public:
//--- Constructor and destructor
CStack(void){};
~CStack(void){};
//--- Maximum stack capacity
static int Capacity();
private:
int m_length; // The number of elements in the stack
static const int s_max_length; // Maximum stack capacity
};
//+------------------------------------------------------------------+
//| Returns the maximum number of elements to store in the stack |
//+------------------------------------------------------------------+
int CStack::Capacity(void)
{
return(s_max_length);
}
//--- Initialization of the static constant of the CStack class
const int CStack::s_max_length=1000;
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare CStack type variable
CStack stack;
//--- call the object's static method
Print("CStack.s_max_length=",stack.Capacity());
//--- it can also be called the following way, as the method is static and does not require the pre
Print("CStack.s_max_length=",CStack::Capacity());
}
A method with the const modifier is called constant and cannot modify implicit members of its class.
Declaration of constant functions of a class and constant parameters is called const-correctness
control. Through this control you can be sure that the compiler will ensure the consistency of values of
objects and will return an error during compilation if there is something wrong.
The const modifier is placed after the list of arguments inside a class declaration. Definition outside a
class should also include the const modifier:
//+------------------------------------------------------------------+
//| Class "Rectangle" |
//+------------------------------------------------------------------+
class CRectangle
{
private:
double m_width; // Width
double m_height; // Height
public:
//--- Constructors and destructor
CRectangle(void):m_width(0),m_height(0){};
CRectangle(const double w,const double h):m_width(w),m_height(h){};
~CRectangle(void){};
//--- Calculating the area
double Square(void) const;
static double Square(const double w,const double h);// { return(w*h); }
};
//+------------------------------------------------------------------+
//| Returns the area of the "Rectangle" object |
//+------------------------------------------------------------------+
double CRectangle::Square(void) const
{
return(Square(m_width,m_height));
}
//+------------------------------------------------------------------+
//| Returns the product of two variables |
//+------------------------------------------------------------------+
static double CRectangle::Square(const double w,const double h)
{
return(w*h);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Create a rectangle rect with the sides equal to 5 and 6
CRectangle rect(5,6);
//--- Find the rectangle area using a constant method
PrintFormat("rect.Square()=%.2f",rect.Square());
//--- Find the product of numbers using the static method of class CRectangle
PrintFormat("CRectangle::Square(2.0,1.5)=%f",CRectangle::Square(2.0,1.5));
}
An additional argument in favor of using the constancy control is the fact that in this case, the
compiler generates a special optimization, for example, places a constant object in read-only memory.
A static function cannot be determined with the const modifier, because this modifier ensures the
constancy of the instance members when calling this function. But, as mentioned above, the static
function cannot access non-static class members.
See also
Static Variables, Variables, R eferences. Modifier & and Keyword this
Function templates
Overloaded functions are commonly used to perform similar operations on various data types.
ArraySize() is a simple example of such function in MQL5. It returns size of any type of array. In fact,
this system function is overloaded and the entire implementation of such an overload is hidden from
MQL5 application developers :
int ArraySize(
void& array[] // checked array
);
It means that MQL5 language compiler inserts necessary implementation for each call of this function.
For example, that is how it can be done for integer type arrays :
int ArraySize(
int& array[] // array with int type elements
);
ArraySize() function can be displayed the following way for M qlR ates type array for work ing with
quotations in historical data format:
int ArraySize(
MqlRates& array[] // array filled with MqlRates type values
);
Thus, it is very convenient to use the same function for work ing with different types. H owever, all
preliminary work should be carried out – the necessary function should be overloaded for all data types
it should correctly work with.
There is a convenient solution. If similar operations should be executed for each data type, it is
possible to use function templates. In this case, a programmer needs to write only one function
template description. W hen describing the template in such a way, we should specify only some formal
parameter instead of some definite data type the function should work with. The compiler will
automatically generate various functions for the appropriate handling of each type based on the types
of the arguments used when calling the function.
Function template definition starts with the template k eyword followed by the list of formal
parameters in angle brack ets. Each formal parameter is preceded by the typename k eyword. Formal
parameter types are built-in or user-defined types. They are used:
Number of template parameters cannot exceed eight. Each formal parameter in the template
definition should appear in the list of function parameters at least once. Each name of the formal
parameter should be unique.
Below is an example of a function template for searching the highest value in the array of any numeric
type (integer and real numbers):
template<typename T>
T ArrayMax(T &arr[])
{
uint size=ArraySize(arr);
if(size==0) return(0);
T max=arr[0];
for(uint n=1;n<size;n++)
if(max<arr[n]) max=arr[n];
//---
return(max);
}
This template defines the function that finds the highest value in the passed array and returns this
value as a result. Keep in mind that the ArrayMaximum() function built in MQL5 returns only the
highest value index that can be used to find the value itself. For example:
Thus, we have performed two steps to get the highest value in the array. W ith ArrayMax() function
template, we can get the result of the necessary type just by passing the array of an appropriate type
into this function. It means that instead of two last lines
we now can use only one line, in which the returned result has the same type as the array passed into
function:
In this case, the type of result returned by the ArrayMax() function will automatically match the type of
array.
Use the typename k eyword to get the argument type as a string in order to create general purpose
methods of work ing with various data types. Let's consider a specific example of the function that
returns data type as a string :
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnStart()
{
//---
CTrade trade;
double d_value=M_PI;
int i_value=INT_MAX;
Print("d_value: type=",GetTypeName(d_value), ", value=", d_value);
Print("i_value: type=",GetTypeName(i_value), ", value=", i_value);
Print("trade: type=",GetTypeName(trade));
//---
}
//+------------------------------------------------------------------+
//| Type is returned as a line |
//+------------------------------------------------------------------+
template<typename T>
string GetTypeName(const T &t)
{
//--- return the type as a line
return(typename(T));
//---
}
Function templates can also be used for class methods, for example:
class CFile
{
...
public:
...
template<typename T>
uint WriteStruct(T &data);
};
template<typename T>
uint CFile::WriteStruct(T &data)
{
...
return(FileWriteStruct(m_handle,data));
}
Function templates should not be declared with export, virtual and #import k eywords.
//+------------------------------------------------------------------+
//| Template function |
//+------------------------------------------------------------------+
template<typename T1,typename T2>
string Assign(T1 &var1,T2 var2)
{
var1=(T1)var2;
return(__FUNCSIG__);
}
//+------------------------------------------------------------------+
//| Special overload for bool+string |
//+------------------------------------------------------------------+
string Assign(bool &var1,string var2)
{
var1=(StringCompare(var2,"true",false) || StringToInteger(var2)!=0);
return(__FUNCSIG__);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int i;
bool b;
Print(Assign(i,"test"));
Print(Assign(b,"test"));
}
As a result of the code execution, we can see that the Assign() template function has been used for
the int+string pair, while the overloaded version has already been used for the bool+string pair during
the second call.
string Assign<int,string>(int&,string)
string Assign(bool&,string)
See also
Overload
Template advantages
Function templates are used when you need to perform similar operations on various data types, for
example, searching for a maximum element in the array. The main advantage of applying the
templates is that you do not have to code a separate overload for each type. Instead of declaring
multiple overloads of each type
template<typename T>
T ArrayMax(T array[])
{
if(ArraySize()==0)
return(0);
uint max_index=ArrayMaximum(array);
return(array[max_index]);
}
double high[];
datetime time[];
....
double max_high=ArrayMax(high);
datetime lasttime=ArrayMax(time);
H ere, the formal parameter specifying a type of used data is replaced with an actually applied type
T
during compilation, i.e. the compiler automatically generates a separate function for each type –
double, datetime, etc. MQL5 also allows you to develop class templates using all the advantages of the
approach.
Class templates
A class template is declared using the template k eyword followed by angle brack ets <> enumerating the
list of formal parameters with the typename k eyword. This entry informs the compiler that it deals
with a generic class with the T formal parameter defining a real variable type when implementing a
class. For example, let's create a vector class for storing an array with T type elements :
Next, let's apply different methods to create three TArray objects in the program for work ing with
various types
void OnStart()
{
TArray<double> double_array; // vector has a default size of 10
TArray<int> int_array(15); // vector has a size of 15
TArray<string> *string_array; // pointer to TArray<string> vector
//--- create a dynamic object
string_array=new TArray<string>(20);
//--- display an object name, data type and vector size in the Journal
PrintFormat("%s (%s)",TOSTR(double_array),double_array.Type());
PrintFormat("%s (%s)",TOSTR(int_array),int_array.Type());
PrintFormat("%s (%s)",TOSTR(string_array),string_array.Type());
//--- remove a dynamic object before completing the program
delete(string_array);
}
double_array (double:10)
int_array (int:15)
string_array (string:20)
Now, we have 3 vectors with different data types : double, int and string.
Class templates are well suited for developing containers – objects designed for encapsulating other
objects of any type. Container objects are collections already containing objects of one certain type.
Usually, work ing with stored data is instantly built into the container.
For example, you can create a class template that does not allow accessing an element outside the
array, thus avoiding the " out of range" critical error.
//+------------------------------------------------------------------+
//| Class for a free access to an array element |
//+------------------------------------------------------------------+
template<typename T>
class TSafeArray
{
protected:
T m_array[];
public:
//--- default constructor
void TSafeArray(void){}
//--- constructor for creating the array of a specified size
void TSafeArray(int size){ArrayResize(m_array,size);}
//--- array size
int Size(void){return(ArraySize(m_array));}
//--- change the array size
int Resize(int size,int reserve){return(ArrayResize(m_array,size,reserve));}
//--- release the array
void Erase(void){ZeroMemory(m_array);}
//--- operator for accessing the array element by index
T operator[](int index);
//--- assignment operator for receiving all elements from the array at once
void operator=(const T &array[]); // T type array
};
//+------------------------------------------------------------------+
//| Receiving an element by index |
//+------------------------------------------------------------------+
template<typename T>
T TSafeArray::operator[](int index)
{
static T invalid_value;
//---
int max=ArraySize(m_array)-1;
if(index<0 || index>=ArraySize(m_array))
{
PrintFormat("%s index %d is not in range (0-%d)!",__FUNCTION__,index,max);
return(invalid_value);
}
//---
return(m_array[index]);
}
//+------------------------------------------------------------------+
Please note that template declaration should also be used when describing methods outside the class
declaration:
template<typename T>
T TSafeArray::operator[](int index)
{
...
}
template<typename T>
void TSafeArray::operator=(const T &array[])
{
...
Class and function templates allow you to define multiple comma-separated formal parameters, for
example, Map collection for storing "k ey – value" pairs :
See also
Function templates, Overload
A class which contains at least one pure virtual function in it is abstract. Therefore, classes derived
from the abstract class must implement all its pure virtual functions, otherwise they will also be
abstract classes.
A virtual function is declared as " pure" by using the pure-specifier syntax. Consider the example of the
CAnimal class, which is only created to provide common functions – the objects of the CAnimal type
are too general for practical use. Thus, CAnimal is a good example for an abstract class :
class CAnimal
{
public:
CAnimal(); // Constructor
virtual void Sound() = 0; // A pure virtual function
private:
double m_legs_count; // The number of the animal's legs
};
H ere Sound() is a pure virtual function, because it is declared with the specifier of the pure virtual
function PURE (=0 ).
Pure virtual functions are only the virtual functions for which the PURE specifier is set: (=NULL) or
(=0). Example of abstract class declaration and use:
class CAnimal
{
public:
virtual void Sound()=NULL; // PURE method, should be overridden in the derived class, CA
};
//--- Derived from an abstract class
class CCat : public CAnimal
{
public:
virtual void Sound() { Print("Myau"); } // PURE is overridden, CCat is not abstract and ca
};
//+------------------------------------------------------------------+
//| An abstract base class |
//+------------------------------------------------------------------+
class CAnimal
{
public:
//--- A pure virtual function
virtual void Sound(void)=NULL;
//--- Function
void CallSound(void) { Sound(); }
//--- Constructor
CAnimal()
{
//--- An explicit call of the virtual method
Sound();
//--- An implicit call (using a third function)
CallSound();
//--- A constructor and/or destructor always calls its own functions,
//--- even if they are virtual and overridden by a called function in a derived class
//--- If the called function is pure virtual,
//--- its call will cause a critical runtime error: "pure virtual function call"
}
};
H owever, constructors and destructors for abstract classes can call other member functions.
· Chart constants are used when work ing with price charts : opening, navigation, setting parameters ;
· Objects constants are intended for processing graphical objects that can be created and displayed in
charts ;
· Indicators constants are used for work ing with standard and custom indicators ;
· Codes of errors and warnings describe compiler messages and trading server answers to trade
requests ;
· In/out constants are designed for work ing with file functions and displaying messages on the screen
by the MessageBox() function.
Chart Constants
Constants describing various properties of charts are divided into the following groups :
· Types of events – events that occur when work ing with charts ;
ENUM_CHART_EVENT
ID Description
CHAR T EVENT _MOUS E_WHEEL Pressing or scrolling the mouse wheel (if
CHAR T _EVENT _MOUS E_WHEEL =True for the
chart)
CHAR T EVENT _OBJECT _CHANGE Graphical object property changed via the
properties dialog
CHAR T EVENT _OBJECT _ENDEDIT End of text editing in the graphical object Edit
CHAR T EVENT _CHAR T _CHANGE Change of the chart size or modification of chart
properties through the Properties dialog
CHAR T EVENT _CUSTOM _L AST The final number of an event from a range of
custom events
For each type of event, the input parameters of the OnChartEvent() function have definite values that
are required for the processing of this event. The events and values passed through this parameters
are listed in the below table.
Event of a CHAR T EVENT _KE code of a R epeat count The string value
k eystrok e YDOWN pressed k ey (the number of of a bit mas k
times the describing the
k eystrok e is status of
repeated as a k eyboard buttons
result of the user
holding down the
k ey)
Mouse events (if CHAR T EVENT _MO the X coordinate the Y coordinate The string value
CHAR T _EVENT _ US E_MOVE of a bit mas k
MOUS E_MOVE=tr describing the
ue is set for the status of mouse
chart) buttons
Mouse wheel CHAR T EVENT _MO Flags of states of The Delta value —
event (if US E_WHEEL k eys and mouse of the mouse
CHAR T _EVENT _ buttons, the X wheel scroll
MOUS E_WHEEL = and Y
true for the coordinates of
chart) the mouse
pointer. See
description in
the example
below
Event of a CHAR T EVENT _OB the X coordinate the Y coordinate Name of the
mouse click in a JECT _CLICK graphical object,
graphical object on which the
belonging to the event occurred
chart
I D of the user CHAR T EVENT _CU Value set by the Value set by the Value set by the
event under the STOM+N EventChartCusto EventChartCusto EventChartCusto
N number m() function m() function m() function
Example:
#define KEY_NUMPAD_5 12
#define KEY_LEFT 37
#define KEY_UP 38
#define KEY_RIGHT 39
#define KEY_DOWN 40
#define KEY_NUMLOCK_DOWN 98
#define KEY_NUMLOCK_LEFT 100
#define KEY_NUMLOCK_5 101
#define KEY_NUMLOCK_RIGHT 102
#define KEY_NUMLOCK_UP 104
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
Print("The expert with name ",MQL5InfoString(MQL5_PROGRAM_NAME)," is running");
//--- enable object create events
ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_CREATE,true);
}
//--- the object has been created
if(id==CHARTEVENT_OBJECT_CREATE)
{
Print("The object with name ",sparam," has been created");
}
//--- the object has been moved or its anchor point coordinates has been changed
if(id==CHARTEVENT_OBJECT_DRAG)
{
Print("The anchor point coordinates of the object with name ",sparam," has been changed");
}
//--- the text in the Edit of object has been changed
if(id==CHARTEVENT_OBJECT_ENDEDIT)
{
Print("The text in the Edit field of the object with name ",sparam," has been changed");
}
}
For CHAR T EVENT _MOUS E_MOVE event the sparam string parameter contains information about state
of the k eyboard and mouse buttons :
Bit Description
Example:
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- enable CHART_EVENT_MOUSE_MOVE messages
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
//--- forced updating of chart properties ensures readiness for event processing
ChartRedraw();
}
//+------------------------------------------------------------------+
//| MouseState |
//+------------------------------------------------------------------+
For the CHAR T EVENT _MOUS E_WHEEL event, parameters lparam and dparam contain information
about the states of the Ctrl and Shift k eys, of mouse buttons, cursor coordinates and the mouse wheel
scroll value. For a better understanding, run this Expert Advisor on a chart and scroll the mouse wheel,
while pressing different buttons and holding down the k eys described in the code.
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
init OnInit()
{
//--- Enabling mouse wheel scrolling messages
ChartSetInteger(0,CHART_EVENT_MOUSE_WHEEL,1);
//--- Forced updating of chart properties ensures readiness for event processing
ChartRedraw();
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
if(id==CHARTEVENT_MOUSE_WHEEL)
{
//--- Consider the state of mouse buttons and wheel for this event
int flg_keys = (int)(lparam>>32); // The flag of states of the Ctrl and Shift keys,
int x_cursor = (int)(short)lparam; // the X coordinate where the mousse wheel event o
int y_cursor = (int)(short)(lparam>>16); // the Y coordinate where the mousse wheel event o
int delta = (int)dparam; // the total value of mouse scroll, triggers when
//--- Processing the flag
string str_keys="";
if((flg_keys&0x0001)!=0) str_keys+="LMOUSE ";
if((flg_keys&0x0002)!=0) str_keys+="RMOUSE ";
if((flg_keys&0x0004)!=0) str_keys+="SHIFT ";
if((flg_keys&0x0008)!=0) str_keys+="CTRL ";
if((flg_keys&0x0010)!=0) str_keys+="MMOUSE ";
if((flg_keys&0x0020)!=0) str_keys+="X1MOUSE ";
if((flg_keys&0x0040)!=0) str_keys+="X2MOUSE ";
if(str_keys!="")
str_keys=", keys='"+StringSubstr(str_keys,0,StringLen(str_keys)-1) + "'";
PrintFormat("%s: X=%d, Y=%d, delta=%d%s",EnumToString(CHARTEVENT_MOUSE_WHEEL),x_cursor,y_curs
}
}
//+------------------------------------------------------------------+ /*
Example of the output
CHARTEVENT_MOUSE_WHEEL: Ctrl pressed: X=193, Y=445, delta=-120
CHARTEVENT_MOUSE_WHEEL: Shift pressed: X=186, Y=446, delta=120
CHARTEVENT_MOUSE_WHEEL: X=178, Y=447, delta=-120
CHARTEVENT_MOUSE_WHEEL: X=231, Y=449, delta=120
CHARTEVENT_MOUSE_WHEEL: MiddleButton pressed: X=231, Y=449, delta=120
CHARTEVENT_MOUSE_WHEEL: LeftButton pressed: X=279, Y=320, delta=-120
CHARTEVENT_MOUSE_WHEEL: RightButton pressed: X=253, Y=330, delta=120 */
See also
Event H andling Functions, W ork ing with events
Chart Timeframes
All predefined timeframes of charts have unique identifiers. The PER IOD_CURRENT identifier means
the current period of a chart, at which a mql5-program is running.
ENUM_TIMEFRAMES
ID Description
Example:
string chart_name="test_Object_Chart";
Print("Let's try to create a Chart object with the name ",chart_name);
//--- If such an object does not exist - create it
if(ObjectFind(0,chart_name)<0)ObjectCreate(0,chart_name,OBJ_CHART,0,0,0,0,0);
Timeseries identifiers
The identifiers of timeseries are used in the iH ighest() and iLowest() functions. They can be equal to
a value the enumeration
ENUM_SERIESMODE
Identifier Description
MODE_SPREAD Spread
See also
Chart Properties
Identifiers of ENUM _CHAR T _PR OPER T Y enumerations are used as parameters of functions for work ing
with charts. The abbreviation of r/o in the " Property Type" column means that this property is read-
only and cannot be changed. The w/o abbreviation in the " Property Type" column means that this
property is write-only and it cannot be received. W hen accessing certain properties, it's necessary to
specify an additional parameter-modifier (modifier), which serves to indicate the number of chart
subwindows. 0 means the main window.
The functions defining the chart properties are actually used for sending change commands to the
chart. If these functions are executed successfully, the command is included in the common queue of
the chart events. The changes are implemented to the chart when handling the queue of the chart
events.
Thus, do not expect an immediate visual update of the chart after calling these functions. Generally,
the chart is updated automatically by the terminal following the change events - a new quote arrival,
resizing the chart window, etc. Use ChartR edraw() function to forcefully update the chart.
ENUM_CHART_PROPERTY _INTEGER
CHAR T _CONT EXT _M ENU Enabling /disabling access to bool (default is true)
the context menu using the
right click .
W hen
CHAR T _CONT EXT _M ENU=false,
only the chart context menu is
disabled. The context menu of
objects on the chart remains
available.
CHAR T _CR OSS HAI R_TOOL Enabling /disablingaccess to bool (default is true)
the Crosshair tool using the
middle click .
CHAR T _EVENT _MOUS E_WHEEL Sending messages about mouse bool (default is true)
wheel events
(CHAR T EVENT _MOUS E_WHEEL)
to all mql5 programs on a chart
CHAR T _MODE Chart type (candlestick s, bars enum ENUM _CHAR T _MODE
or line)
CHAR T _W I NDOW_YDIST ANCE The distance between the int r/o modifier - subwindow
upper frame of the indicator number
subwindow and the upper
frame of the main chart
window, along the vertical Y
axis, in pixels. In case of a
mouse event, the cursor
coordinates are passed in
terms of the coordinates of the
main chart window, while the
coordinates of graphical
objects in an indicator
subwindow are set relative to
the upper left corner of the
subwindow.
The value is required for
converting the absolute
coordinates of the main chart
to the local coordinates of a
subwindow for correct work
with the graphical objects,
whose coordinates are set
relative to the upper left
corner of the subwindow
frame.
CHAR T _FI R ST _VISI BL E_BAR Number of the first visible bar int r/o
in the chart. Indexing of bars is
the same as for timeseries.
CHAR T _HEI GH T _I N_PI XELS Chart height in pixels int modifier - subwindow
number
CHAR T _S H OW_ONE_CLICK Showing the " One click trading " bool
panel on a chart
ENUM_CHART_PROPERTY _DOUBLE
CHAR T _S H I FT _SI ZE The size of the zero bar indent double (from 10 to 50
from the right border in percents)
percents
ENUM_CHART_PROPERTY _STRING
CHAR T _SCR IPT _NAM E The name of the script running string
on the chart with the specified
chart_id
Example:
int chartMode=ChartGetInteger(0,CHART_MODE);
switch(chartMode)
{
case(CHART_BARS): Print("CHART_BARS"); break;
case(CHART_CANDLES): Print("CHART_CANDLES");break;
default:Print("CHART_LINE");
}
bool shifted=ChartGetInteger(0,CHART_SHIFT);
if(shifted) Print("CHART_SHIFT = true");
else Print("CHART_SHIFT = false");
bool autoscroll=ChartGetInteger(0,CHART_AUTOSCROLL);
if(autoscroll) Print("CHART_AUTOSCROLL = true");
else Print("CHART_AUTOSCROLL = false");
int chartHandle=ChartGetInteger(0,CHART_WINDOW_HANDLE);
Print("CHART_WINDOW_HANDLE = ",chartHandle);
int windows=ChartGetInteger(0,CHART_WINDOWS_TOTAL);
Print("CHART_WINDOWS_TOTAL = ",windows);
if(windows>1)
{
for(int i=0;i<windows;i++)
{
int height=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,i);
double priceMin=ChartGetDouble(0,CHART_PRICE_MIN,i);
double priceMax=ChartGetDouble(0,CHART_PRICE_MAX,i);
Print(i+": CHART_HEIGHT_IN_PIXELS = ",height," pixels");
Print(i+": CHART_PRICE_MIN = ",priceMin);
Print(i+": CHART_PRICE_MAX = ",priceMax);
}
}
See also
Positioning Constants
Three identifiers from the ENUM _CHAR T _POSITION list are the possible values of the position
ENUM_CHART_POSITION
ID Description
Example:
long handle=ChartOpen("EURUSD",PERIOD_H12);
if(handle!=0)
{
ChartSetInteger(handle,CHART_AUTOSCROLL,false);
ChartSetInteger(handle,CHART_SHIFT,true);
ChartSetInteger(handle,CHART_MODE,CHART_LINE);
ResetLastError();
bool res=ChartNavigate(handle,CHART_END,150);
if(!res) Print("Navigate failed. Error = ",GetLastError());
ChartRedraw();
}
Chart Representation
Price charts can be displayed in three ways :
· as bars ;
· as candlestick s ;
· as a line.
The specific way of displaying the price chart is set by the function
ChartSetInteger(chart_handle,CHAR T _MODE, chart_mode), where chart_mode is one of the values of
the ENUM _CHAR T _MODE enumeration.
ENUM_CHART_MODE
ID Description
To specify the mode of displaying volumes in the price chart the function
ChartSetInteger(chart_handle, CHAR T _S H OW_VOL UM ES, volume_mode) is used, where volume_mode
is one of values of the ENUM _CHAR T _VOL UM E_MODE enumeration.
ENUM_CHART_VOLUME_MODE
ID Description
Example:
See also
ChartOpen, ChartI D
The screenshot below demonstrates the graphic panel illustrating how changing of the chart property
changes its appearance. Click ing Next button allows setting the new value of the appropriate property
and view the changes in the chart window.
//+------------------------------------------------------------------+
//| Checks if an object is a chart. If it is a graphic object, |
//| the result is true. If it is a real chart, the result variable |
//| has the value of false. |
//+------------------------------------------------------------------+
bool ChartIsObject(bool &result,const long chart_ID=0)
{
//+----------------------------------------------------------------------+
//| Sends command to the terminal to display the chart above all others |
//+----------------------------------------------------------------------+
bool ChartBringToTop(const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- show the chart on top of all others
if(!ChartSetInteger(chart_ID,CHART_BRING_TO_TOP,0,true))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_MOUSE_SCROLL is a property for scrolling the chart using left mouse button.
//+--------------------------------------------------------------------------+
//| Checks if scrolling of chart using left mouse button is enabled |
//+--------------------------------------------------------------------------+
bool ChartMouseScrollGet(bool &result,const long chart_ID=0)
{
//+------------------------------------------------------------------+
//| Checks if messages concerning move events and mouse clicks |
//| are sent to all MQL5 applications on the chart |
//+------------------------------------------------------------------+
bool ChartEventMouseMoveGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_EVENT_MOUSE_MOVE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------------------+
//| Enables/disables the mode of sending messages concerning move events and |
//| mouse clicks to MQL5 applications on the chart |
//+------------------------------------------------------------------------------+
bool ChartEventMouseMoveSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_EVENT_MOUSE_MOVE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+---------------------------------------------------------------------+
//| Checks if messages concerning the event of a graphic |
//| object creation are sent to all MQL5 applications on the chart |
//+---------------------------------------------------------------------+
bool ChartEventObjectCreateGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_EVENT_OBJECT_CREATE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+--------------------------------------------------------------------------+
//| Enables/disables the mode of sending messages concerning the event of a |
//| graphic object creation to all mql5 applications on the chart |
//+--------------------------------------------------------------------------+
bool ChartEventObjectCreateSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_EVENT_OBJECT_CREATE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+---------------------------------------------------------------------+
//| Checks if messages concerning the event of a graphic object |
//| deletion are sent to all mql5 applications on the chart |
//+---------------------------------------------------------------------+
bool ChartEventObjectDeleteGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_EVENT_OBJECT_DELETE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_MODE,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Checks if a price chart is displayed in the foreground |
//+------------------------------------------------------------------+
bool ChartForegroundGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_FOREGROUND,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables displaying of a price chart on the foreground |
//+------------------------------------------------------------------+
bool ChartForegroundSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_FOREGROUND,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_SHIFT – mode of shift of the price chart from the right border.
//+-------------------------------------------------------------------+
//| Checks if shifting a price chart from the right border is enabled |
//+-------------------------------------------------------------------+
bool ChartShiftGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_SHIFT,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+---------------------------------------------------------------------------------+
//| Enables/disables displaying of a price chart with a shift from the right border |
//+---------------------------------------------------------------------------------+
bool ChartShiftSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SHIFT,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_AUTOSCROLL – the mode of automatic shift to the right border of the chart.
//+------------------------------------------------------------------+
//| Checks if automatic scrolling of a chart to the right |
//| on new ticks arrival is enabled |
//+------------------------------------------------------------------+
bool ChartAutoscrollGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_AUTOSCROLL,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables automatic scrolling of a chart to the right |
//| on new ticks arrival |
//+------------------------------------------------------------------+
bool ChartAutoscrollSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_AUTOSCROLL,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Gets chart scale (from 0 to 5) |
//+------------------------------------------------------------------+
int ChartScaleGet(const long chart_ID=0)
{
//--- prepare the variable to get the property value
long result=-1;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_SCALE,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((int)result);
}
//+------------------------------------------------------------------+
//| Sets chart scale (from 0 to 5) |
//+------------------------------------------------------------------+
bool ChartScaleSet(const long value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SCALE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
if(!ChartGetInteger(chart_ID,CHART_SCALEFIX,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables the fixed scale mode |
//+------------------------------------------------------------------+
bool ChartScaleFixSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SCALEFIX,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables the "1:1" scale mode |
//+------------------------------------------------------------------+
bool ChartScaleFix11Set(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SCALEFIX_11,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_SCALE_PT_PER_BAR – the mode of specifying the chart scale in points per bar.
//+------------------------------------------------------------------+
//| Checks if the "points per bar" chart scaling mode is enabled |
//+------------------------------------------------------------------+
bool ChartScalePerBarGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_SCALE_PT_PER_BAR,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables the "points per bar" chart scaling mode |
//+------------------------------------------------------------------+
· CHART_SHOW_BID_LINE – the property of displaying Bid value as a horizontal line on the chart.
//+------------------------------------------------------------------+
//| Checks if displaying of Bid line on chart is enabled |
//+------------------------------------------------------------------+
bool ChartShowBidLineGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_SHOW_BID_LINE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables displaying of Bid line on chart |
//+------------------------------------------------------------------+
bool ChartShowBidLineSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SHOW_BID_LINE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+---------------------------------------------------------------------------------+
//| Checks if displaying of vertical separators between adjacent periods is enabled |
//+---------------------------------------------------------------------------------+
bool ChartShowPeriodSeparatorGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SHOW_VOLUMES,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_VISIBLE_BARS defines the number of bars on a chart that are available for display.
//+----------------------------------------------------------------------+
//| Gets the number of bars that are displayed (visible) in chart window |
//+----------------------------------------------------------------------+
int ChartVisibleBars(const long chart_ID=0)
{
//--- prepare the variable to get the property value
long result=-1;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_VISIBLE_BARS,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((int)result);
}
//+-----------------------------------------------------------------------+
//| Gets the total number of chart windows including indicator subwindows |
//+-----------------------------------------------------------------------+
int ChartWindowsTotal(const long chart_ID=0)
{
//--- prepare the variable to get the property value
long result=-1;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_WINDOWS_TOTAL,0,result))
{
//+------------------------------------------------------------------+
//| Checks if the current chart window or subwindow is visible |
//+------------------------------------------------------------------+
bool ChartWindowsIsVisible(bool &result,const long chart_ID=0,const int sub_window=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_WINDOW_IS_VISIBLE,sub_window,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Gets the chart handle |
//+------------------------------------------------------------------+
int ChartWindowsHandle(const long chart_ID=0)
{
//--- prepare the variable to get the property value
long result=-1;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_WINDOW_HANDLE,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((int)result);
}
· CHART_WINDOW_ Y DISTANCE defines the distance in pixels between the upper frame of the
indicator subwindow and the upper frame of the chart's main window.
//+------------------------------------------------------------------+
//| Gets the distance in pixels between the upper border of |
//| subwindow and the upper border of chart's main window |
//+------------------------------------------------------------------+
int ChartWindowsYDistance(const long chart_ID=0,const int sub_window=0)
{
//--- prepare the variable to get the property value
long result=-1;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_WINDOW_YDISTANCE,sub_window,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((int)result);
}
· CHART_FIRST_VISIBLE_BAR returns the number of the first visible bar on the chart (bar indexing
corresponds to the time series).
//+------------------------------------------------------------------------------+
//| Gets the index of the first visible bar on chart. |
//| Indexing is performed like in timeseries: latest bars have smallest indices. |
//+------------------------------------------------------------------------------+
int ChartFirstVisibleBar(const long chart_ID=0)
{
//--- prepare the variable to get the property value
long result=-1;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_FIRST_VISIBLE_BAR,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//+------------------------------------------------------------------+
//| Gets the width of chart (in bars) |
//+------------------------------------------------------------------+
int ChartWidthInBars(const long chart_ID=0)
{
//--- prepare the variable to get the property value
long result=-1;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_WIDTH_IN_BARS,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((int)result);
}
//+------------------------------------------------------------------+
//| Gets the width of chart (in pixels) |
//+------------------------------------------------------------------+
int ChartWidthInPixels(const long chart_ID=0)
{
//--- prepare the variable to get the property value
long result=-1;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_WIDTH_IN_PIXELS,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((int)result);
}
//+------------------------------------------------------------------+
//| Gets the background color of chart |
//+------------------------------------------------------------------+
color ChartBackColorGet(const long chart_ID=0)
{
//--- prepare the variable to receive the color
long result=clrNONE;
//--- reset the error value
ResetLastError();
//--- receive chart background color
if(!ChartGetInteger(chart_ID,CHART_COLOR_BACKGROUND,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((color)result);
}
//+------------------------------------------------------------------+
//| Sets the background color of chart |
//+------------------------------------------------------------------+
bool ChartBackColorSet(const color clr,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set the chart background color
if(!ChartSetInteger(chart_ID,CHART_COLOR_BACKGROUND,clr))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Sets the color of axes, scale and OHLC line |
//+------------------------------------------------------------------+
bool ChartForeColorSet(const color clr,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set the color of axes, scale and OHLC line
if(!ChartSetInteger(chart_ID,CHART_COLOR_FOREGROUND,clr))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Gets the color of volumes and market entry levels |
//+------------------------------------------------------------------+
color ChartVolumeColorGet(const long chart_ID=0)
{
//--- prepare the variable to receive the color
long result=clrNONE;
//--- reset the error value
ResetLastError();
//--- receive color of volumes and market entry levels
if(!ChartGetInteger(chart_ID,CHART_COLOR_VOLUME,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((color)result);
}
//+------------------------------------------------------------------+
//| Sets the color of volumes and market entry levels |
//+------------------------------------------------------------------+
bool ChartVolumeColorSet(const color clr,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set color of volumes and market entry levels
if(!ChartSetInteger(chart_ID,CHART_COLOR_VOLUME,clr))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_COLOR_CHART_UP – color of up bar, its shadow and border of a bullish candlestick's body.
//+-----------------------------------------------------------------------------+
//| Gets the color of up bar, shadow and border of a bullish candlestick's body |
//+-----------------------------------------------------------------------------+
color ChartUpColorGet(const long chart_ID=0)
{
//--- prepare the variable to receive the color
long result=clrNONE;
//--- reset the error value
ResetLastError();
//--- receive the color of up bar, its shadow and border of bullish candlestick's body
if(!ChartGetInteger(chart_ID,CHART_COLOR_CHART_UP,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((color)result);
}
//+------------------------------------------------------------------+
//| Sets the color of up bar, shadow and border of a bullish candlestick's body |
//+------------------------------------------------------------------+
bool ChartUpColorSet(const color clr,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set the color of up bar, its shadow and border of body of a bullish candlestick
if(!ChartSetInteger(chart_ID,CHART_COLOR_CHART_UP,clr))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_COLOR_CHART_DOWN – color of down bar, its shadow and border of bearish candlestick's
body.
//+-------------------------------------------------------------------------------+
//| Gets the color of down bar, shadow and border of a bearish candlestick's body |
//+-------------------------------------------------------------------------------+
color ChartDownColorGet(const long chart_ID=0)
{
//--- prepare the variable to receive the color
long result=clrNONE;
}
//+------------------------------------------------------------------+
//| Sets the color of chart line and Doji candlesticks |
//+------------------------------------------------------------------+
bool ChartLineColorSet(const color clr,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set color of the chart line and Doji candlesticks
if(!ChartSetInteger(chart_ID,CHART_COLOR_CHART_LINE,clr))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
ResetLastError();
//--- receive the color of Ask price line
if(!ChartGetInteger(chart_ID,CHART_COLOR_ASK,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((color)result);
}
//+------------------------------------------------------------------+
//| Sets the color of Ask line |
//+------------------------------------------------------------------+
bool ChartAskColorSet(const color clr,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set the color of Ask price line
if(!ChartSetInteger(chart_ID,CHART_COLOR_ASK,clr))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Sets the color of the last performed deal's price line |
//+------------------------------------------------------------------+
bool ChartLastColorSet(const color clr,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set color of the last performed deal's price line (Last)
if(!ChartSetInteger(chart_ID,CHART_COLOR_LAST,clr))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_COLOR_STOP_LEVEL – stop order level color (Stop Loss and Take Profit).
//+------------------------------------------------------------------+
//| Gets the color of Stop Loss and Take Profit levels |
//+------------------------------------------------------------------+
color ChartStopLevelColorGet(const long chart_ID=0)
{
//--- prepare the variable to receive the color
long result=clrNONE;
//--- reset the error value
ResetLastError();
//--- receive the color of stop order levels (Stop Loss and Take Profit)
if(!ChartGetInteger(chart_ID,CHART_COLOR_STOP_LEVEL,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return((color)result);
}
//+------------------------------------------------------------------+
//| Sets the color of Stop Loss and Take Profit levels |
//+------------------------------------------------------------------+
bool ChartStopLevelColorSet(const color clr,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set the color of stop order levels (Stop Loss and Take Profit)
if(!ChartSetInteger(chart_ID,CHART_COLOR_STOP_LEVEL,clr))
{
//+------------------------------------------------------------------+
//| Checks if trading levels are displayed on chart |
//+------------------------------------------------------------------+
bool ChartShowTradeLevelsGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_SHOW_TRADE_LEVELS,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables displaying of trading levels |
//+------------------------------------------------------------------+
bool ChartShowTradeLevelsSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SHOW_TRADE_LEVELS,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
//+----------------------------------------------------------------------+
//| Checks if dragging of trading levels on chart using mouse is allowed |
//+----------------------------------------------------------------------+
bool ChartDragTradeLevelsGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_DRAG_TRADE_LEVELS,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables dragging of trading levels on chart using mouse |
//+------------------------------------------------------------------+
bool ChartDragTradeLevelsSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_DRAG_TRADE_LEVELS,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_SHOW_PRICE_SCALE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables displaying of the price scale on chart |
//+------------------------------------------------------------------+
bool ChartShowPriceScaleSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SHOW_PRICE_SCALE,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_SHOW_ONE_CLICK – property of displaying the " One click trading " panel on a chart.
//+------------------------------------------------------------------+
//| Checks if the "One click trading" panel is displayed on chart |
//+------------------------------------------------------------------+
bool ChartShowOneClickPanelGet(bool &result,const long chart_ID=0)
{
//--- prepare the variable to get the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_SHOW_ONE_CLICK,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the value of the chart property in memory
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Enables/disables displaying of the "One click trading" panel |
//| on chart |
//+------------------------------------------------------------------+
bool ChartShowOneClickPanelSet(const bool value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetInteger(chart_ID,CHART_SHOW_ONE_CLICK,0,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
· CHART_SHIFT_SI ZE – shift size of the zero bar from the right border in percentage values.
//+-----------------------------------------------------------------+
//| Gets the size of shifting of the zero bar from the right border |
//| of the chart in percentage values (from 10% up to 50%) |
//+-----------------------------------------------------------------+
double ChartShiftSizeGet(const long chart_ID=0)
{
//--- prepare the variable to get the result
double result=EMPTY_VALUE;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetDouble(chart_ID,CHART_SHIFT_SIZE,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return(result);
}
//+-----------------------------------------------------------------------------+
//| Gets the size of shifting of the zero bar from the right border |
· CHART_FI X ED_POSITION – chart fixed position from the left border in percentage value.
//+----------------------------------------------------------------------------------------+
//| Gets the location of chart's fixed position from the left border (in percentage value) |
//+----------------------------------------------------------------------------------------+
double ChartFixedPositionGet(const long chart_ID=0)
{
//--- prepare the variable to get the result
double result=EMPTY_VALUE;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetDouble(chart_ID,CHART_FIXED_POSITION,0,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return(result);
}
//+-----------------------------------------------------------------------------------------+
//| Gets the location of chart's fixed position from the left border (in percentage value). |
//| To view the location of chart's fixed position, the value of CHART_AUTOSCROLL property |
//| should be set to false. |
//+-----------------------------------------------------------------------------------------+
bool ChartFixedPositionSet(const double value,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetDouble(chart_ID,CHART_FIXED_POSITION,value))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+----------------------------------------------------------------------+
//| Gets the value of chart minimum in the main window or in a subwindow |
//+----------------------------------------------------------------------+
double ChartPriceMin(const long chart_ID=0,const int sub_window=0)
{
//--- prepare the variable to get the result
double result=EMPTY_VALUE;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetDouble(chart_ID,CHART_PRICE_MIN,sub_window,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return(result);
}
//+----------------------------------------------------------------------+
//| Gets the value of chart maximum in the main window or in a subwindow |
//+----------------------------------------------------------------------+
double ChartPriceMax(const long chart_ID=0,const int sub_window=0)
{
//--- prepare the variable to get the result
double result=EMPTY_VALUE;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetDouble(chart_ID,CHART_PRICE_MAX,sub_window,result))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
}
//--- return the value of the chart property
return(result);
}
}
//+------------------------------------------------------------------+
//| Gets comment in the upper left corner of chart |
//+------------------------------------------------------------------+
bool ChartCommentSet(const string str,const long chart_ID=0)
{
//--- reset the error value
ResetLastError();
//--- set property value
if(!ChartSetString(chart_ID,CHART_COMMENT,str))
{
//--- display the error message in Experts journal
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Defines if the current chart window is maximized |
//+------------------------------------------------------------------+
bool ChartWindowsIsMaximized(bool &result,const long chart_ID=0)
{
//--- prepare the variable for receiving the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_IS_MAXIMIZED))
{
//--- display an error message in the Experts log
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the chart property value in the variable
result=value;
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Defines if the current chart window is minimized |
//+------------------------------------------------------------------+
bool ChartWindowsIsMinimized(bool &result,const long chart_ID=0)
{
//--- prepare the variable for receiving the property value
long value;
//--- reset the error value
ResetLastError();
//--- receive the property value
if(!ChartGetInteger(chart_ID,CHART_IS_MINIMIZED))
{
//--- display an error message in the Experts log
Print(__FUNCTION__+", Error Code = ",GetLastError());
return(false);
}
//--- store the chart property value in the variable
result=value;
//--- successful execution
return(true);
}
int index=(int)StringToInteger(obj_name[1]);
//--- unpress the button
ExtButtons[index].State(false);
//--- set the new value of the property depending on its type
if(ExtDataTypes[index]=='I')
ChangeIntegerProperty(index);
if(ExtDataTypes[index]=='D')
ChangeDoubleProperty(index);
if(ExtDataTypes[index]=='S')
ChangeStringProperty(index);
}
}
//--- re-draw property values
RedrawProperties();
ChartRedraw();
}
//+------------------------------------------------------------------+
//| Changes an integer property of chart |
//+------------------------------------------------------------------+
void ChangeIntegerProperty(const int index)
{
//--- receive the current property value
long value=ChartGetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[index]);
//--- define the following property value
switch(ExtDrawTypes[index])
{
case 'C':
value=GetNextColor((color)value);
break;
default:
value=(long)GetNextValue((double)value,index);
break;
}
//--- set the new property value
ChartSetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[index],0,value);
}
//+------------------------------------------------------------------+
//| Changes a double property of chart |
//+------------------------------------------------------------------+
void ChangeDoubleProperty(const int index)
{
//--- receive the current property value
double value=ChartGetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[index]);
//--- define the following property value
value=GetNextValue(value,index);
//--- set the new property value
ChartSetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[index],value);
}
//+------------------------------------------------------------------+
{
case 'I':
//--- receive the current property value
if(!ChartGetInteger(0,(ENUM_CHART_PROPERTY_INTEGER)ExtNumbers[i],0,value))
break;
//--- integer property text
switch(ExtDrawTypes[i])
{
//--- color property
case 'C':
text=(string)((color)value);
break;
//--- boolean property
case 'B':
text=(string)((bool)value);
break;
//--- ENUM_CHART_MODE enumeration property
case 'M':
text=EnumToString((ENUM_CHART_MODE)value);
break;
//--- ENUM_CHART_VOLUME_MODE enumeration property
case 'V':
text=EnumToString((ENUM_CHART_VOLUME_MODE)value);
break;
//--- int type number
default:
text=IntegerToString(value);
break;
}
break;
case 'D':
//--- double property text
text=DoubleToString(ChartGetDouble(0,(ENUM_CHART_PROPERTY_DOUBLE)ExtNumbers[i]),4);
break;
case 'S':
//--- string property text
text=ChartGetString(0,(ENUM_CHART_PROPERTY_STRING)ExtNumbers[i]);
break;
}
//--- display property value
ExtLabelsValue[i].Description(text);
}
}
//+------------------------------------------------------------------+
//| Creates panel for managing chart properties |
//+------------------------------------------------------------------+
bool PrepareControls(void)
{
//--- allocate memory for arrays with a reserve
MemoryAllocation(LAST_PROPERTY_NUMBER+1);
//--- variables
int i=0; // loop variable
int col_1=0; // number of properties in the first column
int col_2=0; // number of properties in the second column
int col_3=0; // number of properties in the third column
//--- current number of properties - 0
ExtCount=0;
//--- looking for properties in the loop
while(i<=LAST_PROPERTY_NUMBER)
{
//--- store the current number of the property
ExtNumbers[ExtCount]=i;
//--- increase the value of the loop variable
i++;
//--- check if there is a property with such a number
if(CheckNumber(ExtNumbers[ExtCount],ExtNames[ExtCount],ExtDataTypes[ExtCount],ExtGroupTypes[E
{
//--- create control elements for the property
switch(ExtGroupTypes[ExtCount])
{
case 1:
//--- create labels and a button for the property
if(!ShowProperty(ExtCount,0,X_PROPERTY_NAME_1,X_PROPERTY_VALUE_1,X_BUTTON_1,Y_PROPER
return(false);
//--- number of the elements in the first column has increased
col_1++;
break;
case 2:
//--- create labels and a button for the property
if(!ShowProperty(ExtCount,1,X_PROPERTY_NAME_2,X_PROPERTY_VALUE_2,X_BUTTON_2,Y_PROPER
return(false);
//--- number of the elements in the second column has increased
col_2++;
break;
case 3:
//--- create only labels for the property
if(!ShowProperty(ExtCount,2,X_PROPERTY_NAME_2,X_PROPERTY_VALUE_2,0,Y_PROPERTY_2+col_
return(false);
//--- number of the elements in the third column has increased
col_3++;
break;
}
//--- define maximum and minimum property value and step
GetMaxMinStep(ExtNumbers[ExtCount],ExtMaxValue[ExtCount],ExtMinValue[ExtCount],ExtStep[Ext
//--- increase the number of properties
ExtCount++;
}
}
case CHART_WIDTH_IN_BARS:
case CHART_WIDTH_IN_PIXELS:
draw_type='I';
break;
//--- double properties
case CHART_PRICE_MIN:
case CHART_PRICE_MAX:
draw_type='D';
break;
//--- in fact, this property is a command of displaying the chart on top of all the others
//--- there is no need to apply this panel, as the window will always be
//--- on top of other ones before we use it
case CHART_BRING_TO_TOP:
draw_type=' ';
break;
//--- property does not belong to the third group
default:
return(false);
}
//--- property belongs to the third group
group_type=3;
return(true);
}
//+----------------------------------------------------------------------+
//| Checks if property belongs to the second group and |
//| defines its display type in case of a positive answer |
//+----------------------------------------------------------------------+
bool CheckSecondGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- check if the property belongs to the second group
switch(property_number)
{
//--- ENUM_CHART_MODE type property
case CHART_MODE:
draw_type='M';
break;
//--- ENUM_CHART_VOLUME_MODE type property
case CHART_SHOW_VOLUMES:
draw_type='V';
break;
//--- string property
case CHART_COMMENT:
draw_type='S';
break;
//--- color property
case CHART_COLOR_BACKGROUND:
case CHART_COLOR_FOREGROUND:
case CHART_COLOR_GRID:
case CHART_COLOR_VOLUME:
case CHART_COLOR_CHART_UP:
case CHART_COLOR_CHART_DOWN:
case CHART_COLOR_CHART_LINE:
case CHART_COLOR_CANDLE_BULL:
case CHART_COLOR_CANDLE_BEAR:
case CHART_COLOR_BID:
case CHART_COLOR_ASK:
case CHART_COLOR_LAST:
case CHART_COLOR_STOP_LEVEL:
draw_type='C';
break;
//--- property does not belong to the second group
default:
return(false);
}
//--- property belongs to the second group
group_type=2;
return(true);
}
//+-----------------------------------------------------------------------+
//| Called only if it is already known that property does not belong |
//| to the second and third property groups |
//+-----------------------------------------------------------------------+
void CheckFirstGroup(const int property_number,uint &group_type,uchar &draw_type)
{
//--- the property belongs to the first group
group_type=1;
//--- define property display type
switch(property_number)
{
//--- integer properties
case CHART_SCALE:
case CHART_HEIGHT_IN_PIXELS:
draw_type='I';
return;
//--- double properties
case CHART_SHIFT_SIZE:
case CHART_FIXED_POSITION:
case CHART_FIXED_MAX:
case CHART_FIXED_MIN:
case CHART_POINTS_PER_BAR:
draw_type='D';
return;
//--- only boolean properties have remained
default:
draw_type='B';
return;
}
}
//+------------------------------------------------------------------+
//| Creates label and button for property |
//+------------------------------------------------------------------+
bool ShowProperty(const int ind,const int type,const int x1,const int x2,
const int xb,const int y,const bool btn)
{
//--- static array for switching inside ExtColors color array
static uint color_index[3]={1,1,1};
//--- change index for receiving another color
color_index[type]=1-color_index[type];
//--- display labels and a button (if btn=true) for the property
if(!LabelCreate(ExtLabelsName[ind],"name_"+(string)ind,ExtNames[ind],ExtColors[color_index[type]
return(false);
if(!LabelCreate(ExtLabelsValue[ind],"value_"+(string)ind,"",ExtColors[color_index[type]],x2,y))
return(false);
if(btn && !ButtonCreate(ExtButtons[ind],(string)ind,xb,y+1))
return(false);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Creates label |
//+------------------------------------------------------------------+
bool LabelCreate(CChartObjectLabel &lbl,const string name,const string text,
const color clr,const int x,const int y)
{
if(!lbl.Create(0,"Label_"+name,0,x,y)) return(false);
if(!lbl.Description(text)) return(false);
if(!lbl.FontSize(10)) return(false);
if(!lbl.Color(clr)) return(false);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Creates button |
//+------------------------------------------------------------------+
bool ButtonCreate(CChartObjectButton &btn,const string name,
const int x,const int y)
{
if(!btn.Create(0,"Button_"+name,0,x,y,50,15)) return(false);
if(!btn.Description("Next")) return(false);
if(!btn.FontSize(10)) return(false);
if(!btn.Color(clrBlack)) return(false);
if(!btn.BackColor(clrWhite)) return(false);
if(!btn.BorderColor(clrBlack)) return(false);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
step=30;
break;
//--- default values
default:
max=1;
min=0;
step=1;
}
}
Object Constants
There are 44 graphical objects that can be created and displayed in the price chart. All constants for
work ing with objects are divided into 9 groups :
· Binding corner – setting the corner relative to which an object is positioned on chart;
· Gann objects – trend constants for Gann fan and Gann grid;
Object Types
W hen a graphical object is created using the ObjectCreate() function, it's necessary to specify the type
of object being created, which can be one of the values of the ENUM _OBJECT enumeration. Further
specifications of object properties are possible using functions for work ing with graphical objects.
ENUM_OBJECT
ID Description
OBJ_ELLIPS E Ellipse
OBJ_ARR OW Arrow
OBJ_BUTTON Button
OBJ_CHAR T Chart
OBJ_BITM AP Bitmap
OBJ_EDIT Edit
OBJ_VLINE
Vertical Line.
Note
W hen drawing a vertical line, it is possible to set the line display mode for all chart windows
(property OBJPR OP_RAY).
Example
The following script creates and moves the vertical line on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Vertical Line\" graphical object."
#property description "Anchor point date is set in percentage of"
#property description "the chart window width in bars."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="VLine"; // Line name
input int InpDate=25; // Event date, %
input color InpColor=clrRed; // Line color
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // Line style
input int InpWidth=3; // Line width
input bool InpBack=false; // Background line
input bool InpSelection=true; // Highlight to move
input bool InpRay=true; // Line's continuation down
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the vertical line |
//+------------------------------------------------------------------+
bool VLineMove(const long chart_ID=0, // chart's ID
const string name="VLine", // line name
datetime time=0) // line time
{
//--- if line time is not set, move the line to the last bar
if(!time)
time=TimeCurrent();
//--- reset the error value
ResetLastError();
//--- move the vertical line
if(!ObjectMove(chart_ID,name,0,time,0))
{
Print(__FUNCTION__,
": failed to move the vertical line! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete the vertical line |
//+------------------------------------------------------------------+
bool VLineDelete(const long chart_ID=0, // chart's ID
const string name="VLine") // line name
{
//--- reset the error value
ResetLastError();
//--- delete the vertical line
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the vertical line! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
OBJ_HLINE
H orizontal Line.
Example
The following script creates and moves the horizontal line on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Horizontal Line\" graphical object."
#property description "Anchor point price is set in percentage of the height of"
#property description "the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="HLine"; // Line name
input int InpPrice=25; // Line price, %
input color InpColor=clrRed; // Line color
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // Line style
input int InpWidth=3; // Line width
input bool InpBack=false; // Background line
input bool InpSelection=true; // Highlight to move
input bool InpHidden=true; // Hidden in the object list
input long InpZOrder=0; // Priority for mouse click
//+------------------------------------------------------------------+
//| Create the horizontal line |
//+------------------------------------------------------------------+
//---
}
OBJ_TREND
Trend Line.
Note
For Trend Line, it is possible to specify the mode of continuation of its display to the right and/or
left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly).
Example
The following script creates and moves the trend line on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Trend Line\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Trend"; // Line name
input int InpDate1=35; // 1 st point's date, %
input int InpPrice1=60; // 1 st point's price, %
input int InpDate2=65; // 2 nd point's date, %
input int InpPrice2=40; // 2 nd point's price, %
input color InpColor=clrRed; // Line color
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // Line style
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- enable (true) or disable (false) the mode of continuation of the line's display to the left
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- enable (true) or disable (false) the mode of continuation of the line's display to the right
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move trend line anchor point |
//+------------------------------------------------------------------+
bool TrendPointChange(const long chart_ID=0, // chart's ID
const string name="TrendLine", // line name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move trend line's anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| The function deletes the trend line from the chart. |
//+------------------------------------------------------------------+
bool TrendDelete(const long chart_ID=0, // chart's ID
const string name="TrendLine") // line name
{
//--- reset the error value
ResetLastError();
//--- delete a trend line
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete a trend line! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of trend line's anchor points and set default |
//| values for empty ones |
//+------------------------------------------------------------------+
void ChangeTrendEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- if the first point's time is not set, it will be on the current bar
if(!time1)
time1=TimeCurrent();
//--- if the first point's price is not set, it will have Bid value
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it is located 9 bars left from the second one
if(!time2)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- set the second point 9 bars left from the first one
time2=temp[0];
}
//--- if the second point's price is not set, it is equal to the first point's one
if(!price2)
price2=price1;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- move the second anchor point vertically
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p2<accuracy-1)
p2+=1;
//--- move the point
if(!TrendPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- half a second of delay
Sleep(500);
//--- loop counter
int h_steps=bars/2;
//--- move both anchor points horizontally at the same time
for(int i=0;i<h_steps;i++)
{
//--- use the following values
if(d1<bars-1)
d1+=1;
if(d2>1)
d2-=1;
//--- shift the points
if(!TrendPointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!TrendPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.03 seconds of delay
Sleep(30);
}
//--- 1 second of delay
Sleep(1000);
OBJ_TRENDBYANGLE
Trend Line By Angle.
Note
For Trend Line By Angle, it is possible to specify the mode of continuation of its display to the right
and/or left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly).
Both angle and the second anchor point's coordinates can be used to set the slope of the line.
Example
The following script creates and moves the trend line on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Trend Line By Angle\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Trend"; // Line name
input int InpDate1=50; // 1 st point's date, %
input int InpPrice1=75; // 1 st point's price, %
input int InpAngle=0; // Line's slope angle
input color InpColor=clrRed; // Line color
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // Line style
time2=second_point_time[0];
price2=price1;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing line anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the line
int d1=InpDate1*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
//--- create a trend line
if(!TrendByAngleCreate(0,InpName,0,date[d1],price[p1],InpAngle,InpColor,InpStyle,
InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
OBJ_CYCLES
Cycle Lines.
Note
The distance between the lines is set by time coordinates of two anchor points of the object.
Example
The following script creates and moves cycle lines on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates cycle lines on the chart."
#property description "Anchor point coordinates are set in percentage"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Cycles"; // Object name
input int InpDate1=10; // 1 st point's date, %
input int InpPrice1=45; // 1 st point's price, %
input int InpDate2=20; // 2 nd point's date, %
input int InpPrice2=55; // 2 nd point's price, %
input color InpColor=clrRed; // Color of cycle lines
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // Style of cycle lines
input int InpWidth=1; // Width of cycle lines
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool CyclesPointChange(const long chart_ID=0, // chart's ID
const string name="Cycles", // object name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete the cycle lines |
//+------------------------------------------------------------------+
bool CyclesDelete(const long chart_ID=0, // chart's ID
const string name="Cycles") // object name
{
//--- reset the error value
ResetLastError();
//--- delete cycle lines
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete cycle lines! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of cycle lines' anchor points and set default |
//| values for empty ones |
//+------------------------------------------------------------------+
void ChangeCyclesEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- if the first point's time is not set, it will be on the current bar
if(!time1)
time1=TimeCurrent();
//--- if the first point's price is not set, it will have Bid value
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it is located 9 bars left from the second one
if(!time2)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- set the second point 9 bars left from the first one
time2=temp[0];
}
//--- if the second point's price is not set, it is equal to the first point's one
if(!price2)
price2=price1;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing the coordinates of cycle lines' anchor points
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
OBJ_ARROWED_LINE
Arrowed line.
Example
The following script creates and moves an arrow line on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Arrowed line\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ArrowedLine"; // Line name
input int InpDate1=35; // 1 st point's date, %
input int InpPrice1=60; // 1 st point's price, %
input int InpDate2=65; // 2 nd point's date, %
input int InpPrice2=40; // 2 nd point's price, %
input color InpColor=clrRed; // Line color
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // Line style
input int InpWidth=2; // Line width
input bool InpBack=false; // Background line
input bool InpSelection=true; // Highlight to move
input bool InpHidden=true; // Hidden in the object list
input long InpZOrder=0; // Priority for mouse click
//+------------------------------------------------------------------+
//| Create an arrowed line by the given coordinates |
//+------------------------------------------------------------------+
bool ArrowedLineCreate(const long chart_ID=0, // chart's ID
const string name="ArrowedLine", // line name
const int sub_window=0, // subwindow index
datetime time1=0, // first point time
double price1=0, // first point price
datetime time2=0, // second point time
double price2=0, // second point price
const color clr=clrRed, // line color
const ENUM_LINE_STYLE style=STYLE_SOLID, // line style
const int width=1, // line width
const bool back=false, // in the background
const bool selection=true, // highlight to move
const bool hidden=true, // hidden in the object list
const long z_order=0) // priority for mouse click
{
//--- set anchor points' coordinates if they are not set
ChangeArrowedLineEmptyPoints(time1,price1,time2,price2);
//--- reset the error value
ResetLastError();
//--- create an arrowed line by the given coordinates
if(!ObjectCreate(chart_ID,name,OBJ_ARROWED_LINE,sub_window,time1,price1,time2,price2))
{
Print(__FUNCTION__,
": failed to create an arrowed line! Error code = ",GetLastError());
return(false);
}
//--- set line color
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set line display style
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set line width
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the line by mouse
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move arrowed line's anchor point |
//+------------------------------------------------------------------+
bool ArrowedLinePointChange(const long chart_ID=0, // chart's ID
const string name="ArrowedLine", // line name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the line's anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| The function removes the arrowed line from the chart |
//+------------------------------------------------------------------+
bool ArrowedLineDelete(const long chart_ID=0, // chart's ID
const string name="ArrowedLine") // line name
{
//--- reset the error value
ResetLastError();
//--- delete an arrowed line
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to create an arrowed line! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check anchor points' values and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
OBJ_CHANNEL
Equidistant Channel
Note
For an equidistant channel, it is possible to specify the mode of its continuation to the right and/or
to the left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly). The mode of
filling the channel with color can also be set.
Example
The following script creates and moves an equidistant channel on the chart. Special functions have
been developed to create and change graphical object's properties. You can use these functions " as
is " in your own applications.
//--- description
#property description "Script draws \"Equidistant Channel\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Channel"; // Channel name
input int InpDate1=25; // 1 st point's date, %
input int InpPrice1=60; // 1 st point's price, %
input int InpDate2=65; // 2 nd point's date, %
input int InpPrice2=80; // 2 nd point's price, %
input int InpDate3=30; // 3 rd point's date, %
//+------------------------------------------------------------------+
//| Delete the channel |
//+------------------------------------------------------------------+
bool ChannelDelete(const long chart_ID=0, // chart's ID
const string name="Channel") // channel name
{
//--- reset the error value
ResetLastError();
//--- delete the channel
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the channel! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+-------------------------------------------------------------------------+
//| Check the values of the channel's anchor points and set default values |
//| for empty ones |
//+-------------------------------------------------------------------------+
void ChangeChannelEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- if the second (right) point's time is not set, it will be on the current bar
if(!time2)
time2=TimeCurrent();
//--- if the second point's price is not set, it will have Bid value
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the first (left) point's time is not set, it is located 9 bars left from the second one
if(!time1)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- set the first point 9 bars left from the second one
time1=temp[0];
}
//--- if the first point's price is not set, move it 300 points higher than the second one
if(!price1)
price1=price2+300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- if the third point's time is not set, it coincides with the first point's one
if(!time3)
time3=time1;
//--- if the third point's price is not set, it is equal to the second point's one
if(!price3)
price3=price2;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing channel anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the channel
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- create the equidistant channel
if(!ChannelCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],InpColor,
InpStyle,InpWidth,InpFill,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the channel's anchor points
//--- loop counter
int h_steps=bars/6;
//--- move the second anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d2<bars-1)
d2+=1;
//--- move the point
if(!ChannelPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- move the first anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d1>1)
d1-=1;
//--- move the point
if(!ChannelPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
int v_steps=accuracy/10;
//--- move the third anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p3>1)
p3-=1;
//--- move the point
if(!ChannelPointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the channel from the chart
ChannelDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_STDDEVCHANNEL
Standard Deviation Channel.
Note
For Standard Deviation Channel, it is possible to specify the mode of continuation of its display to
the right and/or left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly). The
mode of filling the channel with color can also be set.
OBJPR OP_DEVI ATION property is used to change the value of the channel deviation.
Example
The following script creates and moves Standard Deviation Channel on the chart. Special functions
have been developed to create and change graphical object's properties. You can use these functions
" as is " in your own applications.
//--- description
#property description "Script draws \"Standard Deviation Channel\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="StdDevChannel"; // Channel name
input int InpDate1=10; // 1 st point's date, %
input int InpDate2=40; // 2 nd point's date, %
input double InpDeviation=1.0; // Deviation
input color InpColor=clrRed; // Channel color
ObjectSetInteger(chart_ID,name,OBJPROP_FILL,fill);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of highlighting the channel for moving
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- enable (true) or disable (false) the mode of continuation of the channel's display to the lef
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- enable (true) or disable (false) the mode of continuation of the channel's display to the rig
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the channel's anchor point |
//+------------------------------------------------------------------+
bool StdDevChannelPointChange(const long chart_ID=0, // chart's ID
const string name="Channel", // channel name
const int point_index=0, // anchor point index
datetime time=0) // anchor point time coordinate
{
//--- if point time is not set, move the point to the current bar
if(!time)
time=TimeCurrent();
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,point_index,time,0))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change the channel's deviation |
//+------------------------------------------------------------------+
bool StdDevChannelDeviationChange(const long chart_ID=0, // chart's ID
const string name="Channel", // channel name
const double deviation=1.0) // deviation
{
//--- reset the error value
ResetLastError();
//--- change trend line's slope angle
if(!ObjectSetDouble(chart_ID,name,OBJPROP_DEVIATION,deviation))
{
Print(__FUNCTION__,
": failed to change channel deviation! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete the channel |
//+------------------------------------------------------------------+
bool StdDevChannelDelete(const long chart_ID=0, // chart's ID
const string name="Channel") // channel name
{
//--- reset the error value
ResetLastError();
//--- delete the channel
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the channel! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+-------------------------------------------------------------------------+
//| Check the values of the channel's anchor points and set default values |
//| for empty ones |
//+-------------------------------------------------------------------------+
void ChangeChannelEmptyPoints(datetime &time1,datetime &time2)
{
//--- if the second point's time is not set, it will be on the current bar
if(!time2)
time2=TimeCurrent();
//--- if the first point's time is not set, it is located 9 bars left from the second one
if(!time1)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- set the first point 9 bars left from the second one
time1=temp[0];
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 ||
InpDate2<0 || InpDate2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing channel anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the channel
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
//--- create standard deviation channel
if(!StdDevChannelCreate(0,InpName,0,date[d1],date[d2],InpDeviation,InpColor,InpStyle,
InpWidth,InpFill,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the channel horizontally to the right and expand it
//--- loop counter
int h_steps=bars/2;
//--- move the channel
for(int i=0;i<h_steps;i++)
{
//--- use the following values
if(d1<bars-1)
d1+=1;
if(d2<bars-1)
d2+=1;
//--- move the anchor points
if(!StdDevChannelPointChange(0,InpName,0,date[d1]))
return;
if(!StdDevChannelPointChange(0,InpName,1,date[d2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
double v_steps=InpDeviation*2;
//--- expand the channel
for(double i=InpDeviation;i<v_steps;i+=10.0/accuracy)
{
if(!StdDevChannelDeviationChange(0,InpName,i))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the channel from the chart
StdDevChannelDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
OBJ_REGRESSION
Linear R egression Channel.
Note
For Linear R egression Channel, it is possible to specify the mode of continuation of its display to the
right and/or left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly). The mode
of filling the channel with color can also be set.
Example
The following script creates and moves Linear R egression Channel on the chart. Special functions
have been developed to create and change graphical object's properties. You can use these functions
" as is " in your own applications.
//--- description
#property description "Script draws \"Linear Regression Channel\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Regression"; // Channel name
input int InpDate1=10; // 1 st point's date, %
input int InpDate2=40; // 2 nd point's date, %
input color InpColor=clrRed; // Channel color
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // Style of channel lines
input int InpWidth=2; // Width of channel lines
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- enable (true) or disable (false) the mode of continuation of the channel's display to the lef
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- enable (true) or disable (false) the mode of continuation of the channel's display to the rig
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the channel's anchor point |
//+------------------------------------------------------------------+
bool RegressionPointChange(const long chart_ID=0, // chart's ID
const string name="Channel", // channel name
const int point_index=0, // anchor point index
datetime time=0) // anchor point time coordinate
{
//--- if point time is not set, move the point to the current bar
if(!time)
time=TimeCurrent();
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,point_index,time,0))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete the channel |
//+------------------------------------------------------------------+
bool RegressionDelete(const long chart_ID=0, // chart's ID
const string name="Channel") // channel name
{
//--- reset the error value
ResetLastError();
//--- delete the channel
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the channel! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+-------------------------------------------------------------------------+
//| Check the values of the channel's anchor points and set default values |
//| for empty ones |
//+-------------------------------------------------------------------------+
void ChangeRegressionEmptyPoints(datetime &time1,datetime &time2)
{
//--- if the second point's time is not set, it will be on the current bar
if(!time2)
time2=TimeCurrent();
//--- if the first point's time is not set, it is located 9 bars left from the second one
if(!time1)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- set the first point 9 bars left from the second one
time1=temp[0];
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 ||
InpDate2<0 || InpDate2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing channel anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- delete the channel from the chart
RegressionDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_PITCHFORK
Andrews ’ Pitchfork .
Note
For Andrews ’ Pitchfork , it is possible to specify the mode of continuation of its display to the right
and/or left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly).
You can also specify the number of line-levels, their values and color.
Example
The following script creates and moves Andrews ’ Pitchfork on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Andrews’ Pitchfork\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Pitchfork"; // Pitchfork name
input int InpDate1=14; // 1 st point's date, %
input int InpPrice1=40; // 1 st point's price, %
input int InpDate2=18; // 2 nd point's date, %
input int InpPrice2=50; // 2 nd point's price, %
input int InpDate3=18; // 3 rd point's date, %
input int InpPrice3=30; // 3 rd point's price, %
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of highlighting the pitchfork for moving
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- enable (true) or disable (false) the mode of continuation of the pitchfork's display to the l
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- enable (true) or disable (false) the mode of continuation of the pitchfork's display to the r
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Set number of Andrews' Pitchfork levels and their parameters |
//+------------------------------------------------------------------+
bool PitchforkLevelsSet(int levels, // number of level lines
double &values[], // values of level lines
color &colors[], // color of level lines
ENUM_LINE_STYLE &styles[], // style of level lines
int &widths[], // width of level lines
const long chart_ID=0, // chart's ID
const string name="Pitchfork") // pitchfork name
{
//--- check array sizes
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- set the number of levels
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- set the properties of levels in the loop
for(int i=0;i<levels;i++)
{
//--- level value
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- level color
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- level style
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- level width
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
}
//+----------------------------------------------------------------------+
//| Check the values of Andrews' Pitchfork anchor points and set default |
//| values for empty ones |
//+----------------------------------------------------------------------+
void ChangeChannelEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- if the second (upper right) point's time is not set, it will be on the current bar
if(!time2)
time2=TimeCurrent();
//--- if the second point's price is not set, it will have Bid value
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the first (left) point's time is not set, it is located 9 bars left from the second one
if(!time1)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- set the first point 9 bars left from the second one
time1=temp[0];
}
//--- if the first point's price is not set, move it 200 points below the second one
if(!price1)
price1=price2-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- if the third point's time is not set, it coincides with the second point's one
if(!time3)
time3=time2;
//--- if the third point's price is not set, move it 200 points lower than the first one
if(!price3)
price3=price1-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing the coordinates of Andrews' Pitchfork anchor points
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing Andrews' Pitchfork
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- create the pitchfork
if(!PitchforkCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the pitchfork's anchor points
//--- loop counter
int v_steps=accuracy/10;
//--- move the first anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p1>1)
p1-=1;
//--- move the point
if(!PitchforkPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
int h_steps=bars/8;
//--- move the third anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d3<bars-1)
d3+=1;
//--- move the point
if(!PitchforkPointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
v_steps=accuracy/10;
//--- move the second anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p2>1)
p2-=1;
//--- move the point
if(!PitchforkPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the pitchfork from the chart
PitchforkDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_GANNLINE
Gann Line.
Note
For Gann Line, it is possible to specify the mode of continuation of its display to the right and/or
left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly).
Both Gann angle with a scale and coordinates of the second anchor point can be used to set the slope
of the line.
Example
The following script creates and moves Gann Line on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Gann Line\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="GannLine"; // Line name
input int InpDate1=20; // 1 st point's date, %
input int InpPrice1=75; // 1 st point's price, %
input int InpDate2=80; // 2 nd point's date, %
input double InpAngle=0.0; // Gann Angle
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set line display style
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set line width
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of highlighting the lines for moving
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- enable (true) or disable (false) the mode of continuation of the line's display to the left
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- enable (true) or disable (false) the mode of continuation of the line's display to the right
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Gann Line anchor point |
//+------------------------------------------------------------------+
bool GannLinePointChange(const long chart_ID=0, // chart's ID
const string name="GannLine", // line name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the line's anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Gann angle |
//+------------------------------------------------------------------+
bool GannLineAngleChange(const long chart_ID=0, // chart's ID
const string name="GannLine", // line name
const double angle=1.0) // Gann angle
{
//--- reset the error value
ResetLastError();
//--- change Gann angle
if(!ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle))
{
Print(__FUNCTION__,
": failed to change Gann angle! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Gann Line's scale |
//+------------------------------------------------------------------+
bool GannLineScaleChange(const long chart_ID=0, // chart's ID
const string name="GannLine", // line name
const double scale=1.0) // scale
{
//--- reset the error value
ResetLastError();
//--- change the scale (number of pips per bar)
if(!ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale))
{
Print(__FUNCTION__,
": failed to change the scale! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| The function removes Gann Line from the chart |
//+------------------------------------------------------------------+
bool GannLineDelete(const long chart_ID=0, // chart's ID
const string name="GannLine") // line name
{
//--- reset the error value
ResetLastError();
//--- delete Gann line
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Gann Line\"! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of Gann Line anchor points and set default |
//| values for empty ones |
//+------------------------------------------------------------------+
void ChangeGannLineEmptyPoints(datetime &time1,double &price1,datetime &time2)
{
//--- if the second point's time is not set, it will be on the current bar
if(!time2)
time2=TimeCurrent();
//--- if the first point's time is not set, it is located 9 bars left from the second one
if(!time1)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- set the first point 9 bars left from the second one
time1=temp[0];
}
//--- if the first point's price is not set, it will have Bid value
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing line anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing Gann Line
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
//--- create Gann Line
if(!GannLineCreate(0,InpName,0,date[d1],price[p1],date[d2],InpAngle,InpScale,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the line's anchor point and change the angle
//--- loop counter
int v_steps=accuracy/2;
//--- move the first anchor point vertically
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p1>1)
p1-=1;
//--- move the point
if(!GannLinePointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- half a second of delay
Sleep(500);
//--- define the current value of Gann angle (changed
//--- after moving the first anchor point)
double curr_angle;
if(!ObjectGetDouble(0,InpName,OBJPROP_ANGLE,0,curr_angle))
return;
//--- loop counter
v_steps=accuracy/8;
//--- change Gann angle
for(int i=0;i<v_steps;i++)
{
if(!GannLineAngleChange(0,InpName,curr_angle-0.05*i))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the line from the chart
GannLineDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_GANNFAN
Gann Fan.
Note
For Gann Fan, it is possible to specify trend type from ENUM _GANN_DIRECTION enumeration. By
adjusting the scale value (OBJPR OP_SCAL E), it is possible to change slope angle of the fan lines.
Example
The following script creates and moves Gann Fan on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Gann Fan\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="GannFan"; // Fan name
input int InpDate1=15; // 1 st point's date, %
input int InpPrice1=25; // 1 st point's price, %
input int InpDate2=85; // 2 nd point's date, %
input double InpScale=2.0; // Scale
input bool InpDirection=false; // Trend direction
input color InpColor=clrRed; // Fan color
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Gann Fan anchor point |
//+------------------------------------------------------------------+
bool GannFanPointChange(const long chart_ID=0, // chart's ID
const string name="GannFan", // fan name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the fan's anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Gann Fan's scale |
//+------------------------------------------------------------------+
bool GannFanScaleChange(const long chart_ID=0, // chart's ID
const string name="GannFan", // fan name
const double scale=1.0) // scale
{
//--- reset the error value
ResetLastError();
//--- change the scale (number of pips per bar)
if(!ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale))
{
Print(__FUNCTION__,
": failed to change the scale! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Gann Fan's trend direction |
//+------------------------------------------------------------------+
bool GannFanDirectionChange(const long chart_ID=0, // chart's ID
const string name="GannFan", // fan name
const bool direction=true) // trend direction
{
//--- reset the error value
ResetLastError();
//--- change Gann Fan's trend direction
if(!ObjectSetInteger(chart_ID,name,OBJPROP_DIRECTION,direction))
{
Print(__FUNCTION__,
": failed to change trend direction! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| The function removes Gann Fan from the chart |
//+------------------------------------------------------------------+
bool GannFanDelete(const long chart_ID=0, // chart's ID
const string name="GannFan") // fan name
{
//--- reset the error value
ResetLastError();
//--- delete Gann Fan
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Gann Fan\"! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
// | Check the values of Gann Fan anchor points and set default |
//| values for empty ones |
//+------------------------------------------------------------------+
OBJ_GANNGRID
Gann Grid.
Note
For Gann Grid, it is possible to specify trend type from ENUM _GANN_DIRECTION. By adjusting the
scale value (OBJPR OP_SCAL E), it is possible to change slope angle of the grid lines.
Example
The following script creates and moves Gann Grid on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Gann Grid\" graphical object."
#property description "Anchor point coordinates of the grid are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="GannGrid"; // Grid name
input int InpDate1=15; // 1 st point's date, %
input int InpPrice1=25; // 1 st point's price, %
input int InpDate2=35; // 2 nd point's date, %
input double InpScale=3.0; // Scale
input bool InpDirection=false; // Trend direction
input color InpColor=clrRed; // Grid color
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Gann Grid anchor point |
//+------------------------------------------------------------------+
bool GannGridPointChange(const long chart_ID=0, // chart's ID
const string name="GannGrid", // grid name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the grid's anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Gann Grid's scale |
//+------------------------------------------------------------------+
bool GannGridScaleChange(const long chart_ID=0, // chart's ID
const string name="GannGrid", // grids
const double scale=1.0) // scale
{
//--- reset the error value
ResetLastError();
//--- change the scale (number of pips per bar)
if(!ObjectSetDouble(chart_ID,name,OBJPROP_SCALE,scale))
{
Print(__FUNCTION__,
": failed to change the scale! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Gann Grid's trend direction |
//+------------------------------------------------------------------+
bool GannGridDirectionChange(const long chart_ID=0, // chart's ID
const string name="GannGrid", // grid name
const bool direction=true) // trend direction
{
//--- reset the error value
ResetLastError();
//--- change Gann Grid's trend direction
if(!ObjectSetInteger(chart_ID,name,OBJPROP_DIRECTION,direction))
{
Print(__FUNCTION__,
": failed to change trend direction! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| The function removes Gann Fan from the chart |
//+------------------------------------------------------------------+
bool GannGridDelete(const long chart_ID=0, // chart's ID
const string name="GannGrid") // grid name
{
//--- reset the error value
ResetLastError();
//--- delete Gann Grid
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Gann Grid\"! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of Gann Grid anchor points and set default |
//| values for empty ones |
//+------------------------------------------------------------------+
OBJ_FIBO
Fibonacci R etracement.
Note
For Fibonacci R etracement, it is possible to specify the mode of continuation of its display to the
right and/or left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly).
You can also specify the number of line-levels, their values and color.
Example
The following script creates and moves Fibonacci R etracement on the chart. Special functions have
been developed to create and change graphical object's properties. You can use these functions " as
is " in your own applications.
//--- description
#property description "Script draws \"Fibonacci Retracement\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="FiboLevels"; // Object name
input int InpDate1=10; // 1 st point's date, %
input int InpPrice1=65; // 1 st point's price, %
input int InpDate2=90; // 2 nd point's date, %
input int InpPrice2=85; // 2 nd point's price, %
input color InpColor=clrRed; // Object color
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- enable (true) or disable (false) the mode of continuation of the object's display to the left
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_LEFT,ray_left);
//--- enable (true) or disable (false) the mode of continuation of the object's display to the righ
ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Set number of levels and their parameters |
//+------------------------------------------------------------------+
bool FiboLevelsSet(int levels, // number of level lines
double &values[], // values of level lines
color &colors[], // color of level lines
ENUM_LINE_STYLE &styles[], // style of level lines
int &widths[], // width of level lines
const long chart_ID=0, // chart's ID
const string name="FiboLevels") // object name
{
//--- check array sizes
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- set the number of levels
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- set the properties of levels in the loop
for(int i=0;i<levels;i++)
{
//--- level value
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- level color
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- level style
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- level width
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- level description
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1));
}
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing Fibonacci Retracement
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- create an object
if(!FiboLevelsCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor points
//--- loop counter
int v_steps=accuracy*2/5;
//--- move the first anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p1>1)
p1-=1;
//--- move the point
if(!FiboLevelsPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
v_steps=accuracy*4/5;
OBJ_FIBOTIMES
Fibonacci Time Zones.
Note
For "Fibonacci Time Zones " , it is possible to specify the number of line-levels, their values and
color.
Example
The following script creates and moves Fibonacci Time Zones on the chart. Special functions have
been developed to create and change graphical object's properties. You can use these functions " as
is " in your own applications.
//--- description
#property description "Script draws \"Fibonacci Time Zones\" graphical object."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="FiboTimes"; // Object name
input int InpDate1=10; // 1 st point's date, %
input int InpPrice1=45; // 1 st point's price, %
input int InpDate2=20; // 2 nd point's date, %
input int InpPrice2=55; // 2 nd point's price, %
input color InpColor=clrRed; // Object color
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // Line style
input int InpWidth=2; // Line width
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Set number of levels and their parameters |
//+------------------------------------------------------------------+
bool FiboTimesLevelsSet(int levels, // number of level lines
double &values[], // values of level lines
color &colors[], // color of level lines
ENUM_LINE_STYLE &styles[], // style of level lines
int &widths[], // width of level lines
const long chart_ID=0, // chart's ID
const string name="FiboTimes") // object name
{
//--- check array sizes
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- set the number of levels
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- set the properties of levels in the loop
for(int i=0;i<levels;i++)
{
//--- level value
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- level color
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- level style
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- level width
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- level description
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(values[i],1));
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Fibonacci Time Zones anchor point |
//+------------------------------------------------------------------+
bool FiboTimesPointChange(const long chart_ID=0, // chart's ID
const string name="FiboTimes", // object name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it is located 2 bars left from the second one
if(!time2)
{
//--- array for receiving the open time of the last 3 bars
datetime temp[3];
CopyTime(Symbol(),Period(),time1,3,temp);
//--- set the first point 2 bars left from the second one
time2=temp[0];
}
//--- if the second point's price is not set, it is equal to the first point's one
if(!price2)
price2=price1;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing the coordinates of Fibonacci Time Zones anchor points
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing Fibonacci Time Zones
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- create an object
if(!FiboTimesCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor points
//--- loop counter
int h_steps=bars*2/5;
//--- move the second anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d2<bars-1)
d2+=1;
//--- move the point
if(!FiboTimesPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
h_steps=bars*3/5;
//--- move the first anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d1<bars-1)
d1+=1;
//--- move the point
if(!FiboTimesPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- delete the object from the chart
FiboTimesDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_FIBOFAN
Fibonacci Fan.
Note
For "Fibonacci Fan" , it is possible to specify the number of line-levels, their values and color.
Example
The following script creates and moves Fibonacci Fan on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Fibonacci Fan\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="FiboFan"; // Fan name
input int InpDate1=10; // 1 st point's date, %
input int InpPrice1=25; // 1 st point's price, %
input int InpDate2=30; // 2 nd point's date, %
input int InpPrice2=50; // 2 nd point's price, %
input color InpColor=clrRed; // Fan line color
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // Line style
input int InpWidth=2; // Line width
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Set number of levels and their parameters |
//+------------------------------------------------------------------+
bool FiboFanLevelsSet(int levels, // number of level lines
double &values[], // values of level lines
color &colors[], // color of level lines
ENUM_LINE_STYLE &styles[], // style of level lines
int &widths[], // width of level lines
const long chart_ID=0, // chart's ID
const string name="FiboFan") // fan name
{
//--- check array sizes
if(levels!=ArraySize(colors) || levels!=ArraySize(styles) ||
levels!=ArraySize(widths) || levels!=ArraySize(widths))
{
Print(__FUNCTION__,": array length does not correspond to the number of levels, error!");
return(false);
}
//--- set the number of levels
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELS,levels);
//--- set the properties of levels in the loop
for(int i=0;i<levels;i++)
{
//--- level value
ObjectSetDouble(chart_ID,name,OBJPROP_LEVELVALUE,i,values[i]);
//--- level color
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELCOLOR,i,colors[i]);
//--- level style
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELSTYLE,i,styles[i]);
//--- level width
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- level description
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1));
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Fibonacci Fan anchor point |
//+------------------------------------------------------------------+
bool FiboFanPointChange(const long chart_ID=0, // chart's ID
const string name="FiboFan", // fan name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the first point's time is not set, it is located 9 bars left from the second one
if(!time1)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- set the first point 9 bars left from the second one
time1=temp[0];
}
//--- if the first point's price is not set, move it 200 points below the second one
if(!price1)
price1=price2-200*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing the coordinates of Fibonacci Fan anchor points
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing Fibonacci Fan
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- create an object
if(!FiboFanCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the fan's anchor points
//--- loop counter
int v_steps=accuracy/2;
//--- move the first anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p1<accuracy-1)
p1+=1;
//--- move the point
if(!FiboFanPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
int h_steps=bars/4;
//--- move the second anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d2<bars-1)
d2+=1;
//--- move the point
if(!FiboFanPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- delete the object from the chart
FiboFanDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_FIBOARC
Fibonacci Arcs.
Note
For "Fibonacci Arcs " , it is possible to specify the display mode of the entire ellipse. Curvature radius
can be specified by changing the scale and coordinates of the anchor points.
You can also specify the number of line-levels, their values and color.
Example
The following script creates and moves Fibonacci Arcs on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Fibonacci Arcs\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="FiboArc"; // Object name
input int InpDate1=25; // 1 st point's date, %
input int InpPrice1=25; // 1 st point's price, %
input int InpDate2=35; // 2 nd point's date, %
input int InpPrice2=55; // 2 nd point's price, %
input double InpScale=3.0; // Scale
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing Fibonacci Arcs
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- create an object
if(!FiboArcCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],InpScale,
InpFullEllipse,InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor points
//--- loop counter
int v_steps=accuracy/5;
//--- move the first anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p1<accuracy-1)
p1+=1;
//--- move the point
if(!FiboArcPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
int h_steps=bars/5;
OBJ_FIBOCHANNEL
Fibonacci Channel.
Note
For Fibonacci Channel, it is possible to specify the mode of continuation of its display to the right
and/or left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly).
You can also specify the number of line-levels, their values and color.
Example
The following script creates and moves Fibonacci Channel on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Fibonacci Channel\" graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="FiboChannel"; // Channel name
input int InpDate1=20; // 1 st point's date, %
input int InpPrice1=10; // 1 st point's price, %
input int InpDate2=60; // 2 nd point's date, %
input int InpPrice2=30; // 2 nd point's price, %
input int InpDate3=20; // 3 rd point's date, %
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- level description
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,DoubleToString(100*values[i],1));
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Fibonacci Channel anchor point |
//+------------------------------------------------------------------+
bool FiboChannelPointChange(const long chart_ID=0, // chart's ID
const string name="FiboChannel", // channel name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete the channel |
//+------------------------------------------------------------------+
bool FiboChannelDelete(const long chart_ID=0, // chart's ID
const string name="FiboChannel") // channel name
{
//--- reset the error value
ResetLastError();
//--- delete the channel
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Fibonacci Channel\"! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of Fibonacci Channel anchor points and set |
//| default values for empty ones |
//+------------------------------------------------------------------+
void ChangeFiboChannelEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- if the second (right) point's time is not set, it will be on the current bar
if(!time2)
time2=TimeCurrent();
//--- if the second point's price is not set, it will have Bid value
if(!price2)
price2=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the first (left) point's time is not set, it is located 9 bars left from the second one
if(!time1)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time2,10,temp);
//--- set the first point 9 bars left from the second one
time1=temp[0];
}
//--- if the first point's price is not set, move it 300 points higher than the second one
if(!price1)
price1=price2+300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- if the third point's time is not set, it coincides with the first point's one
if(!time3)
time3=time1;
//--- if the third point's price is not set, it is equal to the second point's one
if(!price3)
price3=price2;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
OBJ_EXPANSION
Fibonacci Expansion.
Note
For "Fibonacci Expansion" , it is possible to specify the mode of continuation of its display to the
right and/or left (OBJPR OP_RAY_R I GH T and OBJPR OP_RAY_L EFT properties accordingly).
You can also specify the number of line-levels, their values and color.
Example
The following script creates and moves Fibonacci Expansion on the chart. Special functions have
been developed to create and change graphical object's properties. You can use these functions " as
is " in your own applications.
//--- description
#property description "Script draws \"Fibonacci Expansion\"graphical object."
#property description "Anchor point coordinates are set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="FiboExpansion"; // Object name
input int InpDate1=10; // 1 st point's date, %
input int InpPrice1=55; // 1 st point's price, %
input int InpDate2=30; // 2 nd point's date, %
input int InpPrice2=10; // 2 nd point's price, %
input int InpDate3=80; // 3 rd point's date, %
ObjectSetInteger(chart_ID,name,OBJPROP_LEVELWIDTH,i,widths[i]);
//--- level description
ObjectSetString(chart_ID,name,OBJPROP_LEVELTEXT,i,"FE "+DoubleToString(100*values[i],1));
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Fibonacci Expansion anchor point |
//+------------------------------------------------------------------+
bool FiboExpansionPointChange(const long chart_ID=0, // chart's ID
const string name="FiboExpansion", // object name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete Fibonacci Expansion |
//+------------------------------------------------------------------+
bool FiboExpansionDelete(const long chart_ID=0, // chart's ID
const string name="FiboExpansion") // object name
{
//--- reset the error value
ResetLastError();
//--- delete the object
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Fibonacci Expansion\"! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of Fibonacci Expansion anchor points and set |
//| default values for empty ones |
//+------------------------------------------------------------------+
void ChangeFiboExpansionEmptyPoints(datetime &time1,double &price1,datetime &time2,
double &price2,datetime &time3,double &price3)
{
//--- if the third (right) point's time is not set, it will be on the current bar
if(!time3)
time3=TimeCurrent();
//--- if the third point's price is not set, it will have Bid value
if(!price3)
price3=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the first (left) point's time is not set, it is located 9 bars left from the third one
//--- array for receiving the open time of the last 10 bars
datetime temp[];
ArrayResize(temp,10);
if(!time1)
{
CopyTime(Symbol(),Period(),time3,10,temp);
//--- set the first point 9 bars left from the second one
time1=temp[0];
}
//--- if the first point's price is not set, it is equal to the third point's one
if(!price1)
price1=price3;
//--- if the second point's time is not set, it is located 7 bars left from the third one
if(!time2)
time2=temp[2];
//--- if the second point's price is not set, move it 250 points lower than the first one
if(!price2)
price2=price1-250*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing object anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing Fibonacci Expansion
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- create Fibonacci Expansion
if(!FiboExpansionCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpColor,InpStyle,InpWidth,InpBack,InpSelection,InpRayLeft,InpRayRight,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor points
//--- loop counter
int v_steps=accuracy/10;
//--- move the first anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p1>1)
p1-=1;
//--- move the point
if(!FiboExpansionPointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
v_steps=accuracy/2;
//--- move the third anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p3>1)
p3-=1;
//--- move the point
if(!FiboExpansionPointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
v_steps=accuracy*4/5;
//--- move the second anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p2<accuracy-1)
p2+=1;
//--- move the point
if(!FiboExpansionPointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the object from the chart
FiboExpansionDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_ELLIOTWAVE5
Elliott Motive W ave.
Note
For "Elliott Motive W ave" , it is possible to enable/disable the mode of connecting points by lines
(OBJPR OP_DRAW LI NES property), as well as set the level of wave positioning (from
ENUM _ELLIOT _WAVE_DEGREE enumeration).
Example
The following script creates and moves Elliott motive wave on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Elliott Motive Wave\"."
#property description "Anchor point coordinates are set in percentage of the size of"
#property description "the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ElliotWave5"; // Object name
input int InpDate1=10; // 1 st point's date, %
input int InpPrice1=90; // 1 st point's price, %
input int InpDate2=20; // 2 nd point's date, %
input int InpPrice2=40; // 2 nd point's price, %
input int InpDate3=30; // 3 rd point's date, %
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete Elliott Motive Wave |
//+------------------------------------------------------------------+
bool ElliotWave5Delete(const long chart_ID=0, // chart's ID
const string name="ElliotWave5") // object name
{
//--- reset the error value
ResetLastError();
//--- delete the object
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Elliott Motive Wave\"! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of Elliott Motive Wave's anchor points and |
//| set default values for empty ones |
//+------------------------------------------------------------------+
void ChangeElliotWave5EmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2,
datetime &time3,double &price3,
datetime &time4,double &price4,
datetime &time5,double &price5)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[];
ArrayResize(temp,10);
//--- receive data
CopyTime(Symbol(),Period(),TimeCurrent(),10,temp);
//--- receive the value of one point on the current chart
double point=SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- if the first point's time is not set, it will be 9 bars left from the last bar
if(!time1)
time1=temp[0];
//--- if the first point's price is not set, it will have Bid value
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it will be 7 bars left from the last bar
if(!time2)
time2=temp[2];
//--- if the second point's price is not set, move it 300 points lower than the first one
if(!price2)
price2=price1-300*point;
//--- if the third point's time is not set, it will be 5 bars left from the last bar
if(!time3)
time3=temp[4];
//--- if the third point's price is not set, move it 250 points lower than the first one
if(!price3)
price3=price1-250*point;
//--- if the fourth point's time is not set, it will be 3 bars left from the last bar
if(!time4)
time4=temp[6];
//--- if the fourth point's price is not set, move it 550 points lower than the first one
if(!price4)
price4=price1-550*point;
//--- if the fifth point's time is not set, it will be on the last bar
if(!time5)
time5=temp[9];
//--- if the fifth point's price is not set, move it 450 points lower than the first one
if(!price5)
price5=price1-450*point;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100 ||
InpDate4<0 || InpDate4>100 || InpPrice4<0 || InpPrice4>100 ||
InpDate5<0 || InpDate5>100 || InpPrice5<0 || InpPrice5>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing object anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing Elliott Motive Wave
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int d4=InpDate4*(bars-1)/100;
int d5=InpDate5*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
int p4=InpPrice4*(accuracy-1)/100;
int p5=InpPrice5*(accuracy-1)/100;
//--- Create Elliott Motive Wave
if(!ElliotWave5Create(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
date[d4],price[p4],date[d5],price[p5],InpDegree,InpDrawLines,InpColor,InpStyle,InpWidth,
InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor points
//--- loop counter
int v_steps=accuracy/5;
//--- move the fifth anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p5<accuracy-1)
p5+=1;
//--- move the point
if(!ElliotWave5PointChange(0,InpName,4,date[d5],price[p5]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
v_steps=accuracy/5;
//--- move the second and third anchor points
for(int i=0;i<v_steps;i++)
{
//--- use the following values
if(p2<accuracy-1)
p2+=1;
if(p3>1)
p3-=1;
//--- shift the points
if(!ElliotWave5PointChange(0,InpName,1,date[d2],price[p2]))
return;
if(!ElliotWave5PointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
v_steps=accuracy*4/5;
//--- move the first and fourth anchor points
for(int i=0;i<v_steps;i++)
{
//--- use the following values
if(p1>1)
p1-=1;
if(p4<accuracy-1)
p4+=1;
//--- shift the points
if(!ElliotWave5PointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!ElliotWave5PointChange(0,InpName,3,date[d4],price[p4]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the object from the chart
ElliotWave5Delete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_ELLIOTWAVE3
Elliott Correction W ave.
Note
For "Elliott Correction W ave" , it is possible to enable/disable the mode of connecting points by lines
(OBJPR OP_DRAW LI NES property), as well as set the level of wave positioning (from
ENUM _ELLIOT _WAVE_DEGREE enumeration).
Example
The following script creates and moves Elliott correction wave on the chart. Special functions have
been developed to create and change graphical object's properties. You can use these functions " as
is " in your own applications.
//--- description
#property description "Script draws \"Elliott Correction Wave\" graphical object."
#property description "Anchor point coordinates are set in percentage of the chart's window"
#property description "size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ElliotWave3"; // Object name
input int InpDate1=10; // 1 st point's date, %
input int InpPrice1=90; // 1 st point's price, %
input int InpDate2=30; // 2 nd point's date, %
input int InpPrice2=10; // 2 nd point's price, %
input int InpDate3=50; // 3 rd point's date, %
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor points
//--- loop counter
int v_steps=accuracy/5;
//--- move the third anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p3<accuracy-1)
p3+=1;
//--- move the point
if(!ElliotWave3PointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
v_steps=accuracy*4/5;
//--- move the first and second anchor points
for(int i=0;i<v_steps;i++)
{
//--- use the following values
if(p1>1)
p1-=1;
if(p2<accuracy-1)
p2+=1;
//--- shift the points
if(!ElliotWave3PointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!ElliotWave3PointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the object from the chart
ElliotWave3Delete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_RECTANGLE
R ectangle.
Note
For rectangle, the mode of filling with color can be set using OBJPR OP_FILL property.
Example
The following script creates and moves the rectangle on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates rectangle on the chart."
#property description "Anchor point coordinates are set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Rectangle"; // Rectangle name
input int InpDate1=40; // 1 st point's date, %
input int InpPrice1=40; // 1 st point's price, %
input int InpDate2=60; // 2 nd point's date, %
input int InpPrice2=60; // 2 nd point's price, %
input color InpColor=clrRed; // Rectangle color
input ENUM_LINE_STYLE InpStyle=STYLE_DASH; // Style of rectangle lines
input int InpWidth=2; // Width of rectangle lines
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the rectangle anchor point |
//+------------------------------------------------------------------+
bool RectanglePointChange(const long chart_ID=0, // chart's ID
const string name="Rectangle", // rectangle name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete the rectangle |
//+------------------------------------------------------------------+
bool RectangleDelete(const long chart_ID=0, // chart's ID
const string name="Rectangle") // rectangle name
{
//--- reset the error value
ResetLastError();
//--- delete rectangle
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete rectangle! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of rectangle's anchor points and set default |
//| values for empty ones |
//+------------------------------------------------------------------+
void ChangeRectangleEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2)
{
//--- if the first point's time is not set, it will be on the current bar
if(!time1)
time1=TimeCurrent();
//--- if the first point's price is not set, it will have Bid value
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it is located 9 bars left from the second one
if(!time2)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- set the second point 9 bars left from the first one
time2=temp[0];
}
//--- if the second point's price is not set, move it 300 points lower than the first one
if(!price2)
price2=price1-300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing rectangle anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the rectangle
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
//--- create a rectangle
if(!RectangleCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],InpColor,
InpStyle,InpWidth,InpFill,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the rectangle's anchor points
//--- loop counter
int h_steps=bars/2;
//--- move the anchor points
for(int i=0;i<h_steps;i++)
{
//--- use the following values
if(d1<bars-1)
d1+=1;
if(d2>1)
d2-=1;
//--- shift the points
if(!RectanglePointChange(0,InpName,0,date[d1],price[p1]))
return;
if(!RectanglePointChange(0,InpName,1,date[d2],price[p2]))
return;
OBJ_TRIANGLE
Triangle.
Note
For triangle, the mode of filling with color can be set using OBJPR OP_FILL property.
Example
The following script creates and moves the triangle on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates triangle on the chart."
#property description "Anchor point coordinates are set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Triangle"; // Triangle name
input int InpDate1=25; // 1 st point's date, %
input int InpPrice1=50; // 1 st point's price, %
input int InpDate2=70; // 2 nd point's date, %
input int InpPrice2=70; // 2 nd point's price, %
input int InpDate3=65; // 3 rd point's date, %
input int InpPrice3=20; // 3 rd point's price, %
input color InpColor=clrRed; // Triangle color
//--- enable (true) or disable (false) the mode of highlighting the triangle for moving
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the triangle anchor point |
//+------------------------------------------------------------------+
bool TrianglePointChange(const long chart_ID=0, // chart's ID
const string name="Triangle", // triangle name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete the triangle |
//+------------------------------------------------------------------+
bool TriangleDelete(const long chart_ID=0, // chart's ID
const string name="Triangle") // triangle name
{
//--- reset the error value
ResetLastError();
//--- delete the triangle
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the ellipse! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of triangle's anchor points and set default |
//| values for empty ones |
//+------------------------------------------------------------------+
void ChangeTriangleEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2,
datetime &time3,double &price3)
{
//--- if the first point's time is not set, it will be on the current bar
if(!time1)
time1=TimeCurrent();
//--- if the first point's price is not set, it will have Bid value
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it is located 9 bars left from the second one
if(!time2)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- set the second point 9 bars left from the first one
time2=temp[0];
}
//--- if the second point's price is not set, move it 300 points lower than the first one
if(!price2)
price2=price1-300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- if the third point's time is not set, it coincides with the second point's date
if(!time3)
time3=time2;
//--- if the third point's price is not set, it is equal to the first point's one
if(!price3)
price3=price1;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
int v_steps=accuracy*3/10;
//--- move the first anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p1>1)
p1-=1;
//--- move the point
if(!TrianglePointChange(0,InpName,0,date[d1],price[p1]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
int h_steps=bars*9/20-1;
//--- move the second anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d2>1)
d2-=1;
//--- move the point
if(!TrianglePointChange(0,InpName,1,date[d2],price[p2]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
v_steps=accuracy/4;
//--- move the third anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p3<accuracy-1)
p3+=1;
//--- move the point
if(!TrianglePointChange(0,InpName,2,date[d3],price[p3]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete triangle from the chart
TriangleDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_ELLIPSE
Ellipse.
Note
For ellipse, the mode of filling with color can be set using OBJPR OP_FILL property.
Example
The following script creates and moves the ellipse on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates ellipse on the chart."
#property description "Anchor point coordinates are set"
#property description "in percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Ellipse"; // Ellipse name
input int InpDate1=30; // 1 st point's date, %
input int InpPrice1=20; // 1 st point's price, %
input int InpDate2=70; // 2 nd point's date, %
input int InpPrice2=80; // 2 nd point's price, %
input int InpDate3=50; // 3 rd point's date, %
input int InpPrice3=60; // 3 rd point's price, %
input color InpColor=clrRed; // Ellipse color
input ENUM_LINE_STYLE InpStyle=STYLE_DASHDOTDOT; // Style of ellipse lines
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the ellipse anchor point |
//+------------------------------------------------------------------+
bool EllipsePointChange(const long chart_ID=0, // chart's ID
const string name="Ellipse", // ellipse name
const int point_index=0, // anchor point index
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,point_index,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete ellipse |
//+------------------------------------------------------------------+
bool EllipseDelete(const long chart_ID=0, // chart's ID
const string name="Ellipse") // ellipse name
{
//--- reset the error value
ResetLastError();
//--- delete an ellipse
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete an ellipse! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check the values of ellipse anchor points and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
void ChangeEllipseEmptyPoints(datetime &time1,double &price1,
datetime &time2,double &price2,
datetime &time3,double &price3)
{
//--- if the first point's time is not set, it will be on the current bar
if(!time1)
time1=TimeCurrent();
//--- if the first point's price is not set, it will have Bid value
if(!price1)
price1=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- if the second point's time is not set, it is located 9 bars left from the second one
if(!time2)
{
//--- array for receiving the open time of the last 10 bars
datetime temp[10];
CopyTime(Symbol(),Period(),time1,10,temp);
//--- set the second point 9 bars left from the first one
time2=temp[0];
}
//--- if the second point's price is not set, move it 300 points lower than the first one
if(!price2)
price2=price1-300*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//--- if the third point's time is not set, it coincides with the second point's date
if(!time3)
time3=time2;
//--- if the third point's price is not set, it is equal to the first point's one
if(!price3)
price3=price1;
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate1<0 || InpDate1>100 || InpPrice1<0 || InpPrice1>100 ||
InpDate2<0 || InpDate2>100 || InpPrice2<0 || InpPrice2>100 ||
InpDate3<0 || InpDate3>100 || InpPrice3<0 || InpPrice3>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing ellipse anchor points' coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the ellipse
int d1=InpDate1*(bars-1)/100;
int d2=InpDate2*(bars-1)/100;
int d3=InpDate3*(bars-1)/100;
int p1=InpPrice1*(accuracy-1)/100;
int p2=InpPrice2*(accuracy-1)/100;
int p3=InpPrice3*(accuracy-1)/100;
//--- create an ellipse
if(!EllipseCreate(0,InpName,0,date[d1],price[p1],date[d2],price[p2],date[d3],price[p3],
InpColor,InpStyle,InpWidth,InpFill,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the ellipse anchor points
//--- loop counter
int v_steps=accuracy/5;
OBJ_ARROW_THUMB_UP
Thumbs Up sign.
Note
Anchor point position relative to the sign can be selected from ENUM _ARR OW_ANCH OR
enumeration.
Large signs (more than 5) can only be created by setting the appropriate OBJPR OP_W I DT H property
value when writing a code in MetaEditor.
Example
The following script creates and moves Thumbs Up sign on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Thumbs Up\" sign."
#property description "Anchor point coordinate is set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ThumbUp"; // Sign name
input int InpDate=75; // Anchor point date in %
input int InpPrice=25; // Anchor point price in %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_TOP; // Anchor type
input color InpColor=clrRed; // Sign color
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool ArrowThumbUpMove(const long chart_ID=0, // chart's ID
const string name="ThumbUp", // object name
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Thumbs Up sign anchor type |
//+------------------------------------------------------------------+
bool ArrowThumbUpAnchorChange(const long chart_ID=0, // chart's ID
const string name="ThumbUp", // object name
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // anchor type
{
//--- reset the error value
ResetLastError();
//--- change anchor type
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- arrays for storing the date and price values to be used
//--- for setting and changing sign anchor point coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the sign
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- create Thumbs Up sign on the chart
if(!ArrowThumbUpCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor point and change its position relative to the sign
//--- loop counter
int h_steps=bars/4;
//--- move the anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d>1)
d-=1;
//--- move the point
if(!ArrowThumbUpMove(0,InpName,date[d],price[p]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
OBJ_ARROW_THUMB_DOWN
Thumbs Down sign.
Note
Anchor point position relative to the sign can be selected from ENUM _ARR OW_ANCH OR
enumeration.
Large signs (more than 5) can only be created by setting the appropriate OBJPR OP_W I DT H property
value when writing a code in MetaEditor.
Example
The following script creates and moves Thumbs Down sign on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Thumbs Down\" sign."
#property description "Anchor point coordinate is set in percentage of"
#property description "the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ThumbDown"; // Sign name
input int InpDate=25; // Anchor point date in %
input int InpPrice=75; // Anchor point price in %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_BOTTOM; // Anchor type
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool ArrowThumbDownMove(const long chart_ID=0, // chart's ID
const string name="ThumbDown", // object name
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Thumbs Down sign anchor type |
//+------------------------------------------------------------------+
bool ArrowThumbDownAnchorChange(const long chart_ID=0, // chart's ID
const string name="ThumbDown", // object name
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // anchor type
{
//--- reset the error value
ResetLastError();
//--- change anchor type
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete Thumbs Down sign |
//+------------------------------------------------------------------+
bool ArrowThumbDownDelete(const long chart_ID=0, // chart's ID
const string name="ThumbDown") // sign name
{
//--- reset the error value
ResetLastError();
//--- delete the sign
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Thumbs Down\" sign! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check anchor point values and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- if the point's time is not set, it will be on the current bar
if(!time)
time=TimeCurrent();
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing sign anchor point coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the sign
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- create Thumbs Down sign on the chart
if(!ArrowThumbDownCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor point and change its position relative to the sign
//--- loop counter
int h_steps=bars/4;
//--- move the anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d<bars-1)
d+=1;
//--- move the point
if(!ArrowThumbDownMove(0,InpName,date[d],price[p]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- 1 second of delay
Sleep(1000);
//--- loop counter
int v_steps=accuracy/4;
//--- move the anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p>1)
p-=1;
//--- move the point
if(!ArrowThumbDownMove(0,InpName,date[d],price[p]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- change anchor point location relative to the sign
ArrowThumbDownAnchorChange(0,InpName,ANCHOR_TOP);
//--- redraw the chart
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//--- delete the sign from the chart
ArrowThumbDownDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_ARROW_UP
Arrow Up sign.
Note
Anchor point position relative to the sign can be selected from ENUM _ARR OW_ANCH OR
enumeration.
Large signs (more than 5) can only be created by setting the appropriate OBJPR OP_W I DT H property
value when writing a code in MetaEditor.
Example
The following script creates and moves Arrow Up sign on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Arrow Up\" sign."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ArrowUp"; // Sign name
input int InpDate=25; // Anchor point date in %
input int InpPrice=25; // Anchor point price in %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_TOP; // Anchor type
input color InpColor=clrRed; // Sign color
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool ArrowUpMove(const long chart_ID=0, // chart's ID
const string name="ArrowUp", // object name
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Arrow Down sign anchor type |
//+------------------------------------------------------------------+
bool ArrowUpAnchorChange(const long chart_ID=0, // chart's ID
const string name="ArrowUp", // object name
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // anchor type
{
//--- reset the error value
ResetLastError();
//--- change anchor point location
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- arrays for storing the date and price values to be used
//--- for setting and changing sign anchor point coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the sign
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- create Arrow Up sign on the chart
if(!ArrowUpCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor point and change its position relative to the sign
//--- loop counter
int v_steps=accuracy/2;
//--- move the anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p<accuracy-1)
p+=1;
//--- move the point
if(!ArrowUpMove(0,InpName,date[d],price[p]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
OBJ_ARROW_DOWN
Arrow Down sign.
Note
Anchor point position relative to the sign can be selected from ENUM _ARR OW_ANCH OR
enumeration.
Large signs (more than 5) can only be created by setting the appropriate OBJPR OP_W I DT H property
value when writing a code in MetaEditor.
Example
The following script creates and moves Arrow Down sign on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Arrow Down\" sign."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ArrowDown"; // Sign name
input int InpDate=75; // Anchor point date in %
input int InpPrice=75; // Anchor point price in %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_BOTTOM; // Anchor type
input color InpColor=clrRed; // Sign color
input ENUM_LINE_STYLE InpStyle=STYLE_DOT; // Border line style
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool ArrowDownMove(const long chart_ID=0, // chart's ID
const string name="ArrowDown", // object name
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Arrow Down sign anchor type |
//+------------------------------------------------------------------+
bool ArrowDownAnchorChange(const long chart_ID=0, // chart's ID
const string name="ArrowDown", // object name
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // anchor type
{
//--- reset the error value
ResetLastError();
//--- change anchor point location
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete Arrow Down sign |
//+------------------------------------------------------------------+
bool ArrowDownDelete(const long chart_ID=0, // chart's ID
const string name="ArrowDown") // sign name
{
//--- reset the error value
ResetLastError();
//--- delete the sign
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Arrow Down\" sign! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check anchor point values and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- if the point's time is not set, it will be on the current bar
if(!time)
time=TimeCurrent();
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- change anchor point location relative to the sign
ArrowDownAnchorChange(0,InpName,ANCHOR_TOP);
//--- redraw the chart
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//--- delete the sign from the chart
ArrowDownDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_ARROW_STOP
Stop sign.
Note
Anchor point position relative to the sign can be selected from ENUM _ARR OW_ANCH OR
enumeration.
Large signs (more than 5) can only be created by setting the appropriate OBJPR OP_W I DT H property
value when writing a code in MetaEditor.
Example
The following script creates and moves Stop sign on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Stop\" sign."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ArrowStop"; // Sign name
input int InpDate=10; // Anchor point date in %
input int InpPrice=50; // Anchor point price in %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_BOTTOM; // Anchor type
input color InpColor=clrRed; // Sign color
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool ArrowStopMove(const long chart_ID=0, // chart's ID
const string name="ArrowStop", // object name
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Stop sign anchor type |
//+------------------------------------------------------------------+
bool ArrowStopAnchorChange(const long chart_ID=0, // chart's ID
const string name="ArrowStop", // object name
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // anchor point position
{
//--- reset the error value
ResetLastError();
//--- change anchor type
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- arrays for storing the date and price values to be used
//--- for setting and changing sign anchor point coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the sign
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- create Stop sign on the chart
if(!ArrowStopCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor point and change its position relative to the sign
//--- loop counter
int h_steps=bars*2/5;
//--- move the anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d<bars-1)
d+=1;
//--- move the point
if(!ArrowStopMove(0,InpName,date[d],price[p]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
OBJ_ARROW_CHECK
Check sign.
Note
Anchor point position relative to the sign can be selected from ENUM _ARR OW_ANCH OR
enumeration.
Large signs (more than 5) can only be created by setting the appropriate OBJPR OP_W I DT H property
value when writing a code in MetaEditor.
Example
The following script creates and moves Check sign on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Check\" sign."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="ArrowCheck"; // Sign name
input int InpDate=10; // Anchor point date in %
input int InpPrice=50; // Anchor point price in %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_TOP; // Anchor type
input color InpColor=clrRed; // Sign color
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool ArrowCheckMove(const long chart_ID=0, // chart's ID
const string name="ArrowCheck", // object name
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Check anchor type |
//+------------------------------------------------------------------+
bool ArrowCheckAnchorChange(const long chart_ID=0, // chart's ID
const string name="ArrowCheck", // object name
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // anchor type
{
//--- reset the error value
ResetLastError();
//--- change anchor type
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- arrays for storing the date and price values to be used
//--- for setting and changing sign anchor point coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the sign
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- create Check sign on the chart
if(!ArrowCheckCreate(0,InpName,0,date[d],price[p],InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor point and change its position relative to the sign
//--- loop counter
int h_steps=bars*2/5;
//--- move the anchor point
for(int i=0;i<h_steps;i++)
{
//--- use the following value
if(d<bars-1)
d+=1;
//--- move the point
if(!ArrowCheckMove(0,InpName,date[d],price[p]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
OBJ_ARROW_LEFT_PRICE
Left Price Label
Example
The following script creates and moves left price label on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates the left price label on the chart."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="LeftPrice"; // Price label name
input int InpDate=100; // Anchor point date in %
input int InpPrice=10; // Anchor point price in %
input color InpColor=clrRed; // Price label color
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // Border line style
input int InpWidth=2; // Price label size
input bool InpBack=false; // Background label
input bool InpSelection=true; // Highlight to move
input bool InpHidden=true; // Hidden in the object list
input long InpZOrder=0; // Priority for mouse click
//+------------------------------------------------------------------+
//| Create the left price label |
//+------------------------------------------------------------------+
bool ArrowLeftPriceCreate(const long chart_ID=0, // chart's ID
const string name="LeftPrice", // price label name
const int sub_window=0, // subwindow index
datetime time=0, // anchor point time
double price=0, // anchor point price
const color clr=clrRed, // price label color
const ENUM_LINE_STYLE style=STYLE_SOLID, // border line style
const int width=1, // price label size
const bool back=false, // in the background
const bool selection=true, // highlight to move
const bool hidden=true, // hidden in the object list
const long z_order=0) // priority for mouse click
{
//--- set anchor point coordinates if they are not set
ChangeArrowEmptyPoint(time,price);
//--- reset the error value
ResetLastError();
//--- create a price label
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_LEFT_PRICE,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create the left price label! Error code = ",GetLastError());
return(false);
}
//--- set the label color
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set the border line style
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set the label size
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing label anchor point coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the label
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- create the left price label on the chart
if(!ArrowLeftPriceCreate(0,InpName,0,date[d],price[p],InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor point
//--- loop counter
int v_steps=accuracy*4/5;
//--- move the anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p<accuracy-1)
p+=1;
//--- move the point
if(!ArrowLeftPriceMove(0,InpName,date[d],price[p]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the label from the chart
ArrowLeftPriceDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_ARROW_RIGHT_PRICE
R ight Price Label.
Example
The following script creates and moves right price label on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates the right price label on the chart."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="RightPrice"; // Price label name
input int InpDate=0; // Anchor point date in %
input int InpPrice=90; // Anchor point price in %
input color InpColor=clrRed; // Price label color
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // Border line style
input int InpWidth=2; // Price label size
input bool InpBack=false; // Background label
input bool InpSelection=true; // Highlight to move
input bool InpHidden=true; // Hidden in the object list
input long InpZOrder=0; // Priority for mouse click
//+------------------------------------------------------------------+
//| Create the right price label |
//+------------------------------------------------------------------+
bool ArrowRightPriceCreate(const long chart_ID=0, // chart's ID
const string name="RightPrice", // price label name
const int sub_window=0, // subwindow index
datetime time=0, // anchor point time
double price=0, // anchor point price
const color clr=clrRed, // price label color
const ENUM_LINE_STYLE style=STYLE_SOLID, // border line style
const int width=1, // price label size
const bool back=false, // in the background
const bool selection=true, // highlight to move
const bool hidden=true, // hidden in the object list
const long z_order=0) // priority for mouse click
{
//--- set anchor point coordinates if they are not set
ChangeArrowEmptyPoint(time,price);
//--- reset the error value
ResetLastError();
//--- create a price label
if(!ObjectCreate(chart_ID,name,OBJ_ARROW_RIGHT_PRICE,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create the right price label! Error code = ",GetLastError());
return(false);
}
//--- set the label color
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set the border line style
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set the label size
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing label anchor point coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the label
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- create the right price label on the chart
if(!ArrowRightPriceCreate(0,InpName,0,date[d],price[p],InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the anchor point
//--- loop counter
int v_steps=accuracy*4/5;
//--- move the anchor point
for(int i=0;i<v_steps;i++)
{
//--- use the following value
if(p>1)
p-=1;
//--- move the point
if(!ArrowRightPriceMove(0,InpName,date[d],price[p]))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
}
//--- 1 second of delay
Sleep(1000);
//--- delete the label from the chart
ArrowRightPriceDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_ARROW_BUY
Buy sign.
Example
The following script creates and moves Buy sign on the chart. Special functions have been developed
to create and change graphical object's properties. You can use these functions " as is " in your own
applications.
//--- description
#property description "Script draws \"Buy\" signs in the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input color InpColor=C'3,95,172'; // Color of signs
//+------------------------------------------------------------------+
//| Create Buy sign |
//+------------------------------------------------------------------+
bool ArrowBuyCreate(const long chart_ID=0, // chart's ID
const string name="ArrowBuy", // sign name
const int sub_window=0, // subwindow index
datetime time=0, // anchor point time
double price=0, // anchor point price
const color clr=C'3,95,172', // sign color
const ENUM_LINE_STYLE style=STYLE_SOLID, // line style (when highlighted)
const int width=1, // line size (when highlighted)
const bool back=false, // in the background
const bool selection=false, // highlight to move
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete Buy sign |
//+------------------------------------------------------------------+
bool ArrowBuyDelete(const long chart_ID=0, // chart's ID
const string name="ArrowBuy") // sign name
{
//--- reset the error value
ResetLastError();
//--- delete the sign
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Buy\" sign! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check anchor point values and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- if the point's time is not set, it will be on the current bar
if(!time)
time=TimeCurrent();
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date[]; // array for storing dates of visible bars
double low[]; // array for storing Low prices of visible bars
double high[]; // array for storing High prices of visible bars
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
OBJ_ARROW_SELL
Sell sign.
Example
The following script creates and moves Sell sign on the chart. Special functions have been developed
to create and change graphical object's properties. You can use these functions " as is " in your own
applications.
//--- description
#property description "Script draws \"Sell\" signs in the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input color InpColor=C'225,68,29'; // Color of signs
//+------------------------------------------------------------------+
//| Create Sell sign |
//+------------------------------------------------------------------+
bool ArrowSellCreate(const long chart_ID=0, // chart's ID
const string name="ArrowSell", // sign name
const int sub_window=0, // subwindow index
datetime time=0, // anchor point time
double price=0, // anchor point price
const color clr=C'225,68,29', // sign color
const ENUM_LINE_STYLE style=STYLE_SOLID, // line style (when highlighted)
const int width=1, // line size (when highlighted)
const bool back=false, // in the background
const bool selection=false, // highlight to move
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete Sell sign |
//+------------------------------------------------------------------+
bool ArrowSellDelete(const long chart_ID=0, // chart's ID
const string name="ArrowSell") // sign name
{
//--- reset the error value
ResetLastError();
//--- delete the sign
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Sell\" sign! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check anchor point values and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- if the point's time is not set, it will be on the current bar
if(!time)
time=TimeCurrent();
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date[]; // array for storing dates of visible bars
double low[]; // array for storing Low prices of visible bars
double high[]; // array for storing High prices of visible bars
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
OBJ_ARROW
Arrow object.
Note
Anchor point position relative to the object can be selected from ENUM _ARR OW_ANCH OR .
Large arrows (more than 5) can only be created by setting the appropriate OBJPR OP_W I DT H property
value when writing a code in MetaEditor.
The necessary arrow type can be selected by setting one of the W ingdings font's symbol codes.
Example
The following script creates Arrow object on the chart and changes its type. Special functions have
been developed to create and change graphical object's properties. You can use these functions " as
is " in your own applications.
//--- description
#property description "Script creates a random arrow in the chart window."
#property description "Anchor point coordinate is set in"
#property description "percentage of the chart window size."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Arrow"; // Arrow name
input int InpDate=50; // Anchor point date in %
input int InpPrice=50; // Anchor point price in %
input ENUM_ARROW_ANCHOR InpAnchor=ANCHOR_TOP; // Anchor type
//--- when creating a graphical object using ObjectCreate function, the object cannot be
//--- highlighted and moved by default. Inside this method, selection parameter
//--- is true by default making it possible to highlight and move the object
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool ArrowMove(const long chart_ID=0, // chart's ID
const string name="Arrow", // object name
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change the arrow code |
//+------------------------------------------------------------------+
bool ArrowCodeChange(const long chart_ID=0, // chart's ID
const string name="Arrow", // object name
const uchar code=252) // arrow code
{
//--- reset the error value
ResetLastError();
//--- change the arrow code
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ARROWCODE,code))
{
Print(__FUNCTION__,
": failed to change the arrow code! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change anchor type |
//+------------------------------------------------------------------+
bool ArrowAnchorChange(const long chart_ID=0, // chart's ID
const string name="Arrow", // object name
const ENUM_ARROW_ANCHOR anchor=ANCHOR_TOP) // anchor type
{
//--- reset the error value
ResetLastError();
//--- change anchor type
if(!ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor))
{
Print(__FUNCTION__,
": failed to change anchor type! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete an arrow |
//+------------------------------------------------------------------+
bool ArrowDelete(const long chart_ID=0, // chart's ID
const string name="Arrow") // arrow name
{
//--- reset the error value
ResetLastError();
//--- delete an arrow
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete an arrow! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check anchor point values and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
void ChangeArrowEmptyPoint(datetime &time,double &price)
{
//--- if the point's time is not set, it will be on the current bar
if(!time)
time=TimeCurrent();
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate<0 || InpDate>100 || InpPrice<0 || InpPrice>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- price array size
int accuracy=1000;
//--- arrays for storing the date and price values to be used
//--- for setting and changing sign anchor point coordinates
datetime date[];
double price[];
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(price,accuracy);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of prices
//--- find the highest and lowest values of the chart
double max_price=ChartGetDouble(0,CHART_PRICE_MAX);
double min_price=ChartGetDouble(0,CHART_PRICE_MIN);
//--- define a change step of a price and fill the array
double step=(max_price-min_price)/accuracy;
for(int i=0;i<accuracy;i++)
price[i]=min_price+i*step;
//--- define points for drawing the arrow
int d=InpDate*(bars-1)/100;
int p=InpPrice*(accuracy-1)/100;
//--- create an arrow on the chart
if(!ArrowCreate(0,InpName,0,date[d],price[p],32,InpAnchor,InpColor,
InpStyle,InpWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart
ChartRedraw();
//--- consider all cases of creating arrows in the loop
for(int i=33;i<256;i++)
{
if(!ArrowCodeChange(0,InpName,(uchar)i))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// half a second of delay
Sleep(500);
}
//--- 1 second of delay
Sleep(1000);
//--- delete the arrow from the chart
ArrowDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_TEXT
Text object.
Note
Anchor point position relative to the text can be selected from ENUM _ANCH OR_POINT enumeration.
You can also change text slope angle using OBJPR OP_ANGL E property.
Example
The following script creates several Text objects on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates \"Text\" graphical object."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpFont="Arial"; // Font
input int InpFontSize=10; // Font size
input color InpColor=clrRed; // Color
input double InpAngle=90.0; // Slope angle in degrees
input ENUM_ANCHOR_POINT InpAnchor=ANCHOR_LEFT; // Anchor type
input bool InpBack=false; // Background object
input bool InpSelection=false; // Highlight to move
input bool InpHidden=true; // Hidden in the object list
input long InpZOrder=0; // Priority for mouse click
//+------------------------------------------------------------------+
//| Creating Text object |
//+------------------------------------------------------------------+
bool TextCreate(const long chart_ID=0, // chart's ID
const string name="Text", // object name
const int sub_window=0, // subwindow index
datetime time=0, // anchor point time
double price=0, // anchor point price
const string text="Text", // the text itself
const string font="Arial", // font
const int font_size=10, // font size
const color clr=clrRed, // color
const double angle=0.0, // text slope
const ENUM_ANCHOR_POINT anchor=ANCHOR_LEFT_UPPER, // anchor type
const bool back=false, // in the background
const bool selection=false, // highlight to move
const bool hidden=true, // hidden in the object list
const long z_order=0) // priority for mouse click
{
//--- set anchor point coordinates if they are not set
ChangeTextEmptyPoint(time,price);
//--- reset the error value
ResetLastError();
//--- create Text object
if(!ObjectCreate(chart_ID,name,OBJ_TEXT,sub_window,time,price))
{
Print(__FUNCTION__,
": failed to create \"Text\" object! Error code = ",GetLastError());
return(false);
}
//--- set the text
ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- set text font
ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- set font size
ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- set the slope angle of the text
ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle);
//--- set anchor type
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- set color
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the object by mouse
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the anchor point |
//+------------------------------------------------------------------+
bool TextMove(const long chart_ID=0, // chart's ID
const string name="Text", // object name
datetime time=0, // anchor point time coordinate
double price=0) // anchor point price coordinate
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change the object text |
//+------------------------------------------------------------------+
bool TextChange(const long chart_ID=0, // chart's ID
const string name="Text", // object name
const string text="Text") // text
{
//--- reset the error value
ResetLastError();
//--- change object text
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
{
Print(__FUNCTION__,
": failed to change the text! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete Text object |
//+------------------------------------------------------------------+
bool TextDelete(const long chart_ID=0, // chart's ID
const string name="Text") // object name
{
//--- reset the error value
ResetLastError();
//--- delete the object
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Text\" object! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check anchor point values and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
void ChangeTextEmptyPoint(datetime &time,double &price)
{
//--- if the point's time is not set, it will be on the current bar
if(!time)
time=TimeCurrent();
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date[]; // array for storing dates of visible bars
double low[]; // array for storing Low prices of visible bars
double high[]; // array for storing High prices of visible bars
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(low,bars);
ArrayResize(high,bars);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- half a second of delay
Sleep(500);
//--- delete the texts
for(int i=0;i<bars;i+=step)
{
if(!TextDelete(0,"TextHigh_"+(string)i))
return;
if(!TextDelete(0,"TextLow_"+(string)i))
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//---
}
OBJ_LABEL
Label object.
Note
Anchor point position relative to the label can be selected from ENUM _ANCH OR_POINT enumeration.
Anchor point coordinates are set in pixels.
You can also select text label anchoring corner from ENUM _BAS E_CORNER enumeration.
Example
The following script creates and moves Edit object on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates \"Label\" graphical object."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Label"; // Label name
input int InpX=150; // X-axis distance
input int InpY=150; // Y-axis distance
input string InpFont="Arial"; // Font
input int InpFontSize=14; // Font size
input color InpColor=clrRed; // Color
input double InpAngle=0.0; // Slope angle in degrees
input ENUM_ANCHOR_POINT InpAnchor=ANCHOR_CENTER; // Anchor type
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the text label |
//+------------------------------------------------------------------+
bool LabelMove(const long chart_ID=0, // chart's ID
const string name="Label", // label name
const int x=0, // X coordinate
const int y=0) // Y coordinate
{
//--- reset the error value
ResetLastError();
//--- move the text label
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of the label! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of the label! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change corner of the chart for binding the label |
//+------------------------------------------------------------------+
bool LabelChangeCorner(const long chart_ID=0, // chart's ID
const string name="Label", // label name
const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER) // chart corner for anchori
{
//--- reset the error value
ResetLastError();
//--- change anchor corner
if(!ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner))
{
Print(__FUNCTION__,
": failed to change the anchor corner! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change the label text |
//+------------------------------------------------------------------+
bool LabelTextChange(const long chart_ID=0, // chart's ID
const string name="Label", // object name
const string text="Text") // text
{
//--- reset the error value
ResetLastError();
//--- change object text
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
{
Print(__FUNCTION__,
": failed to change the text! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete a text label |
//+------------------------------------------------------------------+
bool LabelDelete(const long chart_ID=0, // chart's ID
const string name="Label") // label name
{
//--- reset the error value
ResetLastError();
//--- delete the label
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete a text label! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- store the label's coordinates in the local variables
int x=InpX;
int y=InpY;
//--- chart window size
long x_distance;
long y_distance;
//--- set window size
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- check correctness of the input parameters
if(InpX<0 || InpX>x_distance-1 || InpY<0 || InpY>y_distance-1)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- prepare initial text for the label
string text;
StringConcatenate(text,"Upper left corner: ",x,",",y);
//--- create a text label on the chart
if(!LabelCreate(0,InpName,0,InpX,InpY,CORNER_LEFT_UPPER,text,InpFont,InpFontSize,
InpColor,InpAngle,InpAnchor,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for half a second
ChartRedraw();
Sleep(500);
//--- move the label and change its text simultaneously
//--- number of iterations by axes
int h_steps=(int)(x_distance/2-InpX);
int v_steps=(int)(y_distance/2-InpY);
//--- move the label down
for(int i=0;i<v_steps;i++)
{
//--- change the coordinate
y+=2;
//--- move the label and change its text
MoveAndTextChange(x,y,"Upper left corner: ");
}
return;
//--- redraw the chart and wait for two seconds
ChartRedraw();
Sleep(2000);
//--- move to the upper right corner
if(!LabelChangeCorner(0,InpName,CORNER_RIGHT_UPPER))
return;
//--- change the label text
StringConcatenate(text,"Upper right corner: ",x,",",y);
if(!LabelTextChange(0,InpName,text))
return;
//--- redraw the chart and wait for two seconds
ChartRedraw();
Sleep(2000);
//--- move to the upper left corner
if(!LabelChangeCorner(0,InpName,CORNER_LEFT_UPPER))
return;
//--- change the label text
StringConcatenate(text,"Upper left corner: ",x,",",y);
if(!LabelTextChange(0,InpName,text))
return;
//--- redraw the chart and wait for two seconds
ChartRedraw();
Sleep(2000);
//--- delete the label
LabelDelete(0,InpName);
//--- redraw the chart and wait for half a second
ChartRedraw();
Sleep(500);
//---
}
//+------------------------------------------------------------------+
//| The function moves the object and changes its text |
//+------------------------------------------------------------------+
bool MoveAndTextChange(const int x,const int y,string text)
{
//--- move the label
if(!LabelMove(0,InpName,x,y))
return(false);
//--- change the label text
StringConcatenate(text,text,x,",",y);
if(!LabelTextChange(0,InpName,text))
return(false);
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return(false);
//--- redraw the chart
ChartRedraw();
// 0.01 seconds of delay
Sleep(10);
//--- exit the function
return(true);
}
OBJ_BUTTON
Button object.
Note
Anchor point coordinates are set in pixels. You can select button anchoring corner from
ENUM _BAS E_CORNER .
Example
The following script creates and moves Button object on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates the button on the chart."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Button"; // Button name
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // Chart corner for anchoring
input string InpFont="Arial"; // Font
input int InpFontSize=14; // Font size
input color InpColor=clrBlack; // Text color
input color InpBackColor=C'236,233,216'; // Background color
input color InpBorderColor=clrNONE; // Border color
input bool InpState=false; // Pressed/Released
input bool InpBack=false; // Background object
input bool InpSelection=false; // Highlight to move
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set background color
ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
//--- set border color
ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- set button state
ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
//--- enable (true) or disable (false) the mode of moving the button by mouse
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move the button |
//+------------------------------------------------------------------+
bool ButtonMove(const long chart_ID=0, // chart's ID
const string name="Button", // button name
const int x=0, // X coordinate
const int y=0) // Y coordinate
{
//--- reset the error value
ResetLastError();
//--- move the button
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of the button! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of the button! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change button size |
//+------------------------------------------------------------------+
bool ButtonChangeSize(const long chart_ID=0, // chart's ID
ResetLastError();
//--- change object text
if(!ObjectSetString(chart_ID,name,OBJPROP_TEXT,text))
{
Print(__FUNCTION__,
": failed to change the text! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete the button |
//+------------------------------------------------------------------+
bool ButtonDelete(const long chart_ID=0, // chart's ID
const string name="Button") // button name
{
//--- reset the error value
ResetLastError();
//--- delete the button
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete the button! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- chart window size
long x_distance;
long y_distance;
//--- set window size
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- define the step for changing the button size
int x_step=(int)x_distance/32;
int y_step=(int)y_distance/32;
//--- set the button coordinates and its size
int x=(int)x_distance/32;
int y=(int)y_distance/32;
int x_size=(int)x_distance*15/16;
int y_size=(int)y_distance*15/16;
//--- create the button
if(!ButtonCreate(0,InpName,0,x,y,x_size,y_size,InpCorner,"Press",InpFont,InpFontSize,
InpColor,InpBackColor,InpBorderColor,InpState,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart
ChartRedraw();
//--- reduce the button in the loop
int i=0;
while(i<13)
{
//--- half a second of delay
Sleep(500);
//--- switch the button to the pressed state
ObjectSetInteger(0,InpName,OBJPROP_STATE,true);
//--- redraw the chart and wait for 0.2 second
ChartRedraw();
Sleep(200);
//--- redefine coordinates and button size
x+=x_step;
y+=y_step;
x_size-=x_step*2;
y_size-=y_step*2;
//--- reduce the button
ButtonMove(0,InpName,x,y);
ButtonChangeSize(0,InpName,x_size,y_size);
//--- bring the button back to the released state
ObjectSetInteger(0,InpName,OBJPROP_STATE,false);
//--- redraw the chart
ChartRedraw();
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- increase the loop counter
i++;
}
//--- half a second of delay
Sleep(500);
//--- delete the button
ButtonDelete(0,InpName);
ChartRedraw();
OBJ_CHART
Chart object.
Note
Anchor point coordinates are set in pixels. You can select anchoring corner from
ENUM _BAS E_CORNER enumeration.
Symbol, period and scale can be selected for Chart object. Price scale and date display mode can
also be enabled/disabled.
Example
The following script creates and moves Chart object on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates \"Chart\" object."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Chart"; // Object name
input string InpSymbol="EURUSD"; // Symbol
input ENUM_TIMEFRAMES InpPeriod=PERIOD_H1; // Period
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // Anchoring corner
input int InpScale=2; // Scale
input bool InpDateScale=true; // Time scale display
input bool InpPriceScale=true; // Price scale display
ObjectSetString(chart_ID,name,OBJPROP_SYMBOL,symbol);
//--- set the period
ObjectSetInteger(chart_ID,name,OBJPROP_PERIOD,period);
//--- set the scale
ObjectSetInteger(chart_ID,name,OBJPROP_CHART_SCALE,scale);
//--- display (true) or hide (false) the time scale
ObjectSetInteger(chart_ID,name,OBJPROP_DATE_SCALE,date_scale);
//--- display (true) or hide (false) the price scale
ObjectSetInteger(chart_ID,name,OBJPROP_PRICE_SCALE,price_scale);
//--- set the border color when object highlighting mode is enabled
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set the border line style when object highlighting mode is enabled
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set a size of the anchor point for moving an object
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,point_width);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Sets the symbol and time frame of the Chart object |
//+------------------------------------------------------------------+
bool ObjectChartSetSymbolAndPeriod(const long chart_ID=0, // chart's ID (not Chart
const string name="Chart", // object name
const string symbol="EURUSD", // symbol
const ENUM_TIMEFRAMES period=PERIOD_H1) // time frame
{
//--- reset the error value
ResetLastError();
//--- set Chart object's symbol and time frame
if(!ObjectSetString(chart_ID,name,OBJPROP_SYMBOL,symbol))
{
Print(__FUNCTION__,
": failed to set a symbol for \"Chart\" object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_PERIOD,period))
{
Print(__FUNCTION__,
": failed to set a period for \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Chart object |
//+------------------------------------------------------------------+
bool ObjectChartMove(const long chart_ID=0, // chart's ID (not Chart object's one)
const string name="Chart", // object name
const int x=0, // X coordinate
const int y=0) // Y coordinate
{
//--- reset the error value
ResetLastError();
//--- move the object
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of \"Chart\" object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change Chart object size |
//+------------------------------------------------------------------+
bool ObjectChartChangeSize(const long chart_ID=0, // chart's ID (not Chart object's one)
const string name="Chart", // object name
const int width=300, // width
const int height=200) // height
{
//--- reset the error value
ResetLastError();
//--- change the object size
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width))
{
Print(__FUNCTION__,
": failed to change the width of \"Chart\" object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height))
{
Print(__FUNCTION__,
": failed to change the height of \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Return Chart object's ID |
//+------------------------------------------------------------------+
long ObjectChartGetID(const long chart_ID=0, // chart's ID (not Chart object's one)
const string name="Chart") // object name
{
//--- prepare the variable to get Chart object's ID
long id=-1;
//--- reset the error value
ResetLastError();
//--- get ID
if(!ObjectGetInteger(chart_ID,name,OBJPROP_CHART_ID,0,id))
{
Print(__FUNCTION__,
": failed to get \"Chart\" object's ID! Error code = ",GetLastError());
}
//--- return the result
return(id);
}
//+------------------------------------------------------------------+
//| Delete Chart object |
//+------------------------------------------------------------------+
bool ObjectChartDelete(const long chart_ID=0, // chart's ID (not Chart object's one)
const string name="Chart") // object name
{
//--- reset the error value
ResetLastError();
//--- delete the button
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Chart\" object! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
Sleep(1000);
//--- stretch Chart object
int steps=(int)MathMin(x_distance*7/16,y_distance*7/16);
for(int i=0;i<steps;i++)
{
//--- resize
x_size+=1;
y_size+=1;
if(!ObjectChartChangeSize(0,InpName,x_size,y_size))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart and wait for 0.01 seconds
ChartRedraw();
Sleep(10);
}
//--- half a second of delay
Sleep(500);
//--- change chart's time frame
if(!ObjectChartSetSymbolAndPeriod(0,InpName,InpSymbol,PERIOD_M1))
return;
ChartRedraw();
//--- three seconds of delay
Sleep(3000);
//--- delete the object
ObjectChartDelete(0,InpName);
ChartRedraw();
//--- wait for 1 second
Sleep(1000);
//---
}
OBJ_BITMAP
Bitmap object.
Note
Example
The following script creates several bitmaps on the chart. Special functions have been developed to
create and change graphical object's properties. You can use these functions " as is " in your own
applications.
//--- description
#property description "Script creates a bitmap in the chart window."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpFile="\\Images\\dollar.bmp"; // Bitmap file name
input int InpWidth=24; // Visibility scope X coordinate
input int InpHeight=24; // Visibility scope Y coordinate
input int InpXOffset=4; // Visibility scope shift by X axis
input int InpYOffset=4; // Visibility scope shift by Y axis
input color InpColor=clrRed; // Border color when highlighted
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // Line style when highlighted
input int InpPointWidth=1; // Point size to move
input bool InpBack=false; // Background object
input bool InpSelection=false; // Highlight to move
//--- performing a shift from this area displaying another part of the image
ObjectSetInteger(chart_ID,name,OBJPROP_XOFFSET,x_offset);
ObjectSetInteger(chart_ID,name,OBJPROP_YOFFSET,y_offset);
//--- set the border color when object highlighting mode is enabled
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set the border line style when object highlighting mode is enabled
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set a size of the anchor point for moving an object
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,point_width);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Set a new image for the bitmap |
//+------------------------------------------------------------------+
bool BitmapSetImage(const long chart_ID=0, // chart's ID
const string name="Bitmap", // bitmap name
const string file="") // path to the file
{
//--- reset the error value
ResetLastError();
//--- set the path to the image file
if(!ObjectSetString(chart_ID,name,OBJPROP_BMPFILE,file))
{
Print(__FUNCTION__,
": failed to load the image! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move a bitmap in the chart window |
//+------------------------------------------------------------------+
bool BitmapMove(const long chart_ID=0, // chart's ID
const string name="Bitmap", // bitmap name
datetime time=0, // anchor point time
double price=0) // anchor point price
{
//--- if point position is not set, move it to the current bar having Bid price
if(!time)
time=TimeCurrent();
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
//--- reset the error value
ResetLastError();
//--- move the anchor point
if(!ObjectMove(chart_ID,name,0,time,price))
{
Print(__FUNCTION__,
": failed to move the anchor point! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change visibility scope (bitmap) size |
//+------------------------------------------------------------------+
bool BitmapChangeSize(const long chart_ID=0, // chart's ID
const string name="Bitmap", // bitmap name
const int width=0, // bitmap width
const int height=0) // bitmap height
{
//--- reset the error value
ResetLastError();
//--- change bitmap size
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width))
{
Print(__FUNCTION__,
": failed to change the bitmap width! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height))
{
Print(__FUNCTION__,
": failed to change the bitmap height! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+--------------------------------------------------------------------+
//| Change coordinate of the upper left corner of the visibility scope |
//+--------------------------------------------------------------------+
bool BitmapMoveVisibleArea(const long chart_ID=0, // chart's ID
const string name="Bitmap", // bitmap name
const int x_offset=0, // visibility scope X coordinate
const int y_offset=0) // visibility scope Y coordinate
{
//--- reset the error value
ResetLastError();
//--- change the bitmap's visibility scope coordinates
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XOFFSET,x_offset))
{
Print(__FUNCTION__,
": failed to change X coordinate of the visibility scope! Error code = ",GetLastError()
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YOFFSET,y_offset))
{
Print(__FUNCTION__,
": failed to change Y coordinate of the visibility scope! Error code = ",GetLastError()
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Delete a bitmap |
//+------------------------------------------------------------------+
bool BitmapDelete(const long chart_ID=0, // chart's ID
const string name="Bitmap") // bitmap name
{
//--- reset the error value
ResetLastError();
//--- delete the label
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete a bitmap! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Check anchor point values and set default values |
//| for empty ones |
//+------------------------------------------------------------------+
void ChangeBitmapEmptyPoint(datetime &time,double &price)
{
//--- if the point's time is not set, it will be on the current bar
if(!time)
time=TimeCurrent();
//--- if the point's price is not set, it will have Bid value
if(!price)
price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date[]; // array for storing dates of visible bars
double close[]; // array for storing Close prices
//--- bitmap file name
string file="\\Images\\dollar.bmp";
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- memory allocation
ArrayResize(date,bars);
ArrayResize(close,bars);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- fill the array of Close prices
if(CopyClose(Symbol(),Period(),0,bars,close)==-1)
{
Print("Failed to copy the values of Close prices! Error code = ",GetLastError());
return;
}
//--- define how often the images should be displayed
int scale=(int)ChartGetInteger(0,CHART_SCALE);
//--- define the step
int step=1;
switch(scale)
{
case 0:
step=27;
break;
case 1:
step=14;
break;
case 2:
step=7;
break;
case 3:
step=4;
break;
case 4:
step=2;
break;
}
//--- create bitmaps for High and Low bars' values (with gaps)
for(int i=0;i<bars;i+=step)
{
//--- create the bitmaps
if(!BitmapCreate(0,"Bitmap_"+(string)i,0,date[i],close[i],InpFile,InpWidth,InpHeight,InpXOffs
InpYOffset,InpColor,InpStyle,InpPointWidth,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//--- half a second of delay
Sleep(500);
//--- delete Sell signs
for(int i=0;i<bars;i+=step)
{
if(!BitmapDelete(0,"Bitmap_"+(string)i))
return;
if(!BitmapDelete(0,"Bitmap_"+(string)i))
return;
//--- redraw the chart
ChartRedraw();
// 0.05 seconds of delay
Sleep(50);
}
//---
}
OBJ_BITMAP_LABEL
Bitmap Label object.
Note
Anchor point position relative to the label can be selected from ENUM _ANCH OR_POINT enumeration.
Anchor point coordinates are set in pixels.
You can also select bitmap anchoring corner from ENUM _BAS E_CORNER enumeration.
Example
The following script creates several bitmaps on the chart. Special functions have been developed to
create and change graphical object's properties. You can use these functions " as is " in your own
applications.
//--- description
#property description "Script creates \"Bitmap Label\" object."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="BmpLabel"; // Label name
input string InpFileOn="\\Images\\dollar.bmp"; // File name for On mode
input string InpFileOff="\\Images\\euro.bmp"; // File name for Off mode
input bool InpState=false; // Label pressed/released
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // Chart corner for anchoring
input ENUM_ANCHOR_POINT InpAnchor=ANCHOR_CENTER; // Anchor type
input color InpColor=clrRed; // Border color when highlighted
Print(__FUNCTION__,
": failed to load the image for Off mode! Error code = ",GetLastError());
return(false);
}
//--- set label coordinates
ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- set visibility scope for the image; if width or height values
//--- exceed the width and height (respectively) of a source image,
//--- it is not drawn; in the opposite case,
//--- only the part corresponding to these values is drawn
ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- set the part of an image that is to be displayed in the visibility scope
//--- the default part is the upper left area of an image; the values allow
//--- performing a shift from this area displaying another part of the image
ObjectSetInteger(chart_ID,name,OBJPROP_XOFFSET,x_offset);
ObjectSetInteger(chart_ID,name,OBJPROP_YOFFSET,y_offset);
//--- define the label's status (pressed or released)
ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
//--- set the chart's corner, relative to which point coordinates are defined
ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- set anchor type
ObjectSetInteger(chart_ID,name,OBJPROP_ANCHOR,anchor);
//--- set the border color when object highlighting mode is enabled
ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set the border line style when object highlighting mode is enabled
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set a size of the anchor point for moving an object
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,point_width);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Set a new image for Bitmap label object |
//+------------------------------------------------------------------+
bool BitmapLabelSetImage(const long chart_ID=0, // chart's ID
const string name="BmpLabel", // label name
const int on_off=0, // modifier (On or Off)
const string file="") // path to the file
{
//--- reset the error value
ResetLastError();
//--- set the path to the image file
if(!ObjectSetString(chart_ID,name,OBJPROP_BMPFILE,on_off,file))
{
Print(__FUNCTION__,
": failed to load the image! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move Bitmap Label object |
//+------------------------------------------------------------------+
bool BitmapLabelMove(const long chart_ID=0, // chart's ID
const string name="BmpLabel", // label name
const int x=0, // X coordinate
const int y=0) // Y coordinate
{
//--- reset the error value
ResetLastError();
//--- move the object
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of the object! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of the object! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change visibility scope (object) size |
//+------------------------------------------------------------------+
bool BitmapLabelChangeSize(const long chart_ID=0, // chart's ID
const string name="BmpLabel", // label name
const int width=0, // label width
const int height=0) // label height
{
//--- reset the error value
ResetLastError();
ResetLastError();
//--- delete the label
if(!ObjectDelete(chart_ID,name))
{
Print(__FUNCTION__,
": failed to delete \"Bitmap label\" object! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- chart window size
long x_distance;
long y_distance;
//--- set window size
if(!ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0,x_distance))
{
Print("Failed to get the chart width! Error code = ",GetLastError());
return;
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- define bitmap label coordinates
int x=(int)x_distance/2;
int y=(int)y_distance/2;
//--- set label size and visibility scope coordinates
int width=32;
int height=32;
int x_offset=0;
int y_offset=0;
//--- place bitmap label at the center of the window
if(!BitmapLabelCreate(0,InpName,0,x,y,InpFileOn,InpFileOff,width,height,x_offset,y_offset,InpSta
InpCorner,InpAnchor,InpColor,InpStyle,InpPointWidth,InpBack,InpSelection,InpHidden,InpZOrder)
{
return;
}
//--- redraw the chart and wait one second
ChartRedraw();
Sleep(1000);
//--- change label's visibility scope size in the loop
for(int i=0;i<6;i++)
{
//--- change visibility scope size
width--;
height--;
if(!BitmapLabelChangeSize(0,InpName,width,height))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.3 seconds of delay
Sleep(300);
}
//--- 1 second of delay
Sleep(1000);
//--- change label's visibility scope coordinates in the loop
for(int i=0;i<2;i++)
{
//--- change visibility scope coordinates
x_offset++;
y_offset++;
if(!BitmapLabelMoveVisibleArea(0,InpName,x_offset,y_offset))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart
ChartRedraw();
// 0.3 seconds of delay
Sleep(300);
}
//--- 1 second of delay
Sleep(1000);
//--- delete the label
BitmapLabelDelete(0,InpName);
ChartRedraw();
//--- 1 second of delay
Sleep(1000);
//---
}
OBJ_EDIT
Edit object.
Note
Anchor point coordinates are set in pixels. You can select Edit anchoring corner from
ENUM _BAS E_CORNER enumeration.
You can also select one of the text alignment types inside Edit from ENUM _ALIGN_MODE
enumeration.
Example
The following script creates and moves Edit object on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script creates \"Edit\" object."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Edit"; // Object name
input string InpText="Text"; // Object text
input string InpFont="Arial"; // Font
input int InpFontSize=14; // Font size
input ENUM_ALIGN_MODE InpAlign=ALIGN_CENTER; // Text alignment type
input bool InpReadOnly=false; // Permission to edit
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // Chart corner for anchoring
input color InpColor=clrBlack; // Text color
}
if(!ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0,y_distance))
{
Print("Failed to get the chart height! Error code = ",GetLastError());
return;
}
//--- define the step for changing the edit field
int x_step=(int)x_distance/64;
//--- set edit field coordinates and its size
int x=(int)x_distance/8;
int y=(int)y_distance/2;
int x_size=(int)x_distance/8;
int y_size=InpFontSize*2;
//--- store the text in the local variable
string text=InpText;
//--- create edit field
if(!EditCreate(0,InpName,0,x,y,x_size,y_size,InpText,InpFont,InpFontSize,InpAlign,InpReadOnly,
InpCorner,InpColor,InpBackColor,InpBorderColor,InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- stretch the edit field
while(x_size-x<x_distance*5/8)
{
//--- increase edit field's width
x_size+=x_step;
if(!EditChangeSize(0,InpName,x_size,y_size))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart and wait for 0.05 seconds
ChartRedraw();
Sleep(50);
}
//--- half a second of delay
Sleep(500);
//--- change the text
for(int i=0;i<20;i++)
{
//--- add "+" at the beginning and at the end
text="+"+text+"+";
if(!EditTextChange(0,InpName,text))
return;
//--- check if the script's operation has been forcefully disabled
if(IsStopped())
return;
//--- redraw the chart and wait for 0.1 seconds
ChartRedraw();
Sleep(100);
}
//--- half a second of delay
Sleep(500);
//--- delete edit field
EditDelete(0,InpName);
ChartRedraw();
//--- wait for 1 second
Sleep(1000);
//---
}
OBJ_EVENT
Event object.
Note
Example
The following script creates and moves Event object on the chart. Special functions have been
developed to create and change graphical object's properties. You can use these functions " as is " in
your own applications.
//--- description
#property description "Script draws \"Event\" graphical object."
#property description "Anchor point date is set in percentage of"
#property description "the chart window width in bars."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="Event"; // Event name
input int InpDate=25; // Event date, %
input string InpText="Text"; // Event text
input color InpColor=clrRed; // Event color
input int InpWidth=1; // Point size when highlighted
input bool InpBack=false; // Background event
input bool InpSelection=false; // Highlight to move
input bool InpHidden=true; // Hidden in the object list
Print(__FUNCTION__,
": failed to delete \"Event\" object! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- check correctness of the input parameters
if(InpDate<0 || InpDate>100)
{
Print("Error! Incorrect values of input parameters!");
return;
}
//--- number of visible bars in the chart window
int bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- array for storing the date values to be used
//--- for setting and changing Event object anchor point's coordinates
datetime date[];
//--- memory allocation
ArrayResize(date,bars);
//--- fill the array of dates
ResetLastError();
if(CopyTime(Symbol(),Period(),0,bars,date)==-1)
{
Print("Failed to copy time values! Error code = ",GetLastError());
return;
}
//--- define the points to create an object
int d=InpDate*(bars-1)/100;
//--- create Event object
if(!EventCreate(0,InpName,0,InpText,date[d],InpColor,InpWidth,
InpBack,InpSelection,InpHidden,InpZOrder))
{
return;
}
//--- redraw the chart and wait for 1 second
ChartRedraw();
Sleep(1000);
//--- now, move the object
//--- loop counter
int h_steps=bars/2;
//--- move the object
for(int i=0;i<h_steps;i++)
{
OBJ_RECTANGLE_LABEL
R ectangle Label object.
Note
Anchor point coordinates are set in pixels. You can select rectangle label's anchoring corner from
ENUM _BAS E_CORNER enumeration. R ectangle label's border type can be selected from
ENUM _BORDER_T YPE enumeration.
The object is used to create and design the custom graphical interface.
Example
The following script creates and moves R ectangle Label object on the chart. Special functions have
been developed to create and change graphical object's properties. You can use these functions " as
is " in your own applications.
//--- description
#property description "Script creates \"Rectangle Label\" graphical object."
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- input parameters of the script
input string InpName="RectLabel"; // Label name
input color InpBackColor=clrSkyBlue; // Background color
input ENUM_BORDER_TYPE InpBorder=BORDER_FLAT; // Border type
input ENUM_BASE_CORNER InpCorner=CORNER_LEFT_UPPER; // Chart corner for anchoring
input color InpColor=clrDarkBlue; // Flat border color (Flat)
input ENUM_LINE_STYLE InpStyle=STYLE_SOLID; // Flat border style (Flat)
input int InpLineWidth=3; // Flat border width (Flat)
ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);
//--- set flat border width
ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,line_width);
//--- display in the foreground (false) or background (true)
ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the label by mouse
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Move rectangle label |
//+------------------------------------------------------------------+
bool RectLabelMove(const long chart_ID=0, // chart's ID
const string name="RectLabel", // label name
const int x=0, // X coordinate
const int y=0) // Y coordinate
{
//--- reset the error value
ResetLastError();
//--- move the rectangle label
if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
{
Print(__FUNCTION__,
": failed to move X coordinate of the label! Error code = ",GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
{
Print(__FUNCTION__,
": failed to move Y coordinate of the label! Error code = ",GetLastError());
return(false);
}
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Change the size of the rectangle label |
//+------------------------------------------------------------------+
bool RectLabelChangeSize(const long chart_ID=0, // chart's ID
const string name="RectLabel", // label name
const int width=50, // label width
const int height=18) // label height
{
Object Properties
Graphical objects can have various properties depending on the object type. Values of object
properties are set up and received by corresponding functions for work ing with graphical objects.
All objects used in technical analysis are bound to the time and price coordinates : trendline, channels,
Fibonacci tools, etc. But there is a number of auxiliary objects intended to improve the user interface
that are bound to the always visible part of a chart (main chart windows or indicator subwindows):
· OBJPROP_CORNER – defines the chart corner relative to which the anchor point coordinates are
specified. Can be one of the 4 values of the ENUM _BAS E_CORNER enumeration;
· OBJPROP_ANCHOR – defines the anchor point in object itself and can be one of the 9 values of the
ENUM _ANCH OR_POINT enumeration. Coordinates in pixels are specified from this very point to
selected chart corner;
· OBJPROP_ANGLE – defines the object rotation angle counterclock wise.
The functions defining the properties of graphical objects, as well as ObjectCreate() and ObjectMove()
operations for creating and moving objects along the chart are actually used for sending commands to
the chart. If these functions are executed successfully, the command is included in the common queue
of the chart events. Visual changes in the properties of graphical objects are implemented when
handling the queue of the chart events.
Thus, do not expect an immediate visual update of graphical objects after calling these functions.
Generally, the graphical objects on the chart are updated automatically by the terminal following the
change events - a new quote arrival, resizing the chart window, etc. Use ChartR edraw() function to
forcefully update the graphical objects.
ENUM_OBJECT_PROPERTY _INTEGER
OBJPR OP_L EVEL W I DT H Thick ness of the line-level int modifier=level number
OBJPR OP_ANCH OR Location of the anchor point of ENUM _ARR OW_ANCH OR (for
a graphical object OBJ_ARR OW ),
ENUM _ANCH OR_POINT (for
OBJ_L ABEL,
OBJ_BITM AP_L ABEL and
OBJ_T EXT)
OBJPR OP_DRAW LI NES Displaying lines for mark ing the bool
Elliott W ave
OBJPR OP_PER IOD Timeframe for the Chart ENUM _TIM EFRAM ES
object
OBJPR OP_CHAR T _SCAL E The scale for the Chart object int value in the range 0–5
OBJPR OP_CORNER The corner of the chart to link ENUM _BAS E_CORNER
a graphical object
OBJPR OP_BORDER_T YPE Border type for the "R ectangle ENUM _BORDER_T YPE
label" object
W hen using chart operations for the " Chart" object (OBJ_CHAR T), the following limitations are
imposed:
· The following properties are ineffective CHAR T _SCAL E, CHAR T _BR I NG_TO_TOP,
CHAR T _S H OW_DAT E_SCAL E and CHAR T _S H OW_PR ICE_SCAL E (ENUM _CHAR T _PR OPER T Y_I NT EGER ).
You can set a special mode of image display for OBJ_BITM AP_L ABEL and OBJ_BITM AP objects. In this
mode, only part of an original image (at which a rectangular visible area is applied) is displayed, while
the rest of the image becomes invisible. The size of this area should be set using the properties
OBJPR OP_XSI ZE and OBJPR OP_YSI ZE. The visible area can be " moved" only within the original image
using the properties OBJPR OP_XOFFS ET and OBJPR OP_YOFFS ET.
For the fixed-sized objects : OBJ_BUTTON, OBJ_RECT ANGL E_L ABEL, OBJ_EDIT and OBJ_CHAR T,
properties OBJPR OP_XDIST ANCE and OBJPR OP_YDIST ANCE set the position of the top left point of the
object relative to the chart corner (OBJPR OP_CORNER ), from which the X and Y coordinates will be
counted in pixels.
ENUM_OBJECT_PROPERTY _DOUBLE
ENUM_OBJECT_PROPERTY _STRING
OBJPR OP_BMPFIL E The name of BMP-file for string modifier: 0-state ON,
Bitmap Label. See also 1-state OFF
R esources
For the OBJ_RECT ANGL E_L ABEL object ("R ectangle label" ) one of the three design modes can be set,
to which the following values of ENUM _BORDER_T YPE correspond.
ENUM_BORDER_TY PE
Identifier Description
For the OBJ_EDIT object ("Edit" ) and for the ChartScreenShot() function, you can specify the horizontal
alignment type using the values of the ENUM _ALI GN_MODE enumeration.
ENUM_ALIGN_MODE
Identifier Description
Example:
#define UP "\x0431"
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
string label_name="my_OBJ_LABEL_object";
if(ObjectFind(0,label_name)<0)
{
Print("Object ",label_name," not found. Error code = ",GetLastError());
//--- create Label object
ObjectCreate(0,label_name,OBJ_LABEL,0,0,0);
//--- set X coordinate
ObjectSetInteger(0,label_name,OBJPROP_XDISTANCE,200);
//--- set Y coordinate
ObjectSetInteger(0,label_name,OBJPROP_YDISTANCE,300);
//--- define text color
ObjectSetInteger(0,label_name,OBJPROP_COLOR,clrWhite);
//--- define text for object Label
ObjectSetString(0,label_name,OBJPROP_TEXT,UP);
//--- define font
ObjectSetString(0,label_name,OBJPROP_FONT,"Wingdings");
//--- define font size
ObjectSetInteger(0,label_name,OBJPROP_FONTSIZE,10);
//--- 45 degrees rotation clockwise
ObjectSetDouble(0,label_name,OBJPROP_ANGLE,-45);
//--- disable for mouse selecting
ObjectSetInteger(0,label_name,OBJPROP_SELECTABLE,false);
//--- draw it on the chart
ChartRedraw(0);
}
}
· OBJPROP_CORNER – defines the chart corner relative to which the anchor point coordinates are
specified. Can be one of the 4 values of the ENUM _BAS E_CORNER enumeration;
· OBJPROP_ANCHOR – defines the anchor point in object itself and can be one of the 9 values of the
ENUM _ANCH OR_POINT enumeration. Coordinates in pixels are specified from this very point to
selected chart corner;
· OBJPROP_ANGLE – defines the object rotation angle counterclock wise.
ENUM_ANCHOR_POINT
ID Description
ANCH OR_L EFT _UPPER Anchor point at the upper left corner
ANCH OR_L EFT _LOWER Anchor point at the lower left corner
ANCH OR_R IGH T _LOWER Anchor point at the lower right corner
ANCH OR_R IGH T _UPPER Anchor point at the upper right corner
The OBJ_BUTTON, OBJ_RECT ANGL E_L ABEL, OBJ_EDIT and OBJ_CHAR T objects have a fixed anchor
point in the upper left corner (ANCH OR_L EFT _UPPER ).
Example:
string text_name="my_OBJ_TEXT_object";
if(ObjectFind(0,text_name)<0)
{
Print("Object ",text_name," not found. Error code = ",GetLastError());
//--- Get the maximal price of the chart
double chart_max_price=ChartGetDouble(0,CHART_PRICE_MAX,0);
//--- Create object Label
ObjectCreate(0,text_name,OBJ_TEXT,0,TimeCurrent(),chart_max_price);
//--- Set color of the text
ObjectSetInteger(0,text_name,OBJPROP_COLOR,clrWhite);
//--- Set background color
ObjectSetInteger(0,text_name,OBJPROP_BGCOLOR,clrGreen);
//--- Set text for the Label object
ObjectSetString(0,text_name,OBJPROP_TEXT,TimeToString(TimeCurrent()));
//--- Set text font
ObjectSetString(0,text_name,OBJPROP_FONT,"Trebuchet MS");
//--- Set font size
ObjectSetInteger(0,text_name,OBJPROP_FONTSIZE,10);
//--- Bind to the upper right corner
ObjectSetInteger(0,text_name,OBJPROP_ANCHOR,ANCHOR_RIGHT_UPPER);
//--- Rotate 90 degrees counter-clockwise
ObjectSetDouble(0,text_name,OBJPROP_ANGLE,90);
//--- Forbid the selection of the object by mouse
ObjectSetInteger(0,text_name,OBJPROP_SELECTABLE,false);
//--- redraw object
ChartRedraw(0);
}
Graphical objects Arrow (OBJ_ARR OW ) have only 2 ways of link ing their coordinates. Identifiers are
listed in ENUM _ARR OW_ANCH OR .
ENUM_ARROW_ANCHOR
ID Description
Example:
void OnStart()
{
//--- Auxiliary arrays
double Ups[],Downs[];
datetime Time[];
//--- Set the arrays as timeseries
ArraySetAsSeries(Ups,true);
ArraySetAsSeries(Downs,true);
ArraySetAsSeries(Time,true);
//--- Create handle of the Indicator Fractals
int FractalsHandle=iFractals(NULL,0);
Print("FractalsHandle = ",FractalsHandle);
//--- Set Last error value to Zero
ResetLastError();
//--- Try to copy the values of the indicator
int copied=CopyBuffer(FractalsHandle,0,0,1000,Ups);
if(copied<=0)
{
Print("Unable to copy the upper fractals. Error = ",GetLastError());
return;
}
ResetLastError();
//--- Try to copy the values of the indicator
copied=CopyBuffer(FractalsHandle,1,0,1000,Downs);
if(copied<=0)
{
Print("Unable to copy the bottom fractals. Error = ",GetLastError());
return;
}
ResetLastError();
//--- Copy timeseries containing the opening bars of the last 1000 ones
copied=CopyTime(NULL,0,0,1000,Time);
if(copied<=0)
{
Print("Unable to copy the Opening Time of the last 1000 bars");
return;
}
After the script execution the chart will look lik e in this figure.
· Button (OBJ_BUTTON);
· Edit (OBJ_EDIT).
· OBJPROP_CORNER – defines the chart corner relative to which the anchor point coordinates are
specified. Can be one of the 4 values of the ENUM _BAS E_CORNER enumeration;
· OBJPROP_ANCHOR – defines the anchor point in object itself and can be one of the 9 values of the
ENUM _ANCH OR_POINT enumeration. Coordinates in pixels are specified from this very point to
selected chart corner;
· OBJPROP_ANGLE – defines the object rotation angle counterclock wise.
In order to specify the chart corner, from which X and Y coordinates will be measured in pixels, use
ObjectSetInteger(chartI D, name, OBJPR OP_CORNER , chart_corner ), where:
· chart_corner – the desired chart corner, can be one of the values of the ENUM _BAS E_CORNER
enumeration.
ENUM_BASE_CORNER
ID Description
Example:
int width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
string arrows[4]={"LEFT_UPPER","RIGHT_UPPER","RIGHT_LOWER","LEFT_LOWER"};
CreateLabel(0,arrows[0],CORNER_LEFT_UPPER,ANCHOR_LEFT_UPPER,arrows[0],50,50);
CreateLabel(0,arrows[1],CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,arrows[1],50,50);
CreateLabel(0,arrows[2],CORNER_RIGHT_LOWER,ANCHOR_RIGHT_LOWER,arrows[2],50,50);
CreateLabel(0,arrows[3],CORNER_LEFT_LOWER,ANCHOR_LEFT_LOWER,arrows[3],50,50);
}
Visibility of Objects
The combination of object visibility flags determines chart timeframes, where the object is visible. To
set/get the value of the OBJPR OP_TIM EFRAM ES property, you can use functions
ObjectSetInteger()/ObjectGetInteger().
ID Value Description
Visibility flags can be combined using the symbol "|" , for example, the combination of flags
OBJ_PER IOD_M 10|OBJ_PER IOD_H4 means that the object will be visible on the 10-minute and 4-hour
timeframes.
Example:
void OnStart()
{
//---
string highlevel="PreviousDayHigh";
string lowlevel="PreviousDayLow";
double prevHigh; // The previous day High
double prevLow; // The previous day Low
double highs[],lows[]; // Arrays for High and Low
ObjectSetInteger(0,highlevel,OBJPROP_TIMEFRAMES,OBJ_PERIOD_M10|OBJ_PERIOD_H4);
}
else
{
Print("Could not get High prices over the past 2 days, Error = ",GetLastError());
}
See also
ENUM_ELLIOT_WAVE_DEGREE
ID Description
Example:
for(int i=0;i<ObjectsTotal(0);i++)
{
string currobj=ObjectName(0,i);
if((ObjectGetInteger(0,currobj,OBJPROP_TYPE)==OBJ_ELLIOTWAVE3) ||
((ObjectGetInteger(0,currobj,OBJPROP_TYPE)==OBJ_ELLIOTWAVE5)))
{
//--- set the marking level in INTERMEDIATE
ObjectSetInteger(0,currobj,OBJPROP_DEGREE,ELLIOTT_INTERMEDIATE);
//--- show lines between tops of waves
ObjectSetInteger(0,currobj,OBJPROP_DRAWLINES,true);
//--- set line color
ObjectSetInteger(0,currobj,OBJPROP_COLOR,clrBlue);
//--- set line width
ObjectSetInteger(0,currobj,OBJPROP_WIDTH,5);
//--- set description
ObjectSetString(0,currobj,OBJPROP_TEXT,"test script");
}
}
Gann Objects
For Gann Fan (OBJ_GANNFAN) and Gann Grid (OBJ_GANNGR ID) objects you can specify two values of
the ENUM _GANN_DI RECTION enumeration that sets the trend direction.
ENUM_GANN_DIRECTION
ID Description
void OnStart()
{
//---
string my_gann="OBJ_GANNFAN object";
if(ObjectFind(0,my_gann)<0)// Object not found
{
//--- Inform about the failure
Print("Object ",my_gann," not found. Error code = ",GetLastError());
//--- Get the maximal price of the chart
double chart_max_price=ChartGetDouble(0,CHART_PRICE_MAX,0);
//--- Get the minimal price of the chart
double chart_min_price=ChartGetDouble(0,CHART_PRICE_MIN,0);
//--- How many bars are shown in the chart?
int bars_on_chart=ChartGetInteger(0,CHART_VISIBLE_BARS);
//--- Create an array, to write the opening time of each bar to
datetime Time[];
//--- Arrange access to the array as that of timeseries
ArraySetAsSeries(Time,true);
//--- Now copy data of bars visible in the chart into this array
int times=CopyTime(NULL,0,0,bars_on_chart,Time);
if(times<=0)
{
Print("Could not copy the array with the open time!");
return;
}
//--- Preliminary preparations completed
Web Colors
The following color constants are defined for the color type:
clrM aroon clrIndigo clrM idnigh clrDarkBlu clrDarkOliv clrSaddle B clrForestG clrOlive Dra
tBlue e e Green rown reen b
clrLightSe clrDarkViol clrFire Bric clrM edium clrM edium clrChocola clrCrimson clrSteelBlu
aGreen et k VioletRed SeaGreen te e
clrGoldenr clrM edium clrLawn Gr clrCadetBl clrDarkOrc clrYellowG clrLime Gre clrOrange
od SpringGre een ue hid reen en Red
en
clrDeepSk clrBlue clrM agent clrRed clrGray clrSlate Gra clrPeru clrBlue Viol
yBlue a y et
clrLightSla clrDeepPin clrM edium clrDodgerB clrTurquoi clrRoyalBlu clrSlate Blu clrDarkKha
te Gray k Turquoise lue se e e ki
clrIndian R clrM edium clrGreen Y clrM edium clrDarkSea clrTomato clrRosyBro clrOrchid
ed Orchid ellow Aquamarin Green wn
e
clrM edium clrPale Viol clrCoral clrCornflo clrDarkGra clrSandyBr clrM edium clrTan
Purple etRed werBlue y own Slate Blue
clrPale Gre clrThistle clrPowder clrPale Gol clrPaleTur clrLightGra clrWheat clrN avajo W
en Blue denrod quoise y hite
clrLavende clrM istyRo clrOldLace clrWhiteS clrSeashell clrIvory clrHoneyd clrAlice Blu
r se mo ke ew e
Color can be set to an object using the ObjectSetInteger() function. For setting color to custom
indicators the PlotIndexSetInteger() function is used. For getting color values there are similar
functions ObjectGetInteger() and PlotIndex GetInteger().
Example:
Wingdings
Characters of W ingdings used with the OBJ_ARR OW object:
Example:
void OnStart()
{
//---
string up_arrow="up_arrow";
datetime time=TimeCurrent();
double lastClose[1];
int close=CopyClose(Symbol(),Period(),0,1,lastClose); // Get the Close price
//--- If the price was obtained
if(close>0)
{
ObjectCreate(0,up_arrow,OBJ_ARROW,0,0,0,0,0); // Create an arrow
ObjectSetInteger(0,up_arrow,OBJPROP_ARROWCODE,241); // Set the arrow code
ObjectSetInteger(0,up_arrow,OBJPROP_TIME,time); // Set time
ObjectSetDouble(0,up_arrow,OBJPROP_PRICE,lastClose[0]);// Set price
ChartRedraw(0); // Draw arrow now
}
else
Print("Unable to get the latest Close price!");
}
Indicators Constants
There are 37 predefined technical indicators, which can be used in programs written in the MQL5
language. In addition, there is an opportunity to create custom indicators using the iCustom()
function. All constants required for that are divided into 5 groups :
· Price constants – for selecting the type of price or volume, on which an indicator is calculated;
· Indicator lines – identifiers of indicator buffers when accessing indicator values using CopyBuffer();
· Drawing styles – for indicating one of 18 types of drawing and setting the line drawing style;
· Custom indicators properties are used in functions for work ing with custom indicators ;
· Types of indicators are used for specifying the type of technical indicator when creating a handle
using IndicatorCreate();
· Identifiers of data types are used for specifying the type of data passed in an array of the M qlParam
type into the IndicatorCreate() function.
Price Constants
Calculations of technical indicators require price values and/or values of volumes, on which
calculations will be performed. There are 7 predefined identifiers from the ENUM _APPLI ED_PR ICE
enumeration, used to specify the desired price base for calculations.
ENUM_APPLIED_PRICE
ID Description
If the volume is used in calculations, it's necessary to specify one of the two values from the
ENUM _APPLIED_VOL UM E enumeration.
ENUM_APPLIED_VOLUME
ID Description
To select a necessary variant for calculation, specify one of the values of the ENUM _STO_PR ICE
enumeration.
ENUM_STO_PRICE
ID Description
If a technical indicator uses for calculations price data, type of which is set by ENUM _APPLI ED_PR ICE,
then handle of any indicator (built in the terminal or written by a user) can be used as the input price
series. In this case, values of the zero buffer of the indicator will be used for calculations. This mak es
it easy to build values of one indicator using values of another indicator. The handle of a custom
indicator is created by calling the iCustom() function.
Example:
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 2
//--- input parameters
input int RSIperiod=14; // Period for calculating the RSI
input int Smooth=8; // Smoothing period RSI
input ENUM_MA_METHOD meth=MODE_SMMA; // Method of smoothing
//---- plot RSI
#property indicator_label1 "RSI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//---- plot RSI_Smoothed
#property indicator_label2 "RSI_Smoothed"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrNavy
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- indicator buffers
double RSIBuffer[]; // Here we store the values of RSI
double RSI_SmoothedBuffer[]; // Here will be smoothed values of RSI
int RSIhandle; // Handle to the RSI indicator
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,RSIBuffer,INDICATOR_DATA);
SetIndexBuffer(1,RSI_SmoothedBuffer,INDICATOR_DATA);
IndicatorSetString(INDICATOR_SHORTNAME,"iRSI");
IndicatorSetInteger(INDICATOR_DIGITS,2);
//---
RSIhandle=iRSI(NULL,0,RSIperiod,PRICE_CLOSE);
//---
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[]
)
Smoothing Methods
Many technical indicators are based on various methods of the price series smoothing. Some standard
technical indicators require specification of the smoothing type as an input parameter. For specifying
the desired type of smoothing, identifiers listed in the ENUM _M A_M ET H OD enumeration are used.
ENUM_MA_METHOD
ID Description
Example:
double ExtJaws[];
double ExtTeeth[];
double ExtLips[];
//---- handles for moving averages
int ExtJawsHandle;
int ExtTeethHandle;
int ExtLipsHandle;
//--- get MA's handles
ExtJawsHandle=iMA(NULL,0,JawsPeriod,0,MODE_SMMA,PRICE_MEDIAN);
ExtTeethHandle=iMA(NULL,0,TeethPeriod,0,MODE_SMMA,PRICE_MEDIAN);
ExtLipsHandle=iMA(NULL,0,LipsPeriod,0,MODE_SMMA,PRICE_MEDIAN);
Indicators Lines
Some technical indicators have several buffers drawn in the chart. Numbering of indicator buffers
starts with 0. W hen copying indicator values using the CopyBuffer() function into an array of the
double type, for some indicators one may indicate the identifier of a copied buffer instead of its
number.
Identifiers of indicator lines permissible when copying values of iM ACD(), iRVI() and iStochastic().
Identifiers of indicator lines permissible when copying values of ADX() and ADXW ().
Identifiers of indicator lines permissible when copying values of iEnvelopes() and iFractals().
Drawing Styles
W hen creating a custom indicator, you can specify one of 18 types of graphical plotting (as displayed
in the main chart window or a chart subwindow), whose values are specified in the ENUM _DRAW_T YPE
enumeration.
In one custom indicator, it is permissible to use any indicator building /drawing types. Each
construction type requires specification of one to five global arrays for storing data necessary for
drawing. These data arrays must be bound with indicator buffers using the SetIndex Buffer() function.
The type of data from ENUM _I NDEXBUFFER_T YPE should be specified for each buffer.
Depending on the drawing style, you may need one to four value buffers (mark ed as
I NDICATOR_DAT A). If a style admits dynamic alternation of colors (all styles contain COLOR in their
names), then you'll need one more buffer of color (indicated type I NDICATOR_COLOR_I NDEX). The
color buffers are always bound after value buffers corresponding to the style.
ENUM_DRAW_TY PE
DRAW_LINE Line 1 0
buffers
DRAW_COLOR_CANDL Multicolored 4 1
ES candlestick s
To refine the display of the selected drawing type identifiers listed in ENUM _PLOT _PR OPER T Y are
used.
ENUM_PLOT_PROPERTY _INTEGER
ENUM_PLOT_PROPERTY _DOUBLE
ENUM_PLOT_PROPERTY _STRING
5 styles can be used for drawing lines in custom indicators. They are valid only for the line thick ness 0
or 1.
ENUM_LINE_STY LE
ID Description
To set the line drawing style and the type of drawing, the PlotIndexSetInteger() function is used. For
the Fibonacci extensions the thick ness and drawing style of levels can be indicated using the
ObjectSetInteger() function.
Example:
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- indicator buffers
double MABuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
ENUM_INDEX BUFFER_TY PE
ID Description
A custom indicator has a lot of settings to provide convenient displaying. These settings are made
through the assignment of corresponding indicator properties using functions IndicatorSetDouble(),
IndicatorSetInteger() and IndicatorSetString(). Identifiers of indicator properties are listed in the
ENUM _CUSTOMIND_PR OPER T Y enumeration.
ENUM_CUSTOMIND_PROPERTY _INTEGER
ENUM_CUSTOMIND_PROPERTY _DOUBLE
ENUM_CUSTOMIND_PROPERTY _STRING
Examples:
W hen creating an indicator of type IND_CUSTOM, the type field of the first element of an array of
input parameters M qlParam must have the T YPE_ST R I NG value of the enumeration ENUM _DAT AT YPE,
while the field string_value of the first element must contain the name of the custom indicator.
ENUM_INDICATOR
Identifier Indicator
I ND_AD Accumulation/Distribution
I ND_ENVELOPES Envelopes
I ND_M ACD M A CD
I ND_OSM A OsM A
I ND_S AR Parabolic S AR
I ND_VOL UM ES Volumes
ENUM_DATATY PE
T YPE_BOOL bool
T YPE_CHAR char
T YPE_UCHAR uchar
T YPE_S H OR T short
T YPE_US H OR T ushort
T YPE_COLOR color
T YPE_I NT int
T YPE_UI NT uint
T YPE_LONG long
T YPE_ULONG ulong
T YPE_FLOAT float
T YPE_DOUBL E double
T YPE_ST R I NG string
Each element of the array describes the corresponding input parameter of a created technical
indicator, so the type and order of elements in the array must be strictly maintained in accordance
with the description.
Environment State
Constants describing the current runtime environment of an mql5-program are divided into groups :
· Executed MQL5-program properties – mql5 program properties, which help to control its execution;
ENUM_TERMINAL_INFO_INTEGER
T ER MI NAL _COMM UNIT Y_ACCO The flag indicates the presence bool
UNT of MQL5.community
authorization data in the
terminal
terminal (agent), M B
T ER MI NAL _PI NG_L AST The last k nown value of a ping int
to a trade server in
microseconds. One second
comprises of one million
microseconds
T ER MI NAL _KEYST AT E_L EFT State of the " Left arrow" k ey int
T ER MI NAL _KEYST AT E_M ENU State of the "W indows " k ey int
Call to TerminalInfoInteger(T ER MI NAL _KEYST AT E_XXX) returns the same state code of a k ey as the
GetKeyState() function in MS DN.
In the above example, the graphical resource look s the same on monitors with different resolution
characteristics. The size of control elements (buttons, dialog windows, etc.) corresponds to
personalization settings.
ENUM_TERMINAL_INFO_DOUBLE
The
T ER MI NAL _RET RANSMISSION
value is requested from the
operating system once per
minute. The terminal itself
does not calculate this value.
File operations can be performed only in two directories ; corresponding paths can be obtained using
the request for T ER MI NAL _DAT A_PAT H and T ER MI NAL _COMMONDAT A_PAT H properties.
ENUM_TERMINAL_INFO_STRING
For a better understanding of paths, stored in properties of T ER MINAL _PAT H , T ER MINAL _DAT A_PAT H
and T ER MI NAL _COMMONDAT A_PAT H parameters, it is recommended to execute the script, which will
return these values for the current copy of the client terminal, installed on your computer
//+------------------------------------------------------------------+
//| Check_TerminalPaths.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
As result of the script execution in the Experts Journal you will see a messages, lik e the following :
ENUM_MQL_INFO_INTEGER
MQL _PR OGRAM _T YPE Type of the MQL5 program ENUM _PR OGRAM _T YPE
MQL _LICENS E_T YPE Type of license of the EX5 ENUM _LICENS E_T YPE
module. The license refers to
the EX5 module, from which a
request is made using
MQLInfoInteger(MQL _LICENS E_
T YPE).
ENUM_MQL_INFO_STRING
For information about the type of the running program, values of ENUM _PR OGRAM _T YPE are used.
ENUM_PROGRAM_TY PE
Identifier Description
ENUM_LICENSE_TY PE
Identifier Description
Example:
ENUM_PROGRAM_TYPE mql_program=(ENUM_PROGRAM_TYPE)MQLInfoInteger(MQL_PROGRAM_TYPE);
switch(mql_program)
{
case PROGRAM_SCRIPT:
{
Print(__FILE__+" is script");
break;
}
case PROGRAM_EXPERT:
{
Print(__FILE__+" is Expert Advisor");
break;
}
case PROGRAM_INDICATOR:
{
Print(__FILE__+" is custom indicator");
break;
}
default:Print("MQL5 program type value is ",mql_program);
}
Symbol Properties
To obtain the current mark et information there are several functions : SymbolInfoInteger(),
SymbolInfoDouble() and SymbolInfoString(). The first parameter is the symbol name, the values of the
second function parameter can be one of the identifiers of ENUM _S YM BOL _I NFO_I NT EGER ,
ENUM _S YM BOL _INFO_DOUBL E and ENUM _S YM BOL _INFO_ST R ING.
ENUM_SY MBOL_INFO_INTEGER
S YM BOL _CHAR T _MODE The price type used for ENUM _S YM BOL _CHAR T _MODE
generating symbols bars, i.e.
Bid or Last
ENUM_SY MBOL_INFO_DOUBLE
Basic calculation:
ENUM_SY MBOL_INFO_STRING
A symbol price chart can be based on Bid or Last prices. The price selected for symbol charts also
affects the generation and display of bars in the terminal. Possible values of the
S YM BOL _CHAR T _MODE property are described in ENUM _S YM BOL _CHAR T _MODE
ENUM_SY MBOL_CHART_MODE
Identifier Description
For each symbol several expiration modes of pending orders can be specified. A flag is matched to
each mode. Flags can be combined using the operation of logical OR (|), for example,
S YM BOL _EXPI RATION_GTC|S YM BOL _EXPI RATION_SPECI FI ED. In order to check whether a certain mode
is allowed for the symbol, the result of the logical AND (&) should be compared to the mode flag.
If flag S YM BOL _EXPI RATION_SPECI FI ED is specified for a symbol, then while sending a pending order,
you may specify the moment this pending order is valid till.
Example:
//+------------------------------------------------------------------+
//| Checks if the specified expiration mode is allowed |
//+------------------------------------------------------------------+
bool IsExpirationTypeAllowed(string symbol,int exp_type)
{
//--- Obtain the value of the property that describes allowed expiration modes
int expiration=(int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE);
//--- Return true, if mode exp_type is allowed
return((expiration&exp_type)==exp_type);
}
If the S YM BOL _EXPI RATION_MODE property is set to S YM BOL _EXPI RATION_GTC (good till canceled),
the expiration of pending orders, as well as of Stop Loss /Tak e Profit orders should be additionally set
using the ENUM _S YM BOL _ORDER_GTC_MODE enumeration.
ENUM_SY MBOL_ORDER_GTC_MODE
Identifier Description
S YM BOL _ORDER S _GTC Pending orders and Stop Loss /Tak e Profit levels
are valid for an unlimited period until their
explicit cancellation
S YM BOL _ORDER S _DAIL Y Orders are valid during one trading day. At the
end of the day, all Stop Loss and Tak e Profit
levels, as well as pending orders are deleted.
S YM BOL _ORDER S _DAIL Y_EXCL UDI NG_STOPS W hen a trade day changes, only pending orders
are deleted, while Stop Loss and Tak e Profit
levels are preserved.
W hen sending an order, you can specify the filling policy for the volume set in the order. Allowed order
filling modes for each symbol are specified in the table. You can set several modes for one symbol by
combining flags. The flags can be combined by the operation of the logical OR (|), for example,
S YM BOL _FILLI NG_FOK|S YM BOL _FILLI NG_IOC. In order to check whether a certain mode is allowed for
the symbol, the result of the logical AND (&) should be compared to the mode flag.
cannot be filled
completely, the
available volume of
the order will be filled,
and the remaining
volume will be
canceled. The
possibility of using IOC
orders is determined
at the trade server.
In the R equest and Instant execution modes the Fill or Kill policy is always used for mark et orders, and
the R eturn policy is always used for limit orders. In this case, when sending orders using OrderSend or
OrderSendAsync, there is no need to specify a fill policy for them.
In the Mark et and Exchange execution modes the R eturn policy is always allowed for all the order
types. To find out whether the other policies are allowed, use the S YM BOL _FILLI NG_FOK and
S YM BOL _FILLI NG_IOC properties.
Example:
//+------------------------------------------------------------------+
//| Checks if the specified filling mode is allowed |
//+------------------------------------------------------------------+
bool IsFillingTypeAllowed(string symbol,int fill_type)
{
//--- Obtain the value of the property that describes allowed filling modes
int filling=(int)SymbolInfoInteger(symbol,SYMBOL_FILLING_MODE);
//--- Return true, if mode fill_type is allowed
return((filling & fill_type)==fill_type);
}
W hen sending a trade request using OrderSend() function, an order type from ENUM _ORDER_T YPE
enumeration should be specified for some operations. Not all types of orders may be allowed for a
specific symbol. S YM BOL _ORDER_MODE property describes the flags of the allowed order types.
Example:
//+------------------------------------------------------------------+
//| The function prints out order types allowed for a symbol |
//+------------------------------------------------------------------+
void Check_SYMBOL_ORDER_MODE(string symbol)
{
//--- receive the value of the property describing allowed order types
int symbol_order_mode=(int)SymbolInfoInteger(symbol,SYMBOL_ORDER_MODE);
//--- check for market orders (Market Execution)
if((SYMBOL_ORDER_MARKET&symbol_order_mode)==SYMBOL_ORDER_MARKET)
Print(symbol+": Market orders are allowed (Buy and Sell)");
//--- check for Limit orders
if((SYMBOL_ORDER_LIMIT&symbol_order_mode)==SYMBOL_ORDER_LIMIT)
Print(symbol+": Buy Limit and Sell Limit orders are allowed");
//--- check for Stop orders
if((SYMBOL_ORDER_STOP&symbol_order_mode)==SYMBOL_ORDER_STOP)
Print(symbol+": Buy Stop and Sell Stop orders are allowed");
//--- check for Stop Limit orders
if((SYMBOL_ORDER_STOP_LIMIT&symbol_order_mode)==SYMBOL_ORDER_STOP_LIMIT)
Print(symbol+": Buy Stop Limit and Sell Stop Limit orders are allowed");
//--- check if placing a Stop Loss orders is allowed
if((SYMBOL_ORDER_SL&symbol_order_mode)==SYMBOL_ORDER_SL)
Print(symbol+": Stop Loss orders are allowed");
The ENUM _S YM BOL _CALC_MODE enumeration is used for obtaining information about how the margin
requirements for a symbol are calculated.
ENUM_SY MBOL_CALC_MODE
Profit: (close_price -
open_price) *
Contract_Size*Lots
Profit: (close_price -
open_price) * Tick Price /
Tick Size*Lots
Profit: (close_price -
open_price) * Contract_Size *
Lots
Profit: (close_price -
open_price) * Contract_Size *
Lots
Profit: (close_price-
open_price) * Contract_Size *
Lots
Profit: (close_price -
open_price) * Lots *
Tick Price / Tick Size
There are several symbol trading modes. Information about trading modes of a certain symbol is
reflected in the values of enumeration ENUM _S YM BOL _T RADE_MODE.
ENUM_SY MBOL_TRADE_MODE
Identifier Description
Possible deal execution modes for a certain symbol are defined in enumeration
ENUM _S YM BOL _T RADE_EXECUTION.
Identifier Description
ENUM_SY MBOL_SWAP_MODE
Identifier Description
S YM BOL _S WAP_MODE_I NT EREST _CURRENT Swaps are charged as the specified annual
interest from the instrument price at calculation
of swap (standard bank year is 360 days)
S YM BOL _S WAP_MODE_I NT EREST _OPEN Swaps are charged as the specified annual
interest from the open price of position
(standard bank year is 360 days)
Values of the ENUM _DAY_OF_WEEK enumeration are used for specifying days of week .
ENUM_DAY _OF_WEEK
Identifier Description
S UNDAY Sunday
MONDAY Monday
FR IDAY Friday
S AT URDAY Saturday
An option is a contract, which gives the right, but not the obligation, to buy or sell an underlying asset
(goods, stock s, futures, etc.) at a specified price on or before a specific date. The following
enumerations describe option properties, including the option type and the right arising from it.
ENUM_SY MBOL_OPTION_RIGHT
Identifier Description
S YM BOL _OPTION_R I GH T _CALL A call option gives you the right to buy an asset
at a specified price
S YM BOL _OPTION_R I GH T _PUT A put option gives you the right to sell an asset
at a specified price
ENUM_SY MBOL_OPTION_MODE
Identifier Description
Account Properties
To obtain information about the current account there are several functions : AccountInfoInteger(),
AccountInfoDouble() and AccountInfoString(). The function parameter values can accept values from
the corresponding ENUM _ACCOUNT _I NFO enumerations.
ENUM_ACCOUNT_INFO_INTEGER
ACCOUNT _M ARGIN_SO_MODE Mode for setting the minimal ENUM _ACCOUNT _STOPOUT _MO
allowed margin DE
ENUM_ACCOUNT_INFO_DOUBLE
ENUM_ACCOUNT_INFO_STRING
There are several types of accounts that can be opened on a trade server. The type of account on
which an MQL5 program is running can be found out using the ENUM _ACCOUNT _T RADE_MODE
enumeration.
ENUM_ACCOUNT_TRADE_MODE
Identifier Description
In case equity is not enough for maintaining open positions, the Stop Out situation, i.e. forced closing
occurs. The minimum margin level at which Stop Out occurs can be set in percentage or in monetary
terms. To find out the mode set for the account use the ENUM _ACCOUNT _STOPOUT _MODE
enumeration.
ENUM_ACCOUNT_STOPOUT_MODE
Identifier Description
ENUM_ACCOUNT_MARGIN_MODE
Identifier Description
ACCOUNT _M ARGIN_MODE_RET AIL _NETTING Used for the OTC mark ets to interpret positions
in the " netting " mode (only one position can
exist for one symbol). The margin is calculated
ACCOUNT _M ARGIN_MODE_RET AIL _HEDGING Used for the exchange mark ets where individual
positions are possible (hedging, multiple
positions can exist for one symbol). The margin
is calculated based on the symbol type
(S YM BOL _T RADE_CALC_MODE) tak ing into
account the hedged margin
(S YM BOL _M ARGI N_HEDGED).
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Name of the company
string company=AccountInfoString(ACCOUNT_COMPANY);
//--- Name of the client
string name=AccountInfoString(ACCOUNT_NAME);
//--- Account number
long login=AccountInfoInteger(ACCOUNT_LOGIN);
//--- Name of the server
string server=AccountInfoString(ACCOUNT_SERVER);
//--- Account currency
string currency=AccountInfoString(ACCOUNT_CURRENCY);
//--- Demo, contest or real account
ENUM_ACCOUNT_TRADE_MODE account_type=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_M
//--- Now transform the value of the enumeration into an understandable form
string trade_mode;
switch(account_type)
{
case ACCOUNT_TRADE_MODE_DEMO:
trade_mode="demo";
break;
case ACCOUNT_TRADE_MODE_CONTEST:
trade_mode="contest";
break;
default:
trade_mode="real";
break;
}
Testing Statistics
After the testing is over, different parameters of the trading results statistics are calculated. The
values of the parameters can be obtained using the TesterStatistics() function, by specifying the
parameter I D from the ENUM _ST ATISTICS enumeration.
Although two types of parameters (int and double) are used for calculating statistics, the function
returns all values in the double form. All the statistic values of the double type are expressed in the
deposit currency by default, unless otherwise specified.
ENUM_STATISTICS
ST AT _GR OSS _PR OFIT Total profit, the sum of all double
profitable (positive) trades.
The value is greater than or
equal to zero
Trade Constants
Various constants used for programming trading strategies are divided into the following groups :
· Trade orders in DOM – separation of orders according to the direction of a requested operation.
ENUM_SERIES_INFO_INTEGER
Order Properties
R equests to execute trade operations are formalized as orders. Each order has a variety of properties
for reading. Information on them can be obtained using functions OrderGet...() and
H istoryOrderGet...().
ENUM_ORDER_PROPERTY _INTEGER
ENUM_ORDER_PROPERTY _DOUBLE
ENUM_ORDER_PROPERTY _STRING
W hen sending a trade request using the OrderSend() function, some operations require the indication
of the order type. The order type is specified in the type field of the special structure
M qlTradeR equest, and can accept values of the ENUM _ORDER_T YPE enumeration.
ENUM_ORDER_TY PE
Identifier Description
ORDER_T YPE_S ELL _STOP_LIMIT Upon reaching the order price, a pending Sell
Limit order is placed at the StopLimit price
Each order has a status that describes its state. To obtain information, use OrderGetInteger() or
H istoryOrderGetInteger() with the ORDER_ST AT E modifier. Allowed values are stored in the
ENUM _ORDER_ST AT E enumeration.
ENUM_ORDER_STATE
Identifier Description
ORDER_ST AT E_ST AR T ED Order check ed, but not yet accepted by brok er
ORDER_ST AT E_REQUEST _CANCEL Order is being deleted (deleting from the trading
system)
W hen sending a trade request using the OrderSend() function, the filling policy can be set for an order
in the type_filling field of the special structure M qlTradeR equest. Values of the
ENUM _ORDER_T YPE_FILLING enumeration are allowed. To obtain the value of this property, use the
function OrderGetInteger() or H istoryOrderGetInteger() with the ORDER_T YPE_FILLI NG modifier.
ENUM_ORDER_TY PE_FILLING
Identifier Description
ORDER_FILLI NG_RET URN This policy is used only for mark et orders
(ORDER_T YPE_BUY and ORDER_T YPE_S ELL),
limit and stop limit orders
(ORDER_T YPE_BUY_LIMIT,
ORDER_T YPE_S ELL _LIMIT,
ORDER_T YPE_BUY_STOP_LIMIT and
ORDER_T YPE_S ELL _STOP_LIMIT ) and only for
the symbols with Mark et or Exchange execution.
In case of partial filling a mark et or limit order
with remaining volume is not canceled but
processed further.
For the activation of the
ORDER_T YPE_BUY_STOP_LIMIT and
ORDER_T YPE_S ELL _STOP_LIMIT orders, a
corresponding limit order
ORDER_T YPE_BUY_LIMIT /ORDER_T YPE_S ELL _LI
MIT with the ORDER_FILLI NG_RET URN execution
type is created.
The order validity period can be set in the type_time field of the special structure M qlTradeR equest
when sending a trade request using the OrderSend() function. Values of the ENUM _ORDER_T YPE_TIM E
enumeration are allowed. To obtain the value of this property use the function OrderGetInteger() or
H istoryOrderGetInteger() with the ORDER_T YPE_TIM E modifier.
ENUM_ORDER_TY PE_TIME
Identifier Description
ORDER_TIM E_SPECI FI ED_DAY The order will be effective till 23:59:59 of the
specified day. If this time is outside a trading
session, the order expires in the nearest trading
time.
The reason for order placing is contained in the ORDER_REASON property. An order can be placed by
an MQL5 program, from a mobile application, as a result of StopOut, etc. Possible values of
ORDER_REASON are described in the ENUM _ORDER_REASON enumeration.
ENUM_ORDER_REASON
Identifier Description
ORDER_REASON_CLI ENT The order was placed from a des k top terminal
Position Properties
Execution of trade operations results in the opening of a position, changing of its volume and/or
direction, or its disappearance. Trade operations are conducted based on orders, sent by the
OrderSend() function in the form of trade requests. For each financial security (symbol) only one open
position is possible. A position has a set of properties available for reading by the PositionGet...()
functions.
ENUM_POSITION_PROPERTY _INTEGER
POSITION_TICKET value
corresponds to
M qlTradeR equest::position.
ENUM_POSITION_PROPERTY _DOUBLE
ENUM_POSITION_PROPERTY _STRING
Direction of an open position (buy or sell) is defined by the value from the ENUM _POSITION_T YPE
enumeration. In order to obtain the type of an open position use the PositionGetInteger() function
with the POSITION_T YPE modifier.
ENUM_POSITION_TY PE
Identifier Description
The reason for opening a position is contained in the POSITION_REASON property. A position can be
opened as a result of activation of an order placed from a des k top terminal, a mobile application, by
an Expert Advisor, etc. Possible values of POSITION_REASON are described in the
ENUM _POSITION_REASON enumeration.
ENUM_POSITION_REASON
Identifier Description
Deal Properties
A deal is the reflection of the fact of a trade operation execution based on an order that contains a
trade request. Each trade is described by properties that allow to obtain information about it. In order
to read values of properties, functions of the H istoryDealGet...() type are used, that return values
from corresponding enumerations.
ENUM_DEAL_PROPERTY _INTEGER
DEAL _ENT RY Deal entry - entry in, entry out, ENUM _DEAL _ENT RY
reverse
DEAL _REASON The reason or source for deal ENUM _DEAL _REASON
execution
ENUM_DEAL_PROPERTY _DOUBLE
ENUM_DEAL_PROPERTY _STRING
Each deal is characterized by a type, allowed values are enumerated in ENUM _DEAL _T YPE. In order to
obtain information about the deal type, use the H istoryDealGetInteger() function with the DEAL _T YPE
modifier.
ENUM_DEAL_TY PE
Identifier Description
DEAL _T YPE_S ELL _CANCEL ED Canceled sell deal. There can be a situation
when a previously executed sell deal is canceled.
In this case, the type of the previously executed
deal (DEA L _T YPE_S ELL) is changed to
DEAL _T YPE_S ELL _CANCEL ED, and its profit/loss
is zeroized. Previously obtained profit/loss is
charged/withdrawn using a separated balance
operation
Deals differ not only in their types set in ENUM _DEAL _T YPE, but also in the way they change positions.
This can be a simple position opening, or accumulation of a previously opened position (mark et
entering), position closing by an opposite deal of a corresponding volume (mark et exiting), or position
reversing, if the opposite-direction deal covers the volume of the previously opened position.
All these situations are described by values from the ENUM _DEAL _ENT RY enumeration. In order to
receive this information about a deal, use the H istoryDealGetInteger() function with the DEAL _ENT RY
modifier.
ENUM_DEAL_ENTRY
Identifier Description
The reason for deal execution is contained in the DEAL _REASON property. A deal can be executed as a
result of triggering of an order placed from a mobile application or an MQL5 program, as well as as a
result of the StopOut event, variation margin calculation, etc. Possible values of DEAL _REASON are
described in the ENUM _DEAL _REASON enumeration. For non-trading deals resulting from balance,
credit, commission and other operations, DEAL _REASON_CLI ENT is indicated as the reason.
ENUM_DEAL_REASON
Identifier Description
DEAL _REASON_VM ARGIN The deal was executed after charging the
variation margin
DEAL _REASON_SPLIT The deal was executed after the split (price
reduction) of an instrument, which had an open
position during split announcement
ENUM_TRADE_REQUEST_ACTIONS
Identifier Description
}
}
//+------------------------------------------------------------------+
Example of the T RADE_ACTION_SLTP trade operation for modifying the Stop Loss and Tak e Profit
values of an open position:
//--- calculation and rounding of the Stop Loss and Take Profit values
price_level=stop_level*SymbolInfoDouble(position_symbol,SYMBOL_POINT);
if(type==POSITION_TYPE_BUY)
{
sl=NormalizeDouble(bid-price_level,digits);
tp=NormalizeDouble(ask+price_level,digits);
}
else
{
sl=NormalizeDouble(ask+price_level,digits);
tp=NormalizeDouble(bid-price_level,digits);
}
//--- zeroing the request and result values
ZeroMemory(request);
ZeroMemory(result);
//--- setting the operation parameters
request.action =TRADE_ACTION_SLTP; // type of trade operation
request.position=position_ticket; // ticket of the position
request.symbol=position_symbol; // symbol
request.sl =sl; // Stop Loss of the position
request.tp =tp; // Take Profit of the position
request.magic=EXPERT_MAGIC; // MagicNumber of the position
//--- output information about the modification
PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
//--- send the request
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // if unable to send the request, ou
//--- information about the operation
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order)
}
}
}
//+------------------------------------------------------------------+
Example of the T RADE_ACTION_MODIFY trade operation for modifying the price levels of pending
orders :
request.sl = NormalizeDouble(price-offset*point,digits);
request.price =NormalizeDouble(price,digits); // normalized opening
}
else if(type==ORDER_TYPE_SELL_STOP)
{
price = SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;
request.tp = NormalizeDouble(price-offset*point,digits);
request.sl = NormalizeDouble(price+offset*point,digits);
request.price =NormalizeDouble(price,digits); // normalized opening
}
//--- send the request
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // if unable to send the request, ou
//--- information about the operation
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order)
//--- zeroing the request and result values
ZeroMemory(request);
ZeroMemory(result);
}
}
}
//+------------------------------------------------------------------+
Example of the T RADE_ACTION_CLOS E_BY trade operation for closing positions by opposite positions :
· Sending a trade request from any MQL5 application in the client terminal using OrderSend and
OrderSendAsync functions and its further execution;
· Sending a trade request via the terminal graphical interface and its further execution;
· changing positions.
For example, when sending a mark et buy order, it is handled, an appropriate buy order is created for
the account, the order is then executed and removed from the list of the open ones, then it is added
to the orders history, an appropriate deal is added to the history and a new position is created. All
these actions are trade transactions.
Trade transaction type is submitted in the type parameter of M qlTradeTransaction structure. Possible
types of trade transactions are described by the following enumeration:
ENUM_TRADE_TRANSACTION_TY PE
Identifier Description
T RADE_T RANS ACTION_ORDER_UPDAT E Updating an open order. The updates include not
only evident changes from the client terminal or
a trade server sides but also changes of an order
state when setting it (for example, transition
from ORDER_ST AT E_ST AR T ED to
ORDER_ST AT E_PL ACED or from
ORDER_ST AT E_PL ACED to
ORDER_ST AT E_PAR TI AL, etc.).
T RADE_T RANS ACTION_ORDER_DEL ET E R emoving an order from the list of the open
ones. An order can be deleted from the open
ones as a result of setting an appropriate
request or execution (filling) and moving to the
history.
T RADE_T RANS ACTION_DEAL _ADD Adding a deal to the history. The action is
performed as a result of an order execution or
performing operations with an account balance.
T RADE_T RANS ACTION_DEAL _UPDAT E Updating a deal in the history. There may be
cases when a previously executed deal is
changed on a server. For example, a deal has
been changed in an external trading system
(exchange) where it was previously transferred
by a brok er.
T RADE_T RANS ACTION_DEAL _DEL ET E Deleting a deal from the history. There may be
cases when a previously executed deal is deleted
from a server. For example, a deal has been
deleted in an external trading system
(exchange) where it was previously transferred
by a brok er.
T RADE_T RANS ACTION_H ISTORY_UPDAT E Changing an order located in the orders history.
This type is provided for enhancing functionality
on a trade server side.
T RADE_T RANS ACTION_H ISTORY_DEL ET E Deleting an order from the orders history. This
type is provided for enhancing functionality on a
trade server side.
T RADE_T RANS ACTION_REQUEST Notification of the fact that a trade request has
been processed by a server and processing result
has been received. Only type field (trade
transaction type) must be analyzed for such
transactions in M qlTradeTransaction structure.
The second and third parameters of
OnTradeTransaction (request and result) must
be analyzed for additional data.
Depending on a trade transaction type, various parameters are filled in M qlTradeTransaction structure
describing it. A detailed description of submitted data is shown in " Structure of a Trade Transaction" .
See also
To obtain information about the current state of the DOM by MQL5 means, the Mark etBookGet()
function is used, which places the DOM " screen shot" into the M qlBook Info array of structures. Each
element of the array in the type field contains information about the direction of the order - the value
of the ENUM _BOOK_T YPE enumeration.
ENUM_BOOK_TY PE
Identifier Description
See also
Structures and classes, Structure of the DOM, Trade operation types, Mark et Info
Signal Properties
The following enumerations are used when work ing with trading signals and signal copy settings.
ENUM_SIGNAL_BASE_DOUBLE
ID Description
ENUM_SIGNAL_BASE_INTEGER
ID Description
SI GNAL _BAS E_DAT E_PUBLIS HED Publication date (date when it become available
for subscription)
SI GNAL _BAS E_DAT E_UPDAT ED The date of the last update of the signal's
trading statistics
ENUM_SIGNAL_BASE_STRING
ID Description
ENUM_SIGNAL_INFO_DOUBLE
ID Description
SI GNAL _I NFO_VOL UM E_PER CENT Maximum percent of deposit used (%), r/o
ENUM_SIGNAL_INFO_INTEGER
ID Description
SI GNAL _I NFO_CONFI R M ATIONS _DIS ABL ED The flag enables synchronization without
confirmation dialog
SI GNAL _I NFO_S UBSCR IPTION_ENABL ED " Copy trades by subscription" permission flag
ENUM_SIGNAL_INFO_STRING
ID Description
See also
Trade signals
Named Constants
All constants used in MQL5 can be divided into the following groups :
Constant Description
Example:
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- information output at tick receipt
Print(" __MQLBUILD__ = ",__MQLBUILD__," __FILE__ = ",__FILE__);
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__);
test1(__FUNCTION__);
test2();
//---
}
//+------------------------------------------------------------------+
//| test1 |
//+------------------------------------------------------------------+
void test1(string par)
{
//--- information output inside the function
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__," par = ",par);
}
//+------------------------------------------------------------------+
//| test2 |
//+------------------------------------------------------------------+
void test2()
{
//--- information output inside the function
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__);
}
//+------------------------------------------------------------------+
//| OnTimer event handler |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
Print(" __FUNCTION__ = ",__FUNCTION__," __LINE__ = ",__LINE__);
test1(__FUNCTION__);
}
Mathematical Constants
Special constants containing values are reserved for some mathematical expressions. These constants
can be used in any place of the program instead of calculating their values using mathematical
functions.
M _E e 2.71828182845904523536
M _L N2 ln(2) 0.693147180559945309417
M _PI pi 3.14159265358979323846
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- print the values of constants
Print("M_E = ",DoubleToString(M_E,16));
Print("M_LOG2E = ",DoubleToString(M_LOG2E,16));
Print("M_LOG10E = ",DoubleToString(M_LOG10E,16));
Print("M_LN2 = ",DoubleToString(M_LN2,16));
Print("M_LN10 = ",DoubleToString(M_LN10,16));
Print("M_PI = ",DoubleToString(M_PI,16));
Print("M_PI_2 = ",DoubleToString(M_PI_2,16));
Print("M_PI_4 = ",DoubleToString(M_PI_4,16));
Print("M_1_PI = ",DoubleToString(M_1_PI,16));
Print("M_2_PI = ",DoubleToString(M_2_PI,16));
Print("M_2_SQRTPI = ",DoubleToString(M_2_SQRTPI,16));
Print("M_SQRT2 = ",DoubleToString(M_SQRT2,16));
Print("M_SQRT1_2 = ",DoubleToString(M_SQRT1_2,16));
Example:
void OnStart()
{
//--- print the constant values
printf("CHAR_MIN = %d",CHAR_MIN);
printf("CHAR_MAX = %d",CHAR_MAX);
printf("UCHAR_MAX = %d",UCHAR_MAX);
printf("SHORT_MIN = %d",SHORT_MIN);
printf("SHORT_MAX = %d",SHORT_MAX);
printf("USHORT_MAX = %d",USHORT_MAX);
printf("INT_MIN = %d",INT_MIN);
printf("INT_MAX = %d",INT_MAX);
printf("UINT_MAX = %u",UINT_MAX);
printf("LONG_MIN = %I64d",LONG_MIN);
printf("LONG_MAX = %I64d",LONG_MAX);
printf("ULONG_MAX = %I64u",ULONG_MAX);
printf("EMPTY_VALUE = %.16e",EMPTY_VALUE);
printf("DBL_MIN = %.16e",DBL_MIN);
printf("DBL_MAX = %.16e",DBL_MAX);
printf("DBL_EPSILON = %.16e",DBL_EPSILON);
printf("DBL_DIG = %d",DBL_DIG);
printf("DBL_MANT_DIG = %d",DBL_MANT_DIG);
printf("DBL_MAX_10_EXP = %d",DBL_MAX_10_EXP);
printf("DBL_MAX_EXP = %d",DBL_MAX_EXP);
printf("DBL_MIN_10_EXP = %d",DBL_MIN_10_EXP);
printf("DBL_MIN_EXP = %d",DBL_MIN_EXP);
printf("FLT_MIN = %.8e",FLT_MIN);
printf("FLT_MAX = %.8e",FLT_MAX);
printf("FLT_EPSILON = %.8e",FLT_EPSILON);
}
The uninitialization reason code is also passed as a parameter of the predetermined function
OnDeinit(const int reason).
Example:
//+------------------------------------------------------------------+
//| get text description |
//+------------------------------------------------------------------+
string getUninitReasonText(int reasonCode)
{
string text="";
//---
switch(reasonCode)
{
case REASON_ACCOUNT:
text="Account was changed";break;
case REASON_CHARTCHANGE:
text="Symbol or timeframe was changed";break;
case REASON_CHARTCLOSE:
text="Chart was closed";break;
case REASON_PARAMETERS:
text="Input-parameter was changed";break;
case REASON_RECOMPILE:
text="Program "+__FILE__+" was recompiled";break;
case REASON_REMOVE:
text="Program "+__FILE__+" was removed from chart";break;
case REASON_TEMPLATE:
text="New template was applied to chart";break;
default:text="Another reason";
}
//---
return text;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- The first way to get the uninitialization reason code
Print(__FUNCTION__,"_Uninitalization reason code = ",reason);
//--- The second way to get the uninitialization reason code
Print(__FUNCTION__,"_UninitReason = ",getUninitReasonText(_UninitReason));
}
Objects created by the new() operator are of POI NT ER_DYNAMIC type. The delete() operator can and
should be used only for such pointers.
All other pointers are of POINT ER_AUTOM ATIC type, which means that this object has been created
automatically by the mql5 program environment. Such objects are deleted automatically after being
used.
ENUM_POINTER_TY PE
Constant Description
See also
R untime errors, Object Delete Operator delete, Check Pointer
Other Constants
The CL R_NONE constant is used to outline the absence of color, it means that the graphical object or
graphical series of an indicator will not be plotted. This constant was not included into the W eb-color
constants list, but it can be applied everywhere where the color arguments are required.
The I NVALI D_HANDL E constant can be used for check ing file handles (see FileOpen() and
FileFindFirst()).
IS _PR OFIL E_MODE Flag that a mq5-program non zero in profiling mode,
operates in profiling mode otherwise zero
The EMPT Y_VAL UE constant usually corresponds to the values of indicators that are not shown in the
chart. For example, for built-in indicator Standard Deviation with a period of 20, the line for the first
19 bars in the history is not shown in the chart. If you create a handle of this indicator with the
iStdDev() function and copy it to an array of indicator values for these bars through CopyBuffer(), then
these values will be equal to EMPT Y_VAL UE.
You can choose to specify for a custom indicator your own empty value of the indicator, when the
indicator shouldn't be drawn in the chart. Use the PlotIndexSetDouble() function with the
PLOT _EMPT Y_VAL UE modifier.
The NULL constant can be assigned to a variable of any simple type or to an object structure or class
pointer. The NULL assignment for a string variable means the full deinitialization of this variable.
The WR ONG_VAL UE constant is intended for cases, when it is necessary to return value of an
enumeration, and this must be a wrong value. For example, when we need to inform that a return
value is a value from this enumeration. Let's consider as an example some function Check LineStyle(),
which returns the line style for an object, specified by its name. If at style check by
ObjectGetInteger() the result is true, a value from ENUM _LI NE_ST YL E is returned; otherwise
WR ONG_VAL UE is returned.
void OnStart()
{
if(CheckLineStyle("MyChartObject")==WRONG_VALUE)
printf("Error line style getting.");
}
//+------------------------------------------------------------------+
//| returns the line style for an object specified by its name |
//+------------------------------------------------------------------+
ENUM_LINE_STYLE CheckLineStyle(string name)
{
long style;
//---
if(ObjectGetInteger(0,name,OBJPROP_STYLE,0,style))
return((ENUM_LINE_STYLE)style);
else
return(WRONG_VALUE);
}
The WH OL E_ARRAY constant is intended for functions that require specifying the number of elements
in processed arrays :
· ArrayCopy();
· ArrayMinimum();
· ArrayMaximum();
· FileR eadArray();
· FileW riteArray().
If you want to specify that all the array values from a specified position till the end must be processed,
you should specify just the WH OL E_ARRAY value.
IS _PR OFIL E_MODE constant allows changing a program operation for correct data collection in the
profiling mode. Profiling allows measuring the execution time of the individual program fragments
(usually comprising functions), as well as calculating the number of such calls. Sleep() function calls
can be disabled to determine the execution time in the profiling mode, lik e in this example:
IS _PR OFIL E_MODE constant value is set by the compiler during the compilation, while it is set to zero
in conventional mode. W hen launching a program in the profiling mode, a special compilation is
performed and IS _PR OFIL E_MODE is replaced with a non-zero value.
The IS _DEBUG_MODE constant can be useful when you need to slightly change the operation of a mql5
program in the debugging mode. For example, in debug mode you may need to display additional
debugging information in the terminal log or create additional graphical objects in a chart.
The following example creates a Label object and sets its description and color depending on the script
running mode. In order to run a script in the debug mode from MetaEditor, press F5 . If you run the
script from the browser window in the terminal, then the color and text of the object Label will be
different.
Example:
//+------------------------------------------------------------------+
//| Check_DEBUG_MODE.mq5 |
//| Copyright © 2009, MetaQuotes Software Corp. |
//| https://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link "https://www.metaquotes.net"
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
string label_name="invisible_label";
if(ObjectFind(0,label_name)<0)
{
Print("Object",label_name,"not found. Error code = ",GetLastError());
//--- create Label
ObjectCreate(0,label_name,OBJ_LABEL,0,0,0);
//--- set X coordinate
ObjectSetInteger(0,label_name,OBJPROP_XDISTANCE,200);
//--- set Y coordinate
ObjectSetInteger(0,label_name,OBJPROP_YDISTANCE,300);
ResetLastError();
if(IS_DEBUG_MODE) // debug mode
{
//--- show message about the script execution mode
ObjectSetString(0,label_name,OBJPROP_TEXT,"DEBUG MODE");
//--- set text color to red
if(!ObjectSetInteger(0,label_name,OBJPROP_COLOR,clrRed))
Print("Unable to set the color. Error",GetLastError());
}
else // operation mode
{
ObjectSetString(0,label_name,OBJPROP_TEXT,"RELEASE MODE");
//--- set text color to invisible
if(!ObjectSetInteger(0,label_name,OBJPROP_COLOR,CLR_NONE))
Print("Unable to set the color. Error ",GetLastError());
}
ChartRedraw();
DebugBreak(); // here termination will occur, if we are in debug mode
}
Crypt Methods
The ENUM _CRYPT _M ET H OD enumeration is used to specify the data transformation method, used in
CryptEncode() and CryptDecode() functions.
ENUM_CRY PT_METHOD
Constant Description
CRYPT _AES 128 AES encryption with 128 bit k ey (16 bytes)
CRYPT _AES 256 AES encryption with 256 bit k ey (32 bytes)
See also
Debug Break , Executed MQL5 program properties, CryptEncode(), CryptDecode()
Data Structures
MQL5 Language offers 12 predefined structures :
· M qlParam can send input parameters when creating a handle of the indicator using the
IndicatorCreate() function;
· M qlR ates is intended for manipulating the historical data, it contains information about the price,
volume and spread;
· M qlBook Info is intended for obtaining information about the Depth of Mark et;
· M qlTradeR equest is used for creating a trade request for trade operations ;
· M qlTradeCheckR esult is intended for check ing the prepared trade request before sending it;
· M qlTradeR esult contains a trade server reply to a trade request, sent by OrderSend() function;
· M qlTick is designed for fast retrieval of the most requested information about current prices.
· Economic calendar structures are used to obtain data on the economic calendar events sent to the
MetaTrader 5 platform in real time. Economic calendar functions allow analyzing macroeconomic
parameters immediately after new reports are released, since relevant values are broadcast directly
from the source with no delay.
MqlDateTime
The date type structure contains eight fields of the int type:
struct MqlDateTime
{
int year; // Year
int mon; // Month
int day; // Day
int hour; // Hour
int min; // Minutes
int sec; // Seconds
int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday)
int day_of_year; // Day number of the year (January 1st is assigned the number value of zero)
};
Note
The day number of the year day_of_year for the leap year, since March, will differ from a number of
the corresponding day for a non-leap year.
Example:
void OnStart()
{
//---
datetime date1=D'2008.03.01';
datetime date2=D'2009.03.01';
MqlDateTime str1,str2;
TimeToStruct(date1,str1);
TimeToStruct(date2,str2);
printf("%02d.%02d.%4d, day of year = %d",str1.day,str1.mon,
str1.year,str1.day_of_year);
printf("%02d.%02d.%4d, day of year = %d",str2.day,str2.mon,
str2.year,str2.day_of_year);
}
/* Result:
01.03.2008, day of year = 60
01.03.2009, day of year = 59
*/
See also
struct MqlParam
{
ENUM_DATATYPE type; // type of the input parameter, value of ENUM_DATATYP
long integer_value; // field to store an integer type
double double_value; // field to store a double type
string string_value; // field to store a string type
};
All input parameters of an indicator are transmitted in the form of an array of the M qlParam type, the
type field of each element of this array specifies the type of data transmitted by the element. The
indicator values must be first placed in the appropriate fields for each element (in integer_value, in
double_value or string_value) depending on what value of ENUM _DA T A T YPE enumeration is specified
If the I ND_CUSTOM value is passed third as the indicator type to the IndicatorCreate() function, the
first element of the array of input parameters must have the type field with the value of T YPE_ST R I NG
from the ENUM _DAT AT YPE enumeration, and the string_value field must contain the name of the
custom indicator.
MqlRates
This structure stores information about the prices, volumes and spread.
struct MqlRates
{
datetime time; // Period start time
double open; // Open price
double high; // The highest price of the period
double low; // The lowest price of the period
double close; // Close price
long tick_volume; // Tick volume
int spread; // Spread
long real_volume; // Trade volume
};
Example:
void OnStart()
{
MqlRates rates[];
int copied=CopyRates(NULL,0,0,100,rates);
if(copied<=0)
Print("Error copying price data ",GetLastError());
else Print("Copied ",ArraySize(rates)," bars");
}
See also
MqlBookInfo
It provides information about the mark et depth data.
struct MqlBookInfo
{
ENUM_BOOK_TYPE type; // Order type from ENUM_BOOK_TYPE enumeration
double price; // Price
long volume; // Volume
double volume_real; // Volume with greater accuracy
};
Note
The M qlBook Info structure is predefined, thus it doesn't require any declaration and description. To
use the structure, just declare a variable of this type.
Example:
MqlBookInfo priceArray[];
bool getBook=MarketBookGet(NULL,priceArray);
if(getBook)
{
int size=ArraySize(priceArray);
Print("MarketBookInfo about ",Symbol());
}
else
{
Print("Failed to receive DOM for the symbol ",Symbol());
}
See also
Mark etBookAdd, Mark etBookR elease, Mark etBookGet, Trade Orders in DOM, Data Types
struct MqlTradeRequest
{
ENUM_TRADE_REQUEST_ACTIONS action; // Trade operation type
ulong magic; // Expert Advisor ID (magic number)
ulong order; // Order ticket
string symbol; // Trade symbol
double volume; // Requested volume for a deal in lots
double price; // Price
double stoplimit; // StopLimit level of the order
double sl; // Stop Loss level of the order
double tp; // Take Profit level of the order
ulong deviation; // Maximal possible deviation from the requested
ENUM_ORDER_TYPE type; // Order type
ENUM_ORDER_TYPE_FILLING type_filling; // Order execution type
ENUM_ORDER_TYPE_TIME type_time; // Order expiration type
datetime expiration; // Order expiration time (for the orders of ORDE
string comment; // Order comment
ulong position; // Position ticket
ulong position_by; // The ticket of an opposite position
};
Fields description
Field Description
W hen modifying or closing a position in the hedging system, mak e sure to specify its tick et
(M qlTradeR equest::position). The tick et can also be specified in the netting system, though a
position is identified by the symbol name.
For sending orders to perform trade operations it is necessary to use the OrderSend() function. For
each trade operation it is necessary to specify obligatory fields ; optional fields also may be filled.
There are seven possible cases to send a trade order:
Request Execution
This is a trade order to open a position in the R equest Execution mode (trade upon requested
prices). It requires to specify the following 9 fields :
· action
· symbol
· volume
· price
· sl
· tp
· deviation
· type
· type_filling
Also it is possible to specify the " magic" and " comment" field values.
Instant Execution
This is a trade order to open a position in the Instant Execution mode (trade by current prices). It
requires specification of the following 9 fields :
· action
· symbol
· volume
· price
· sl
· tp
· deviation
· type
· type_filling
Also it is possible to specify the " magic" and " comment" field values.
Market Execution
This is a trade order to open a position in the Mark et Execution mode. It requires to specify the
following 5 fields :
· action
· symbol
· volume
· type
· type_filling
Also it is possible to specify the " magic" and " comment" field values.
Exchange Execution
This is a trade order to open a position in the Exchange Execution mode. It requires to specify the
following 5 fields :
· action
· symbol
· volume
· type
· type_filling
Also it is possible to specify the " magic" and " comment" field values.
}
}
//+------------------------------------------------------------------+
SL & TP Modification
Trade order to modify the StopLoss and/or Tak eProfit price levels. It requires to specify the
following 4 fields :
· action
· symbol
· sl
· tp
· position
Example of the T RADE_ACTION_SLTP trade operation for modifying the Stop Loss and Tak e Profit
values of an open position:
#define EXPERT_MAGIC 123456 // MagicNumber of the expert
//+------------------------------------------------------------------+
//| Modification of Stop Loss and Take Profit of position |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare and initialize the trade request and result of trade request
MqlTradeRequest request;
MqlTradeResult result;
int total=PositionsTotal(); // number of open positions
//--- iterate over all open positions
for(int i=0; i<total; i++)
{
//--- parameters of the order
ulong position_ticket=PositionGetTicket(i);// ticket of the position
string position_symbol=PositionGetString(POSITION_SYMBOL); // symbol
int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // number of decimal pla
ulong magic=PositionGetInteger(POSITION_MAGIC); // MagicNumber of the position
double volume=PositionGetDouble(POSITION_VOLUME); // volume of the position
double sl=PositionGetDouble(POSITION_SL); // Stop Loss of the position
double tp=PositionGetDouble(POSITION_TP); // Take Profit of the position
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // type of th
//--- output information about the position
PrintFormat("#%I64u %s %s %.2f %s sl: %s tp: %s [%I64d]",
position_ticket,
position_symbol,
EnumToString(type),
volume,
DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
DoubleToString(sl,digits),
DoubleToString(tp,digits),
magic);
//--- if the MagicNumber matches, Stop Loss and Take Profit are not defined
if(magic==EXPERT_MAGIC && sl==0 && tp==0)
{
//--- calculation and rounding of the Stop Loss and Take Profit values
price_level=stop_level*SymbolInfoDouble(position_symbol,SYMBOL_POINT);
if(type==POSITION_TYPE_BUY)
{
sl=NormalizeDouble(bid-price_level,digits);
tp=NormalizeDouble(bid+price_level,digits);
}
else
{
sl=NormalizeDouble(ask+price_level,digits);
tp=NormalizeDouble(ask-price_level,digits);
}
//--- zeroing the request and result values
ZeroMemory(request);
ZeroMemory(result);
//--- setting the operation parameters
request.action =TRADE_ACTION_SLTP; // type of trade operation
request.position=position_ticket; // ticket of the position
request.symbol=position_symbol; // symbol
request.sl =sl; // Stop Loss of the position
request.tp =tp; // Take Profit of the position
request.magic=EXPERT_MAGIC; // MagicNumber of the position
//--- output information about the modification
PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
//--- send the request
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // if unable to send the request, ou
//--- information about the operation
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order)
}
}
}
//+------------------------------------------------------------------+
Pending Order
Trade order to place a pending order. It requires to specify the following 11 fields :
· action
· symbol
· volume
· price
· stoplimit
· sl
· tp
· type
· type_filling
· type_time
· expiration
Also it is possible to specify the " magic" and " comment" field values.
Trade order to modify the prices of a pending order. It requires to specify the following 7 fields :
· action
· order
· price
· sl
· tp
· type_time
· expiration
Example of the T RADE_ACTION_MODIFY trade operation for modifying the price levels of pending
orders :
request.sl = NormalizeDouble(price-offset*point,digits);
request.price =NormalizeDouble(price,digits); // normalized opening
}
else if(type==ORDER_TYPE_SELL_STOP)
{
price = SymbolInfoDouble(Symbol(),SYMBOL_BID)-offset*point;
request.tp = NormalizeDouble(price-offset*point,digits);
request.sl = NormalizeDouble(price+offset*point,digits);
request.price =NormalizeDouble(price,digits); // normalized opening
}
//--- send the request
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // if unable to send the request, ou
//--- information about the operation
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order)
//--- zeroing the request and result values
ZeroMemory(request);
ZeroMemory(result);
}
}
}
//+------------------------------------------------------------------+
Trade order to delete a pending order. It requires to specify the following 2 fields :
· action
· order
//+------------------------------------------------------------------+
//| Deleting pending orders |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare and initialize the trade request and result of trade request
MqlTradeRequest request={0};
MqlTradeResult result={0};
int total=OrdersTotal(); // total number of placed pending orders
//--- iterate over all placed pending orders
for(int i=total-1; i>=0; i--)
{
ulong order_ticket=OrderGetTicket(i); // order ticket
ulong magic=OrderGetInteger(ORDER_MAGIC); // MagicNumber of the order
//--- if the MagicNumber matches
if(magic==EXPERT_MAGIC)
{
//--- zeroing the request and result values
ZeroMemory(request);
ZeroMemory(result);
//--- setting the operation parameters
request.action=TRADE_ACTION_REMOVE; // type of trade operation
request.order = order_ticket; // order ticket
//--- send the request
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // if unable to send the request, ou
//--- information about the operation
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order)
}
}
}
//+------------------------------------------------------------------+
See also
struct MqlTradeCheckResult
{
uint retcode; // Reply code
double balance; // Balance after the execution of the deal
double equity; // Equity after the execution of the deal
double profit; // Floating profit
double margin; // Margin requirements
double margin_free; // Free margin
double margin_level; // Margin level
string comment; // Comment to the reply code (description of the error)
};
Description of Fields
Field Description
See also
struct MqlTradeResult
{
uint retcode; // Operation return code
ulong deal; // Deal ticket, if it is performed
ulong order; // Order ticket, if it is placed
double volume; // Deal volume, confirmed by broker
double price; // Deal price, confirmed by broker
double bid; // Current Bid price
double ask; // Current Ask price
string comment; // Broker comment to operation (by default it is filled by descriptio
uint request_id; // Request ID set by the terminal during the dispatch
uint retcode_external; // Return code of an external trading system
};
Fields description
Field Description
The trade operation result is returned to a variable of the M qlTradeR esult type, which is passed as the
second parameter to OrderSend() to perform trade operations.
The terminal fixes request I D in request_id field when sending it to the trade server using
OrdersSend() and OrderSendAsync() functions. The terminal receives messages about performed
transactions from the trade server and submits them for processing by OnTradeTransaction() function
containing the following components as parameters :
· description of the trade request sent from OrderSend() or OrdersSendAsync() function. R equest I D is
sent by the terminal to the trade server, while the request itself and its request_id are stored in the
terminal memory;
· the trade request execution result as M qlTradeR esult structure with request_id field containing I D of
this request.
OnTradeTransaction() function receives three input parameters but the last two should be analyzed
only for transactions having T RADE_T RANS ACTION_REQUEST type. In all other cases, data on the trade
request and its execution result are not filled. Example of parameters analysis can be found at
Structure of a Trade R equest.
Setting request_id by the terminal for the trade request when sending it to the server is mainly
introduced for work ing with OrderSendAsync() asynchronous function. This identifier allows to
associate the performed action (OrderSend or OrderSendAsync functions call) with the result of this
action sent to OnTradeTransaction().
Example:
//+------------------------------------------------------------------+
//| Sending a trade request with the result processing |
//+------------------------------------------------------------------+
bool MyOrderSend(MqlTradeRequest request,MqlTradeResult result)
{
//--- reset the last error code to zero
ResetLastError();
//--- send request
bool success=OrderSend(request,result);
//--- if the result fails - try to find out why
if(!success)
{
int answer=result.retcode;
Print("TradeLog: Trade request failed. Error = ",GetLastError());
switch(answer)
{
//--- requote
case 10004:
{
Print("TRADE_RETCODE_REQUOTE");
Print("request.price = ",request.price," result.ask = ",
result.ask," result.bid = ",result.bid);
break;
}
//--- order is not accepted by the server
case 10006:
{
Print("TRADE_RETCODE_REJECT");
Print("request.price = ",request.price," result.ask = ",
result.ask," result.bid = ",result.bid);
break;
}
//--- invalid price
case 10015:
{
Print("TRADE_RETCODE_INVALID_PRICE");
Print("request.price = ",request.price," result.ask = ",
result.ask," result.bid = ",result.bid);
break;
}
//--- invalid SL and/or TP
case 10016:
{
Print("TRADE_RETCODE_INVALID_STOPS");
Print("request.sl = ",request.sl," request.tp = ",request.tp);
Print("result.ask = ",result.ask," result.bid = ",result.bid);
break;
}
//--- invalid volume
case 10014:
{
Print("TRADE_RETCODE_INVALID_VOLUME");
Print("request.volume = ",request.volume," result.volume = ",
result.volume);
break;
}
//--- not enough money for a trade operation
case 10019:
{
Print("TRADE_RETCODE_NO_MONEY");
Print("request.volume = ",request.volume," result.volume = ",
result.volume," result.comment = ",result.comment);
break;
}
//--- some other reason, output the server response code
default:
{
Print("Other answer = ",answer);
}
}
//--- notify about the unsuccessful result of the trade request by returning false
return(false);
}
//--- OrderSend() returns true - repeat the answer
return(true);
}
· Sending a trade request from any MQL5 application in the client terminal using OrderSend and
OrderSendAsync functions and its further execution;
· Sending a trade request via the terminal graphical interface and its further execution;
· changing positions.
For example, when sending a mark et buy order, it is handled, an appropriate buy order is created for
the account, the order is then executed and removed from the list of the open ones, then it is added
to the orders history, an appropriate deal is added to the history and a new position is created. All
these actions are trade transactions.
struct MqlTradeTransaction
{
ulong deal; // Deal ticket
ulong order; // Order ticket
string symbol; // Trade symbol name
ENUM_TRADE_TRANSACTION_TYPE type; // Trade transaction type
ENUM_ORDER_TYPE order_type; // Order type
ENUM_ORDER_STATE order_state; // Order state
ENUM_DEAL_TYPE deal_type; // Deal type
ENUM_ORDER_TYPE_TIME time_type; // Order type by action period
datetime time_expiration; // Order expiration time
double price; // Price
double price_trigger; // Stop limit order activation price
double price_sl; // Stop Loss level
double price_tp; // Take Profit level
double volume; // Volume in lots
ulong position; // Position ticket
ulong position_by; // Ticket of an opposite position
};
Fields Description
Field Description
The essential parameter for received transaction analysis is its type specified in type field. For
example, if a transaction is of T RADE_T RANS ACTION_REQUEST type (a result of handling a trade
request by the server has been received), the structure has only only one field that is filled completely
- type. Other fields are not analyzed. In this case, we may analyze two additional request and result
parameters submitted to OnTradeTransaction() handler, as shown below.
H aving data on a trading operation type, you can decide on the analysis of the current state of orders,
positions and deals on a trading account. R emember that one trade request sent to the server from
the terminal can generate several new transactions. The priority of their arrival at the terminal is not
guaranteed.
The following fields in M qlTradeTransaction structure are filled for trade transactions related to
open orders handling (T RADE_T RANS ACTION_ORDER_ADD, T RADE_T RANS ACTION_ORDER_UPDAT E
and T RADE_T RANS ACTION_ORDER_DEL ET E) and orders history
(T RADE_T RANS ACTION_H ISTORY_ADD, T RADE_T RANS ACTION_H ISTORY_UPDAT E,
T RADE_T RANS ACTION_H ISTORY_DEL ET E):
· order - order tick et;
· symbol - order symbol name;
· type - trade transaction type;
· order_type - order type;
· orders _state - order current state;
· time_type - order expiration type;
· time_expiration - order expiration time (for orders having ORDER_TIM E_SPECI FI ED and
ORDER_TIM E_SPECI FI ED_DAY expiration types);
· price - order price specified by a client;
· price_trigger - stop limit order stop price (only for ORDER_T YPE_BUY_STOP_LIMIT and
ORDER_T YPE_S ELL _STOP_LIMIT);
· price_sl - Stop Loss order price (filled, if specified in the order);
· price_tp - Tak e Profit order price (filled, if specified in the order);
· volume - order current volume (unfilled). Initial order volume can be found in the orders history
using H istoryOrders * function.
· position - the tick et of the position that was opened, modified or closed as a result of order
execution. It is only filled for mark et orders, not filled for T RADE_T RANS ACTION_ORDER_ADD.
· position_by - the tick et of the opposite position. It is only filled for the close by orders (to close a
position by an opposite one).
TRADE_TRANSACTION_DEAL_*
The following fields in M qlTradeTransaction structure are filled for trade transactions related to
deals handling (T RADE_T RANS ACTION_DEAL _ADD, T RADE_T RANS ACTION_DEAL _UPDAT E and
T RADE_T RANS ACTION_DEAL _DEL ET E):
· deal - deal tick et;
· order - order tick et, based on which a deal has been performed;
· symbol - deal symbol name;
· type - trade transaction type;
TRADE_TRANSACTION_POSITION
The following fields in M qlTradeTransaction structure are filled for trade transactions related to
changing the positions not connected with deals execution (T RADE_T RANS ACTION_POSITION):
· symbol - position symbol name;
· type - trade transaction type;
· deal_type - position type (DEAL _T YPE_BUY or DEAL _T YPE_S ELL);
· price - weighted average position open price;
· price_sl - Stop Loss price;
· price_tp - Tak e Profit price;
· volume - position volume in lots, if it has been changed.
Position change (adding, changing or closing), as a result of a deal execution, does not lead to
the occurrence of T RADE_T RANS ACTION_POSITION transaction.
TRADE_TRANSACTION_REQUEST
Only one field in M qlTradeTransaction structure is filled for trade transactions describing the fact
that a trade request has been processed by a server and processing result has been received
(T RADE_T RANS ACTION_REQUEST):
· type - trade transaction type;
Only type field (trade transaction type) must be analyzed for such transactions. The second and
third parameters of OnTradeTransaction function (request and result) must be analyzed for
additional data.
Example:
//--- enable CTrade trading class and declare the variable of this class
#include <Trade\Trade.mqh>
CTrade trade;
//--- flags for installing and deleting the pending order
bool pending_done=false;
bool pending_deleted=false;
//--- pending order ticket will be stored here
ulong order_ticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- set MagicNumber to mark all our orders
trade.SetExpertMagicNumber(MagicNumber);
//--- trade requests will be sent in asynchronous mode using OrderSendAsync() function
trade.SetAsyncMode(true);
//--- initialize the variable by zero
order_ticket=0;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---installing a pending order
if(!pending_done)
{
double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_D
bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);
//--- if BuyStop() function performed successfully
if(res)
{
pending_done=true;
//--- get a result of the request sending from ctrade
MqlTradeResult trade_result;
trade.Result(trade_result);
//--- get request_id for the sent request
uint request_id=trade_result.request_id;
Print("Request has been sent to set a pending order. Request_ID=",request_id);
//--- storing the order ticket (will be zero if using the asynchronous mode of sending to
order_ticket=trade_result.order;
//--- all is done, early exit from OnTick() handler
return;
}
}
//--- delete the pending order
if(!pending_deleted)
//--- additional check
if(pending_done && (order_ticket!=0))
{
//--- trying to delete the pending order
bool res=trade.OrderDelete(order_ticket);
Print("OrderDelete=",res);
//---
}
//+------------------------------------------------------------------+
//| Returns transaction textual description |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans)
{
//---
string desc=EnumToString(trans.type)+"\r\n";
desc+="Symbol: "+trans.symbol+"\r\n";
desc+="Deal ticket: "+(string)trans.deal+"\r\n";
desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
desc+="Order ticket: "+(string)trans.order+"\r\n";
desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
desc+="Position: "+(string)trans.position+"\r\n";
desc+="Position by: "+(string)trans.position_by+"\r\n";
//--- return the obtained string
return desc;
}
//+------------------------------------------------------------------+
//| Returns the trade request textual description |
//+------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request)
{
//---
string desc=EnumToString(request.action)+"\r\n";
desc+="Symbol: "+request.symbol+"\r\n";
desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
desc+="Order ticket: "+(string)request.order+"\r\n";
desc+="Order type: "+EnumToString(request.type)+"\r\n";
desc+="Order filling: "+EnumToString(request.type_filling)+"\r\n";
desc+="Order time type: "+EnumToString(request.type_time)+"\r\n";
desc+="Order expiration: "+TimeToString(request.expiration)+"\r\n";
desc+="Price: "+StringFormat("%G",request.price)+"\r\n";
desc+="Deviation points: "+StringFormat("%G",request.deviation)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
desc+="Comment: "+request.comment+"\r\n";
//--- return the obtained string
return desc;
}
//+------------------------------------------------------------------+
//| Returns the textual description of the request handling result |
//+------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result)
{
//---
string desc="Retcode "+(string)result.retcode+"\r\n";
desc+="Request ID: "+StringFormat("%d",result.request_id)+"\r\n";
desc+="Order ticket: "+(string)result.order+"\r\n";
desc+="Deal ticket: "+(string)result.deal+"\r\n";
desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
desc+="Price: "+StringFormat("%G",result.price)+"\r\n";
desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
desc+="Comment: "+result.comment+"\r\n";
//--- return the obtained string
return desc;
}
See also
struct MqlTick
{
datetime time; // Time of the last prices update
double bid; // Current Bid price
double ask; // Current Ask price
double last; // Price of the last deal (Last)
ulong volume; // Volume for the current Last price
long time_msc; // Time of a price last update in milliseconds
uint flags; // Tick flags
double volume_real; // Volume for the current Last price with greater accuracy
};
The variable of the M qlTick type allows obtaining values of As k , Bid, Last and Volume within a single
call of the SymbolInfoTick () function.
The parameters of each tick are filled in regardless of whether there are changes compared to the
previous tick . Thus, it is possible to find out a correct price for any moment in the past without the
need to search for previous values at the tick history. For example, even if only a Bid price changes
during a tick arrival, the structure still contains other parameters as well, including the previous As k
price, volume, etc.
You can analyze the tick flags to find out what data have been changed exactly:
· TICK_FL AG_BI D – tick has changed a Bid price
· TICK_FL AG_AS K – a tick has changed an As k price
· TICK_FL AG_L AST – a tick has changed the last deal price
· TICK_FL AG_VOL UM E – a tick has changed a volume
· TICK_FL AG_BUY – a tick is a result of a buy deal
· TICK_FL AG_S ELL – a tick is a result of a sell deal
Example:
void OnTick()
{
MqlTick last_tick;
//---
if(SymbolInfoTick(Symbol(),last_tick))
{
Print(last_tick.time,": Bid = ",last_tick.bid,
" Ask = ",last_tick.ask," Volume = ",last_tick.volume);
}
else Print("SymbolInfoTick() failed, error = ",GetLastError());
//---
}
See also
Economic calendar functions allow conducting the auto analysis of incoming events according to
custom importance criteria from a perspective of necessary countries /currency pairs.
struct MqlCalendarCountry
{
ulong id; // country ID (ISO 3166-1)
string name; // country text name (in the current
string code; // country code name (ISO 3166-1 alph
string currency; // country currency code
string currency_symbol; // country currency symbol
string url_name; // country name used in the mql5.com
};
Event descriptions are set by the M qlCalendarEvent structure. It is used in the CalendarEventById(),
CalendarEventByCountry() and CalendarEventByCurrency() functions
struct MqlCalendarEvent
{
ulong id; // event ID
ENUM_CALENDAR_EVENT_TYPE type; // event type from the ENUM_CALENDAR_
ENUM_CALENDAR_EVENT_SECTOR sector; // sector an event is related to
ENUM_CALENDAR_EVENT_FREQUENCY frequency; // event frequency
ENUM_CALENDAR_EVENT_TIMEMODE time_mode; // event time mode
ulong country_id; // country ID
ENUM_CALENDAR_EVENT_UNIT unit; // economic indicator value's unit of
ENUM_CALENDAR_EVENT_IMPORTANCE importance; // event importance
ENUM_CALENDAR_EVENT_MULTIPLIER multiplier; // economic indicator value multiplie
uint digits; // number of decimal places
string source_url; // URL of a source where an event is
string event_code; // event code
string name; // event text name in the terminal la
};
Event values are set by the M qlCalendarValue structure. It is used in the CalendarValueById(),
CalendarValueH istoryByEvent(), CalendarValueH istory(), CalendarValueLastByEvent() and
CalendarValueLast() functions
struct MqlCalendarValue
{
ulong id; // value ID
ulong event_id; // event ID
datetime time; // event time and date
datetime period; // event report period
int revision; // released indicator's revision in r
long actual_value; // indicator's actual value
long prev_value; // indicator's previous value
long revised_prev_value; // indicator's revised previous value
long forecast_value; // indicator's forecast value
ENUM_CALENDAR_EVENT_IMPACT impact_type; // potential impact on an exchange ra
};
Event frequency is specified in the M qlCalendarEvent structure. Possible values are set in the listing
ENUM_CALENDAR_EVENT_FREQUENCY
ID Description
Event type is specified in the M qlCalendarEvent structure. Possible values are set in the listing
ENUM_CALENDAR_EVENT_TY PE
ID Description
A sector of the economy an event is related to is specified in the M qlCalendarEvent structure. Possible
values are set in the listing ENUM_CALENDAR_EVENT_SECTOR
ID Description
Event importance is specified in the M qlCalendarEvent structure. Possible values are set in the listing
ENUM_CALENDAR_EVENT_IMPORTANCE
ID Description
Measurement unit type used in displaying event values is specified in the M qlCalendarEvent structure.
Possible values are set in the listing ENUM_CALENDAR_EVENT_UNIT
ID Description
In some cases, economic parameter values require a multiplier set in the M qlCalendarEvent structure.
Possible multiplier values are set in the listing ENUM_CALENDAR_EVENT_MULTIPLIER
ID Description
Event's potential impact on a national currency rate is indicated in the M qlCalendarValue structure.
Possible values are set in the listing ENUM_CALENDAR_EVENT_IMPACT
ID Description
Event time is specified in the M qlCalendarEvent structure. Possible values are set in the listing
ENUM_CALENDAR_EVENT_TIMEMODE
ID Description
CAL ENDAR_TIM EMODE_T ENT ATI VE Source publishes a day of an event rather than
its exact time. The time is specified upon the
occurrence of the event.
See also
Economic Calendar
· R eturn codes of the trade server – analyzing results of the trade request sent by function
OrderSend();
· Compiler warnings – codes of warning messages that appear at compilation (not errors);
· R untime errors – error codes in the execution of mql5-programs, which can be obtained using the
GetLastError() function.
Compiler Warnings
Compiler warnings are shown for informational purposes only and are not error messages.
Code Description
30 Overriding macro
Compilation Errors
MetaEdtior 5 shows error messages about the program errors detected by the built-in compiler during
compilation. The list of these errors is given below in table. To compile a source code into an
executable one, press F 7 . Programs that contain errors cannot be compiled until the errors identified
by the compiler are eliminated.
Code Description
144 No pair for " )" or "]" , i.e. " (or" [ " is absent
145 No pair for " (or" [ " , i.e. " ) " or"] " is absent
method
Runtime Errors
GetLastError() is the function that returns the last error code that is stored in the predefined variable
_LastError. This value can be reset to zero by the R esetLastError() function.
Charts
Graphical Objects
ERR_OBJECT _ERR OR 4201 Error work ing with a graphical
object
MarketInfo
ERR_M ARKET _L ASTTIM E_UNKN 4304 Time of the last tick is not
OWN k nown (no tick s)
History Access
ERR_H ISTORY_NOT _FOUND 4401 R equested history not found
Global_Variables
ERR_GLOBAL VAR IABL E_NOT _F 4501 Global variable of the client
OUND terminal is not found
already exists
ERR_GLOBAL VAR IABL E_CANNO 4504 Cannot read file with global
T READ variable values
ERR_GLOBAL VAR IABL E_CANNO 4505 Cannot write file with global
T WR IT E variable values
buffers
Account
Indicators
Depth of Market
File Operations
String Casting
ERR_ST R ING_OUT _OF_M EMOR 5034 Not enough memory for the
Y string
ERR_SM ALL _ASS ER IES _ARRAY 5051 The receiving array is declared
as AS _S ER I ES, and it is of
insufficient size
ERR_NETSOCKET _TOO_M ANY_ 5271 Too many open sock ets (max
OPENED 128)
Custom Symbols
ERR_CUSTOM _TICKS _WR ONG_ 5310 Tick s in the array are not
ORDER arranged in the order of time
Economic Calendar
User-Defined Errors
See also
Trade Server R eturn Codes
· File properties
· MessageBox
One or several flags can be specified when opening a file. This is a combination of flags. The
combination of flags is written using the sign of logical OR (|), which is positioned between
enumerated flags. For example, to open a file in CS V format for reading and writing at the same time,
specify the combination FIL E_READ|FIL E_WR IT E|FIL E_CS V.
Example:
int filehandle=FileOpen(filename,FILE_READ|FILE_WRITE|FILE_CSV);
There are some specific features of work when you specify read and write flags :
· If FIL E_READ is specified, an attempt is made to open an existing file. If a file does not exist, file
opening fails, a new file is not created.
· FIL E_READ|FIL E_WR IT E – a new file is created if the file with the specified name does not exist.
W hen opening a file, specification of FIL E_WR IT E and/or FIL E_READ is required.
Flags that define the type of reading of an open file possess priority. The highest flag is FIL E_CS V,
then goes FIL E_BI N, and FIL E_T XT is of lowest priority. Thus, if several flags are specified at the same
time, (FIL E_T XT |FIL E_CS V or FIL E_T XT |FIL E_BI N or FIL E_BI N|FIL E_CS V), the flag with the highest
priority will be used.
Flags that define the type of encoding also have priority. FIL E_UNICODE is of a higher priority than
FIL E_ANSI. So if you specify combination FIL E_UNICODE|FIL E_ANSI, flag FIL E_UNICODE will be used.
If neither FIL E_UNICODE nor FIL E_ANSI is indicated, FIL E_UNICODE is implied. If neither FIL E_CS V, nor
FIL E_BIN, nor FIL E_T XT is specified, FIL E_CS V is implied.
If a file is opened for reading as a text file (FIL E_T XT or FIL E_CS V), and at the file beginning a special
two-byte indication 0xff,0xfe is found, the encoding flag will be FIL E_UNICODE, even if FIL E_ANSI is
specified.
See also
File Functions
File Properties
The FileGetInteger() function is used for obtaining file properties. The identifier of the required
property from the ENUM _FIL E_PR OPER T Y_I NT EGER enumeration is passed to it during call.
ENUM_FILE_PROPERTY _INTEGER
ID ID description
FIL E_IS _T EXT The file is opened as a text file (see FIL E_T XT)
FIL E_IS _ANSI The file is opened as ANSI (see FIL E_ANSI)
FIL E_IS _READABL E The opened file is readable (see FIL E_READ)
FIL E_IS _WR IT ABL E The opened file is writable (see FIL E_WR IT E)
The FileGetInteger() function has two different options of call. In the first option, for getting
properties of a file, its handle is specified, which is obtained while opening the file using the
FileOpen() function. This option allows getting all properties of a file.
The second option of the FileGetInteger() function returns values of file properties by the file name.
Using this option, only the following general properties can be obtained:
· FIL E_CREAT E_DAT E – date of creation of the file with the specified name
· FIL E_MODI FY_DAT E – date of modification of the file with the specified name
· FIL E_ACCESS _DAT E – date of the last access to the file with the specified name
W hen trying to get properties other than specified above, the second option of FileGetInteger() call
will return an error.
ENUM_FILE_POSITION
Identifier Description
See also
FileIs Ending, FileIsLineEnding
The table lists the built-in constants for some of the most popular code pages. Not mentioned code
pages can be specified by a code corresponding to the page.
See also
Client Terminal Properties
The main flags of the MessageBox() function define contents and behavior of the dialog window. This
value can be a combination of the following flag groups :
MQL5 Programs
For the mql5-program to operate, it must be compiled (Compile button or F7 k ey). Compilation should
pass without errors (some warnings are possible; they should be analyzed). At this process, an
executable file with the same name and with EX5 extension must be created in the corresponding
directory, terminal_dir\ MQL5\Experts, terminal_dir\ MQL5\ indicators or terminal_dir\ MQL5\ scripts.
This file can be run.
· Testing trading strategies – operating features of MQL5 programs in the Strategy Tester.
· Call of imported functions – description order, allowed parameters, search details and call agreement
for imported functions.
· R untime errors – getting information about runtime and critical errors.
Expert Advisors, custom indicators and scripts are attached to one of opened charts by Drag 'n'Drop
method from the Navigator window.
For an expert Advisor to stop operating, it should be removed from a chart. To do it select "Expert
list" in chart context menu, then select an Expert Advisor from list and click "R emove" button.
Operation of Expert Advisors is also affected by the state of the "AutoTrading " button.
Custom indicators and Expert Advisors work until they are explicitly removed from a chart;
information about attached Expert Advisors and Indicators is saved between client terminal sessions.
Scripts are executed once and are deleted automatically upon operation completion or change of the
current chart state, or upon client terminal shutdown. After the restart of the client terminal scripts
are not started, because the information about them is not saved.
Maximum one Expert Advisor, one script and unlimited number of indicators can operate in one chart.
Services do not require to be bound to a chart to work and are designed to perform auxiliary functions.
For example, in a service, you can create a custom symbol, open its chart, receive data for it in an
endless loop using the network functions and constantly update it.
Program Running
Each script, each service and each Expert Advisor runs in its own separate thread. All indicators
calculated on one symbol, even if they are attached to different charts, work in the same thread.
Thus, all indicators on one symbol share the resources of one thread.
All other actions associated with a symbol, lik e processing of tick s and history synchronization, are
also consistently performed in the same thread with indicators. This means that if an infinite action is
performed in an indicator, all other events associated with its symbol will never be performed.
W hen running an Expert Advisor, mak e sure that it has an actual trading environment and can access
the history of the required symbol and period, and synchronize data between the terminal and the
server. For all these procedures, the terminal provides a start delay of no more than 5 seconds, after
which the Expert Advisor will be started with available data. Therefore, in case there is no connection
to the server, this may lead to a delay in the start of an Expert Advisor.
R ight after a program is attached to a chart, it is uploaded to the client terminal memory, as well as
global variable are initialized. If some global variable of the class type has a constructor, this
constructor will be called during initialization of global variables.
After that the program is waiting for an event from the client terminal. Each mql5-program should
have at least one event-handler, otherwise the loaded program will not be executed. Event handlers
have predefined names, parameters and return types.
A client terminal sends new events to the corresponding open charts. Events can also be generated by
charts (chart events) or mql5-programs (custom events). Generation of events of creation or deletion
of graphical objects on a chart can be enabled or disabled by setting CHAR T _EVENT _OBJECT _CREAT E
and CHAR T _EVENT _OBJECT _DEL ET E chart properties. Each MQL5 program and each chart has its own
queue of events, where all new incoming events are added.
A program receives only events from the chart it runs on. All events are processed one after another in
the order they are received. If a queue already has a NewTick event, or this event is currently being
processed, then the new NewTick event is not placed in the queue of the MQL5 program. Similarly, if
ChartEvent is already enqueued, or this event is being processed, no new event of this k ind is
enqueued. The timer events are handled the same way – if the Timer event is in the queue or being
handled, the new timer event is not enqueued.
Event queues have a limited but sufficient size, so that the queue overflow for well written programs
is unlik ely. In case of queue overflow, new events are discarded without queuing.
It is strongly recommended not to use infinite loops to handle events. Possible exceptions are scripts
and services handling a single Start event.
Indicators, scripts and Expert Advisors are executable programs written in MQL5. They are designed
for different types of tas k s. Therefore there are some restrictions on the use of certain functions,
depending on the type of program. The following functions are prohibited in indicators :
· OrderCalcMargin();
· OrderCalcProfit();
· OrderCheck ();
· OrderSend();
· SendFTP();
· Sleep();
· ExpertR emove();
· MessageBox().
All functions designed for indicators are prohibited in Expert Advisors and scripts :
· SetIndex Buffer();
· IndicatorSetDouble();
· IndicatorSetInteger();
· IndicatorSetString();
· PlotIndexSetDouble();
· PlotIndexSetInteger();
· PlotIndexSetString();
· PlotIndex GetInteger.
The library is not an independent program and is executed in the context of the MQL5 program that
has called it: script, indicator or Expert Advisor. Accordingly, the above restrictions apply to the called
library.
Services do not accept any events, as they are not bound to a chart. The following functions are
prohibited in services :
ExpertR emove();
EventSetMillisecondTimer();
EventSetTimer();
EventKillTimer();
SetIndex Buffer();
IndicatorSetDouble();
IndicatorSetInteger();
IndicatorSetString();
PlotIndexSetDouble();
PlotIndexSetInteger();
PlotIndexSetString();
PlotIndex GetInteger();
· terminal start (if the indicator was attached to the chart prior to the shutdown of the terminal);
· loading of a template (if the indicator attached to a chart is specified in the template);
· change of a profile (if the indicator is attached to one of the profile charts);
· after the successful recompilation of an indicator (if the indicator was attached to a chart);
· change of a profile (if the indicator is attached to one of charts of the changed profile);
· terminal start (if the Expert Advisor was attached to the chart prior to the shutdown of the
terminal);
· loading of a template (if the Expert Advisor attached to the chart is specified in the template);
· change of a profile (if the Expert Advisor is attached to the one of the profile charts);
· connection to an account, even if the account number is the same (if the Expert Advisor was
attached to the chart before the authorization of the terminal on the server).
· if a new Expert Advisor is attached to a chart, if another Expert Advisor has been attached already,
this Expert Advisor is unloaded.
· terminal shutdown (if the Expert Advisor was attached to a chart);
· change of a profile (if the Expert Advisor is attached to one of charts of the changed profile);
· change of the account to which the terminal is connected (if the Expert Advisor was attached to the
chart before the authorization of the terminal on the server);
· calling the ExpertR emove() function.
In case the symbol or timeframe of a chart, to which the Expert Advisor is attached, changes,
Expert Advisors are not loaded or unloaded. In this case client terminal subsequently calls OnDeinit()
handlers on the old symbol/timeframe and OnInit() on the new symbol/timeframe (if they are such),
values of global variables and static variables are not reset. All events, which have been received for
the Expert Advisor before the initialization is completed (OnInit() function) are s k ipped.
Scripts are loaded immediately after they are attached to a chart and unloaded immediately after they
complete their operation. OnInit() and OnDeinit() are not called for scripts.
W hen a program is unloaded (deleted from a chart) the client terminal performs deinitialization of
global variables and deletes the events queue. In this case deinitialization means reset of all the
string-type variables, deallocation of dynamical array objects and call of their destructors if they are
available.
Services are loaded right after starting the terminal if they were launched at the moment of the
terminal shutdown. Services are unloaded immediately after completing their work .
Services have a single OnStart() handler, in which you can implement an endless data receiving and
handling loop, for example creating and updating custom symbols using the network functions.
Unlik e Expert Advisors, indicators and scripts, services are not bound to a specific chart, therefore a
separate mechanism is provided to launch them. A new service instance is created in the Navigator
using the "Add Service" command. A service instance can be launched, stopped and removed using the
appropriate instance menu. To manage all instances, use the service menu.
For a better understanding of the Expert Advisor operation we recommend to compile the code of the
following Expert Advisor and perform actions of load/unload, template change, symbol change,
timeframe change etc:
Example:
//+------------------------------------------------------------------+
//| TestExpert.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
class CTestClass
{
public:
CTestClass() { Print("CTestClass constructor"); }
~CTestClass() { Print("CTestClass destructor"); }
};
CTestClass global;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
Print("Initialization");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Print("Deinitialization with reason",reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
See also
Client terminal events, Event handlers
Trade Permission
Trade Automation
MQL5 language provides a special group of trade functions designed for developing automated trading
systems. Programs developed for automated trading with no human intervention are called Expert
Advisors or trading robots. In order to create an Expert Advisor in MetaEditor, launch MQL5 W izard
and select one of the two options :
· Expert Advisor (template) – allows you to create a template with ready-made event handling
functions that should be supplemented with all necessary functionality by means of programming.
· Expert Advisor (generate) – allows you to develop a full-fledged trading robot simply by selecting the
necessary modules : trading signals module, money management module and trailing stop module.
Trading functions can work only in Expert Advisors and scripts. Trading is not allowed for indicators.
The terminal settings provide you with an ability to allow or forbid automated trading for all programs.
You can switch automated trading option right on the terminal's Standard panel:
Sample check:
if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
Alert("Check if automated trading is allowed in the terminal settings!");
You can allow or forbid automated trading for a certain program when launching it. To do this, use the
special check box in the program properties.
Sample check:
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
Alert("Check if automated trading is allowed in the terminal settings!");
else
{
if(!MQLInfoInteger(MQL_TRADE_ALLOWED))
Alert("Automated trading is forbidden in the program settings for ",__FILE__);
}
Checking if trading is allowed for any Expert Advisors/scripts for the current
account
Automated trading can be disabled at the trade server side. Sample check:
if(!AccountInfoInteger(ACCOUNT_TRADE_EXPERT))
Alert("Automated trading is forbidden for the account ",AccountInfoInteger(ACCOUNT_LOGIN),
" at the trade server side");
If automated trading is disabled for a trading account, trading operations of Expert Advisors /scripts
are not executed.
In some cases, any trading operations are disabled for a certain trading account – neither manual nor
automated trading can be performed. Sample check when an investor password has been used to
connect to a trading account:
if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED))
Comment("Trading is forbidden for the account ",AccountInfoInteger(ACCOUNT_LOGIN),
".\n Perhaps an investor password has been used to connect to the trading account.",
"\n Check the terminal journal for the following entry:",
See also
Client Terminal Properties, Account Properties, Properties of a R unning MQL5 Program
Deinit
Before global variables are deinitialized and the program (Expert Advisor or custom indicator) is
unloaded, the client terminal sends the Deinit event to the program. Deinit is also generated when the
client terminal is closed, when a chart is closed, right before the security and/or timeframe is
changed, at a successful program re-compilation, when input parameters are changed, and when
account is changed.
The deinitialization reason can be obtained from the parameter, passed to the OnDeinit() function.
The OnDeinit() function run is restricted to 2.5 seconds. If during this time the function hasn't been
completed, then it is forcibly terminated. The Deinit event is not generated for scripts.
Start
Start is a special event for launching a script or a service after loading it. It is handled by the OnStart
function. The Start event is not passed to EAs and custom indicators.
NewTick
The NewTick event is generated if there are new quotes, it is processed by OnTick () of Expert
Advisors attached. In case when OnTick function for the previous quote is being processed when a new
quote is received, the new quote will be ignored by an Expert Advisor, because the corresponding
event will not enqueued.
All new quotes that are received while the program is running are ignored until the OnTick () is
completed. After that the function will run only after a new quote is received. The NewTick event is
generated irrespective of whether automated trade is allowed or not ("Allow/prohibit Auto trading "
button). The prohibition of automated trading denotes only that sending of trade requests from an
Expert Advisor is not allowed, while the Expert Advisor k eeps work ing.
The prohibition of automated trading by pressing the appropriate button will not stop the current
execution of the OnTick () function.
Calculate
The Calculate event is generated only for indicators right after the Init event is sent and at any change
of price data. It is processed by the OnCalculate function.
Timer
The Timer event is periodically generated by the client terminal for the Expert Advisor that has
activated the timer by the EventSetTimer function. Usually, this function is called by OnInit. Timer
event processing is performed by the OnTimer function. After the operation of the Expert Advisor is
completed, it is necessary to destroy the timer using the EventKillTimer function, which is usually
called in the OnDeinit function.
Trade
The Trade event is generated when a trade operation is completed on a trade server. The Trade event
is handled by the OnTrade() function for the following trade operations :
· modifying of the open position (change stops – Stop Loss and/or Tak e Profit).
TradeTransaction
W hen performing some definite actions on a trade account, its state changes. Such actions include:
· Sending a trade request from any MQL5 application in the client terminal using OrderSend and
OrderSendAsync functions and its further execution;
· Sending a trade request via the terminal graphical interface and its further execution;
· changing positions.
For example, when sending a mark et buy order, it is handled, an appropriate buy order is created for
the account, the order is then executed and removed from the list of the open ones, then it is added
to the orders history, an appropriate deal is added to the history and a new position is created. All
these actions are trade transactions. Arrival of such a transaction at the terminal is a
TradeTransaction event. This event is handled by OnTradeTransaction function.
Tester
The Tester event is generated after testing of an Expert Advisor on history data is over. The event is
handled by the OnTester() function.
TesterInit
The TesterInit event is generated with the start of optimization in the strategy tester before the first
optimization pass. The TesterInit event is handled by the OnTesterInit() function.
TesterPass
The TesterPass event is generated when a new data frame is received. The TesterPass event is
handled by the OnTesterPass() function.
TesterDeinit
The TesterDeinit event is generated after the end of optimization of an Expert Advisor in the strategy
tester. The TesterDeinit event is handled by the OnTesterDeinit() function.
ChartEvent
The ChartEvent event is generated by the client terminal when a user is work ing with a chart:
Also there is a custom event ChartEvent, which can be sent to an Expert Advisor by any mql5 program
by using the EventChartCustom function. The event is processed by the OnChartEvent function.
BookEvent
The BookEvent event is generated by the client terminal after the Depth Of Mark et is changed; it is
processed by the OnBookEvent function. To start generation of BookEvent for the specified symbol, it
is necessary to subscribe the symbol to this event by using the Mark etBookAdd function.
To unsubscribe from BookEvent for a specified symbol, it is necessary to call the Mark etBookR elease
function. The BookEvent event is a broadcasting-type event - it means that it is sufficient to subscribe
just one Expert Advisor for this event, and all other Expert Advisors that have the OnBookEvent event
handler, will receive it. That's why it is necessary to analyze the symbol name, which is passed to a
handler as a parameter.
See also
Event handlers, Program running
Resources
Using graphics and sound in MQL5 programs
Programs in MQL5 allow work ing with sound and graphic files :
· ObjectCreate() allows creating user interfaces using graphical objects OBJ_BITM AP and
OBJ_BITM AP_L ABEL.
PlaySound()
//+------------------------------------------------------------------+
//| Calls standard OrderSend() and plays a sound |
//+------------------------------------------------------------------+
void OrderSendWithAudio(MqlTradeRequest &request, MqlTradeResult &result)
{
//--- send a request to a server
OrderSend(request,result);
//--- if a request is accepted, play sound Ok.wav
if(result.retcode==TRADE_RETCODE_PLACED) PlaySound("Ok.wav");
//--- if fails, play alarm from file timeout.wav
else PlaySound("timeout.wav");
}
The example shows how to play sounds from files 'Ok .wav ' and 'timeout.wav ', which are included into
the standard terminal pack age. These files are located in the folder terminal_directory\ Sounds . H ere
terminal_directory is a folder, from which the MetaTrader 5 Client Terminal is started. The location
of the terminal directory can be found out from an mql5 program in the following way:
You can use sound files not only from the folder terminal_directory\Sounds , but also from any
subfolder located in terminal_data_directory\ MQL5. You can find out the location of the terminal
data directory from the terminal menu "File" -> " Open Data Folder" or using program method:
For example, if the Demo.wav sound file is located in terminal_data_directory\MQL5\Files, then call of
PlaySound() should be written the following way:
Please note that in the comment the path to the file is written using back slash "\" , and in the function
"\\" is used.
W hen specifying the path, always use only the double back slash as a separator, because a single
back slash is a control symbol for the compiler when dealing with constant strings and character
constants in the program source code.
ObjectCreate()
Example of an Expert Advisor, which creates a graphical label (OBJ_BITM AP_L ABEL) using the
ObjectCreate() function.
if(!set)
{
PrintFormat("Failed to download image from file %s. Error code %d",dollar,GetLastError(
}
//--- send a command for a chart to refresh so that the button appears immediately without
ChartRedraw(0);
}
else
{
//--- failed to create an object, notify
PrintFormat("Failed to create object OBJ_BITMAP_LABEL. Error code %d",GetLastError());
}
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- delete an object from a chart
ObjectDelete(0,label_name);
}
Creation and setup of the graphical object named currency_label are carried out in the OnInit()
function. The paths to the graphical files are set in global variables euro and dollar , a double back lash
is used for a separator:
Object OBJ_BITM AP_L ABEL is actually a button, which displays one of the two images, depending on
the button state (pressed or unpressed): euro.bmp or dollar.bmp.
The size of the button with a graphical interface is automatically adjusted to the size of the picture.
The image is changed by a left mouse button click on the OBJ_BITM AP_L ABEL object (" Disable
selection" option must be checked in the properties). The OBJ_BITM AP object is created the same
way - it is used for creating the back ground with a necessary image.
The value of the OBJPR OP_BMPFIL E property, which is responsible for the appearance of the objects
OBJ_BITM AP and OBJ_BITM AP_L ABEL, can be changed dynamically. This allows creating various
interactive user interfaces for mql5 programs.
#resource path_to_resource_file
The #resource command tells the compiler that the resource at the specified path
path_to_resource_file should be included into the executable EX5 file. Thus all the necessary images
and sounds can be located directly in an EX5 file, so that there is no need to transfer separately the
files used in it, if you want to run the program on a different terminal. Any EX5 file can contain
resources, and any EX5 program can use resources from another EX5 program.
The files in format BMP and WAV are automatically compressed before including them to an EX5 file.
This denotes that in addition to the creation of complete programs in MQL5, using resources also
allows to reduce the total size of necessary files when using graphics and sounds, as compared to the
usual way of MQL5 program writing.
#resource "<path_to_resource_file>"
The length of the constant string <path_to_resource_file> must not exceed 63 characters.
The compiler searches for a resource at the specified path in the following order:
· if the back slash "\" separator (written as "\\" ) is placed at the beginning of the path, it searches for
the resource relative to the directory terminal_data_directory\ MQL5\ ,
· if there is no back slash, it searches for the resource relative to the location of the source file, in
which the resource is written.
The resource path cannot contain the substrings " ..\\" and ":\\" .
Use of Resources
Resource name
After a resource is declared using the #resource directive, it can be used in any part of a program. The
name of the resource is its path without a back slash at the beginning of the line, which sets the path
to the resource. To use your own resource in the code, the special sign "::" should be added before the
resource name.
Examples :
ObjectSetString(0,bitmap_name,OBJPROP_BMPFILE,0,"::Images\\euro.bmp");
...
ObjectSetString(0,my_bitmap,OBJPROP_BMPFILE,0,"::picture.bmp");
...
set=ObjectSetString(0,bitmap_label,OBJPROP_BMPFILE,1,"::Files\\Pictures\\good.bmp");
...
PlaySound("::Files\\Demo.wav");
...
PlaySound("::Sounds\\thrill.wav");
It should be noted that when setting images from a resource to the OBJ_BITM AP and
OBJ_BITM AP_L ABEL objects, the value of the OBJPR OP_BMPFIL E property cannot be modified
manually. For example, for creating OBJ_BITM AP_L ABEL we use resources euro.bmp and dollar.bmp.
W hen viewing the properties of this object, we'll see that the properties BitMap File (On) and BitMap
File (Off) are dimmed and cannot be change manually:
There is another advantage of using resources – in any MQL5 program, resources of another EX5 file
can be used. Thus the resources from one EX5 file can be used in many other mql5 programs.
#resource "\\Files\\triangle.bmp"
Then its name, for using in the script itself, will look lik e "Files \ triangle.bmp" , and in order to use it,
"::" should be added to the resource name.
In order to use the same resource from another program, e.g. from an Expert Advisor, we need to add
to the resource name the path to the EX5 file relative to terminal_data_directory\ MQL5 \ and the
name of the script's EX5 file - Draw_Triangles_Script.ex5 . Suppose the script is located in the
standard folder terminal_data_directory\ MQL5 \ Scripts \ , then the call should be written the following
way:
If the path to the executable file is not specified when calling the resource from another EX5, the
executable file is searched for in the same folder that contains the program that calls the resource.
This means that if an Expert Advisor calls a resource from Draw_Triangles _Script.ex5 without
specification of the path, lik e this :
then the file will be searched for in the folder terminal_data_directory\ MQL5 \ Experts \ , if the Expert
Advisor is located in terminal_data_directory\MQL5\Experts \.
One or several custom indicators may be necessary for the operation of MQL5 applications. All of them
can be included into the code of an executable MQL5 program. Inclusion of indicators as resources
simplifies the distribution of applications.
//+------------------------------------------------------------------+
//| SampleEA.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#resource "\\Indicators\\SampleIndicator.ex5"
int handle_ind;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
handle_ind=iCustom(_Symbol,_Period,"::Indicators\\SampleIndicator.ex5");
if(handle_ind==INVALID_HANDLE)
{
Print("Expert: iCustom call: Error code=",GetLastError());
return(INIT_FAILED);
}
//--- ...
return(INIT_SUCCEEDED);
}
The case when a custom indicator in OnInit() function creates one or more copies of itself requires
special consideration. Please k eep in mind that the resource should be specified in the following way:
<path_EX 5_file_name>::<resource_name>.
The path to itself can be received using GetR elativeProgramPath() function. The example of its usage
is provided below:
//+------------------------------------------------------------------+
//| SampleIndicator.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_separate_window
#property indicator_plots 0
int handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- the wrong way to provide a link to itself
//--- string path="\\Experts\\SampleEA.ex5::Indicators\\SampleIndicator.ex5";
//--- the right way to receive a link to itself
string path=GetRelativeProgramPath();
//--- indicator buffers mapping
handle=iCustom(_Symbol,_Period,path,0,0);
if(handle==INVALID_HANDLE)
{
Print("Indicator: iCustom call: Error code=",GetLastError());
return(INIT_FAILED);
}
else Print("Indicator handle=",handle);
//---
return(INIT_SUCCEEDED);
}
///....
//+------------------------------------------------------------------+
//| GetRelativeProgramPath |
//+------------------------------------------------------------------+
string GetRelativeProgramPath()
{
int pos2;
//--- get the absolute path to the application
string path=MQLInfoString(MQL_PROGRAM_PATH);
//--- find the position of "\MQL5\" substring
int pos =StringFind(path,"\\MQL5\\");
//--- substring not found - error
if(pos<0)
return(NULL);
//--- skip "\MQL5" directory
pos+=5;
//--- skip extra '\' symbols
while(StringGetCharacter(path,pos+1)=='\\')
pos++;
//--- if this is a resource, return the path relative to MQL5 directory
if(StringFind(path,"::",pos)>=0)
return(StringSubstr(path,pos));
//--- find a separator for the first MQL5 subdirectory (for example, MQL5\Indicators)
//--- if not found, return the path relative to MQL5 directory
if((pos2=StringFind(path,"\\",pos+1))<0)
return(StringSubstr(path,pos));
//--- return the path relative to the subdirectory (for example, MQL5\Indicators)
return(StringSubstr(path,pos2+1));
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double& price[])
{
//--- return value of prev_calculated for next call
return(rates_total);
}
Resource variables
R esources can be declared using the resource variables and treated as if they are variables of the
appropriate type. Declaration format:
Sample declarations :
#resource "data.bin" as int ExtData[] // declare the numeric array containing data from
#resource "data.bin" as MqlRates ExtData[] // declare the simple structures array containing
//--- strings
#resource "data.txt" as string ExtCode // declare the string containing the data.txt fil
//--- graphical resources
#resource "image.bmp" as bitmap ExtBitmap[] // declare the one-dimensional array containing a
#resource "image.bmp" as bitmap ExtBitmap2[][] // declare the two-dimensional array containing a
In case of such declaration, the resource data can be addressed only via the variable, auto addressing
via "::<rsource name>" does not work .
Script execution result – only two OBJ_BITM AP_L ABEL objects out of three ones are created. The
image of the first object has the red stripe in the middle.
An important advantage of applying the resources is that the resource files are automatically
compressed before they are included into an executable EX5 file prior to compilation. Thus, using the
resource variables allows you to put all necessary data directly into the executable EX5 file as well as
reduce the number and total size of the files compared to the conventional way of writing MQL5
programs.
Using the resource variables is particularly convenient for publishing products in the Mark et.
Features
· The special bitmap resource variable type informs the compiler that the resource is an image. Such
· The automatic encoding detection by BOM (header) presence is performed for string files. If BOM is
absent, the encoding is defined by the file contents. The files in the ANSI, UT F-8 and UT F-16
encodings are supported. All strings are converted to Unicode when reading data from the files.
OpenCL programs
Using the resource string variables may greatly facilitate the development of some programs. For
example, you are able to write a code of an OpenCL program in a separate CL file and then include it
as a string into your MQL5 program resources.
In this example, you would have had to write the entire code as a single big string if no cl_program
See also
R esourceCreate(), R esourceSave(), PlaySound(), ObjectSetInteger(), ChartApplyTemplate(), File
Functions
It is not recommended to use the fully specified name of the module to be loaded lik e Drive:
\Directory\FileName.Ext. The MQL5 libraries are loaded from the terminal_dir\MQL5\Libraries folder.
If the library hasn't been found, then the client terminal performs an attempt to load it from
terminal_dir\experts folder.
The system libraries (DLL) are loaded by the operating system rules. If the library is already loaded
(for example, another Expert Advisor, and even from another client terminal, running in parallel), then
it uses requests to the library already loaded. Otherwise, it performs a search in the following
sequence:
1. Directory, from which the module importing dll was started. The module here is an Expert Advisor,
a script, an indicator or EX5 library;
2. Directory terminal_data_directory\MQL5\Libraries (T ER MINAL _DAT A_PAT H\MQL5\Libraries);
3. Directory, from which the MetaTrader 5 client terminal was started;
4. System directory;
5. W indows directory;
6. Current directory;
7. Directories listed in the PAT H system variable.
If the DLL library uses another DLL in its work , the first one cannot be loaded in case when there is no
second DLL.
Before an Expert Advisor (script, indicator) is loaded, a common list of all EX5 library modules is
formed. It's going to be used both from a loaded Expert Advisor (script, indicator) and from libraries
of this list. Thus the one-time loading of many times used EX5 library modules is needed. Libraries use
predefined variables of the Expert Advisor (script, indicator) they were called by.
1. Directory, path to which is set relative to the directory of the Expert Advisor (script, indicator) that
imports EX5;
2. Directory terminal_directory\MQL5\Libraries ;
3. Directory MQL5\Libraries in the common directory of all MetaTrader 5 client terminals
(Common\ MQL5\ Libraries).
Functions imported DLL into a mql5-program must ensure the W indows API calls agreement. To ensure
such an agreement, in the source text of programs written in C or C++, use the k eyword __stdcall,
which is specific to the Microsoft(r) compilers. This agreement is characterized by the following :
· caller (in our case it is a mq5-program) should " see" a prototype of a function called (imported from
the DLL), in order to properly combine parameters to a stack;
· caller (in our case it is a mql5-program) puts parameters to the stack in a reverse order, from right
to left - in this order an imported function reads parameters passed to it;
· parameters are passed by value, except those explicitly passed by reference (in our case strings)
· an imported function cleans the stack independently by reading parameters passed to it.
W hen describing the prototype of an imported function, default parameters can be used.
If the corresponding library is unable to load, or there is a prohibition on the DLL use, or the imported
function is not found - the Expert Advisor stops its operation with the appropriate message "Expert
Advisor stopped" in the Journal (log file). In this case the Expert Advisor will not run until it is
reinitialized. An Expert Advisor can be reinitialized as a result of recompilation or after the table of its
properties is opened and OK is pressed.
Passing Parameters
All parameters of simple types are passed by values unless it is explicitly indicated that they are
passed by reference. W hen a string is passed, the address of the buffer of the copied string is passed;
if a string is passed by reference, the address of the buffer of this string without copying it is passed
to the function imported from DLL.
Structures that contain dynamic arrays, strings, classes, other complex structures, as well as static or
dynamic arrays of the enumerated objects, can't be passed as a parameter to an imported function.
W hen passing an array to DLL, the address of the beginning of the data buffer is always passed
(irrespective of the AS _S ER I ES flag). A function inside a DLL k nows nothing about the AS _S ER I ES flag,
the passed array is a static array of an undefined length; an additional parameter should be used for
specifying the array size.
Runtime Errors
The executing subsystem of the client terminal has an opportunity to save the error code in case it
occurs during a MQL5 program run. There is a predefined variable _LastError for each executable
MQL5 program.
Before starting the OnInit function, the _LastError variable is reset. In case an erroneous situation
occurs during calculations or in the process of internal function calls, the _LastError variable accepts a
corresponding error code. The value stored in this variable can be obtained using the GetLastError()
function.
There are several critical errors in case of which a program is terminated immediately:
· division by zero
· The Expert Advisor performs trading operations in accordance with the rules of the trading system;
· The trading strategy, implemented in the EA, demonstrates a profit on the history.
To get answers to these questions, we turn to the Strategy Tester, included in the MetaTrader 5 client
terminal.
This section covers the features of program testing and optimization in the strategy tester:
· Simulation of spread
· Multi-Currency Testing
· Testing Agents
· Using DLLs
To increase performance Comment(), Print() and PrintFormat() functions are not executed when
optimizing the trading robot's parameters. The exception is the use of these functions inside the
OnInit() handler. This allows you to easily find the cause of errors when they occur.
The Alert(), MessageBox(), PlaySound(), SendFTP(), SendMail(), SendNotification() and W ebR equest()
functions designed for interaction with the " outside world" are not executed in the Strategy Tester.
The NewTick event (price change) is the main event for the EA and, therefore, we need to generate a
tick sequence to test the EA. There are 3 modes of tick generation implemented in the Strategy Tester
of MetaTrader 5 client terminal:
· Every tick
The basic and the most detailed is the "Every tick" mode, the other two modes are the simplifications
of the basic one, and will be described in comparison to the "Every tick" mode. Consider all three
modes in order to understand the differences between them.
"Every Tick"
The historical quotes data for financial instruments is transferred from the trading server to the
MetaTrader 5 client terminal in the form of pack ed minute bars. Detailed information on the
occurrence of requests and the construction of the required time-frames can be obtained from the
Organizing Data Access chapter of MQL5 R eference.
The minimal element of the price history is the minute bar, from which you can obtain information on
the four values of the price:
· H igh - the maximum that was achieved during this minute bar;
· Low - the minimum that was achieved during this minute bar;
The new minute bar is not opened at the moment when the new minute begins (number of seconds
becomes equal to 0), but when a tick occurs - a price change by at least one point. The figure shows
the first minute bar of the new trading week , which has the opening time of 2011.01.10 00:00. The
price gap between Friday and Monday, which we see on the chart, is common, since currency rates
fluctuates even on week ends in response to incoming news.
For this bar, we only k now that the minute bar was opened on January 10th 2011 at 00 hours 00
minutes, but we k now nothing about the seconds. It could have been opened at 00:00:12 or 00:00:36
(12 or 36 seconds after the start of a new day) or any other time within that minute. But we do k now
that the Open price of EURUS D was at 1.28940 at the opening time of the new minute bar.
W e also don't k now (accurate within a second) when we received the tick corresponding to the closing
price of the considered minute bar. W e k nown only one thing - the last Close price of the minute bar.
For this minute, the price was 1.28958. The time of the appearance of H igh and Low prices is also
unk nown, but we k now that the maximum and minimum prices were on the levels of 1.28958 and
1.28940, respectively.
To test the trading strategy, we need a sequence of tick s, on which the work of the Expert Advisor will
be simulated. Thus, for every minute bar, we k now the 4 control points , where the price has
definitely been. If a bar has only 4 tick s, then this is enough information to perform a testing, but
usually the tick volume is greater than 4.
H ence, there is a need to generate additional control points for tick s, which occurred between the
Open, H igh, Low, and Close prices. The principle of the "Every tick" tick s generation mode is
described in the The Algorithm of Tick s ’ Generation within the Strategy Tester of the MetaTrader 5
Terminal a figure from which is presented below.
W hen testing in the "Every tick" mode, the OnTick () function of the EA will be called at every control
point. Each control point is a tick from a generated sequence. The EA will receive the time and price
of the simulated tick , just as it would when work ing online.
Important: the "Every tick" testing mode is the most accurate, but at the same time, the most
time consuming. For an initial testing of the majority of trading strategies, it is usually sufficient
to use one of the other two testing modes.
In the "1 minute OH LC" mode, the tick sequence is constructed only by the OHLC prices of the minute
bars, the number of the generated control points is significantly reduced - hence, so is the testing
time. The launch of the OnTick () function is performed on all control points, which are constructed by
the prices of OH LC minute bars.
The refusal to generate additional intermediate tick s between the Open, H igh, Low, and Close prices,
leads to an appearance of rigid determinism in the development of prices, from the moment that the
Open price is determined. This mak es it possible to create a " Testing Grail" , which shows a nice
upward graph of the testing balance.
The figure shows a very attractive graph of this EA testing. H ow was it obtained? W e k now 4 prices for
a minute bar, and we also k now that the first is the Open price, and the last is the Close price. W e
have the H igh and Low prices between them, and the sequence of their occurrence is unk nown, but it
is k nown, that the H igh price is greater than or equal to the Open price (and the Low price is less than
or equal to the Open price).
It is sufficient enough to determine the moment of receiving the Open price, and then analyze the
next tick in order to determine what price we have at the moment - either the H igh or the Low. If the
price is below the Open price, then we have a Low price and buy at this tick , the next tick will
correspond to the H igh price, at which we will close the buy and open for sell. The next tick is the last
one, this is the Close price, and we close the sale on it.
If after the price, we receive a tick with a price greater than the opening price, then the sequence of
deals is reversed. Process a minute bar in this " cheat" mode, and wait for the next one.
W hen testing such EA on the history, everything goes smoothly, but once we launch it online, the truth
begins to get revealed - the balance line remains steady, but heads downwards. To expose this trick ,
we simply need to run the EA in the "Every tick" mode.
Note: If the test results of the EA in the rough testing modes ("1 minute OH LC" and " Open Prices
only" ) seem too good, mak e sure to test it in the "Every tick" mode.
W1 and M N1 periods are the exceptions in the " Open Price Only" tick s generation mode: for these
timeframes tick s are generated for the OH LC prices of each day, not OH LC prices of the week or
month.
Suppose we test an Expert Advisor on EURUS D H1 in the " Open Prices Only" mode. In this case the
total number of tick s (control points) will be no more than 4*number of one-hour bars within the tested
interval. But the OnTick() handler is called only at the opening of the one-hour bar . The check s
required for a correct testing occur on the rest of the tick s (that are " hidden" from the EA).
If there are no open positions or pending orders, we don't need to perform these check s on hidden
tick s, and the increase of speed may be quite substantial. This " Open prices only" mode is well suited
for testing strategies, which process deals only at the opening of the bar and do not use pending
orders, as well as StopLoss and Tak eProfit orders. For the class of such strategies, the necessary
accuracy of testing is preserved.
Let's use the Moving Average Expert Advisor from the standard pack age as an example of an EA,
which can be tested in any mode. The logic of this EA is built in such a way that all of the decisions are
made at the opening of the bar, and deals are carried out immediately, without the use of pending
orders.
R un a testing of the EA on EURUS D H1 on an interval from 2010.09.01 to 2010.12.31, and compare the
graphs. The figure shows the balance graph from the test report for all of the three modes.
As you can see, the graphs on different testing modes are exactly the same for the Moving Average EA
from the standard pack age.
There are some limitations on the " Open Prices Only" mode:
· In the tested Expert Advisor, you cannot access data of the timeframe lower than that used for
testing /optimization. For example, if you run testing /optimization on the H1 period, you can access
data of H2, H3, H4 etc., but not M 30, M 20, M 10 etc. In addition, the higher timeframes that are
accessed must be multiple of the testing timeframe. For example, if you run testing in M 20, you
cannot access data of M 30, but it is possible to access H1. These limitations are connected with the
impossibility to obtain data of lower or non-multiple timeframes out of the bars generated during
testing /optimization.
· Limitations on accessing data of other timeframes also apply to other symbols whose data are used
by the Expert Advisor. In this case the limitation for each symbol depends on the first timeframe
accessed during testing /optimization. Suppose, during testing on EURUS D H1, an Expert Advisor
accesses data of GBPUS D M 20. In this case the Expert Advisor will be able to further use data of
EURUS D H1, H2, etc., as well as GBPUS D M 20, H1, H2 etc.
Note: The " Open prices only" mode has the fastest testing time, but it is not suitable for all of the
trading strategies. Select the desired test mode based on the characteristics of the trading
system.
To conclude the section on the tick generation modes, let's consider a visual comparison of the
different tick generation modes for EURUS D, for two M 15 bars on an interval from 2011.01.11
21:00:00 - 2011.01.11 21:30:00.
The tick s were saved into different files using the W riteTick s FromTester.mq5 EA and the ending of
these files names are specified in filenameEveryTick , filenameOH LC and filenameOpenPrice input-
parameters.
To obtain three files with three tick sequences (for each of the following modes "Every tick" , "1 minute
OH LC" and " Open prices only), the EA was launched three times in the corresponding modes, in single
runs. Then, the data from these three files were displayed on the chart using the
Tick s FromTester.mq5 indicator. The indicator code is attached to this article.
By default, all of the file operations in the MQL5 language are made within the " file sandbox " , and
during testing the EA has access only to its own " file sandbox " . In order for the indicator and the EA to
work with files from one folder during testing, we used the flag FIL E_COMMON. An example of code
from the EA:
For reading the data in the indicator, we also used the flag FIL E_COMMON. This allowed us to avoid
manually transferring the necessary files from one folder to another.
Simulation of spread
The price difference between the Bid and the As k prices is called the spread. During testing, the
spread is not modeled but is tak en from historical data. If the spread is less than or equal to zero in
the historical data, then the last k nown (at the moment of generation) spread is used by testing
agent.
In the Strategy Tester, the spread is always considered floating. That is, SymbolInfoInteger(symbol,
S YM BOL _SPREAD_FLOAT) always returns true.
In addition, the historical data contains tick values and trading volumes. For the storage and retrieval
of data we use a special M qlR ates structure:
struct MqlRates
{
datetime time; // Period start time
double open; // Open price
double high; // The highest price of the period
double low; // The lowest price of the period
double close; // Close price
long tick_volume; // Tick volume
int spread; // Spread
long real_volume; // Trade volume
};
To ensure the greatest test accuracy, minute bars are also used in the real tick s mode. The bars are
applied to check and correct tick data. This also allows you to avoid the divergence of charts in the
tester and the client terminal.
The tester compares the tick data to the minute bar parameters : a tick should not exceed the bar's
H igh/Low levels, also initial and final tick s should coincide with the bar's Open/Close prices. The
volume is compared as well. If a mismatch is detected, all tick s corresponding to this minute bar are
discarded. Generated tick s are used instead (lik e in the "Every tick" mode).
If a symbol history has a minute bar with no tick data for it, the tester generates tick s in the "Every
tick" mode. This allows plotting a correct chart in the tester in case a brok er's tick data is insufficient.
If a symbol history has no minute bar but the appropriate tick data for the minute is present, the data
can be used in the tester. For example, exchange symbol pairs are formed using Last prices. If only
tick s with Bid/As k prices without the Last price arrive from the server, the bar is not generated. The
tester uses these tick data since they do not contradict the minute ones.
Tick data may not coincide with minute bars for various reasons, for example because of connection
losses or other failures when transmitting data from a source to the client terminal. The minute data
is considered more reliable during tests.
· W hen launching a test, the minute data on a symbol is synchronized along with the tick one.
· Tick s are stored in the symbol cache of the strategy tester. The cache size does not exceed 128 000
tick s. W hen new tick s arrive, the oldest data is removed from the cache. H owever, the CopyTick s
function allows receiving tick s outside the cache (only when testing on real tick s). In that case, the
data is requested from the tester tick database that is completely similar to the corresponding client
terminal database. No minute bar corrections are implemented to this base. Therefore, the tick s
there may differ from the ones stored in the cache.
It does not matter whether or not there is a call for the indicator in a specific event handler. All
the indicators with handles created by the iCustom() or IndicatorCreate() functions will be
recalculated before calling the event handler.
Consequently, when testing in the "Every tick" mode, the calculation of the indicators tak es place
before the call of OnTick () function.
If the timer is on in the EA, using the EventSetTimer() function, then the indicators will be
recalculated before each call of the OnTimer() handler. Therefore, the testing time can be greatly
increased with the use of an indicators, written in a non-optimal way.
A testing agent receives the history of a symbol to be tested from the client terminal right after the
start of testing. If data of other instruments are used in the process of testing (for example, it is a
multicurrency Expert Advisor), the testing agent requests the required history from the client terminal
during the first call to such data. If historical data are available in the terminal, they are immediately
passed to the testing agent. If data are not available, the terminal requests and downloads them from
the server, and then passes to the testing agent.
Data of additional instruments is also required for calculating cross-rates for trade operations. For
example, when testing a strategy on EUR CHF with the deposit currency in US D, prior to processing the
first trading operation, the testing agent requests the history data of EURUS D and US DCHF from the
client terminal, though the strategy does not contain direct use call of these symbols.
Before testing a multi-currency strategy, it is recommended to download all the necessary historical
data to the client terminal. This will help to avoid delays in testing /optimization associated with
download of the required data. You can download history, for example, by opening the appropriate
charts and scrolling them to the history beginning. An example of forced loading of history into the
terminal is available in the Organizing Access to Data section of the MQL5 R eference.
Testing agents, in turn, receive history from the terminal in the pack ed form. During the next testing,
the tester does not load history from the terminal, because the required data is available since the
previous run of the tester.
· The terminal loads history from a trade server only once, the first time the agent requests the
history of a symbol to be tested from the terminal. The history is loaded in a pack ed form to
reduce the traffic.
· Tick s are not sent over the network , they are generated on testing agents.
Multi-Currency Testing
The Strategy Tester allows us to perform a testing of strategies, trading on multiple symbols. Such EAs
are conventionally referred to as multi-currency Expert Advisors, since originally, in the previous
platforms, testing was performed only for a single symbol. In the Strategy Tester of the MetaTrader 5
terminal, we can model trading for all of the available symbols.
The tester loads the history of the used symbols from the client terminal (not from the trade server!)
automatically during the first call of the symbol data.
The testing agent downloads only the missing history, with a small margin to provide the necessary
data on the history, for the calculation of the indicators at the starting time of testing. For the time-
frames D1 and less, the minimum volume of the downloaded history is one year.
Thus, if we run a testing on an interval 2010.11.01-2010.12.01 (testing for an interval of one month)
with a period of M 15 (each bar is equal to 15 minutes), then the terminal will be requested the history
for the instrument for the entire year of 2010. For the week ly time-frame, we will request a history of
100 bars, which is about two years (a year has 52 week s). For testing on a monthly time-frame the
agent will request the history of 8 years (12 months x 8 years = 96 months).
If there isn't necessary bars, the starting date of testing will be automatically shifted from past to
present to provide the necessary reserve of bars before the testing.
During testing, the " Mark et W atch" is emulated as well, from which one can obtain information on
symbols.
By default, at the beginning of testing, there is only one symbol in the " Mark et W atch" of the Strategy
Tester - the symbol that the testing is running on. All of the necessary symbols are connected to the
" Mark et W atch" of the Strategy Tester (not terminal!) automatically when referred to.
R eferral to the data of an " other" symbol occurs in the following cases :
· W hen using the technical indicators function and IndicatorCreate() on the symbol/timeframe;
· The request to the " Mark et W atch" data for the other symbol:
1. SeriesInfoInteger
2. Bars
3. SymbolSelect
4. SymbolIsSynchronized
5. SymbolInfoDouble
6. SymbolInfoInteger
7. SymbolInfoString
8. SymbolInfoTick
9. SymbolInfoSessionQuote
10.SymbolInfoSessionTrade
11.Mark etBookAdd
12.Mark etBookGet
· R equest of the time-series for a symbol/timeframe by using the following functions :
1. CopyBuffer
2. CopyR ates
3. CopyTime
4. CopyOpen
5. CopyH igh
6. CopyLow
7. CopyClose
8. CopyTickVolume
9. CopyR ealVolume
10.CopySpread
At the moment of the first call to an " other" symbol, the testing process is stopped and the history is
downloaded for the symbol/timeframe, from the terminal to the testing agent. At the same time, the
generation of tick sequence for this symbol is made.
An individual tick sequence is generated for each symbol, according to the selected tick generation
mode. You can also request the history explicitly for the desired symbols by calling the SymbolSelect()
in the OnInit() handler - the downloading of the history will be made immediately prior to the testing
of the Expert Advisor.
Thus, it does not require any extra effort to perform multi-currency testing in the MetaTrader 5 client
terminal. Just open the charts of the appropriate symbols in the client terminal. The history will be
automatically uploaded from the trading server for all the required symbols, provided that it contains
this data.
The lack of a difference between the GMT, the Local, and the server time in the Strategy Tester is
done deliberately in case there is no connection to the server. The test results should always be the
same, regardless of whether or not there is a connection. Information about the server time is not
stored locally, and is tak en from the server.
To check the dependence of the testing time from the given frequency of the timer, we have created a
simple EA without any trading operations.
{
EventSetTimer(timer);
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- stop the timer
EventKillTimer();
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
// take no actions, the body of the handler is empty
}
//+------------------------------------------------------------------+
Testing time measurements were tak en at different values of the timer parameter (periodicity of the
Timer event). On the obtained data, we plot a testing time as function of Timer period.
It can be clearly seen that the smaller is the parameter timer, during the initialization of the
EventSetTimer(Timer) function, the smaller is the period (Period) between the calls of the OnTimer()
handler, and the larger is the testing time T, under the same other conditions.
The Sleep() function allows the EA or script to suspend the execution of the mql5-program for a while,
when work ing on the graph. This can be useful when requesting data, which is not ready at the time of
the request and you need to wait until it is ready. A detailed example of using the Sleep() function can
be found in the section Organizing Data Access.
The testing process is not lingered by the Sleep() calls.W hen you call the Sleep(), the generated tick s
are " played" within a specified delay, which may result in the triggering of pending orders, stops, etc.
After a Sleep() call, the simulated time in the Strategy Tester increases by an interval, specified in the
parameter of the Sleep function.
If as a result of the execution of the Sleep() function, the current time in the Strategy Tester went
over the testing period, then you will receive an error " Infinite Sleep loop detected while testing " . If
you receive this error, the test results are not rejected, all of the computations are performed in their
full volume (the number of deals, subsidence, etc.), and the results of this testing are passed on to
the terminal.
The Sleep() function will not work in OnDeinit(), since after it is called, the testing time will be
guaranteed to surpass the range of the testing interval.
In this case, only three functions will be called: OnInit(), OnTester(), OnDeinit(). In " Math calculations "
mode the Strategy Tester doesn't generate any tick s and download the history.
The Strategy Tester work s in " Math calculations " mode also if you specify the starting date greater
than ending date.
W hen using the tester to solve mathematical problems, the uploading of the history and the
generation of tick s does not occur.
A typical mathematical problem for solving in the MetaTrader 5 Strategy Tester - searching for an
extremum of a function with many variables.
Compile the EA, open the " Strategy Tester" window. In the " Input parameters " tab, select the required
input variables, and define the set of parameter values by specifying the start, stop and step values
for each of the function variables.
Select the optimization type - " Slow complete algorithm" (full search of parameters space) or "Fast
genetic based algorithm" . For a simple search of the extremum of the function, it is better to choose a
fast optimization, but if you want to calculate the values for the entire set of variables, then it is best
to use the slow optimization.
Select " Math calculation" mode and using the " Start" button, run the optimization procedure. Note that
during the optimization the Strategy Tester will search for the maximum values of the OnTester
function. To find a local minimum, return the inverse of the computed function value from the
OnTester function:
return(1/function_value);
It is necessary to check that the function_value is not equal to zero, since otherwise we can obtain a
critical error of dividing by zero.
There is another way, it is more convenient and does not distort the results of optimization, it was
suggested by the readers of this article:
return(-function_value);
This option does not require the check ing of the function_value for being equal to zero, and the
surface of the optimization results in a 3D-representation has the same shape. The only difference is
that it is mirrored comparing to the original.
The code of the EA for finding the extremum of this function is placed into the OnTester():
//+------------------------------------------------------------------+
//| Sink.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- input parameters
input double x=-3.0; // start=-3, step=0.05, stop=3
input double y=-3.0; // start=-3, step=0.05, stop=3
//+------------------------------------------------------------------+
//| Tester function |
//+------------------------------------------------------------------+
double OnTester()
{
//---
double sink=MathSin(x*x+y*y);
//---
return(sink);
}
//+------------------------------------------------------------------+
Perform an optimization and see the optimization results in the form of a 2D graph.
The better the value is for a given pair of parameters (x, y), the more saturated the color is. As was
expected from the view of the form of the sink () formula, its values forms concentric circles with a
center at (0,0). One can see in the 3D-graph, that the sink () function has no single global extremum:
The testing of strategies, that are trading on multiple symbols, imposes a few additional technical
requirements on the tester:
The Strategy Tester generates and plays a tick sequence for each instrument in accordance with the
selected trading mode. At the same time, a new bar for each symbol is opened, regardless of how the
bar opened on another symbol. This means that when testing a multi-currency EA, a situation may
occur (and often does), when for one instrument a new bar has already opened, and for the other it
has not. Thus, in testing, everything happens just lik e in reality.
This authentic simulation of the history in the tester does not cause any problems as long as the
"Every tick" and "1 minute OH LC" testing modes are used. For these modes, enough tick s are
generated for one candlestick , to be able to wait until the synchronization of bars from different
symbols tak es place. But how do we test multi-currency strategies in the " Open prices only" mode, if
the synchronization of bars on trading instruments is mandatory? In this mode, the EA is called only on
one tick , which corresponds to the time of the opening of the bars.
W e'll illustrate it on an example: we are testing an EA on the EURUS D, and a new H1 candlestick has
been opened on EURUS D. W e can easily recognize this fact - while testing in the " Open prices only"
mode, the NewTick event corresponds to the moment of a bar opening on the tested period. But there
is no guarantee that the new candlestick was opened on the US DJPY symbol, which is used in the EA.
Under normal circumstances, it is sufficient enough to complete the work of the OnTick () function and
to check for the emergence of a new bar on US DJPY at the next tick . But when testing in the " Open
prices only" mode, there will be no other tick , and so it may seem that this mode is not fit for testing
multi-currency EAs. But this is not so - do not forget that the tester in MetaTrader 5 behaves just as it
would in real life. You can wait until a new bar is opened on another symbols using the function
Sleep()!
The code of the EA Synchronize_Bars _Use_Sleep.mq5, which shows an example of the synchronization
of bars in the " Open prices only" mode:
//+------------------------------------------------------------------+
//| Synchronize_Bars_Use_Sleep.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- input parameters
input string other_symbol="USDJPY";
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- check symbol
if(_Symbol==other_symbol)
{
PrintFormat("You have to specify the other symbol in input parameters or select other symbol
//--- forced stop testing
return(INIT_PARAMETERS_INCORRECT);
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- static variable, used for storage of last bar time
static datetime last_bar_time=0;
//--- sync flag
static bool synchonized=false;
//--- if static variable isn't initialized
if(last_bar_time==0)
{
//--- it's first call, save bar time and exit
last_bar_time=(datetime)SeriesInfoInteger(_Symbol,Period(),SERIES_LASTBAR_DATE);
PrintFormat("The last_bar_time variable is initialized with value %s",TimeToString(last_bar_t
}
//--- get open time of the last bar of chart symbol
datetime curr_time=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);
//--- if times aren't equal
if(curr_time!=last_bar_time)
{
//--- save open bar time to the static variable
last_bar_time=curr_time;
//--- not synchronized
synchonized=false;
//--- print message
PrintFormat("A new bar has appeared on symbol %s at %s",_Symbol,TimeToString(TimeCurrent()));
}
//--- open time of the other symbol's bar
datetime other_time;
//--- loop until the open time of other symbol become equal to curr_time
while(!(curr_time==(other_time=(datetime)SeriesInfoInteger(other_symbol,Period(),SERIES_LASTBAR_
{
PrintFormat("Waiting 5 seconds..");
//--- wait 5 seconds and call SeriesInfoInteger(other_symbol,Period(),SERIES_LASTBAR_DATE)
Sleep(5000);
}
//--- bars are synchronized
synchonized=true;
PrintFormat("Open bar time of the chart symbol %s: is %s",_Symbol,TimeToString(last_bar_time));
PrintFormat("Open bar time of the symbol %s: is %s",other_symbol,TimeToString(other_time));
//--- TimeCurrent() is not useful, use TimeTradeServer()
Notice the last line in the EA, which displays the current time when the fact of synchronization was
established:
To display the current time we used the TimeTradeServer() function rather than TimeCurrent(). The
TimeCurrent() function returns the time of the last tick , which does not change after using Sleep().
R un the EA in the " Open prices only" mode, and you will see a message about the synchronization of
the bars.
Use the TimeTradeServer() function instead of the TimeCurrent(), if you need to obtain the current
server time, and not the time of the last tick arrival.
Note: indicators, displayed on the chart, which automatically opens after the completion of the
testing, are calculated anew after the completion of testing. Even if these indicators were used in
the tested EA.
But in some cases, the programmer may want to hide the information on which indicators were
involved in the trading algorithms. For example, the code of the EA is rented or sold as an executable
file, without the provision of the source code. For this purpose, the IndicatorR elease() function is
suitable.
If the terminal sets a template with the name tester.tpl in the directory/profiles /templates of the
client terminal, then it will be applied to the opened chart. In its absence, the default template is
applied. (default.tpl).
The IndicatorR elease() function is originally intended for releasing the calculating portion of the
indicator, if it is no longer needed. This allows you to save both the memory and the CPU resources,
because each tick calls for an indicator calculation. Its second purpose is to prohibit the showing of an
indicator on the testing chart, after a single test run.
To prohibit the showing of the indicator on the chart after testing, call the IndicatorR elease() with the
handle of the indicator in the handler OnDeinit(). The OnDeinit() function is always called after the
completion and before the showing of the testing chart.
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
bool hidden=IndicatorRelease(handle_ind);
if(hidden) Print("IndicatorRelease() successfully completed");
else Print("IndicatorRelease() returned false. Error code ",GetLastError());
}
In order to prohibit the showing of the indicator on the chart, after the completion of a single test, use
the function IndicatorR elease() in the handler OnDeinit().
W hen testing in an EA, we can handle custom events using the OnChartEvent() function, but in the
indicators, this function can not be called in the tester. Even if the indicator has the OnChartEvent()
event handler and this indicator is used in the tested EA, the indicator itself will not receive any
custom events.
During testing, an Indicator can generate custom events using the EventChartCustom() function, and
the EA can process this event in the OnChartEvent().
In addition to these events, special events associated with the process of testing and optimization are
generated in the strategy tester:
· Tester - this event is generated after completion of Expert Advisor testing on history data. The
Tester event is handled using the OnTester() function. This function can be used only when testing
Expert Advisor and is intended primarily for the calculation of a value that is used as a Custom max
criterion for genetic optimization of input parameters.
· TesterInit - this event is generated during the start of optimization in the strategy tester before the
very first pass. The TesterInit event is handled using the OnTesterInit() function. During the start of
optimization, an Expert Advisor with this handler is automatically loaded on a separate terminal
chart with the symbol and period specified in the tester, and receives the TesterInit event. The
function is used to initiate an Expert Advisor before start of optimization for further processing of
optimization results.
· TesterPass - this event is generated when a new data frame is received. The TesterPass event is
handled using the OnTesterPass() function. An Expert Advisor with this handler is automatically
loaded on a separate terminal chart with the symbol/period specified for testing, and receives the
TesterPass event when a frame is received during optimization. The function is used for dynamic
handling of optimization results " on the spot" without waiting for its completion. Frames are added
using the FrameAdd() function, which can be called after the end of a single pass in the OnTester()
handler.
· TesterDeinit - this event is generated after the end of Expert Advisor optimization in the strategy
tester. The TesterDeinit event is handles using the OnTesterDeinit() function. An Expert Advisor
with this handler is automatically loaded on a chart at the start of optimization, and receives
TesterDeinit after its completion. The function is used for final processing of all optimization
results.
Testing Agents
Testing in the MetaTrader 5 client terminal is carried out using test agents. Local agents are created
and enabled automatically. The default number of local agents corresponds to the number of cores in a
computer.
Each testing agent has its own copy of the global variables, which is not related to the client terminal.
The terminal itself is the dispatcher, which distributes the tas k s to the local and remote agents. After
executing a tas k on the testing of an EA, with the given parameters, the agent returns the results to
the terminal. W ith a single test, only one agent is used.
The agent stores the history, received from the terminal, in separate folders, by the name of the
instrument, so the history for EURUS D is stored in a folder named EURUS D. In addition, the history of
the instruments is separated by their sources. The structure for storing the history look s the following
way:
tester_catalog\Agent-IPaddress-Port\bases\name_source\history\symbol_name
For example, the history for EURUS D from the server MetaQuotes-Demo can be stored in the folder
tester_catalog \Agent-127.0.0.1-3000\ bases \ MetaQuotes-Demo\EURUS D.
A local agent, after the completion of testing, goes into a standby mode, awaiting for the next tas k
for another 5 minutes, so as not to waste time on launching for the next call. Only after the waiting
period is over, the local agent shuts down and unloads from the CPU memory.
In case of an early completion of the testing, from the user's side (the " Cancel" button), as well as with
the closing of the client terminal, all local agents immediately stop their work and are unloaded from
the memory.
· Input parameters for testing (simulation mode, the interval of testing, instruments, optimization
criterion, etc.)
· The list of the selected symbols in the " Mark et W atch"
· The specification of the testing symbol (the contract size, the allowable margins from the mark et
for setting a StopLoss and Tak eprofit, etc)
· The Expert Advisor to be tested and the values of its input parameters
· Information about additional files (libraries, indicators, data files - # property tester_ ...)
For each block of parameters, a digital fingerprint in the form of M D5-hash is created, which is sent to
the agent. M D5-hash is unique for each set, its volume is many more times smaller than the amount of
information on which it is calculated.
The agent receives a hash of block s and compares them with those that it already has. If the
fingerprint of the given parameter block is not present in the agent, or the received hash is different
from the existing one, the agent requests this block of parameters. This reduces the traffic between
the terminal and the agent.
After the testing, the agent returns to the terminal all of the results of the run, which are shown in the
tabs " Test R esults " and " Optimization R esults ": the received profit, the number of deals, the Sharpe
coefficient, the result of the OnTester() function, etc.
During optimizing, the terminal hands out testing tas k s to the agents in small pack ages, each pack age
contains several tas k s (each tas k means single testing with a set of input parameters). This reduces
the exchange time between the terminal and the agent.
The agents never record to the hard dis k the EX5-files, obtained from the terminal (EA, indicators,
libraries, etc.) for security reasons, so that a computer with a running agent could not use the sent
data. All other files, including DLL, are recorded in the sandbox. In remote agents you can not test EAs
using DLL.
The testing results are added up by the terminal into a special cache of results (the result cache), for a
quick access to them when they are needed. For each set of parameters, the terminal searches the
result cache for already available results from the previous runs, in order to avoid re-runs. If the result
with such a set of parameters is not found, the agent is given the tas k to conduct the testing.
Tick s are not sent over the network , they are generated on testing agents.
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- the shared folder for all of the client terminals
common_folder=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
//--- draw out the name of this folder
PrintFormat("Open the file in the shared folder of the client terminals %s", common_folder);
//--- open a file in the shared folder (indicated by FILE_COMMON flag)
handle=FileOpen(filename,FILE_WRITE|FILE_READ|FILE_COMMON);
... further actions
//---
return(INIT_SUCCEEDED);
}
Using DLLs
To speed up the optimization we can use not only local, but also remote agents. In this case, there are
some limitations for remote agents. First of all, remote agents do not display in their logs the results
of the execution of the Print() function, messages about the opening and closing of positions. A
minimum of information is displayed in the log to prevent incorrectly written EAs from trashing up the
computer, on which the remote agent is work ing, with messages.
A second limitation - the prohibition on the use of DLL when testing EAs. DLL calls are absolutely
forbidden on remote agents for security reasons. On local agent, DLL calls in tested EAs are allowed
only with the appropriate permission "Allow import DLL " .
Note: W hen using 3rd party EAs (scripts, indicators) that require allowed DLL calls, you should be
aware of the ris k s which you assume when allowing this option in the settings of the terminal.
R egardless of how the EA will be used - for testing or for running on a chart.
Values of predefined variables are set by the client terminal before a mql5-program is started.
Predefined variables are constant and cannot be changed from a mql5-program. As exception, there is
a special variable _LastError, which can be reset to 0 by the R esetLastError function.
Variable Value
_Is X64 The _Is X64 variable allows finding out the bit
version of the terminal, in which an MQL5
application is running
Predefined variables cannot be defined in a library. A library uses such variables that are defined in
program from which this library is called.
int _AppliedTo
The _AppliedTo variable allows finding out the type of data, used for indicator calculation:
Example:
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
// Getting the type of data used for indicator calculation
Print("_AppliedTo=",_AppliedTo);
Print(getIndicatorDataDescription(_AppliedTo));
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Description of data used for indicator calculation |
//+------------------------------------------------------------------+
string getIndicatorDataDescription(int data_id)
{
string descr="";
switch(data_id)
{
case(0):descr="It's first type of OnCalculate() - no data buffer";
break;
case(1):descr="Indicator calculates on Close price";
break;
case(2):descr="Indicator calculates on Open price";
break;
case(3):descr="Indicator calculates on High price";
break;
case(4):descr="Indicator calculates on Low price";
break;
case(5):descr="Indicator calculates on Median Price (HL/2)";
break;
case(6):descr="Indicator calculates on Typical Price (HLC/3)";
break;
case(7):descr="Indicator calculates on Weighted Price (HLCC/4)";
break;
case(8):descr="Indicator calculates Previous Indicator's data";
break;
case(9):descr="Indicator calculates on First Indicator's data";
break;
default: descr="Indicator calculates on data of indicator with handle="+string(data_id);
break;
}
//---
return descr;
}
See also
ENUM _APPLIED_PR ICE
int _Digits
The _Digits variable stores number of digits after a decimal point, which defines the price accuracy of
the symbol of the current chart.
double _Point
The _Point variable contains the point size of the current symbol in the quote currency.
int _LastError
The _LastError variable contains code of the last error, that occurred during the mql5-program run. Its
value can be reset to zero by R esetLastError().
To obtain the code of the last error, you may also use the GetLastError() function.
int _Period
The _Period variable contains the value of the timeframe of the current chart.
See also
_RandomSeed
Variable for storing the current state when generating pseudo-random integers. _R andomSeed changes
its value when calling MathR and(). Use MathSrand() to set the required initial condition.
x random number received by MathR and() function is calculated in the following way at each call:
x=_RandomSeed*214013+2531011;
_RandomSeed=x;
x=(x>>16)&0x7FFF;
See also
MathR and(), MathSrand(), Integer types
bool _StopFlag
The _StopFlag variable contains the flag of the mql5-program stop. W hen the client terminal is trying
to stop the program, it sets the _StopFlag variable to true.
To check the state of the _StopFlag you may also use the IsStopped() function.
string _Symbol
The _Symbol variable contains the symbol name of the current chart.
int _UninitReason
The _UninitR eason variable contains the code of the program uninitialization reason.
int _IsX64
The _Is X64 variable allows finding out the bit version of the terminal, in which an MQL5 application is
running : _Is X64=0 for the 32-bit terminal and _Is X64!=0 for the 64-bit terminal.
Example:
See also
MQLInfoInteger, Importing functions (#import)
Common Functions
General-purpose functions not included into any specialized group are listed here.
Function Action
SetR eturnError Sets the code that returns the terminal process
when completing the operation.
Alert
Displays a message in a separate window.
void Alert(
argument, // first value
... // other values
);
Parameters
argument
[in] Any values separated by commas. To split the information output in several lines you can use
the line feed character "\ n" or "\ r\ n" . The number of parameters can not exceed 64.
Return Value
No return value.
Note
Arrays can't be passed to the Alert() function. Arrays should be output elementwise. Data of the
double type are output with 8 digits after the decimal point, data of the float type are displayed with
5 digits after the decimal point. To output the real numbers with a different precision or in a
scientific format, use the DoubleToString() function.
Data of the bool type is output as " true" or " false" strings. Dates are output as YYYY.MM.DD
HH:MI:SS. To display a date in another format use the TimeToString() function. Data of the color
type are output either as an R ,G,B string or as a color name, if the color is present in a color set.
CheckPointer
The function returns the type of the object pointer.
ENUM_POINTER_TYPE CheckPointer(
object* anyobject // object pointer
);
Parameters
anyobject
[in] Object pointer.
Return value
Note
An attempt to call an incorrect pointer results in the critical termination of a program. That's why
it's necessary to call the Check Pointer function before using a pointer. A pointer can be incorrect in
the following cases :
This function can be used for check ing pointer validity. A non-zero value warranties that the pointer
can be used for accessing.
Example:
//+------------------------------------------------------------------+
//| Deletes list by deleting its elements |
//+------------------------------------------------------------------+
void CMyList::Destroy()
{
//--- service pointer for working in the loop
CItem* item;
//--- go through loop and try to delete dynamic pointers
while(CheckPointer(m_items)!=POINTER_INVALID)
{
item=m_items;
m_items=m_items.Next();
if(CheckPointer(item)==POINTER_DYNAMIC)
{
Print("Dynamic object ",item.Identifier()," to be deleted");
delete (item);
}
else Print("Non-dynamic object ",item.Identifier()," cannot be deleted");
}
//---
}
See also
Object Pointers, Check ing the Object Pointer, Object Delete Operator delete
Comment
This function outputs a comment defined by a user in the top left corner of a chart.
void Comment(
argument, // first value
... // next values
);
Parameters
...
[in] Any values, separated by commas. To delimit output information into several lines, a line
break symbol "\ n" or "\ r\ n" is used. Number of parameters cannot exceed 64. Total length of the
input comment (including invisible symbols) cannot exceed 2045 characters (excess symbols will be
cut out during output).
Return Value
No return value
Note
Arrays can't be passed to the Comment() function. Arrays must be entered element-by-element.
Data of double type are output with the accuracy of up to 16 digits after a decimal point, and can be
output either in traditional or in scientific format, depending on what notation will be more
compact. Data of float type are output with 5 digits after a decimal point. To output real numbers
with another accuracy or in a predefined format, use the DoubleToString() function.
Data of bool type are output as " true" or " false" strings. Dates are shown as YYYY.MM.DD HH:MI:SS.
To show dates in another format, use the TimeToString() function. Data of color type are output
either as R ,G,B string or as a color name, if this color is present in the color set.
Comment() function does not work during optimization in the Strategy Tester.
Example:
void OnTick()
{
//---
double Ask,Bid;
int Spread;
Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
Spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD);
//--- Output values in three lines
Comment(StringFormat("Show prices\nAsk = %G\nBid = %G\nSpread = %d",Ask,Bid,Spread));
}
See also
ChartSetString, ChartGetString
CryptEncode
Transforms the data from array with the specified method.
int CryptEncode(
ENUM_CRYPT_METHOD method, // method
const uchar& data[], // source array
const uchar& key[], // key
uchar& result[] // destination array
);
Parameters
method
[in] Data transformation method. Can be one of the values of ENUM _CRYPT _M ET H OD
enumeration.
data[]
[in] Source array.
key[]
[in] Key array.
result[]
[out] Destination array.
Return Value
Amount of bytes in the destination array or 0 in case of error. To obtain information about the error
call the GetLastError() function.
Example:
//+------------------------------------------------------------------+
//| ArrayToHex |
//+------------------------------------------------------------------+
string ArrayToHex(uchar &arr[],int count=-1)
{
string res="";
//--- check
if(count<0 || count>ArraySize(arr))
count=ArraySize(arr);
//--- transform to HEX string
for(int i=0; i<count; i++)
res+=StringFormat("%.2X",arr[i]);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string text="The quick brown fox jumps over the lazy dog";
string keystr="ABCDEFG";
uchar src[],dst[],key[];
//--- prepare key
StringToCharArray(keystr,key);
//--- copy text to source array src[]
StringToCharArray(text,src);
//--- print initial data
PrintFormat("Initial data: size=%d, string='%s'",ArraySize(src),CharArrayToString(src));
//--- encrypt src[] with DES 56-bit key in key[]
int res=CryptEncode(CRYPT_DES,src,key,dst);
//--- check error
if(res>0)
{
//--- print encrypted data
PrintFormat("Encoded data: size=%d %s",res,ArrayToHex(dst));
//--- decode dst[] to src[]
res=CryptDecode(CRYPT_DES,dst,key,src);
//--- check error
if(res>0)
{
//--- print decoded data
PrintFormat("Decoded data: size=%d, string='%s'",ArraySize(src),CharArrayToString(src));
}
else
Print("Error in CryptDecode. Error code=",GetLastError());
}
else
Print("Error in CryptEncode. Error code=",GetLastError());
}
See also
Array Functions, CryptDecode()
CryptDecode
Performs the inverse transformation of the data from array, tranformed by CryptEncode().
int CryptEncode(
ENUM_CRYPT_METHOD method, // method
const uchar& data[], // source array
const uchar& key[], // key
uchar& result[] // destination array
);
Parameters
method
[in] Data transformation method. Can be one of the values of ENUM _CRYPT _M ET H OD
enumeration.
data[]
[in] Source array.
key[]
[in] Key array.
result[]
[out] Destination array.
Return Value
Amount of bytes in the destination array or 0 in case of error. To obtain information about the error
call the GetLastError() function.
See also
Array Functions, CryptEncode()
DebugBreak
It is a program break point in debugging.
void DebugBreak();
Return Value
No return value.
Note
Execution of an MQL5 program is interrupted only if a program is started in a debugging mode. The
function can be used for viewing values of variables and/or for further step-by-step execution.
ExpertRemove
The function stops an Expert Advisor and unloads it from a chart.
void ExpertRemove();
Return Value
No return value.
Note
The Expert Advisor is not stopped immediately as you call ExpertR emove(); just a flag to stop the
EA operation is set. That is, any next event won't be processed, OnDeinit() will be called and the
Expert Advisor will be unloaded and removed from the chart.
Calling ExpertR emove() in the strategy tester inside the OnInit() handler cancels testing on the
current set of parameters. Such completion is considered an initialization error.
W hen calling ExpertR emove() in the strategy tester after successful initialization of an EA, a test is
completed normally with the call of OnDeinit() and OnTester(). In this case, the entire trading
statistics and an optimization criterion value are obtained, but the EA is unloaded from the test
agent's memory. This means that the agent will need time to reload the EA to test the next
optimization pass. Therefore, TesterStop() is a preferred option for an early routine completion of a
test.
Example:
//+------------------------------------------------------------------+
//| Test_ExpertRemove.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
input int ticks_to_close=20;// number of ticks before EA unload
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Print(TimeCurrent(),": " ,__FUNCTION__," reason code = ",reason);
//--- "clear" comment
Comment("");
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
static int tick_counter=0;
//---
tick_counter++;
Comment("\nBefore unloading expert advisor ",__FILE__," left",
(ticks_to_close-tick_counter)," ticks");
//--- before
if(tick_counter>=ticks_to_close)
{
ExpertRemove();
Print(TimeCurrent(),": ",__FUNCTION__," expert advisor will be unloaded");
}
Print("tick_counter =",tick_counter);
//---
}
//+------------------------------------------------------------------+
See also
Program running, Client terminal events
GetPointer
The function returns the object pointer.
void* GetPointer(
any_class anyobject // object of any class
);
Parameters
anyobject
[in] Object of any class.
Return Value
Note
Only class objects have pointers. Instances of structures and simple-type variables can't have
pointers. The class object not created using the new() operator, but, e.g., automatically created in
the array of objects, still has a pointer. But this pointer will be of the automatic type
POI NT ER_AUTOM ATIC, therefore the delete() operator can't be applied to it. Aside from that, the
type pointer doesn't differ from dynamic pointers of the POI NT ER_AUTOM ATIC type.
Since variables of structure types and simple types do not have pointers, it's prohibited to apply the
GetPointer() function to them. It's also prohibited to pass the pointer as a function argument. In all
these cases the compiler will notify an error.
An attempt to call an incorrect pointer causes the critical termination of a program. That's why the
Check Pointer() function should be called prior to using a pointer. A pointer can be incorrect in the
following cases :
This function can be used to check the validity of a pointer. A non-zero value guarantees, that the
pointer can be used for accessing.
Example:
//+------------------------------------------------------------------+
//| Check_GetPointer.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Class implementing the list element |
//+------------------------------------------------------------------+
class CItem
{
int m_id;
string m_comment;
CItem* m_next;
public:
CItem() { m_id=0; m_comment=NULL; m_next=NULL; }
~CItem() { Print("Destructor of ",m_id,
(CheckPointer(GetPointer(this))==POINTER_DYNAMIC)?
"dynamic":"non-dynamic"); }
void Initialize(int id,string comm) { m_id=id; m_comment=comm; }
void PrintMe() { Print(__FUNCTION__,":",m_id,m_comment); }
int Identifier() { return(m_id); }
CItem* Next() {return(m_next); }
void Next(CItem *item) { m_next=item; }
};
//+------------------------------------------------------------------+
//| Simplest class of the list |
//+------------------------------------------------------------------+
class CMyList
{
CItem* m_items;
public:
CMyList() { m_items=NULL; }
~CMyList() { Destroy(); }
bool InsertToBegin(CItem* item);
void Destroy();
};
//+------------------------------------------------------------------+
//| Inserts list element at the beginning |
//+------------------------------------------------------------------+
bool CMyList::InsertToBegin(CItem* item)
{
if(CheckPointer(item)==POINTER_INVALID) return(false);
//---
item.Next(m_items);
m_items=item;
//---
return(true);
}
//+------------------------------------------------------------------+
//| Deleting the list by deleting elements |
//+------------------------------------------------------------------+
void CMyList::Destroy()
{
//--- service pointer to work in a loop
CItem* item;
//--- go through the loop and try to delete dynamic pointers
while(CheckPointer(m_items)!=POINTER_INVALID)
{
item=m_items;
m_items=m_items.Next();
if(CheckPointer(item)==POINTER_DYNAMIC)
{
Print("Dynamyc object ",item.Identifier()," to be deleted");
delete (item);
}
else Print("Non-dynamic object ",item.Identifier()," cannot be deleted");
}
//---
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
CMyList list;
CItem items[10];
CItem* item;
//--- create and add into the list a dynamic object pointer
item=new CItem;
if(item!=NULL)
{
item.Initialize(100,"dynamic");
item.PrintMe();
list.InsertToBegin(item);
}
//--- add automatic pointers into the list
for(int i=0; i<10; i++)
{
items[i].Initialize(i,"automatic");
items[i].PrintMe();
item=GetPointer(items[i]);
if(CheckPointer(item)!=POINTER_INVALID)
list.InsertToBegin(item);
}
//--- add one more dynamic object pointer at the list beginning
item=new CItem;
if(item!=NULL)
{
item.Initialize(200,"dynamic");
item.PrintMe();
list.InsertToBegin(item);
}
//--- delete all the list elements
list.Destroy();
//--- all the list elements will be deleted after the script is over
//--- see the Experts tab in the terminal
See also
Object Pointers, Check ing the Object Pointer, Object Delete Operator delete
GetTickCount
The GetTick Count() function returns the number of milliseconds that elapsed since the system start.
uint GetTickCount();
Return Value
Note
Counter is limited by the restrictions of the system timer. Time is stored as an unsigned integer, so
it's overfilled every 49.7 days if a computer work s uninterruptedly.
Example:
#define MAX_SIZE 40
//+------------------------------------------------------------------+
//| Script for measuring computation time of 40 Fibonacci numbers |
//+------------------------------------------------------------------+
void OnStart()
{
//--- Remember the initial value
uint start=GetTickCount();
//--- A variable for getting the next number in the Fibonacci series
long fib=0;
//--- In loop calculate the specified amount of numbers from Fibonacci series
for(int i=0;i<MAX_SIZE;i++) fib=TestFibo(i);
//--- Get the spent time in milliseconds
uint time=GetTickCount()-start;
//--- Output a message to the Experts journal
PrintFormat("Calculating %d first Fibonacci numbers took %d ms",MAX_SIZE,time);
//--- Script completed
return;
}
//+------------------------------------------------------------------+
//| Function for getting Fibonacci number by its serial number |
//+------------------------------------------------------------------+
long TestFibo(long n)
{
//--- The first member of the Fibonacci series
if(n<2) return(1);
//--- All other members are calculated by the following formula
return(TestFibo(n-2)+TestFibo(n-1));
}
See also
GetMicrosecondCount
The GetMicrosecondCount() function returns the number of microseconds that have elapsed since the
start of MQL5-program.
ulong GetMicrosecondCount();
Return Value
Example:
//+------------------------------------------------------------------+
//| Test function |
//+------------------------------------------------------------------+
void Test()
{
int res_int=0;
double res_double=0;
//---
for(int i=0;i<10000;i++)
{
res_int+=i*i;
res_int++;
res_double+=i*i;
res_double++;
}
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
uint ui=0,ui_max=0,ui_min=INT_MAX;
ulong ul=0,ul_max=0,ul_min=INT_MAX;
//--- number of measurements
for(int count=0;count<1000;count++)
{
uint ui_res=0;
ulong ul_res=0;
//---
for(int n=0;n<2;n++)
{
//--- select measurement type
if(n==0) ui=GetTickCount();
else ul=GetMicrosecondCount();
//--- execute code
Test();
//--- add measurement result (depending on type)
if(n==0) ui_res+=GetTickCount()-ui;
else ul_res+=GetMicrosecondCount()-ul;
}
//--- calculate minimum and maximum time for both measurements
if(ui_min>ui_res) ui_min=ui_res;
if(ui_max<ui_res) ui_max=ui_res;
if(ul_min>ul_res) ul_min=ul_res;
if(ul_max<ul_res) ul_max=ul_res;
}
//---
Print("GetTickCount error(msec): ",ui_max-ui_min);
Print("GetMicrosecondCount error(msec): ",DoubleToString((ul_max-ul_min)/1000.0,2));
}
See also
MessageBox
It creates and shows a message box and manages it. A message box contains a message and header,
any combination of predefined signs and command buttons.
int MessageBox(
string text, // message text
string caption=NULL, // box header
int flags=0 // defines set of buttons in the box
);
Parameters
text
[in] Text, containing message to output.
caption=NULL
[in] Optional text to be displayed in the box header. If the parameter is empty, Expert Advisor
name is shown in the box header.
flags=0
[in] Optional flags defining appearance and behavior of a message box. Flags can be a
combination of a special group of flags.
Return Value
If the function is successfully performed, the returned value is one of values of MessageBox() return
codes.
Note
The function is not recommended for use in custom indicators, as the call to the MessageBox()
suspends the indicator's thread of execution for the whole time while waiting for the user's
response. And since all indicators for each symbol are executed in a single thread, all charts of all
timeframes for this symbol will be suspended.
PeriodSeconds
This function returns number of seconds in a period.
int PeriodSeconds(
ENUM_TIMEFRAMES period=PERIOD_CURRENT // chart period
);
Parameters
period=PERIOD_CURRENT
[in] Value of a chart period from the enumeration ENUM _TIM EFRAM ES. If the parameter isn't
specified, it returns the number of seconds of the current chart period, at which the program runs.
Return Value
See also
PlaySound
It plays a sound file.
bool PlaySound(
string filename // file name
);
Parameters
filename
[in] Path to a sound file. If filename=NULL, the playback is stopped.
Return Value
Note
The file must be located in terminal_directory\ Sounds or its sub-directory. Only WAV files are
played.
See also
R esources
Print
It enters a message in the Expert Advisor log. Parameters can be of any type.
void Print(
argument, // first value
... // next values
);
Parameters
...
[in] Any values separated by commas. The number of parameters cannot exceed 64.
Note
Arrays cannot be passed to the Print() function. Arrays must be input element-by-element.
Data of double type are shown with the accuracy of up to 16 digits after a decimal point, and can be
output either in traditional or in scientific format, depending on what entry will be more compact.
Data of float type are output with 5 digits after a decimal point. To output real numbers with
another accuracy or in a predefined format, use the PrintFormat() function.
Data of bool type are output as " true" or " false" lines. Dates are shown as YYYY.MM.DD HH:MI:SS. To
show data in another format, use TimeToString(). Data of color type are returned either as R ,G,B
line or as a color name, if this color is present in the color set.
Print() function does not work during optimization in the Strategy Tester.
Example:
void OnStart()
{
//--- Output DBL_MAX using Print(), this is equivalent to PrintFormat(%%.16G,DBL_MAX)
Print("---- how DBL_MAX looks like -----");
Print("Print(DBL_MAX)=",DBL_MAX);
//--- Now output a DBL_MAX number using PrintFormat()
PrintFormat("PrintFormat(%%.16G,DBL_MAX)=%.16G",DBL_MAX);
//--- Output to the Experts journal
// Print(DBL_MAX)=1.797693134862316e+308
// PrintFormat(%.16G,DBL_MAX)=1.797693134862316E+308
//--- Show what can happen with arithmetic operations with real types
double a=7,b=200;
Print("---- Before arithmetic operations");
Print("a=",a," b=",b);
Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));
//--- Divide a by b (7/200)
a=a/b;
//--- Now emulate restoring a value in the b variable
b=7.0/a; // It is expected that b=7.0/(7.0/200.0)=>7.0/7.0*200.0=200 - but it differs
//--- Output the newly calculated value of b
Print("----- After arithmetic operations");
Print("Print(b)=",b);
Print("Print(DoubleToString(b,16))=",DoubleToString(b,16));
//--- Output to the Experts journal
// Print(b)=200.0
// Print(DoubleToString(b,16))=199.9999999999999716 (see that b is no more equal to 200.0)
See also
DoubleToString, String Format
PrintFormat
It formats and enters sets of symbols and values in the Expert Advisor log in accordance with a preset
format.
void PrintFormat(
string format_string, // format string
... // values of simple types
);
Parameters
format_string
[in] A format string consists of simple symbols, and if the format string is followed by arguments,
it also contains format specifications.
...
[in] Any values of simple types separated by commas. Total number of parameters can't exceed 64
including the format string.
Return Value
String.
Note
PrintFormat() function does not work during optimization in the Strategy Tester.
The number, order and type of parameters must exactly match the set of qualifiers, otherwise the
print result is undefined. Instead of PrintFormat() you can use printf().
If the format string is followed by parameters, this string must contain format specifications that
denote output format of these parameters. Specification of format always starts with the percent
sign (%).
A format string is read from left to right. W hen the first format specification is met (if there is
any), the value of the first parameter after the format string is transformed and output according to
the preset specification. The second format specification calls transformation and output of the
second parameter, and so on till the format string end.
flags
+ (plus) Output of the + or - sign for The sign is shown only if the
values of sign types value is negative
width
A non-negative decimal number that sets the minimal number of output symbols of the formatted
value. If the number of output symbols is less than the specified width, the corresponding number of
spaces is added from the left or right depending on the alignment (flag –). If there is flag zero (0),
the corresponding number of zeroes is added before the output value. If the number of output
symbols is greater than the specified width, the output value is never cut off.
If an asteris k (*) is specified as width, value of int type must be indicated in the corresponding place
of the list of passed parameters. It will be used for specifying width of the output value.
precision
A non-negative decimal number that sets the output precision - number of digits after a decimal
point. As distinct from width specification, precision specification can cut off the part of fractional
type with or without rounding.
c, C Not used
h | l | ll | I32 | I64
short h d, i, o, x, or X
ushort h o, u, x, or X
int I 32 d, i, o, x, or X
uint I 32 o, u, x, or X
long I 64 d, i, o, x, or X
ulong I 64 o, u, x, or X
type
Example:
void OnStart()
{
//--- trade server name
string server=AccountInfoString(ACCOUNT_SERVER);
//--- account number
int login=(int)AccountInfoInteger(ACCOUNT_LOGIN);
//--- long value output
long leverage=AccountInfoInteger(ACCOUNT_LEVERAGE);
PrintFormat("%s %d: leverage = 1:%I64d",
server,login,leverage);
//--- account currency
string currency=AccountInfoString(ACCOUNT_CURRENCY);
//--- double value output with 2 digits after the decimal point
double equity=AccountInfoDouble(ACCOUNT_EQUITY);
PrintFormat("%s %d: account equity = %.2f %s",
server,login,equity,currency);
//--- double value output with mandatory output of the +/- sign
double profit=AccountInfoDouble(ACCOUNT_PROFIT);
PrintFormat("%s %d: current result for open positions = %+.2f %s",
server,login,profit,currency);
//--- double value output with variable number of digits after the decimal point
double point_value=SymbolInfoDouble(_Symbol,SYMBOL_POINT);
string format_string=StringFormat("%%s: point value = %%.%df",_Digits);
PrintFormat(format_string,_Symbol,point_value);
//--- int value output
int spread=(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
PrintFormat("%s: current spread in points = %d ",
_Symbol,spread);
//--- double value output in the scientific (floating point) format with 17 meaningful digits after
PrintFormat("DBL_MAX = %.17e",DBL_MAX);
//--- double value output in the scientific (floating point) format with 17 meaningful digits after
PrintFormat("EMPTY_VALUE = %.17e",EMPTY_VALUE);
//--- output using PrintFormat() with default accuracy
PrintFormat("PrintFormat(EMPTY_VALUE) = %e",EMPTY_VALUE);
//--- simple output using Print()
Print("Print(EMPTY_VALUE) = ",EMPTY_VALUE);
/* execution result
MetaQuotes-Demo 1889998: leverage = 1:100
MetaQuotes-Demo 1889998: account equity = 22139.86 USD
MetaQuotes-Demo 1889998: current result for open positions = +174.00 USD
EURUSD: point value = 0.00001
EURUSD: current spread in points = 12
DBL_MAX = 1.79769313486231570e+308
EMPTY_VALUE = 1.79769313486231570e+308
PrintFormat(EMPTY_VALUE) = 1.797693e+308
Print(EMPTY_VALUE) = 1.797693134862316e+308
*/
}
See also
StringFormat, DoubleToString, R eal types (double, float)
ResetLastError
Sets the value of the predefined variable _LastError into zero.
void ResetLastError();
Return Value
No return value.
Note
It should be noted that the GetLastError() function doesn't zero the _LastError variable. Usually the
R esetLastError() function is called before calling a function, after which an error appearance is
check ed.
ResourceCreate
Creates an image resource based on a data set. There are two variants of the function:
Creating a resource based on a file
bool ResourceCreate(
const string resource_name, // Resource name
const string path // A relative path to the file
);
bool ResourceCreate(
const string resource_name, // Resource name
const uint& data[], // Data set as an array
uint img_width, // The width of the image resource
uint img_height, // The height of the image resource
uint data_xoffset, // The horizontal rightward offset of the upper left corn
uint data_yoffset, // The vertical downward offset of the upper left corner
uint data_width, // The total width of the image based on the data set
ENUM_COLOR_FORMAT color_format // Color processing method
);
Parameters
resource_name
[in] R esource name.
data[][]
[in] A one-dimensional or two-dimensional array for creating a complete image.
img_width
[in] The width of the rectangular image area in pixels to be placed in the resource in the form of
an image. It cannot be greater than the data_width value.
img_height
[in] The height of the rectangular image area in pixels to be placed in the resource in the form of
an image.
data_xoffset
[in] The horizontal rightward offset of the rectangular area of the image.
data_yoffset
[in] The vertical downward offset of the rectangular area of the image.
data_width
[in] R equired only for one-dimensional arrays. It denotes the full width of the image from the data
set. If data_width=0, it is assumed to be equal to img_width. For two-dimensional arrays the
parameter is ignored and is assumed to be equal to the second dimension of the data[] array.
color_format
[in] Color processing method, from a value from the ENUM _COLOR_FOR M AT enumeration.
Return Value
R eturns true if successful, otherwise false. To get information about the error call the
GetLastError() function. The following errors may occur:
· 4015 – ERR_RESOUR CE_NAM E_DUPLICAT ED (identical names of the dynamic and the static
resource)
· 4016 – ERR_RESOUR CE_NOT _FOUND (the resource is not found)
· 4017 – ERR_RESOUR CE_UNS UPPOR T ED_T YPE (this type of resource is not supported)
· 4018 – ERR_RESOUR CE_NAM E_IS _TOO_LONG (the name of the resource is too long)
Note
If the second version of the function is called for creating the same resource with different width,
height and shift parameters, it does not create a new resource, but simply updates the existing one.
The first version of the function is used for uploading images and sounds from files, and the second
version is used only for the dynamic creation of images.
Images must be in the BMP format with a color depth of 24 or 32 bits. Sounds can only be in the
WAV format. The size of the resource should not exceed 16 Mb.
ENUM_COLOR_FORMAT
Identifier Description
See also
ResourceFree
The function deletes dynamically created resource (freeing the memory allocated for it).
bool ResourceFree(
const string resource_name // resource name
);
Parameters
resource_name
[in] R esource name should start with "::" .
Return Value
True if successful, otherwise false. To get information about the error, call the GetLastError()
function.
Note
R esourceFree() allows mql5 application developers to manage memory consumption when actively
work ing with resources. Graphical objects bound to the resource being deleted from the memory will
be displayed correctly after its deletion. H owever, newly created graphical objects (OBJ_BITM AP and
OBJ_BITM AP_L ABEL) will not be able to use the deleted resource.
See also
ResourceReadImage
The function reads data from the graphical resource created by R esourceCreate() function or saved in
EX5 file during compilation.
bool ResourceReadImage(
const string resource_name, // graphical resource name for reading
uint& data[], // array for receiving data from the resource
uint& width, // for receiving the image width in the resource
uint& height, // for receiving the image height in the resource
);
Parameters
resource_name
[in] Name of the graphical resource containing an image. To gain access to its own resources, the
name is used in brief form "::resourcename" . If we download a resource from a compiled EX5 file,
the full name should be used with the path relative to MQL5 directory, file and resource names –
" path\\filename.ex5::resourcename" .
data[][]
[in] One- or two-dimensional array for receiving data from the graphical resource.
img_width
[out] Graphical resource image width in pixels .
img_height
[out] Graphical resource image height in pixels .
Return Value
true if successful, otherwise false. To get information about the error, call the GetLastError()
function.
Note
If data[] array is two-dimensional and its second dimension is less than X(width) graphical resource
size, R esourceR eadImage() function returns false and reading is not performed. But if the resource
exists, actual image size is returned to width and height parameters. This will allow mak ing another
attempt to receive data from the resource.
See also
ResourceSave
Saves a resource into the specified file.
bool ResourceSave(
const string resource_name // Resource name
const string file_name // File name
);
Parameters
resource_name
[in] The name of the resource, must start with "::" .
file_name
[in] The name of the file relative to MQL5\Files.
Return Value
true – in case of success, otherwise false. For the error information call GetLastError().
Note
The function always overwrites a file and creates all the required intermediate directories in the file
name if necessary.
See also
SetReturnError
Sets the code that returns the terminal process when completing the operation.
void SetReturnError(
int ret_code // client terminal completion code
);
Parameters
ret_code
[in] The code to be returned by the client terminal process when completing the operation.
Return Value
No return value.
Note
Setting the specified ret_code return code using the SetR eturnError() function is useful for analyzing
reasons of the programmatic operation completion when launching the terminal via the command
line.
Unlik e TerminalClose(), the SetR eturnError() function does not complete the terminal operation.
Instead, it only sets the code that returns the terminal process upon its completion.
If the SetR eturnError() function is called multiple times and/or from different MQL5 programs, the
terminal returns the last set return code.
The set code is returned upon the terminal process completion except for the following cases :
· a critical error has occurred during execution;
· the TerminalClose(int ret_code) function issuing the terminal operation completion command with
a specified code has been called.
See also
Program R unning, R untime Errors, Uninitialization R eason Codes, TerminalClose
SetUserError
Sets the predefined variable _LastError into the value equal to ERR_US ER_ERR OR_FI R ST + user_error
void SetUserError(
ushort user_error, // error number
);
Parameters
user_error
[in] Error number set by a user.
Return Value
No return value.
Note
After an error has been set using the SetUserError(user_error) function, GetLastError() returns value
equal to ERR_US ER_ERR OR_FI R ST + user_error.
Example:
void OnStart()
{
//--- set error number 65537=(ERR_USER_ERROR_FIRST +1)
SetUserError(1);
//--- get last error code
Print("GetLastError = ",GetLastError());
/*
Result
GetLastError = 65537
*/
}
Sleep
The function suspends execution of the current Expert Advisor or script within a specified interval.
void Sleep(
int milliseconds // interval
);
Parameters
milliseconds
[in] Delay interval in milliseconds.
Return Value
No return value.
Note
The Sleep() function can't be called for custom indicators, because indicators are executed in the
interface thread and must not slow down it. The function has the built-in check of EA halt flag every
0.1 seconds.
TerminalClose
The function commands the terminal to complete operation.
bool TerminalClose(
int ret_code // closing code of the client terminal
);
Parameters
ret_code
[in] R eturn code, returned by the process of the client terminal at the operation completion.
Return Value
Note
The TerminalClose() function does not stop the terminal immediately, it just commands the terminal
to complete its operation.
The code of an Expert Advisor that called TerminalClose() must have all arrangements for the
immediate completion (e.g. all previously opened files must be closed in the normal mode). Call of
this function must be followed by the return operator.
The ret_code parameter allows indicating the necessary return code for analyzing reasons of the
program termination of the terminal operation when starting it from the command prompt.
Example:
MqlTick tick;
double distance;
//---
SymbolInfoTick(_Symbol,tick);
tick_counter++;
if(first_bid==0.0)
{
launch_time=tick.time;
first_bid=tick.bid;
Print("first_bid =",first_bid);
return;
}
//--- price distance in pips
distance=(tick.bid-first_bid)/_Point;
//--- show a notification to track the EA operation
string comm="From the moment of start:\r\n\x25CF elapsed seconds: "+
IntegerToString(tick.time-launch_time)+" ;"+
"\r\n\x25CF ticks received: "+(string)tick_counter+" ;"+
"\r\n\x25CF price went in points: "+StringFormat("%G",distance);
Comment(comm);
//--- section for checking condition to close the terminal
if(tick_counter>=tiks_before)
TerminalClose(0); // exit by tick counter
if(distance>pips_to_go)
TerminalClose(1); // go up by the number of pips equal to pips_to_go
if(distance<-pips_to_go)
TerminalClose(-1); // go down by the number of pips equal to pips_to_go
if(tick.time-launch_time>seconds_st)
TerminalClose(100); // termination by timeout
//---
}
See also
Program running, Execution errors, R easons for deinitialization
TesterHideIndicators
Sets the mode of displaying /hiding indicators used in an EA. The function is intended for managing
the visibility of used indicators only during testing.
void TesterHideIndicators(
bool hide // flag
);
Parameters
hide
[in] Flag for hiding indicators when testing. Set true to hide created indicators, otherwise false.
Return Value
None.
Note
By default, all indicators created in a tested EA are displayed on the visual testing chart. Besides,
these indicators are displayed on the chart that is automatically opened when testing is complete.
The TesterH ideIndicators() function allows developers to implement the ability to disable the display
of used indicators.
To disable the display of an applied indicator when testing an EA, call TesterH ideIndicators() equal
to true before creating the EA's handle – all indicators created after that are mark ed with the hide
flag. These indicators are not displayed during a visual test and on the chart that is automatically
opened upon completion of the test.
To disable the hide mode of the newly created indicators, call TesterH ideIndicators() equal to false.
Only indicators generated directly from the tested EA can be displayed on the testing chart. This rule
applies only to cases where there is not a single template in <data_folder>MQL5\ Profiles \ Templates.
If the strategy tester finds no suitable template (<EA_name>.tpl, tester.tpl or default.tpl), display of
the indicators applied in the EA is fully managed by the TesterH ideIndicators() function.
Example:
bool CSampleExpert::InitIndicators(void)
{
TesterHideIndicators(true);
//--- create MACD indicator
if(m_handle_macd==INVALID_HANDLE)
if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
{
printf("Error creating MACD indicator");
return(false);
}
TesterHideIndicators(false);
//--- create EMA indicator and add it to collection
if(m_handle_ema==INVALID_HANDLE)
if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE)
{
printf("Error creating EMA indicator");
return(false);
}
//--- succeed
return(true);
}
See also
IndicatorR elease
TesterStatistics
The function returns the value of the specified statistical parameter calculated based on testing
results.
double TesterStatistics(
ENUM_STATISTICS statistic_id // ID
);
Parameters
statistic_id
[in] The ID of the statistical parameter from the ENUM _ST ATISTICS enumeration.
Return Value
Note
The function can be called inside OnTester() or OnDeinit() in the tester. In other cases the result is
undefined.
TesterStop
Gives program operation completion command when testing.
void TesterStop();
Return Value
No return value.
Note
The TesterStop() function is designed for a routine early shutdown of an EA on a test agent – for
example, when reaching a specified number of losing trades or a preset drawdown level.
TesterStop() call is considered a normal completion of a test, therefore the OnTester() function is
called, and the entire accumulated trading statistics and optimization criterion value are submitted
to the strategy tester.
Calling ExpertR emove() in the strategy tester also means normal test completion and allows for
obtaining trading statistics, but the EA is unloaded from the agent’s memory. In this case,
performing a pass on the next set of parameters requires time in order to reload the program.
Therefore, TesterStop() is a preferred option for an early routine completion of a test.
See also
Program R unning, Testing Trading Strategies, ExpertR emove, SetR eturnError
TesterDeposit
The special function that emulates depositing funds during a test. It can be used in some money
management systems.
bool TesterDeposit(
double money // deposited sum
);
Parameters
money
[in] Money to be deposited to an account in the deposit currency.
Return Value
See also
TesterW ithdrawal
TesterWithdrawal
The special function to emulate the operation of money withdrawal in the process of testing. Can be
used in some asset management systems.
bool TesterWithdrawal(
double money // the sum to withdraw
);
Parameters
money
[in] The sum of money that we need to withdraw (in the deposit currency).
Return Value
See also
TesterDeposit
TranslateKey
R eturns a Unicode character by a virtual k ey code considering the current input language and the
status of control k eys.
short TranslateKey(
int key_code // key code for receiving a Unicode character
);
Parameters
key_code
[in] Key code.
Return Value
Unicode character in case of a successful conversion. The function returns -1 in case of an error.
Note
The function uses ToUnicodeEx to convert k eys pressed by a user into Unicode characters. An error
may occur in case ToUnicodeEx is not triggered – for example, when trying to receive the S H I FT k ey
character.
Example:
void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
{
if(id==CHARTEVENT_KEYDOWN)
{
short sym=TranslateKey((int)lparam);
//--- if the entered character is successfully converted to Unicode
if(sym>0)
Print(sym,"'",ShortToString(sym),"'");
else
Print("Error in TranslateKey for key=",lparam);
}
}
See also
Client terminal events, OnChartEvent
ZeroMemory
The function resets a variable passed to it by reference.
void ZeroMemory(
void & variable // reset variable
);
Parameters
variable
[in] [out] Variable passed by reference, you want to reset (initialize by zero values).
Return Value
No return value.
Note
If the function parameter is a string, the call will be equivalent to indicating NULL as its value.
For simple types and their arrays, as well as for structures /classes consisting of such types, this is a
simple reset.
For objects containing strings and dynamic arrays, ZeroMemory() is called for each element.
For any arrays not protected by the const modifier, this is the zeroing of all elements.
For arrays of complex objects, ZeroMemory() is called for each element.
Function Action
ArrayR esize Sets the new size in the first dimension of the
array
ArrayBsearch
Searches for a specified value in a multidimensional numeric array sorted ascending. Search is
performed through the elements of the first dimension.
int ArrayBsearch(
const double& array[], // array for search
double value // what is searched for
);
int ArrayBsearch(
const float& array[], // array for search
float value // what is searched for
);
int ArrayBsearch(
const long& array[], // array for search
long value // what is searched for
);
int ArrayBsearch(
const int& array[], // array for search
int value // what is searched for
);
int ArrayBsearch(
const short& array[], // array for search
short value // what is searched for
);
int ArrayBsearch(
const char& array[], // array for search
char value // what is searched for
);
Parameters
array[]
[in] Numeric array for search.
value
Return Value
The function returns index of a found element. If the wanted value isn't found, the function returns
the index of an element nearest in value.
Note
Binary search processes only sorted arrays. To sort numeric arrays use the ArraySort() function.
Example:
ResetLastError();
if(CopyBuffer(rsi_handle,0,InpDateStart,InpDateFinish,rsi_buff)==-1)
{
PrintFormat("Failed to copy the indicator values. Error code = %d",GetLastError());
return;
}
//--- receive the array size
size=ArraySize(rsi_buff);
//--- sort out the array
ArraySort(rsi_buff);
//--- find out the time (in percentage terms) the market was in the oversold area
double ovs=(double)ArrayBsearch(rsi_buff,InpOversoldValue)*100/(double)size;
//--- find out the time (in percentage terms) the market was in the overbought area
double ovb=(double)(size-ArrayBsearch(rsi_buff,InpOverboughtValue))*100/(double)size;
//--- form the strings for displaying the data
string str="From "+TimeToString(InpDateStart,TIME_DATE)+" to "
+TimeToString(InpDateFinish,TIME_DATE)+" the market was:";
string str_ovb="in overbought area "+DoubleToString(ovb,2)+"% of time";
string str_ovs="in oversold area "+DoubleToString(ovs,2)+"% of time";
//--- display the data on the chart
CreateLabel("top",5,60,str,clrDodgerBlue);
CreateLabel("overbought",5,35,str_ovb,clrDodgerBlue);
CreateLabel("oversold",5,10,str_ovs,clrDodgerBlue);
//--- redraw the chart
ChartRedraw(0);
//--- pause
Sleep(10000);
}
//+------------------------------------------------------------------+
//| Display comment in the bottom left corner of the chart |
//+------------------------------------------------------------------+
void CreateLabel(const string name,const int x,const int y,
const string str,const color clr)
{
//--- create the label
ObjectCreate(0,name,OBJ_LABEL,0,0,0);
//--- bind the label to the bottom left corner
ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_LOWER);
//--- change position of the anchor point
ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_LEFT_LOWER);
//--- distance from the anchor point in X-direction
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x);
//--- distance from the anchor point in Y-direction
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y);
//--- label text
ObjectSetString(0,name,OBJPROP_TEXT,str);
//--- text color
ObjectSetInteger(0,name,OBJPROP_COLOR,clr);
//--- text size
ObjectSetInteger(0,name,OBJPROP_FONTSIZE,12);
}
ArrayCopy
It copies an array into another one.
int ArrayCopy(
void& dst_array[], // destination array
const void& src_array[], // source array
int dst_start=0, // index starting from which write into destination array
int src_start=0, // first index of a source array
int count=WHOLE_ARRAY // number of elements
);
Parameters
dst_array[]
[out] Destination array
src_array[]
[in] Source array
dst_start=0
[in] Starting index from the destination array. By default, start index is 0.
src_start=0
[in] Starting index for the source array. By default, start index is 0.
count=WHOLE_ARRAY
[in] Number of elements that should be copied. By default, the whole array is copied
(count=WH OL E_ARRAY).
Return Value
Note
If count<0 or count>src_size-src_start, all the remaining array part is copied. Arrays are copied from
left to right. For series arrays, the starting position is correctly defined adjusted for copying from
left to right.
If arrays are of different types, during copying it tries to transform each element of a source array
into the type of the destination array. A string array can be copied into a string array only. Array of
classes and structures containing objects that require initialization aren't copied. An array of
structures can be copied into an array of the same type only.
For dynamic arrays with indexing as in timeseries, the size of a destination array is automatically
increased to the amount of copied data (if the latter exceeds the array size). The destination array
size is not decreased automatically.
Example:
#property description "The indicator highlights the candlesticks that are local"
#property description "highs and lows. Interval length for finding"
#property description "extreme values should be found using an input parameters."
PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- set straight indexing in time series
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- variable of the bar calculation start
int start=prev_calculated;
//--- calculation is not performed for the first InpNum*2 bars
if(start==0)
{
start+=InpNum*2;
ExtStart=0;
ExtCount=0;
}
//--- if the bar has just formed, check the next potential extremum
if(rates_total-start==1)
start--;
//--- bar index to be checked for the extremum
int ext;
//--- indicator value calculation loop
for(int i=start;i<rates_total-1;i++)
{
//--- initially on i bar without drawing
ExtOpen[i]=0;
ExtHigh[i]=0;
ExtLow[i]=0;
ExtClose[i]=0;
//--- extremum index for check
ext=i-InpNum;
//--- check for the local maximum
if(IsMax(high,ext))
{
//--- highlight an extremum candlestick
ExtOpen[ext]=open[ext];
ExtHigh[ext]=high[ext];
ExtLow[ext]=low[ext];
ExtClose[ext]=close[ext];
ExtColor[ext]=1;
//--- highlight other candles up to the extremum with a neutral color
FillCandles(open,high,low,close);
//--- change the variable colors
ExtStart=ext+1;
ExtCount=0;
//--- pass to the next iteration
continue;
}
//--- check for the local minimum
if(IsMin(low,ext))
{
//--- highlight an extremum candlestick
ExtOpen[ext]=open[ext];
ExtHigh[ext]=high[ext];
ExtLow[ext]=low[ext];
ExtClose[ext]=close[ext];
ExtColor[ext]=2;
//--- highlight other candles up to the extremum with a neutral color
FillCandles(open,high,low,close);
//--- change variable values
ExtStart=ext+1;
ExtCount=0;
//--- pass to the next iteration
continue;
}
//--- increase the number of non-extremums at the interval
ExtCount++;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Check if the current array element is a local high |
//+------------------------------------------------------------------+
bool IsMax(const double &price[],const int ind)
{
//--- interval start variable
int i=ind-InpNum;
//--- interval end period
int finish=ind+InpNum+1;
//--- check for the first half of the interval
for(;i<ind;i++)
{
if(price[ind]<=price[i])
return(false);
}
//--- check for the second half of the interval
for(i=ind+1;i<finish;i++)
{
if(price[ind]<=price[i])
return(false);
}
//--- this is an extremum
return(true);
}
//+------------------------------------------------------------------+
//| Check if the current array element is a local low |
//+------------------------------------------------------------------+
bool IsMin(const double &price[],const int ind)
{
//--- interval start variable
int i=ind-InpNum;
//--- interval end variable
int finish=ind+InpNum+1;
//--- check for the first half of the interval
for(;i<ind;i++)
{
if(price[ind]>=price[i])
return(false);
}
//--- check for the second half of the interval
for(i=ind+1;i<finish;i++)
{
if(price[ind]>=price[i])
return(false);
}
//--- this is an extremum
return(true);
}
ArrayCompare
The function returns the result of comparing two arrays of the same type. It can be used to compare
arrays of simple types or custom structures without complex objects, that is the custom structures
that do not contain strings, dynamic arrays, classes and other structures with complex objects.
int ArrayCompare(
const void& array1[], // first array
const void& array2[], // second array
int start1=0, // initial offset in the first array
int start2=0, // initial offset in the second array
int count=WHOLE_ARRAY // number of elements for comparison
);
Parameters
array1[]
[in] First array.
array2[]
[in] Second array.
start1=0
[in] The element's initial index in the first array, from which comparison starts. The default start
index - 0.
start2=0
[in] The element's initial index in the second array, from which comparison starts. The default
start index - 0.
count=WHOLE_ARRAY
[in] Number of elements to be compared. All elements of both arrays participate in comparison by
default (count=WH OL E_ARRAY).
Return Value
· -1, if array1[] less than array2[]
· 0, if array1[] equal to array2[]
· 1, if array1[] more than array2[]
· -2, if an error occurs due to incompatibility of the types of compared arrays or if start1, start2 or
count values lead to falling outside the array.
Note
The function will not return 0 (the arrays will not be considered equal) if the arrays differ in size and
count=WH OL E_ARRAY for the case when one array is a faithful subset of another one. In this case,
the result of comparing the sizes of that arrays will be returned: -1, if the size of array1[] is less
than the size of array2[] , otherwise 1.
ArrayFree
It frees up a buffer of any dynamic array and sets the size of the zero dimension to 0.
void ArrayFree(
void& array[] // array
);
Parameters
array[]
[in] Dynamic array.
Return Value
No return value.
Note
The need for using ArrayFree() function may not appear too often considering that all used memory
is freed at once and main work with the arrays comprises the access to the indicator buffers. The
sizes of the buffers are automatically managed by the terminal's executive subsystem.
In case it is necessary to manually manage the memory in complex dynamic environment of the
application, ArrayFree() function allows users to free the memory occupied by the already
unnecessary dynamic array explicitly and immediately.
Example:
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Label.mqh>
#include <Controls\ComboBox.mqh>
//--- predefined constants
#define X_START 0
#define Y_START 0
#define X_SIZE 280
#define Y_SIZE 300
//+------------------------------------------------------------------+
//| Dialog class for working with memory |
//+------------------------------------------------------------------+
class CMemoryControl : public CAppDialog
{
private:
//--- array size
int m_arr_size;
//--- arrays
char m_arr_char[];
int m_arr_int[];
float m_arr_float[];
double m_arr_double[];
long m_arr_long[];
//--- labels
CLabel m_lbl_memory_physical;
CLabel m_lbl_memory_total;
CLabel m_lbl_memory_available;
CLabel m_lbl_memory_used;
CLabel m_lbl_array_size;
CLabel m_lbl_array_type;
CLabel m_lbl_error;
CLabel m_lbl_change_type;
CLabel m_lbl_add_size;
//--- buttons
CButton m_button_add;
CButton m_button_free;
//--- combo boxes
CComboBox m_combo_box_step;
CComboBox m_combo_box_type;
//--- current value of the array type from the combo box
int m_combo_box_type_value;
public:
CMemoryControl(void);
~CMemoryControl(void);
//--- class object creation method
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const
//--- handler of chart events
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &spa
protected:
//--- create labels
bool CreateLabel(CLabel &lbl,const string name,const int x,const int y,const string
//--- create control elements
bool CreateButton(CButton &button,const string name,const int x,const int y,const s
bool CreateComboBoxStep(void);
bool CreateComboBoxType(void);
//--- event handlers
void OnClickButtonAdd(void);
void OnClickButtonFree(void);
void OnChangeComboBoxType(void);
//--- methods for working with the current array
void CurrentArrayFree(void);
bool CurrentArrayAdd(void);
};
//+------------------------------------------------------------------+
//| Free memory of the current array |
//+------------------------------------------------------------------+
void CMemoryControl::CurrentArrayFree(void)
{
//--- reset array size
m_arr_size=0;
//| Destructor |
//+------------------------------------------------------------------+
CMemoryControl::~CMemoryControl(void)
{
}
//+------------------------------------------------------------------+
//| Class object creation method |
//+------------------------------------------------------------------+
bool CMemoryControl::Create(const long chart,const string name,const int subwin,
const int x1,const int y1,const int x2,const int y2)
{
//--- create base class object
if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- prepare strings for labels
string str_physical="Memory physical = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_PHYSICAL)+"
string str_total="Memory total = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_TOTAL)+" Mb";
string str_available="Memory available = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_AVAILABLE
string str_used="Memory used = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_USED)+" Mb";
//--- create labels
if(!CreateLabel(m_lbl_memory_physical,"physical_label",X_START+10,Y_START+5,str_physical,12,clrB
return(false);
if(!CreateLabel(m_lbl_memory_total,"total_label",X_START+10,Y_START+30,str_total,12,clrBlack))
return(false);
if(!CreateLabel(m_lbl_memory_available,"available_label",X_START+10,Y_START+55,str_available,12,
return(false);
if(!CreateLabel(m_lbl_memory_used,"used_label",X_START+10,Y_START+80,str_used,12,clrBlack))
return(false);
if(!CreateLabel(m_lbl_array_type,"type_label",X_START+10,Y_START+105,"Array type = double",12,cl
return(false);
if(!CreateLabel(m_lbl_array_size,"size_label",X_START+10,Y_START+130,"Array size = 0",12,clrBlac
return(false);
if(!CreateLabel(m_lbl_error,"error_label",X_START+10,Y_START+155,"",12,clrRed))
return(false);
if(!CreateLabel(m_lbl_change_type,"change_type_label",X_START+10,Y_START+185,"Change type",10,cl
return(false);
if(!CreateLabel(m_lbl_add_size,"add_size_label",X_START+10,Y_START+210,"Add to array",10,clrBlac
return(false);
//--- create control elements
if(!CreateButton(m_button_add,"add_button",X_START+15,Y_START+245,"Add",12,clrBlue))
return(false);
if(!CreateButton(m_button_free,"free_button",X_START+75,Y_START+245,"Free",12,clrBlue))
return(false);
if(!CreateComboBoxType())
return(false);
if(!CreateComboBoxStep())
return(false);
//--- initialize the variable
m_arr_size=0;
if(!Add(m_combo_box_step))
return(false);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Create a combo box for the array type |
//+------------------------------------------------------------------+
bool CMemoryControl::CreateComboBoxType(void)
{
//--- create the combo box
if(!m_combo_box_type.Create(m_chart_id,"type_combobox",m_subwin,X_START+100,Y_START+210,X_START+
return(false);
//--- add elements to the combo box
if(!m_combo_box_type.ItemAdd("char",0))
return(false);
if(!m_combo_box_type.ItemAdd("int",1))
return(false);
if(!m_combo_box_type.ItemAdd("float",2))
return(false);
if(!m_combo_box_type.ItemAdd("double",3))
return(false);
if(!m_combo_box_type.ItemAdd("long",4))
return(false);
//--- set the current combo box element
if(!m_combo_box_type.SelectByValue(3))
return(false);
//--- store the current combo box element
m_combo_box_type_value=3;
//--- add the combo box to control elements
if(!Add(m_combo_box_type))
return(false);
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Create a label |
//+------------------------------------------------------------------+
bool CMemoryControl::CreateLabel(CLabel &lbl,const string name,const int x,
const int y,const string str,const int font_size,
const int clr)
{
//--- create a label
if(!lbl.Create(m_chart_id,name,m_subwin,x,y,0,0))
return(false);
//--- text
if(!lbl.Text(str))
return(false);
//--- font size
if(!lbl.FontSize(font_size))
return(false);
//--- color
if(!lbl.Color(clr))
return(false);
//--- add the label to control elements
if(!Add(lbl))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of clicking "Add" button event |
//+------------------------------------------------------------------+
void CMemoryControl::OnClickButtonAdd(void)
{
//--- increase the array size
m_arr_size+=(int)m_combo_box_step.Value();
//--- attempt to allocate memory for the current array
if(CurrentArrayAdd())
{
//--- memory allocated, display the current status on the screen
m_lbl_memory_available.Text("Memory available = "+(string)TerminalInfoInteger(TERMINAL_MEMORY
m_lbl_memory_used.Text("Memory used = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_USED)+" M
m_lbl_array_size.Text("Array size = "+IntegerToString(m_arr_size));
m_lbl_error.Text("");
}
else
{
//--- failed to allocate memory, display the error message
m_lbl_error.Text("Array is too large, error!");
//--- return the previous array size
m_arr_size-=(int)m_combo_box_step.Value();
}
}
//+------------------------------------------------------------------+
//| Handler of clicking "Free" button event |
//+------------------------------------------------------------------+
void CMemoryControl::OnClickButtonFree(void)
{
//--- free the memory of the current array
CurrentArrayFree();
//--- display the current status on the screen
m_lbl_memory_available.Text("Memory available = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_AV
m_lbl_memory_used.Text("Memory used = "+(string)TerminalInfoInteger(TERMINAL_MEMORY_USED)+" Mb")
m_lbl_array_size.Text("Array size = 0");
m_lbl_error.Text("");
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
ExtDialog.ChartEvent(id,lparam,dparam,sparam);
}
ArrayGetAsSeries
It check s direction of an array index.
bool ArrayGetAsSeries(
const void& array[] // array for checking
);
Parameters
array
[in] Check ed array.
Return Value
R eturns true, if the specified array has the AS _S ER IES flag set, i.e. access to the array is performed
back to front as in timeseries. A timeseries differs from a usual array in that the indexing of
timeseries elements is performed from its end to beginning (from the newest data to old).
Note
To check whether an array belongs to timeseries, use the ArrayIsSeries() function. Arrays of price
data passed as input parameters into the OnCalculate() function do not obligatorily have the
indexing direction the same as in timeseries. The necessary indexing direction can be set using the
ArraySetAsSeries() function.
Example:
//--- work at the last bar if the indicator values have already been calculated at the previous tic
if(prev_calculated>0)
start--;
//--- define indexing direction in arrays
bool as_series_first=ArrayGetAsSeries(first);
bool as_series_second=ArrayGetAsSeries(second);
bool as_series_buffer=ArrayGetAsSeries(buffer);
//--- replace indexing direction with direct one if necessary
if(as_series_first)
ArraySetAsSeries(first,false);
if(as_series_second)
ArraySetAsSeries(second,false);
if(as_series_buffer)
ArraySetAsSeries(buffer,false);
//--- calculate indicator values
for(int i=start;i<rates_total;i++)
buffer[i]=MathAbs(first[i]-second[i]);
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- bind indicator buffers
SetIndexBuffer(0,ExtBuffer);
//--- set indexing element in the indicator buffer
ArraySetAsSeries(ExtBuffer,InpAsSeries);
//--- check for what prices the indicator is calculated
if(InpPrices)
{
//--- Open and Close prices
PlotIndexSetString(0,PLOT_LABEL,"BodySize");
//--- set the indicator color
PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrOrange);
}
else
{
//--- High and Low prices
PlotIndexSetString(0,PLOT_LABEL,"ShadowSize");
//--- set the indicator color
PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrDodgerBlue);
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
See also
Access to timeseries, ArraySetAsSeries
ArrayInitialize
The function initializes a numeric array by a preset value.
int ArrayInitialize(
char array[], // initialized array
char value // value that will be set
);
int ArrayInitialize(
short array[], // initialized array
short value // value that will be set
);
int ArrayInitialize(
int array[], // initialized array
int value // value that will be set
);
int ArrayInitialize(
long array[], // initialized array
long value // value that will be set
);
int ArrayInitialize(
float array[], // initialized array
float value // value that will be set
);
int ArrayInitialize(
double array[], // initialized array
double value // value that will be set
);
int ArrayInitialize(
bool array[], // initialized array
bool value // value that will be set
);
int ArrayInitialize(
uint array[], // initialized array
uint value // value that will be set
);
Parameters
array[]
[out] Numeric array that should be initialized.
value
[in] New value that should be set to all array elements.
Return Value
Note
The ArrayR esize() function allows to set size of an array with a reserve for further expansion
without the physical relocation of memory. It is implemented for the better performance, because
the operations of memory relocation are reasonably slow.
Initialization of the array using ArrayInitialize(array, init_val) doesn't mean the initialization with
the same value of reserve elements allocated for this array. At further expanding of the array using
the ArrayR esize() function, the elements will be added at the end of the array, their values will be
undefined and in most cases will not be equal to init_value.
Example:
void OnStart()
{
//--- dynamic array
double array[];
//--- let's set the array size for 100 elements and reserve a buffer for another 10 elements
ArrayResize(array,100,10);
//--- initialize the array elements with EMPTY_VALUE=DBL_MAX value
ArrayInitialize(array,EMPTY_VALUE);
Print("Values of 10 last elements after initialization");
for(int i=90;i<100;i++) printf("array[%d] = %G",i,array[i]);
//--- expand the array by 5 elements
ArrayResize(array,105);
Print("Values of 10 last elements after ArrayResize(array,105)");
//--- values of 5 last elements are obtained from reserve buffer
for(int i=95;i<105;i++) printf("array[%d] = %G",i,array[i]);
}
ArrayFill
The function fills an array with the specified value.
void ArrayFill(
void& array[], // array
int start, // starting index
int count, // number of elements to fill
void value // value
);
Parameters
array[]
[out] Array of simple type (char, uchar, short, ushort, int, uint, long, ulong, bool, color, datetime,
float, double).
start
[in] Starting index. In such a case, specified AS _S ER IES flag is ignored.
count
[in] Number of elements to fill.
value
[in] Value to fill the array with.
Return Value
No return value.
Note
W hen ArrayFill() function is called, normal indexation direction (from left to right) is always implied.
It means that the change of the order of access to the array elements using ArraySetAsSeries()
function is ignored.
Example:
void OnStart()
{
//--- declare dynamic array
int a[];
//--- set size
ArrayResize(a,10);
//--- fill first 5 elements with 123
ArrayFill(a,0,5,123);
//--- fill next 5 elements with 456
ArrayFill(a,5,5,456);
ArrayIsDynamic
The function check s whether an array is dynamic.
bool ArrayIsDynamic(
const void& array[] // checked array
);
Parameters
array[]
[in] Check ed array.
Return Value
Example:
#property description "This indicator does not calculate values. It makes a single attempt to"
#property description "apply the call of ArrayFree() function to three arrays: dynamic one, static
#property description "an indicator buffer. Results are shown in Experts journal."
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- global variables
double ExtDynamic[]; // dynamic array
double ExtStatic[100]; // static array
bool ExtFlag=true; // flag
double ExtBuff[]; // indicator buffer
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- allocate memory for the array
ArrayResize(ExtDynamic,100);
//--- indicator buffers mapping
SetIndexBuffer(0,ExtBuff);
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
//--- perform a single analysis
if(ExtFlag)
{
//--- attempt to free memory for arrays
//--- 1. Dynamic array
Print("+============================+");
Print("1. Check dynamic array:");
Print("Size before memory is freed = ",ArraySize(ExtDynamic));
Print("Is this a dynamic array = ",ArrayIsDynamic(ExtDynamic) ? "Yes" : "No");
//--- attempt to free array memory
ArrayFree(ExtDynamic);
Print("Size after memory is freed = ",ArraySize(ExtDynamic));
//--- 2. Static array
Print("2. Check static array:");
Print("Size before memory is freed = ",ArraySize(ExtStatic));
Print("Is this a dynamic array = ",ArrayIsDynamic(ExtStatic) ? "Yes" : "No");
//--- attempt to free array memory
ArrayFree(ExtStatic);
Print("Size after memory is freed = ",ArraySize(ExtStatic));
//--- 3. Indicator buffer
Print("3. Check indicator buffer:");
Print("Size before memory is freed = ",ArraySize(ExtBuff));
Print("Is this a dynamic array = ",ArrayIsDynamic(ExtBuff) ? "Yes" : "No");
//--- attempt to free array memory
ArrayFree(ExtBuff);
Print("Size after memory is freed = ",ArraySize(ExtBuff));
//--- change the flag value
ExtFlag=false;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
See also
Access to timeseries and indicators
ArrayIsSeries
The function check s whether an array is a timeseries.
bool ArrayIsSeries(
const void& array[] // checked array
);
Parameters
array[]
[in] Check ed array.
Return Value
It returns true, if a check ed array is an array timeseries, otherwise it returns false. Arrays passed as
a parameter to the OnCalculate() function must be check ed for the order of accessing the array
elements by ArrayGetAsSeries().
Example:
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "Label1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- indicator buffers
double Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
//---
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
See also
Access to timeseries and indicators
ArrayMaximum
Searches for the largest element in the first dimension of a multidimensional numeric array.
int ArrayMaximum(
const void& array[], // array for search
int start=0, // index to start checking with
int count=WHOLE_ARRAY // number of checked elements
);
Parameters
array[]
[in] A numeric array, in which search is made.
start=0
[in] Index to start check ing with.
count=WHOLE_ARRAY
[in] Number of elements for search. By default, searches in the entire array
(count=WH OL E_ARRAY).
Return Value
The function returns an index of a found element tak ing into account the array serial. In case of
failure it returns -1.
Note
The AS _S ER I ES flag value is tak en into account while searching for a maximum.
Example:
#property description "The indicator displays larger timeframe's candlesticks on the current one."
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 16
#property indicator_plots 8
//---- plot 1
#property indicator_label1 "BearBody"
#property indicator_color1 clrSeaGreen,clrSeaGreen
//---- plot 2
#property indicator_label2 "BearBodyEnd"
#property indicator_color2 clrSeaGreen,clrSeaGreen
//---- plot 3
#property indicator_label3 "BearShadow"
#property indicator_color3 clrSalmon,clrSalmon
//---- plot 4
#property indicator_label4 "BearShadowEnd"
#property indicator_color4 clrSalmon,clrSalmon
//---- plot 5
#property indicator_label5 "BullBody"
#property indicator_color5 clrOlive,clrOlive
//---- plot 6
#property indicator_label6 "BullBodyEnd"
#property indicator_color6 clrOlive,clrOlive
//---- plot 7
#property indicator_label7 "BullShadow"
#property indicator_color7 clrSkyBlue,clrSkyBlue
//---- plot 8
#property indicator_label8 "BullShadowEnd"
#property indicator_color8 clrSkyBlue,clrSkyBlue
//--- predefined constant
#define INDICATOR_EMPTY_VALUE 0.0
//--- input parameters
input ENUM_TIMEFRAMES InpPeriod=PERIOD_H4; // Time frame for the indicator calculation
input datetime InpDateStart=D'2013.01.01 00:00'; // Analysis start date
//--- indicator buffers for bearish candlesticks
double ExtBearBodyFirst[];
double ExtBearBodySecond[];
double ExtBearBodyEndFirst[];
double ExtBearBodyEndSecond[];
double ExtBearShadowFirst[];
double ExtBearShadowSecond[];
double ExtBearShadowEndFirst[];
double ExtBearShadowEndSecond[];
//--- indicator buffers for bullish candlesticks
double ExtBullBodyFirst[];
double ExtBullBodySecond[];
double ExtBullBodyEndFirst[];
double ExtBullBodyEndSecond[];
double ExtBullShadowFirst[];
double ExtBullShadowSecond[];
double ExtBullShadowEndFirst[];
double ExtBullShadowEndSecond[];
//--- global variables
datetime ExtTimeBuff[]; // larger time frame's time buffer
int ExtSize=0; // time buffer size
int ExtCount=0; // index inside time buffer
int ExtStartPos=0; // initial position for the indicator calculation
bool ExtStartFlag=true; // auxiliary flag for receiving the initial position
datetime ExtCurrentTime[1]; // last time of the larger time frame's bar generation
datetime ExtLastTime; // last time from the larger time frame, for which the calculation is
bool ExtBearFlag=true; // flag for defining the order of writing the data to bearish indicato
bool ExtBullFlag=true; // flag for defining the order of writing the data to bullish indicato
int ExtIndexMax=0; // index of the maximum element in the array
int ExtIndexMin=0; // index of the minimum element in the array
int ExtDirectionFlag=0; // price movement direction for the current candlestick
//--- shift between the candlestick's open and close price for correct drawing
//--- if close and open prices are equal, use the shift for correct display
if(high[index_max]!=low[index_min])
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,open
open[start]-ExtEmptyBodySize,high[index_max],low[index_min],start,count,ExtBea
else
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,
open[start],open[start]-ExtEmptyBodySize,high[index_max],
high[index_max]-ExtEmptyBodySize,start,count,ExtBearFlag);
}
//+------------------------------------------------------------------+
//| Fill out the end of the candlestick |
//+------------------------------------------------------------------+
void FillCandleEnd(const double &open[],const double &close[],
const double &high[],const double &low[],
const int start,const int last,const int fill_index,
const int index_max,const int index_min)
{
//--- do not draw in case of a single bar
if(last-start==0)
return;
//--- if the close price at the first bar exceeds the one at the last bar, the candlestick is beari
if(open[start]>close[last])
{
//--- generate the end of the candlestick
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEnd
open[start],close[last],high[index_max],low[index_min],fill_index,ExtBearFlag);
//--- exit the function
return;
}
//--- if the close price at the first bar is less than the one at the last bar, the candlestick is
if(open[start]<close[last])
{
//--- generate the end of the candlestick
FormCandleEnd(ExtBullBodyEndFirst,ExtBullBodyEndSecond,ExtBullShadowEndFirst,ExtBullShadowEnd
close[last],open[start],high[index_max],low[index_min],fill_index,ExtBullFlag);
//--- exit the function
return;
}
//--- if you are in this part of the function, the open price at the first bar is equal to
//--- the close price at the last bar; such candlestick is considered bearish
//--- generate the end of the candlestick
if(high[index_max]!=low[index_min])
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEnd
open[start]-ExtEmptyBodySize,high[index_max],low[index_min],fill_index,ExtBearF
else
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEnd
open[start]-ExtEmptyBodySize,high[index_max],high[index_max]-ExtEmptyBodySize,f
}
//+------------------------------------------------------------------+
{
//--- in case there are no calculated bars yet
if(prev_calculated==0)
{
//--- receive larger time frame's bars arrival time
if(!GetTimeData())
return(0);
}
//--- set direct indexing
ArraySetAsSeries(time,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(close,false);
//--- start variable for calculation of bars
int start=prev_calculated;
//--- if the bar is generated, recalculate the indicator value on it
if(start!=0 && start==rates_total)
start--;
//--- the loop for calculating the indicator values
for(int i=start;i<rates_total;i++)
{
//--- fill i elements of the indicator buffers by empty values
FillIndicatorBuffers(i);
//--- perform calculation for bars starting from InpDateStart date
if(time[i]>=InpDateStart)
{
//--- define position, from which the values are to be displayed, for the first time
if(ExtStartFlag)
{
//--- store the number of the initial bar
ExtStartPos=i;
//--- define the first date from the larger time frame exceeding time[i]
while(time[i]>=ExtTimeBuff[ExtCount])
if(ExtCount<ExtSize-1)
ExtCount++;
//--- change the value of the flag in order not to run into this block again
ExtStartFlag=false;
}
//--- check if there are still any elements in the array
if(ExtCount<ExtSize)
{
//--- wait for the current time frame's value to reach the larger time frame's one
if(time[i]>=ExtTimeBuff[ExtCount])
{
//--- draw the main part of the candlestick (without filling out the area between th
FillCandleMain(open,close,high,low,ExtStartPos,i-1,i-2,ExtIndexMax,ExtIndexMin);
//--- fill out the end of the candlestick (the area between the last and the penulti
FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
//--- shift the initial position for drawing the next candlestick
ExtStartPos=i;
//--- increase the array counter
ExtCount++;
}
else
continue;
}
else
{
//--- reset the array values
ResetLastError();
//--- receive the last date from the larger time frame
if(CopyTime(Symbol(),InpPeriod,0,1,ExtCurrentTime)==-1)
{
Print("Data copy error, code = ",GetLastError());
return(0);
}
//--- if the new date is later, stop generating the candlestick
if(ExtCurrentTime[0]>ExtLastTime)
{
//--- clear the area between the last and penultimate bars in the main indicator buf
ClearEndOfBodyMain(i-1);
//--- fill out the area using auxiliary indicator buffers
FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
//--- shift the initial position for drawing the next candlestick
ExtStartPos=i;
//--- reset price direction flag
ExtDirectionFlag=0;
//--- store the new last date
ExtLastTime=ExtCurrentTime[0];
}
else
{
//--- generate the candlestick
FillCandleMain(open,close,high,low,ExtStartPos,i,i,ExtIndexMax,ExtIndexMin);
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Check correctness of the specified indicator period |
//+------------------------------------------------------------------+
bool CheckPeriod(int current_period,int high_period)
{
//--- the indicator period should exceed the timeframe on which it is displayed
if(current_period>=high_period)
{
Print("Error! The value of the indicator period should exceed the value of the current time f
return(false);
}
//--- if the indicator period is one week or month, the period is correct
if(high_period>32768)
return(true);
//--- convert period values to minutes
if(high_period>30)
high_period=(high_period-16384)*60;
if(current_period>30)
current_period=(current_period-16384)*60;
//--- the indicator period should be multiple of the time frame it is displayed on
if(high_period%current_period!=0)
{
Print("Error! The value of the indicator period should be multiple of the value of the curren
return(false);
}
//--- the indicator period should exceed the time frame it is displayed on 3 or more times
if(high_period/current_period<3)
{
Print("Error! The indicator period should exceed the current time frame 3 or more times!");
return(false);
}
//--- the indicator period is correct for the current time frame
return(true);
}
//+------------------------------------------------------------------+
//| Receive time data from the larger time frame |
//+------------------------------------------------------------------+
bool GetTimeData(void)
{
//--- reset the error value
ResetLastError();
//--- copy all data for the current time
if(CopyTime(Symbol(),InpPeriod,InpDateStart,TimeCurrent(),ExtTimeBuff)==-1)
{
//--- receive the error code
int code=GetLastError();
//--- print out the error message
PrintFormat("Data copy error! %s",code==4401
? "History is still being uploaded!"
: "Code = "+IntegerToString(code));
//--- return false to make a repeated attempt to download data
return(false);
}
//--- receive the array size
ExtSize=ArraySize(ExtTimeBuff);
if(flag)
{
//--- generate the end of the candlestick's body
FormEnd(body_fst,body_snd,fst_value,snd_value,end);
//--- generate the end of the candlestick's shadow
FormEnd(shadow_fst,shadow_snd,fst_extremum,snd_extremum,end);
//--- change the flag's value to the opposite one
flag=false;
}
else
{
//--- generate the end of the candlestick's body
FormEnd(body_fst,body_snd,snd_value,fst_value,end);
//--- generate the end of the candlestick's shadow
FormEnd(shadow_fst,shadow_snd,snd_extremum,fst_extremum,end);
//--- change the flag's value to the opposite one
flag=true;
}
}
//+---------------------------------------------------------------------------------+
//| Clear the end of the candlestick (the area between the last and the penultimate |
//| bar) |
//+---------------------------------------------------------------------------------+
void ClearEndOfBodyMain(const int ind)
{
ClearCandle(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,ind,1);
ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,ind,1);
}
//+--------------------------------------------------------------------------+
//| Clear the candlestick |
//+--------------------------------------------------------------------------+
void ClearCandle(double &body_fst[],double &body_snd[],double &shadow_fst[],
double &shadow_snd[],const int start,const int count)
{
//--- check
if(count!=0)
{
//--- fill indicator buffers with empty values
ArrayFill(body_fst,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(body_snd,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(shadow_fst,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(shadow_snd,start,count,INDICATOR_EMPTY_VALUE);
}
}
//+--------------------------------------------------------------------------+
//| Generate the main part of the candlestick |
//+--------------------------------------------------------------------------+
void FormMain(double &fst[],double &snd[],const double fst_value,
const double snd_value,const int start,const int count)
{
//--- check
if(count!=0)
{
//--- fill indicator buffers with values
ArrayFill(fst,start,count,fst_value);
ArrayFill(snd,start,count,snd_value);
}
}
//+-----------------------------------------------------------------------------+
//| Generate the end of the candlestick |
//+-----------------------------------------------------------------------------+
void FormEnd(double &fst[],double &snd[],const double fst_value,
const double snd_value,const int last)
{
//--- fill indicator buffers with values
ArrayFill(fst,last-1,2,fst_value);
ArrayFill(snd,last-1,2,snd_value);
}
//+------------------------------------------------------------------+
//| Fill i element of the indicator buffers by empty values |
//+------------------------------------------------------------------+
void FillIndicatorBuffers(const int i)
{
//--- set an empty value in the cell of the indicator buffers
ExtBearBodyFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodySecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodySecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
}
ArrayMinimum
Searches for the lowest element in the first dimension of a multidimensional numeric array.
int ArrayMinimum(
const void& array[], // array for search
int start=0, // index to start checking with
int count=WHOLE_ARRAY // number of checked elements
);
Parameters
array[]
[in] A numeric array, in which search is made.
start=0
[in] Index to start check ing with.
count=WHOLE_ARRAY
[in] Number of elements for search. By default, searches in the entire array
(count=WH OL E_ARRAY).
Return Value
The function returns an index of a found element tak ing into account the array serial. In case of
failure it returns -1.
Note
The AS _S ER I ES flag value is tak en into account while searching for a minimum.
Example:
#property description "The indicator displays larger timeframe's candlesticks on the current one."
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 16
#property indicator_plots 8
//---- plot 1
#property indicator_label1 "BearBody"
#property indicator_color1 clrSeaGreen,clrSeaGreen
//---- plot 2
#property indicator_label2 "BearBodyEnd"
#property indicator_color2 clrSeaGreen,clrSeaGreen
//---- plot 3
#property indicator_label3 "BearShadow"
#property indicator_color3 clrSalmon,clrSalmon
//---- plot 4
#property indicator_label4 "BearShadowEnd"
#property indicator_color4 clrSalmon,clrSalmon
//---- plot 5
#property indicator_label5 "BullBody"
#property indicator_color5 clrOlive,clrOlive
//---- plot 6
#property indicator_label6 "BullBodyEnd"
#property indicator_color6 clrOlive,clrOlive
//---- plot 7
#property indicator_label7 "BullShadow"
#property indicator_color7 clrSkyBlue,clrSkyBlue
//---- plot 8
#property indicator_label8 "BullShadowEnd"
#property indicator_color8 clrSkyBlue,clrSkyBlue
//--- predefined constant
#define INDICATOR_EMPTY_VALUE 0.0
//--- input parameters
input ENUM_TIMEFRAMES InpPeriod=PERIOD_H4; // Time frame for the indicator calculation
input datetime InpDateStart=D'2013.01.01 00:00'; // Analysis start date
//--- indicator buffers for bearish candlesticks
double ExtBearBodyFirst[];
double ExtBearBodySecond[];
double ExtBearBodyEndFirst[];
double ExtBearBodyEndSecond[];
double ExtBearShadowFirst[];
double ExtBearShadowSecond[];
double ExtBearShadowEndFirst[];
double ExtBearShadowEndSecond[];
//--- indicator buffers for bullish candlesticks
double ExtBullBodyFirst[];
double ExtBullBodySecond[];
double ExtBullBodyEndFirst[];
double ExtBullBodyEndSecond[];
double ExtBullShadowFirst[];
double ExtBullShadowSecond[];
double ExtBullShadowEndFirst[];
double ExtBullShadowEndSecond[];
//--- global variables
datetime ExtTimeBuff[]; // larger time frame's time buffer
int ExtSize=0; // time buffer size
int ExtCount=0; // index inside time buffer
int ExtStartPos=0; // initial position for the indicator calculation
bool ExtStartFlag=true; // auxiliary flag for receiving the initial position
datetime ExtCurrentTime[1]; // last time of the larger time frame's bar generation
datetime ExtLastTime; // last time from the larger time frame, for which the calculation is
bool ExtBearFlag=true; // flag for defining the order of writing the data to bearish indicato
bool ExtBullFlag=true; // flag for defining the order of writing the data to bullish indicato
int ExtIndexMax=0; // index of the maximum element in the array
int ExtIndexMin=0; // index of the minimum element in the array
int ExtDirectionFlag=0; // price movement direction for the current candlestick
//--- shift between the candlestick's open and close price for correct drawing
//--- if close and open prices are equal, use the shift for correct display
if(high[index_max]!=low[index_min])
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,open
open[start]-ExtEmptyBodySize,high[index_max],low[index_min],start,count,ExtBea
else
FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,
open[start],open[start]-ExtEmptyBodySize,high[index_max],
high[index_max]-ExtEmptyBodySize,start,count,ExtBearFlag);
}
//+------------------------------------------------------------------+
//| Fill out the end of the candlestick |
//+------------------------------------------------------------------+
void FillCandleEnd(const double &open[],const double &close[],
const double &high[],const double &low[],
const int start,const int last,const int fill_index,
const int index_max,const int index_min)
{
//--- do not draw in case of a single bar
if(last-start==0)
return;
//--- if the close price at the first bar exceeds the one at the last bar, the candlestick is beari
if(open[start]>close[last])
{
//--- generate the end of the candlestick
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEnd
open[start],close[last],high[index_max],low[index_min],fill_index,ExtBearFlag);
//--- exit the function
return;
}
//--- if the close price at the first bar is less than the one at the last bar, the candlestick is
if(open[start]<close[last])
{
//--- generate the end of the candlestick
FormCandleEnd(ExtBullBodyEndFirst,ExtBullBodyEndSecond,ExtBullShadowEndFirst,ExtBullShadowEnd
close[last],open[start],high[index_max],low[index_min],fill_index,ExtBullFlag);
//--- exit the function
return;
}
//--- if you are in this part of the function, the open price at the first bar is equal to
//--- the close price at the last bar; such candlestick is considered bearish
//--- generate the end of the candlestick
if(high[index_max]!=low[index_min])
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEnd
open[start]-ExtEmptyBodySize,high[index_max],low[index_min],fill_index,ExtBearF
else
FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEnd
open[start]-ExtEmptyBodySize,high[index_max],high[index_max]-ExtEmptyBodySize,f
}
//+------------------------------------------------------------------+
{
//--- in case there are no calculated bars yet
if(prev_calculated==0)
{
//--- receive larger time frame's bars arrival time
if(!GetTimeData())
return(0);
}
//--- set direct indexing
ArraySetAsSeries(time,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(close,false);
//--- start variable for calculation of bars
int start=prev_calculated;
//--- if the bar is generated, recalculate the indicator value on it
if(start!=0 && start==rates_total)
start--;
//--- the loop for calculating the indicator values
for(int i=start;i<rates_total;i++)
{
//--- fill i elements of the indicator buffers by empty values
FillIndicatorBuffers(i);
//--- perform calculation for bars starting from InpDateStart date
if(time[i]>=InpDateStart)
{
//--- define position, from which the values are to be displayed, for the first time
if(ExtStartFlag)
{
//--- store the number of the initial bar
ExtStartPos=i;
//--- define the first date from the larger time frame exceeding time[i]
while(time[i]>=ExtTimeBuff[ExtCount])
if(ExtCount<ExtSize-1)
ExtCount++;
//--- change the value of the flag in order not to run into this block again
ExtStartFlag=false;
}
//--- check if there are still any elements in the array
if(ExtCount<ExtSize)
{
//--- wait for the current time frame's value to reach the larger time frame's one
if(time[i]>=ExtTimeBuff[ExtCount])
{
//--- draw the main part of the candlestick (without filling out the area between th
FillCandleMain(open,close,high,low,ExtStartPos,i-1,i-2,ExtIndexMax,ExtIndexMin);
//--- fill out the end of the candlestick (the area between the last and the penulti
FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
//--- shift the initial position for drawing the next candlestick
ExtStartPos=i;
//--- increase the array counter
ExtCount++;
}
else
continue;
}
else
{
//--- reset the array values
ResetLastError();
//--- receive the last date from the larger time frame
if(CopyTime(Symbol(),InpPeriod,0,1,ExtCurrentTime)==-1)
{
Print("Data copy error, code = ",GetLastError());
return(0);
}
//--- if the new date is later, stop generating the candlestick
if(ExtCurrentTime[0]>ExtLastTime)
{
//--- clear the area between the last and penultimate bars in the main indicator buf
ClearEndOfBodyMain(i-1);
//--- fill out the area using auxiliary indicator buffers
FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
//--- shift the initial position for drawing the next candlestick
ExtStartPos=i;
//--- reset price direction flag
ExtDirectionFlag=0;
//--- store the new last date
ExtLastTime=ExtCurrentTime[0];
}
else
{
//--- generate the candlestick
FillCandleMain(open,close,high,low,ExtStartPos,i,i,ExtIndexMax,ExtIndexMin);
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Check correctness of the specified indicator period |
//+------------------------------------------------------------------+
bool CheckPeriod(int current_period,int high_period)
{
//--- the indicator period should exceed the timeframe on which it is displayed
if(current_period>=high_period)
{
Print("Error! The value of the indicator period should exceed the value of the current time f
return(false);
}
//--- if the indicator period is one week or month, the period is correct
if(high_period>32768)
return(true);
//--- convert period values to minutes
if(high_period>30)
high_period=(high_period-16384)*60;
if(current_period>30)
current_period=(current_period-16384)*60;
//--- the indicator period should be multiple of the time frame it is displayed on
if(high_period%current_period!=0)
{
Print("Error! The value of the indicator period should be multiple of the value of the curren
return(false);
}
//--- the indicator period should exceed the time frame it is displayed on 3 or more times
if(high_period/current_period<3)
{
Print("Error! The indicator period should exceed the current time frame 3 or more times!");
return(false);
}
//--- the indicator period is correct for the current time frame
return(true);
}
//+------------------------------------------------------------------+
//| Receive time data from the larger time frame |
//+------------------------------------------------------------------+
bool GetTimeData(void)
{
//--- reset the error value
ResetLastError();
//--- copy all data for the current time
if(CopyTime(Symbol(),InpPeriod,InpDateStart,TimeCurrent(),ExtTimeBuff)==-1)
{
//--- receive the error code
int code=GetLastError();
//--- print out the error message
PrintFormat("Data copy error! %s",code==4401
? "History is still being uploaded!"
: "Code = "+IntegerToString(code));
//--- return false to make a repeated attempt to download data
return(false);
}
//--- receive the array size
ExtSize=ArraySize(ExtTimeBuff);
if(flag)
{
//--- generate the end of the candlestick's body
FormEnd(body_fst,body_snd,fst_value,snd_value,end);
//--- generate the end of the candlestick's shadow
FormEnd(shadow_fst,shadow_snd,fst_extremum,snd_extremum,end);
//--- change the flag's value to the opposite one
flag=false;
}
else
{
//--- generate the end of the candlestick's body
FormEnd(body_fst,body_snd,snd_value,fst_value,end);
//--- generate the end of the candlestick's shadow
FormEnd(shadow_fst,shadow_snd,snd_extremum,fst_extremum,end);
//--- change the flag's value to the opposite one
flag=true;
}
}
//+-------------------------------------------------------------------------------------+
//| Clear the end of the candlestick (the area between the last and the penultimate |
//| bar) |
//+-------------------------------------------------------------------------------------+
void ClearEndOfBodyMain(const int ind)
{
ClearCandle(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,ind,1);
ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,ind,1);
}
//+------------------------------------------------------------------+
//| Clear the candlestick |
//+------------------------------------------------------------------+
void ClearCandle(double &body_fst[],double &body_snd[],double &shadow_fst[],
double &shadow_snd[],const int start,const int count)
{
//--- check
if(count!=0)
{
//--- fill indicator buffers with empty values
ArrayFill(body_fst,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(body_snd,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(shadow_fst,start,count,INDICATOR_EMPTY_VALUE);
ArrayFill(shadow_snd,start,count,INDICATOR_EMPTY_VALUE);
}
}
//+------------------------------------------------------------------+
//| Generate the main part of the candlestick |
//+------------------------------------------------------------------+
void FormMain(double &fst[],double &snd[],const double fst_value,
const double snd_value,const int start,const int count)
{
//--- check
if(count!=0)
{
//--- fill indicator buffers with values
ArrayFill(fst,start,count,fst_value);
ArrayFill(snd,start,count,snd_value);
}
}
//+------------------------------------------------------------------+
//| Generate the end of the candlestick |
//+------------------------------------------------------------------+
void FormEnd(double &fst[],double &snd[],const double fst_value,
const double snd_value,const int last)
{
//--- fill indicator buffers with values
ArrayFill(fst,last-1,2,fst_value);
ArrayFill(snd,last-1,2,snd_value);
}
//+------------------------------------------------------------------+
//| Fill i element of the indicator buffers by empty values |
//+------------------------------------------------------------------+
void FillIndicatorBuffers(const int i)
{
//--- set an empty value in the cell of the indicator buffers
ExtBearBodyFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodySecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBearShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodySecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
ExtBullShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
}
ArrayPrint
Prints an array of a simple type or a simple structure into journal.
void ArrayPrint(
const void& array[], // printed array
uint digits=_Digits, // number of decimal places
const string separator=NULL, // separator of the structure field values
ulong start=0, // first printed element index
ulong count=WHOLE_ARRAY, // number of printed elements
ulong flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN
);
Parameters
array[]
[in] Array of a simple type or a simple structure.
digits=_Digits
[in] The number of decimal places for real types. The default value is _Digits.
separator=NULL
[in] Separator of the structure element field values. The default value NULL means an empty line.
A space is used as a separator in that case.
start=0
[in] The index of the first printed array element. It is printed from the zero index by default.
count=WHOLE_ARRAY
[in] Number of the array elements to be printed. The entire array is displayed by default
(count=WH OL E_ARRAY).
flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN
[in] Combination of flags setting the output mode. All flags are enabled by default:
Note
ArrayPrint() does not print all structure array fields into journal – array and object pointer fields are
s k ipped. These columns are simply not printed for more convenient presentation. If you need to
print all structure fields, you need to write your own mass print function with the desired
formatting.
Example:
See also
FileSave, FileLoad
ArrayRange
The function returns the number of elements in a selected array dimension.
int ArrayRange(
const void& array[], // array for check
int rank_index // index of dimension
);
Parameters
array[]
[in] Check ed array.
rank_index
[in] Index of dimension.
Return Value
Note
Since indexes start at zero, the number of the array dimensions is one greater than the index of the
last dimension.
Example:
void OnStart()
{
//--- create four-dimensional array
double array[][5][2][4];
//--- set the size of the zero dimension
ArrayResize(array,10,10);
//--- print dimensions
int temp;
for(int i=0;i<4;i++)
{
//--- receive the size of i dimension
temp=ArrayRange(array,i);
//--- print
PrintFormat("dim = %d, range = %d",i,temp);
}
//--- Result
// dim = 0, range = 10
// dim = 1, range = 5
// dim = 2, range = 2
// dim = 3, range = 4
}
ArrayResize
The function sets a new size for the first dimension
int ArrayResize(
void& array[], // array passed by reference
int new_size, // new array size
int reserve_size=0 // reserve size value (excess)
);
Parameters
array[]
[out] Array for changing sizes.
new_size
[in] New size for the first dimension.
reserve_size=0
[in] Distributed size to get reserve.
Return Value
If executed successfully, it returns count of all elements contained in the array after resizing,
otherwise, returns -1, and array is not resized.
If ArrayR esize() is applied to a static array, a timeseries or an indicator buffer, the array size
remains the same – these arrays will not be reallocated. In this case, if new_size<=ArraySize(array),
the function will only return new_size; otherwise a value of -1 will be returned.
Note
The function can be applied only to dynamic arrays. It should be noted that you cannot change the
size of dynamic arrays assigned as indicator buffers by the SetIndex Buffer() function. For indicator
buffers, all operations of resizing are performed by the runtime subsystem of the terminal.
W ith the frequent memory allocation, it is recommended to use a third parameter that sets a
reserve to reduce the number of physical memory allocations. All the subsequent calls of ArrayR esize
do not lead to physical reallocation of memory, but only change the size of the first array dimension
within the reserved memory. It should be remembered that the third parameter will be used only
during physical memory allocation. For example:
ArrayResize(arr,1000,1000);
for(int i=1;i<3000;i++)
ArrayResize(arr,i,1000);
In this case the memory will be reallocated twice, first before entering the 3000 iterations loop (the
array size will be set to 1000), and the second time with i equal to 2000. If we s k ip the third
parameter, there will be 2000 physical reallocations of memory, which will slow down the program.
Example:
//+------------------------------------------------------------------+
/*
Test_ArrayResize (EURUSD,H1) --- Test Fast: ArrayResize(arr,100000,100000)
Test_ArrayResize (EURUSD,H1) 1. ArraySize(arr)=100000 Time=0 ms
Test_ArrayResize (EURUSD,H1) 2. ArraySize(arr)=200000 Time=0 ms
Test_ArrayResize (EURUSD,H1) 3. ArraySize(arr)=300000 Time=0 ms
Test_ArrayResize (EURUSD,H1) ---- Test Slow: ArrayResize(slow,100000)
Test_ArrayResize (EURUSD,H1) 1. ArraySize(slow)=100000 Time=0 ms
Test_ArrayResize (EURUSD,H1) 2. ArraySize(slow)=200000 Time=0 ms
Test_ArrayResize (EURUSD,H1) 3. ArraySize(slow)=300000 Time=228511 ms
*/
See also
ArrayInitialize
ArrayInsert
Inserts the specified number of elements from a source array to a receiving one starting from a
specified index.
bool ArrayInsert(
void& dst_array[], // receiving array
const void& src_array[], // source array
uint dst_start, // receiver array index to be inserted
uint src_start=0, // source array index to be copied
uint count=WHOLE_ARRAY // number of elements to insert
);
Parameters
dst_array[]
[in][out] R eceiving array the elements should be added to.
src_array[]
[in] Source array the elements are to be added from.
dst_start
[in] Index in the receiving array for inserting elements from the source array.
src_start=0
[in] Index in the receiving array, starting from which the elements of the source array are tak en
for insertion.
count
[in] Number of elements to be added from the source array. The WH OL E_ARRAY means all
elements from the specified index up to the end of the array.
Return Value
R eturns true if successful, otherwise - false. To get information about the error, call the
GetLastError() function. Possible errors :
· 5052 – ERR_SM ALL _ARRAY (the start and/or count parameters are set incorrectly or the
src_array[] source array is empty),
· 5056 – ERR_S ER I ES _ARRAY (the array cannot be changed, indicator buffer),
· 4006 – ERR_I NVALI D_ARRAY (copying to oneself is not allowed, or the arrays are of different
types, or there is a fixed-size array containing class objects or destructor structures),
· 4005 - ERR_ST RUCT _W IT H OBJECTS _OR CL ASS (the array contains no POD structures meaning a
simple copying is impossible),
· Errors occurred when changing the dst_array[] receiving array size are provided in the
ArrayR emove() function description.
Note
If the function is used for a fixed-size array, the size of the dst_array[] receiving array itself does
not change. Starting from the dst_start position, the elements of the receiving array are shifted to
the right (the last counts of the elements " come off" ), while the elements copied from the source
array tak e their place.
You cannot insert the elements to the dynamic arrays designated as the indicator buffers by the
SetIndex Buffer() function. For indicator buffers, all size changing operations are performed by the
terminal's executing subsystem.
In the source array, the elements are copied starting from the src_start index. The source array size
remains unchanged. The elements to be added to the receiving array are not link s to the source
array elements. This means that subsequent changes of the elements in any of the two arrays are
not reflected in the second one.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare the fixed-size array and fill in the values
int array_dest[10];
for(int i=0;i<10;i++)
{
array_dest[i]=i;
}
//--- source array
int array_source[10];
for(int i=0;i<10;i++)
{
array_source[i]=10+i;
}
//--- display arrays before inserting the elements
Print("Before calling ArrayInsert()");
ArrayPrint(array_dest);
ArrayPrint(array_source);
//--- insert 3 elements from the source array and show the new set of the receiving array
ArrayInsert(array_dest,array_source,4,0,3);
Print("After calling ArrayInsert()");
ArrayPrint(array_dest);
/*
Execution result
Before calling ArrayInsert()
0 1 2 3 4 5 6 7 8 9
After calling ArrayInsert()
0 1 2 3 10 11 12 7 8 9
*/
See also
ArrayR emove, ArrayCopy, ArrayR esize, ArrayFree
ArrayRemove
R emoves the specified number of elements from the array starting with a specified index.
bool ArrayRemove(
void& array[], // array of any type
uint start, // index the removal starts from
uint count=WHOLE_ARRAY // number of elements
);
Parameters
array[]
[in][out] Array.
start
[in] Index, starting from which the array elements are removed.
count=WHOLE_ARRAY
[in] Number of removed elements. The WH OL E_ARRAY value means removing all elements from
the specified index up the end of the array.
Return Value
R eturns true if successful, otherwise - false. To get information about the error, call the
GetLastError() function. Possible errors :
· 5052 – ERR_SM ALL _ARRAY (too big start value),
· 5056 – ERR_S ER I ES _ARRAY (the array cannot be changed, indicator buffer),
· 4003 – ERR_I NVALI D_PARAM ET ER (too big count value),
· 4005 - ERR_ST RUCT _W IT H OBJECTS _OR CL ASS (fixed-size array containing complex objects with
the destructor),
· 4006 - ERR_I NVALI D_ARRAY (fixed-size array containing structure or class objects with a
destructor).
Note
If the function is used for a fixed-size array, the array size does not change: the remaining " tail" is
physically copied to the start position. For accurate understanding of how the function work s, see
the example below. " Physical" copying means the copied objects are not created by calling the
constructor or copying operator. Instead, the binary representation of an object is copied. For this
reason, you cannot apply the ArrayR emove() function to the fixed-size array containing objects with
the destructor (the ERR_I NVALI D_ARRAY or ERR_ST RUCT _W IT H OBJECTS _OR CL ASS error is
activated). W hen removing such an object, the destructor should be called twice – for the original
object and its copy.
You cannot remove elements from dynamic arrays designated as the indicator buffers by the
SetIndex Buffer() function. This will result in the ERR_S ER I ES _ARRAY error. For indicator buffers, all
size changing operations are performed by the terminal's executing subsystem.
Example:
//+------------------------------------------------------------------+
See also
ArrayInsert, ArrayCopy, ArrayR esize, ArrayFree
ArrayReverse
R everses the specified number of elements in the array starting with a specified index.
bool ArrayReverse(
void& array[], // array of any type
uint start=0, // index to start reversing the array from
uint count=WHOLE_ARRAY // number of elements
);
Parameters
array[]
[in][out] Array.
start=0
[in] Index the array reversal starts from.
count=WHOLE_ARRAY
[in] Number of reversed elements. If WH OL E_ARRAY, then all array elements are moved in the
inversed manner starting with the specified start index up to the end of the array.
Return Value
Note
The ArraySetAsSeries() function does not move the array elements physically. Instead, it only
changes the indexation direction back wards to arrange the access to the elements as in the
timeseries. The ArrayR everse() function physically moves the array elements so that the array is
" reversed" .
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare the fixed-size array and fill in the values
int array[10];
for(int i=0;i<10;i++)
{
array[i]=i;
}
//--- display the array before reversing the elements
Print("Before calling ArrayReverse()");
ArrayPrint(array);
//--- reverse 3 elements in the array and show the new set
ArrayReverse(array,4,3);
Print("After calling ArrayReverse()");
ArrayPrint(array);
/*
Execution result:
Before calling ArrayReverse()
0 1 2 3 4 5 6 7 8 9
After calling ArrayReverse()
0 1 2 3 6 5 4 7 8 9
*/
See also
ArrayInsert, ArrayR emove, ArrayCopy, ArrayR esize, ArrayFree, ArrayGetAsSeries, ArraySetAsSeries
ArraySetAsSeries
The function sets the AS _S ER I ES flag to a selected object of a dynamic array, and elements will be
indexed lik e in timeseries.
bool ArraySetAsSeries(
const void& array[], // array by reference
bool flag // true denotes reverse order of indexing
);
Parameters
array[]
[in][out] Numeric array to set.
flag
[in] Array indexing direction.
Return Value
Note
The AS _S ER I ES flag can't be set for multi-dimensional arrays or static arrays (arrays, whose size in
s quare brack ets is preset already on the compilation stage). Indexing in timeseries differs from a
common array in that the elements of timeseries are indexed from the end towards the beginning
(from the newest to oldest data).
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot Numeration
See also
Access to timeseries, ArrayGetAsSeries
ArraySize
The function returns the number of elements of a selected array.
int ArraySize(
const void& array[] // checked array
);
Parameters
array[]
[in] Array of any type.
Return Value
Note
For a one-dimensional array, the value to be returned by the ArraySize is equal to that of
ArrayR ange(array,0).
Example:
void OnStart()
{
//--- create arrays
double one_dim[];
double four_dim[][10][5][2];
//--- sizes
int one_dim_size=25;
int reserve=20;
int four_dim_size=5;
//--- auxiliary variable
int size;
//--- allocate memory without backup
ArrayResize(one_dim,one_dim_size);
ArrayResize(four_dim,four_dim_size);
//--- 1. one-dimensional array
Print("+==========================================================+");
Print("Array sizes:");
Print("1. One-dimensional array");
size=ArraySize(one_dim);
PrintFormat("Zero dimension size = %d, Array size = %d",one_dim_size,size);
//--- 2. multidimensional array
Print("2. Multidimensional array");
size=ArraySize(four_dim);
PrintFormat("Zero dimension size = %d, Array size = %d",four_dim_size,size);
//--- dimension sizes
int d_1=ArrayRange(four_dim,1);
int d_2=ArrayRange(four_dim,2);
int d_3=ArrayRange(four_dim,3);
Print("Check:");
Print("Zero dimension = Array size / (First dimension * Second dimension * Third dimension)");
PrintFormat("%d = %d / (%d * %d * %d)",size/(d_1*d_2*d_3),size,d_1,d_2,d_3);
//--- 3. one-dimensional array with memory backup
Print("3. One-dimensional array with memory backup");
//--- double the value
one_dim_size*=2;
//--- allocate memory with backup
ArrayResize(one_dim,one_dim_size,reserve);
//--- print out the size
size=ArraySize(one_dim);
PrintFormat("Size with backup = %d, Actual array size = %d",one_dim_size+reserve,size);
}
ArraySort
Sorts the values in the first dimension of a multidimensional numeric array in the ascending order.
bool ArraySort(
void& array[] // array for sorting
);
Parameters
array[]
[in][out] Numeric array for sorting.
Return Value
Note
An array is always sorted in the ascending order irrespective of the AS _S ER IES flag value.
Example:
#property description "The indicator analyzes data for the last month and draws all candlesticks wi
#property description "and large tick volumes. The tick volume array is sorted out"
#property description "to define such candlesticks. The candlesticks having the volumes comprising
#property description "per cent of the array are considered small. The candlesticks having the tick
#property description "the last InpBigVolume per cent of the array are considered large."
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//--- plot
#property indicator_label1 "VolumeFactor"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrDodgerBlue,clrOrange
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- predefined constant
#define INDICATOR_EMPTY_VALUE 0.0
//--- input parameters
input int InpSmallVolume=15; // Percentage value of small volumes (<50)
input int InpBigVolume=20; // Percentage value of large volumes (<50)
//--- analysis start time (will be shifted)
datetime ExtStartTime;
//--- indicator buffers
double ExtOpenBuff[];
double ExtHighBuff[];
double ExtLowBuff[];
double ExtCloseBuff[];
double ExtColorBuff[];
//--- volume boundary values for displaying the candlesticks
long ExtLeftBorder=0;
long ExtRightBorder=0;
//+------------------------------------------------------------------+
//| Receive border values for tick volumes |
//+------------------------------------------------------------------+
bool GetVolumeBorders(void)
{
//--- variables
datetime stop_time; // copy end time
long buff[]; // buffer for copying
//--- end time is the current one
stop_time=TimeCurrent();
//--- start time is one month earlier from the current one
ExtStartTime=GetStartTime(stop_time);
//--- receive the values of tick volumes
ResetLastError();
if(CopyTickVolume(Symbol(),Period(),ExtStartTime,stop_time,buff)==-1)
{
//--- failed to receive the data, return false to launch recalculation command
PrintFormat("Failed to receive tick volume values. Error code = %d",GetLastError());
return(false);
}
//--- calculate array size
int size=ArraySize(buff);
//--- sort out the array
ArraySort(buff);
//--- define the values of the left and right border for tick volumes
ExtLeftBorder=buff[size*InpSmallVolume/100];
ExtRightBorder=buff[(size-1)*(100-InpBigVolume)/100];
//--- successful execution
return(true);
}
//+------------------------------------------------------------------+
//| Receive the data that is one month less than the passed one |
//+------------------------------------------------------------------+
datetime GetStartTime(const datetime stop_time)
{
//--- convert end time into MqlDateTime type structure variable
MqlDateTime temp;
TimeToStruct(stop_time,temp);
//--- receive the data that is one month less
if(temp.mon>1)
temp.mon-=1; // the current month is not the first one in the year, therefore, the number of
else
{
temp.mon=12; // the current month is the first in the year, therefore, the number of the pre
//--- receive new values of the right and left borders for volumes
if(!GetVolumeBorders())
return(0);
}
//--- start variable for bar calculation
int start=prev_calculated;
//--- work at the last bar if the indicator values have already been calculated at the previous tic
if(start>0)
start--;
//--- set direct indexing in time series
ArraySetAsSeries(time,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
ArraySetAsSeries(tick_volume,false);
//--- the loop of calculation of the indicator values
for(int i=start;i<rates_total;i++)
{
//--- fill out candlesticks starting from the initial date
if(ExtStartTime<=time[i])
{
//--- if the value is not less than the right border, fill out the candlestick
if(tick_volume[i]>=ExtRightBorder)
{
//--- receive data for drawing the candlestick
ExtOpenBuff[i]=open[i];
ExtHighBuff[i]=high[i];
ExtLowBuff[i]=low[i];
ExtCloseBuff[i]=close[i];
//--- DodgerBlue color
ExtColorBuff[i]=0;
//--- continue the loop
continue;
}
//--- fill out the candlestick if the value does not exceed the left border
if(tick_volume[i]<=ExtLeftBorder)
{
//--- receive data for drawing the candlestick
ExtOpenBuff[i]=open[i];
ExtHighBuff[i]=high[i];
ExtLowBuff[i]=low[i];
ExtCloseBuff[i]=close[i];
//--- Orange color
ExtColorBuff[i]=1;
//--- continue the loop
continue;
}
}
//--- set empty values for bars that have not been included in the calculation
ExtOpenBuff[i]=INDICATOR_EMPTY_VALUE;
ExtHighBuff[i]=INDICATOR_EMPTY_VALUE;
ExtLowBuff[i]=INDICATOR_EMPTY_VALUE;
ExtCloseBuff[i]=INDICATOR_EMPTY_VALUE;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
See also
ArrayBsearch
ArraySwap
Swaps the contents of two dynamic arrays of the same type. For multidimensional arrays, the number
of elements in all dimensions except the first one should match.
bool ArraySwap(
void& array1[], // first array
void& array2[] // second array
);
Parameters
array1[]
[in][out] Array of numerical type.
array2[]
[in][out] Array of numerical type.
Return Value
R eturns true if successful, otherwise false. In this case, GetLastError() returns the
ERR_INVALID_ARRAY error code.
Note
The function accepts dynamic arrays of the same type and the same dimensions except the first
one. For integer types, the sign is ignored, i.e. char==uchar)
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- arrays for storing quotes
double source_array[][8];
double dest_array[][8];
MqlRates rates[];
//--- get the data of the last 20 candles on the current timeframe
int copied=CopyRates(NULL,0,0,20,rates);
if(copied<=0)
{
PrintFormat("CopyRates(%s,0,0,20,rates) failed, error=%d",
Symbol(),GetLastError());
return;
}
//--- set the array size for the amount of copied data
ArrayResize(source_array,copied);
//--- fill the rate_array_1[] array by data from rates[]
for(int i=0;i<copied;i++)
{
source_array[i][0]=(double)rates[i].time;
source_array[i][1]=rates[i].open;
source_array[i][2]=rates[i].high;
source_array[i][3]=rates[i].low;
source_array[i][4]=rates[i].close;
source_array[i][5]=(double)rates[i].tick_volume;
source_array[i][6]=(double)rates[i].spread;
source_array[i][7]=(double)rates[i].real_volume;
}
//--- swap data between source_array[] and dest_array[]
if(!ArraySwap(source_array,dest_array))
{
PrintFormat("ArraySwap(source_array,rate_array_2) failed, error code=%d",GetLastError());
return;
}
//--- ensure that the source array has become zero after the swap
PrintFormat("ArraySwap() done: ArraySize(source_array)=%d",ArraySize(source_array));
//--- display the data of the dest_array[] destination array
ArrayPrint(dest_array);
}
See also
ArrayCopy, ArrayFill, ArrayR ange, ArrayIs Dynamic
Conversion Functions
This is a group of functions that provide conversion of data from one format into another.
The NormalizeDouble() function must be specially noted as it provides the necessary accuracy of the
price presentation. In trading operations, no unnormalized prices may be used if their accuracy even a
digit exceeds that required by the trade server.
Function Action
See also
Use of a Codepage
CharToString
Converting a symbol code into a one-character string.
string CharToString(
uchar char_code // numeric code of symbol
);
Parameters
char_code
[in] Code of ANSI symbol.
Return Value
See also
StringToCharArray, ShortToString, String GetCharacter
CharArrayToString
It copies and converts part of array of uchar type into a returned string.
string CharArrayToString(
uchar array[], // array
int start=0, // starting position in the array
int count=-1 // number of symbols
uint codepage=CP_ACP // code page
);
Parameters
array[]
[in] Array of uchar type.
start=0
[in] Position from which copying starts. by default 0 is used.
count=-1
[in] Number of array elements for copying. Defines the length of a resulting string. Default value
is -1, which means copying up to the array end, or till terminal 0.
codepage=CP_ACP
[in] The value of the code page. There is a number of built-in constants for the most used code
pages.
Return Value
String.
See also
StringToCharArray, ShortArrayToString, Use of a Codepage
CharArrayToStruct
Copy uchar type array to POD structure.
bool CharArrayToStruct(
void& struct_object, // structure
const uchar& char_array[], // array
uint start_pos=0 // starting position in the array
);
Parameters
struct_object
[in] R eference to any type of POD structure (containing only simple data types).
char_array[]
[in] uchar type array.
start_pos=0
[in] Position in the array, data copying starts from.
Return Value
See also
StringToCharArray, ShortArrayToString, StructToCharArray, Use of a Codepage, FileR eadStruct,
Unions (union), MathSwap
StructToCharArray
Copy POD structure to uchar type array.
bool StructToCharArray(
const void& struct_object, // structure
uchar& char_array[], // array
uint start_pos=0 // starting position in the array
);
Parameters
struct_object
[in] R eference to any type of POD structure (containing only simple data types).
char_array[]
[in] uchar type array.
start_pos=0
[in] Position in the array, starting from which the copied data are added.
Return Value
Note
W hen copying, the dynamic array automatically expands (ArrayR esize) if there is not enough space.
If the array cannot be expanded up to the required value, the function returns an error.
See also
StringToCharArray, ShortArrayToString,CharArrayToStruct, Use of a Codepage, FileW riteStruct,
Unions (union), MathSwap
ColorToARGB
The function converts color type into uint type to get ARGB representation of the color. ARGB color
format is used to generate a graphical resource, text display, as well as for CCanvas standard library
class.
uint ColorToARGB(
color clr, // converted color in color format
uchar alpha=255 // alpha channel managing color transparency
);
Parameters
clr
[in] Color value in color type variable.
alpha
[in] The value of the alpha channel used to receive the color in ARGB format. The value may be
set from 0 (a color of a foreground pixel does not change the display of an underlying one) up to
255 (a color of an underlying pixel is completely replaced by the foreground pixel's one). Color
transparency in percentage terms is calculated as (1-alpha/255)*100%. In other words, the lesser
value of the alpha channel leads to more transparent color.
Return Value
Presenting the color in ARGB format where Alfa, R ed, Green, Blue (alpha channel, red, green, blue)
values are set in series in four uint type bytes.
Note
RGB is a basic and commonly used format for pixel color description on a screen in computer
graphics. Names of basic colors are used to set red, green and blue color components. Each
component is described by one byte specifying the color saturation in the range of 0 to 255 (0x 00 to
0XFF in hexadecimal format). Since the white color contains all colors, it is described as 0x FFFFFF,
that is, each one of three components is presented by the maximum value of 0x FF.
H owever, some tas k s require to specify the color transparency to describe the look of an image in
case it is covered by the color with some degree of transparency. The concept of alpha channel is
introduced for such cases. It is implemented as an additional component of RGB format. ARGB
format structure is shown below.
ARGB values are typically expressed using hexadecimal format with each pair of digits representing
the values of Alpha, R ed, Green and Blue channels, respectively. For example, 80FFFF00 color
represents 50.2% opaque yellow. Initially, 0x 80 sets 50.2% alpha value, as it is 50.2% of 0x FF value.
Then, the first FF pair defines the highest value of the red component; the next FF pair is lik e the
previous but for the green component; the final 00 pair represents the lowest value the blue
component can have (absence of blue). Combination of green and red colors yields yellow one. If the
alpha channel is not used, the entry can be reduced down to 6 RRGGBB digits, this is why the alpha
channel values are stored in the top bits of uint integer type.
Depending on the context, hexadecimal digits can be written with '0x ' or '#' prefix, for example,
80FFFF00, 0x 80FFFF00 or #80FFFF00.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- set transparency
uchar alpha=0x55; // 0x55 means 55/255=21.6 % of transparency
//--- derive conversion to ARGB for clrBlue color
PrintFormat("0x%.8X - clrBlue",clrBlue);
PrintFormat("0x%.8X - clrBlue ARGB with alpha=0x55 (transparency 21.6%%)",ColorToARGB(clrBlue,al
//--- derive conversion to ARGB for clrGreen color
PrintFormat("0x%.8X - clrGreen",clrGreen);
PrintFormat("0x%.8X - clrGreen ARGB with alpha=0x55 (transparency 21.6%%)",ColorToARGB(clrGreen,
//--- derive conversion to ARGB for clrRed color
PrintFormat("0x%.8X - clrRed",clrRed);
PrintFormat("0x%.8X - clrRed ARGB with alpha=0x55 (transparency 21.6%%)",ColorToARGB(clrRed,alph
}
See also
R esources, R esourceCreate(), TextOut(), color type, char, short, int and long types
ColorToString
It converts color value into string of "R ,G,B" form.
string ColorToString(
color color_value, // color value
bool color_name // show color name or not
);
Parameters
color_value
[in] Color value in color type variable.
color_name
[in] R eturn color name if it is identical to one of predefined color constants.
Return Value
String presentation of color as "R ,G,B" , where R , G and B are decimal constants from 0 to 255
converted into a string. If the color_name=true parameter is set, it will try to convert color value
into color name.
Example:
See also
StringToColor, ColorToARGB
DoubleToString
Converting numeric value into text string.
string DoubleToString(
double value, // number
int digits=8 // number of digits after decimal point
);
Parameters
value
[in] Value with a floating point.
digits
[in] Accuracy format. If the digits value is in the range between 0 and 16, a string presentation of
a number with the specified number of digits after the point will be obtained. If the digits value is
in the range between -1 and -16, a string representation of a number in the scientific format with
the specified number of digits after the decimal point will be obtained. In all other cases the string
value will contain 8 digits after the decimal point.
Return Value
Example:
See also
NormalizeDouble, StringToDouble
EnumToString
Converting an enumeration value of any type to a text form.
string EnumToString(
any_enum value // any type enumeration value
);
Parameters
value
[in] Any type enumeration value.
Return Value
A string with a text representation of the enumeration. To get the error message call the
GetLastError() function.
Note
The function can set the following error values in the _LastError variable:
· ERR_I NT ERNAL _ERR OR – error of the execution environment
· ERR_NOT _ENOUGH_M EMORY – not enough memory to complete the operation
· ERR_I NVALI D_PARAM ET ER – can't allow the name of the enumeration value
Example:
//--- set the time interval equal to one year (12 months)
period=year;
Print(EnumToString(period)+"="+IntegerToString(period));
ENUM_ORDER_TYPE type=ORDER_TYPE_BUY;
Print(EnumToString(type)+"="+IntegerToString(type));
// Result:
// month=1
// quarter=3
// year=12
// ORDER_TYPE_BUY=0
// ENUM_ORDER_TYPE::-1=-1
}
See also
Enumerations, Input variables
IntegerToString
This function converts value of integer type into a string of a specified length and returns the obtained
string.
string IntegerToString(
long number, // number
int str_len=0, // length of result string
ushort fill_symbol=' ' // filler
);
Parameters
number
[in] Number for conversion.
str_len=0
[in] String length. If the resulting string length is larger than the specified one, the string is not
cut off. If it is smaller, filler symbols will be added to the left.
fill_symbol=' '
[in] Filler symbol. By default it is a space.
Return Value
String.
See also
StringToInteger
ShortToString
It converts the symbol code (unicode) into one-symbol string and returns resulting string.
string ShortToString(
ushort symbol_code // symbol
);
Parameters
symbol_code
[in] Symbol code. Instead of a symbol code you can use literal string containing a symbol or a
literal string with 2-byte hexadecimal code corresponding to the symbol from the Unicode table.
Return Value
String.
See also
StringToCharArray, CharToString, String GetCharacter
ShortArrayToString
It copies part of array into a returned string.
string ShortArrayToString(
ushort array[], // array
int start=0, // starting position in the array
int count=-1 // number of symbols
);
Parameters
array[]
[in] Array of ushort type (analog of wchar_t type).
start=0
[in] Position, from which copying starts, Default - 0.
count=-1
[in] Number of array elements to copy. Defines the length of a resulting string. Default value is -
1, which means copying up to the array end, or till terminal 0.
Return Value
String.
See also
StringToShortArray, CharArrayToString, Use of a Codepage
TimeToString
Converting a value containing time in seconds elapsed since 01.01.1970 into a string of " yyyy.mm.dd
hh:mi" format.
string TimeToString(
datetime value, // number
int mode=TIME_DATE|TIME_MINUTES // output format
);
Parameters
value
[in] Time in seconds from 00:00 1970/01/01.
mode=TIME_DATE|TIME_MINUTES
[in] Additional data input mode. Can be one or combined flag :
TIM E_DAT E gets result as " yyyy.mm.dd" ,
TIM E_MI NUT ES gets result as " hh:mi" ,
TIM E_S ECONDS gets results as " hh:mi:ss " .
Return Value
String.
See also
StringToTime, TimeToStruct
NormalizeDouble
R ounding floating point number to a specified accuracy.
double NormalizeDouble(
double value, // normalized number
int digits // number of digits after decimal point
);
Parameters
value
[in] Value with a floating point.
digits
[in] Accuracy format, number of digits after point (0-8).
Return Value
Note
Calculated values of StopLoss, Tak eProfit, and values of open prices for pending orders must be
normalized with the accuracy, the value of which can be obtained by Digits().
Please note that when output to Journal using the Print() function, a normalized number may contain
a greater number of decimal places than you expect. For example, for:
DoubleToString(a,8)=76.67100000
Print(76.671)=76.67100000000001
Example:
double pi=M_PI;
Print("pi = ",DoubleToString(pi,16));
double pi_3=NormalizeDouble(M_PI,3);
Print("NormalizeDouble(pi,3) = ",DoubleToString(pi_3,16))
;
double pi_8=NormalizeDouble(M_PI,8);
Print("NormalizeDouble(pi,8) = ",DoubleToString(pi_8,16));
double pi_0=NormalizeDouble(M_PI,0);
Print("NormalizeDouble(pi,0) = ",DoubleToString(pi_0,16));
/*
Result:
pi= 3.1415926535897931
NormalizeDouble(pi,3)= 3.1419999999999999
NormalizeDouble(pi,8)= 3.1415926499999998
NormalizeDouble(pi,0)= 3.0000000000000000
*/
See also
DoubleToString, R eal types (double, float), Typecasting
StringToCharArray
Symbol-wise copies a string converted from Unicode to ANSI, to a selected place of array of uchar
type. It returns the number of copied elements.
int StringToCharArray(
string text_string, // source string
uchar& array[], // array
int start=0, // starting position in the array
int count=-1 // number of symbols
uint codepage=CP_ACP // code page
);
Parameters
text_string
[in] String to copy.
array[]
[out] Array of uchar type.
start=0
[in] Position from which copying starts. Default - 0.
count=-1
[in] Number of array elements to copy. Defines length of a resulting string. Default value is -1,
which means copying up to the array end, or till terminal 0. Terminal 0 will also be copied to the
recipient array, in this case the size of a dynamic array can be increased if necessary to the size of
the string. If the size of the dynamic array exceeds the length of the string, the size of the array
will not be reduced.
codepage=CP_ACP
[in] The value of the code page. For the most-used code pages provide appropriate constants.
Return Value
See also
CharArrayToString, StringToShortArray, Use of a Codepage
StringToColor
Converting "R ,G,B" string or string with color name into color type value.
color StringToColor(
string color_string // string representation of color
);
Parameters
color_string
[in] String representation of a color of "R ,G,B" type or name of one of predefined W eb-colors.
Return Value
Color value.
Example:
color str_color=StringToColor("0,127,0");
Print(str_color);
Print((string)str_color);
//--- change color a little
str_color=StringToColor("0,128,0");
Print(str_color);
Print((string)str_color);
See also
ColorToString, ColorToARGB
StringToDouble
The function converts string containing a symbol representation of number into number of double
type.
double StringToDouble(
string value // string
);
Parameters
value
[in] String containing a symbol representation of a number.
Return Value
See also
NormalizeDouble, R eal types (double, float), Typecasting
StringToInteger
The function converts string containing a symbol representation of number into number of int
(integer) type.
long StringToInteger(
string value // string
);
Parameters
value
[in] String containing a number.
Return Value
See also
IntegerToString, R eal types (double, float), Typecasting
StringToShortArray
The function symbol-wise copies a string into a specified place of an array of ushort type. It returns
the number of copied elements.
int StringToShortArray(
string text_string, // source string
ushort& array[], // array
int start=0, // starting position in the array
int count=-1 // number of symbols
);
Parameters
text_string
[in] String to copy
array[]
[out] Array of ushort type (analog of wchar_t type).
start=0
[in] Position, from which copying starts. Default - 0.
count=-1
[in] Number of array elements to copy. Defines length of a resulting string. Default value is -1,
which means copying up to the array end, or till terminal 0.Terminal 0 will also be copied to the
recipient array, in this case the size of a dynamic array can be increased if necessary to the size of
the string. If the size of the dynamic array exceeds the length of the string, the size of the array
will not be reduced.
Return Value
See also
ShortArrayToString, StringToCharArray, Use of a Codepage
StringToTime
Transforms the string containing time and/or date in the " yyyy.mm.dd [hh:mi]" format into the
datetime type number.
datetime StringToTime(
const string time_string // date string
);
Parameters
time_string
[in] String in one of the specified formats :
Return Value
datetime type value containing the number of seconds elapsed since 01.01.1970.
Note
Any sequence of space and tabulation characters between date and time is considered to be a single
space to avoid additional processing of the time_string before calling StringToTime().
See also
TimeToString, TimeToStruct
StringFormat
The function formats obtained parameters and returns a string.
string StringFormat(
string format, // string with format description
... ... // parameters
);
Parameters
format
[in] String containing method of formatting. Formatting rules are the same as for the PrintFormat
function.
...
[in] Parameters, separated by a comma.
Return Value
String.
Example:
void OnStart()
{
//--- string variables
string output_string;
string temp_string;
string format_string;
//--- prepare the specification header
temp_string=StringFormat("Contract specification for %s:\n",_Symbol);
StringAdd(output_string,temp_string);
//--- int value output
int digits=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
temp_string=StringFormat(" SYMBOL_DIGITS = %d (number of digits after the decimal point)\n",
digits);
StringAdd(output_string,temp_string);
//--- double value output with variable number of digits after the decimal point
double point_value=SymbolInfoDouble(_Symbol,SYMBOL_POINT);
format_string=StringFormat(" SYMBOL_POINT = %%.%df (point value)\n",
digits);
temp_string=StringFormat(format_string,point_value);
StringAdd(output_string,temp_string);
//--- int value output
int spread=(int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD);
temp_string=StringFormat(" SYMBOL_SPREAD = %d (current spread in points)\n",
spread);
StringAdd(output_string,temp_string);
//--- int value output
int min_stop=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
temp_string=StringFormat(" SYMBOL_TRADE_STOPS_LEVEL = %d (minimal indention in points for Stop
min_stop);
StringAdd(output_string,temp_string);
//--- double value output without the fractional part
double contract_size=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE);
temp_string=StringFormat(" SYMBOL_TRADE_CONTRACT_SIZE = %.f (contract size)\n",
contract_size);
StringAdd(output_string,temp_string);
//--- double value output with default accuracy
double tick_size=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
temp_string=StringFormat(" SYMBOL_TRADE_TICK_SIZE = %f (minimal price change)\n",
tick_size);
StringAdd(output_string,temp_string);
//--- determining the swap calculation mode
int swap_mode=(int)SymbolInfoInteger(_Symbol,SYMBOL_SWAP_MODE);
string str_swap_mode;
switch(swap_mode)
{
case SYMBOL_SWAP_MODE_DISABLED: str_swap_mode="SYMBOL_SWAP_MODE_DISABLED (no swaps)"; break;
case SYMBOL_SWAP_MODE_POINTS: str_swap_mode="SYMBOL_SWAP_MODE_POINTS (in points)"; break;
case SYMBOL_SWAP_MODE_CURRENCY_SYMBOL: str_swap_mode="SYMBOL_SWAP_MODE_CURRENCY_SYMBOL (in mo
case SYMBOL_SWAP_MODE_CURRENCY_MARGIN: str_swap_mode="SYMBOL_SWAP_MODE_CURRENCY_MARGIN (in mo
case SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT: str_swap_mode="SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT (in
case SYMBOL_SWAP_MODE_INTEREST_CURRENT: str_swap_mode="SYMBOL_SWAP_MODE_INTEREST_CURRENT (as
case SYMBOL_SWAP_MODE_INTEREST_OPEN: str_swap_mode="SYMBOL_SWAP_MODE_INTEREST_OPEN (as the sp
case SYMBOL_SWAP_MODE_REOPEN_CURRENT: str_swap_mode="SYMBOL_SWAP_MODE_REOPEN_CURRENT (by reop
case SYMBOL_SWAP_MODE_REOPEN_BID: str_swap_mode="SYMBOL_SWAP_MODE_REOPEN_BID (by reopening po
}
//--- string value output
temp_string=StringFormat(" SYMBOL_SWAP_MODE = %s\n",
str_swap_mode);
StringAdd(output_string,temp_string);
//--- double value output with default accuracy
double swap_long=SymbolInfoDouble(_Symbol,SYMBOL_SWAP_LONG);
margin_maintenance);
StringAdd(output_string,temp_string);
//--- int value output
int freeze_level=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_FREEZE_LEVEL);
temp_string=StringFormat(" SYMBOL_TRADE_FREEZE_LEVEL = %d (order freeze level in points)",
freeze_level);
StringAdd(output_string,temp_string);
Print(output_string);
Comment(output_string);
/* execution result
Contract specification for EURUSD:
SYMBOL_DIGITS = 5 (number of digits after the decimal point)
SYMBOL_POINT = 0.00001 (point value)
SYMBOL_SPREAD = 10 (current spread in points)
SYMBOL_TRADE_STOPS_LEVEL = 18 (minimal indention in points for Stop orders)
SYMBOL_TRADE_CONTRACT_SIZE = 100000 (contract size)
SYMBOL_TRADE_TICK_SIZE = 0.000010 (minimal price change)
SYMBOL_SWAP_MODE = SYMBOL_SWAP_MODE_POINTS (in points)
SYMBOL_SWAP_LONG = -0.700000 (buy order swap value)
SYMBOL_SWAP_SHORT = -1.000000 (sell order swap value)
SYMBOL_TRADE_MODE = SYMBOL_TRADE_MODE_FULL (no trade restrictions)
SYMBOL_VOLUME_MIN = 0.01 (minimal volume for a deal)
SYMBOL_VOLUME_STEP = 0.01 (minimal volume change step)
SYMBOL_VOLUME_MAX = 500 (maximal volume for a deal)
SYMBOL_TRADE_CALC_MODE = SYMBOL_CALC_MODE_FOREX (Forex)
SYMBOL_MARGIN_INITIAL = 0.00 (initial margin)
SYMBOL_MARGIN_MAINTENANCE = 0.00 (maintenance margin)
SYMBOL_TRADE_FREEZE_LEVEL = 0 (order freeze level in points)
*/
}
See also
PrintFormat, DoubleToString,ColorToString, TimeToString
Mathematical Functions
A set of mathematical and trigonometric functions.
Function Action
MathAbs
The function returns the absolute value (modulus) of the specified numeric value.
double MathAbs(
double value // numeric value
);
Parameters
value
[in] Numeric value.
Return Value
Note
MathArccos
The function returns the arccosine of x within the range 0 to p in radians.
double MathArccos(
double val // -1<val<1
);
Parameters
val
[in] The val value between -1 and 1, the arc cosine of which is to be calculated.
Return Value
Arc cosine of a number in radians. If val is less than -1 or more than 1, the function returns NaN
(indeterminate value).
Note
See also
R eal types (double, float)
MathArcsin
The function returns the arc sine of x within the range of -p /2 to p /2 radians.
double MathArcsin(
double val // -1<value<1
);
Parameters
val
[in] The val value between -1 and 1, the arc sine of which is to be calculated.
Return Value
Arc sine of the val number in radians within the range of -p /2 to p /2 radians. If val is less than -1
or more than 1, the function returns NaN (indeterminate value).
Note
See also
R eal types (double, float)
MathArctan
The function returns the arc tangent of x. If x is equal to 0, the function returns 0.
double MathArctan(
double value // tangent
);
Parameters
value
[in] A number representing a tangent.
Return Value
Note
MathCeil
The function returns integer numeric value closest from above.
double MathCeil(
double val // number
);
Parameters
val
[in] Numeric value.
Return Value
Numeric value representing the smallest integer that exceeds or equals to val.
Note
MathCos
The function returns the cosine of an angle.
double MathCos(
double value // number
);
Parameters
value
[in] Angle in radians.
Return Value
Note
MathExp
The function returns the value of e raised to the power of d.
double MathExp(
double value // power for the number e
);
Parameters
value
[in] A number specifying the power.
Return Value
A number of double type. In case of overflow the function returns INF (infinity), in case of underflow
MathExp returns 0.
Note
See also
R eal types (double, float)
MathFloor
The function returns integer numeric value closest from below.
double MathFloor(
double val // number
);
Parameters
val
[in] Numeric value.
Return Value
A numeric value representing the largest integer that is less than or equal to val.
Note
MathLog
The function returns a natural logarithm.
double MathLog(
double val // value to take the logarithm
);
Parameters
val
[in] Value logarithm of which is to be found.
Return Value
The natural logarithm of val in case of success. If val is negative, the function returns NaN
(undetermined value). If val is equal to 0, the function returns I NF (infinity).
Note
See also
R eal types (double, float)
MathLog
R eturns the logarithm of a number by base 10.
double MathLog10(
double val // number to take logarithm
);
Parameters
val
[in] Numeric value the common logarithm of which is to be calculated.
Return Value
The common logarithm in case of success. If val is negative, the function returns NaN
(undetermined value). If val is equal to 0, the function returns I NF (infinity).
Note
See also
R eal types (double, float)
MathMax
The function returns the maximal value of two values.
double MathMax(
double value1, // first value
double value2 // second value
);
Parameters
value1
[in] First numeric value.
value2
[in] Second numeric value.
Return Value
Note
Instead of MathMax() you can use fmax(). Functions fmax(), fmin(), MathMax(), MathMin() can
work with integer types without typecasting them to the type of double.
If parameters of different types are passed into a function, the parameter of the smaller type is
automatically cast to the larger type. The type of the return value corresponds to the larger type.
MathMin
The function returns the minimal value of two values.
double MathMin(
double value1, // first value
double value2 // second value
);
Parameters
value1
[in] First numeric value.
value2
[in] Second numeric value.
Return Value
Note
Instead of MathMin() you can use fmin(). Functions fmax(), fmin(), MathMax(), MathMin() can work
with integer types without typecasting them to the type of double.
If parameters of different types are passed into a function, the parameter of the smaller type is
automatically cast to the larger type. The type of the return value corresponds to the larger type.
MathMod
The function returns the real remainder of division of two numbers.
double MathMod(
double value, // dividend value
double value2 // divisor value
);
Parameters
value
[in] Dividend value.
value2
[in] Divisor value.
Return Value
The MathMod function calculates the real remainder f from expression val/y so that val = i * y + f ,
where i is an integer, f has the same sign as val, and the absolute value of f is less than the
absolute value of y.
Note
MathPow
The function raises a base to a specified power.
double MathPow(
double base, // base
double exponent // exponent value
);
Parameters
base
[in] Base.
exponent
[in] Exponent value.
Return Value
Note
MathRand
R eturns a pseudorandom integer within the range of 0 to 32767.
int MathRand();
Return Value
Note
Before the first call of the function, it's necessary to call MathSrand to set the generator of
pseudorandom numbers to the initial state.
Note
MathRound
The function returns a value rounded off to the nearest integer of the specified numeric value.
double MathRound(
double value // value to be rounded
);
Parameters
value
[in] Numeric value before rounding.
Return Value
Note
MathSin
R eturns the sine of a specified angle.
double MathSin(
double value // argument in radians
);
Parameters
value
[in] Angle in radians.
Return Value
Note
MathSqrt
R eturns the s quare root of a number.
double MathSqrt(
double value // positive number
);
Parameters
value
[in] Positive numeric value.
Return Value
S quare root of value. If value is negative, MathS qrt returns NaN (indeterminate value).
Note
See also
R eal types (double, float)
MathSrand
Sets the starting point for generating a series of pseudorandom integers.
void MathSrand(
int seed // initializing number
);
Parameters
seed
[in] Starting number for the sequence of random numbers.
Return Value
No return value.
Note
The MathR and() function is used for generating a sequence of pseudorandom numbers. Call of
MathSrand() with a certain initializing number allows to always produces the same sequence of
pseudorandom numbers.
To ensure receipt of non-recurring sequence, use the call of MathSrand(GetTick Count()), since the
value of GetTick Count() increases from the moment of the start of the operating system and is not
repeated within 49 days, until the built-in counter of milliseconds overflows. Use of
MathSrand(TimeCurrent()) is not suitable, because the TimeCurrent() function returns the time of
the last tick , which can be unchanged for a long time, for example at the week end.
Initialization of the random number generator using MathSrand() for indicators and Expert Advisors
is better performed in the OnInit() handler; it saves you from the following multiple restarts of the
generator in OnTick () and OnCalculate().
Instead of the MathSrand() function you can use the srand() function.
Example:
#property description "The indicator shows the central limit theorem, which states:"
#property description "The sum of a sufficiently large number of weakly dependent random variables,
#property description "having approximately equal magnitude (none of the summands dominates,"
#property description "or makes a determining contribution to the sum), has a distribution close to
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- Properties of the graphical construction
#property indicator_label1 "Label"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrRoyalBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 5
//--- An input variable
input int sample_number=10;
//--- An indicator buffer to for drawing the distribution
double LabelBuffer[];
//--- A counter of ticks
double ticks_counter;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- Binding an array and an indicator buffer
SetIndexBuffer(0,LabelBuffer,INDICATOR_DATA);
//--- turn the indicator buffer around from the present to the past
ArraySetAsSeries(LabelBuffer,true);
//--- Initialize the generator of random numbers
MathSrand(GetTickCount());
//--- Initialize the counter of ticks
ticks_counter=0;
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- For a zero counter reset the indicator buffer
if(ticks_counter==0) ArrayInitialize(LabelBuffer,0);
//--- Increase the counter
ticks_counter++;
//--- We should periodically reset the counter ticks, to revive the distribution
if(ticks_counter>100)
{
Print("We've reset the indicator values, let's start filling the cells once again");
ticks_counter=0;
}
//--- Get a sample of random values as the sum of three numbers from 0 to 7
for(int i=0;i<sample_number;i++)
{
//--- Calculation of the index of the cell, where the random number falls as the sum of three
int rand_index=0;
//--- Get three random numbers from 0 to 7
for(int k=0;k<3;k++)
{
MathTan
The function returns a tangent of a number.
double MathTan(
double rad // argument in radians
);
Parameters
rad
[in] Angle in radians.
Return Value
Tangent of rad. If rad is greater than or equal to 263, or less than or equal to -263, a loss of
significance in the result occurs, in which case the function returns an indefinite number.
Note
See also
R eal types (double, float)
MathIsValidNumber
It check s the correctness of a real number.
bool MathIsValidNumber(
double number // number to check
);
Parameters
number
[in] Check ed numeric value.
Return Value
It returns true, if the check ed value is an acceptable real number. If the check ed value is a plus or
minus infinity, or " not a number" (NaN), the function returns false.
Example:
double abnormal=MathArcsin(2.0);
if(!MathIsValidNumber(abnormal)) Print("Attention! MathArcsin(2.0) = ",abnormal);
See also
R eal types (double, float)
MathExp1
R eturns the value of the expression MathExp(x)-1.
double MathExp1(
double value // power for the number e
);
Parameters
value
[in] The number specifying the power.
Return Value
A value of the double type. In case of overflow the function returns INF (infinity), in case of
underflow MathExp returns 0.
Note
At values of x close to 0, the MathExp1(x) function generates much more accurate values than the
MathExp(x)-1 function.
Instead of the MathExp1() function you can use the expm1() function.
See also
R eal types (double, float)
MathLog1p
R eturns the value of the expression MathLog(1+x).
double MathLog1p(
double value // value to take the logarithm
);
Parameters
value
[in] The value, the logarithm of which is to be calculated.
Return Value
The natural logarithm of the value (value + 1) if successful. If value is < -1, the function returns NaN
(undefined value). If value is equal to -1, the function returns I NF (infinity).
Note
At values of x close to 0, the MathLog 1p(x) function generates much more accurate values than the
MathLog(1+x) function.
Instead of the MathLog 1p() function you can use the log 1p() function.
See also
R eal types (double, float)
MathArccosh
R eturns the hyperbolic arccosine.
double MathArccosh(
double value // 1 <= value < ∞
);
Parameters
value
[in] The value, the hyperbolic arccosine of which is to be calculated.
Return Value
The hyperbolic arccosine of the number. If value is less than +1, the function returns NaN (undefined
value).
Note
Instead of the MathArccosh() function you can use the acosh() function.
See also
R eal types (double, float)
MathArcsinh
R eturns the hyperbolic arcsine.
double MathArcsinh(
double value // -∞ < value < +∞
);
Parameters
val
[in] The value, the hyperbolic arcsine of which is to be calculated.
Return Value
Note
Instead of the MathArcsinh() function you can use the asinh() function.
See also
R eal types (double, float)
MathArctanh
R eturns the hyperbolic arctangent.
double MathArctanh(
double value // value in the range of -1 < value < 1
);
Parameters
value
[in] Number within the range of -1 < value < 1, which represents the tangent.
Return Value
Note
Instead of the MathArctanh() function you can use the atanh() function.
MathCosh
R eturns the hyperbolic cosine of the number.
double MathCosh(
double value // number
);
Parameters
value
[in] Value.
Return Value
The hyperbolic cosine of the number, value within the range of +1 to positive infinity.
Note
Instead of the MathCosh() function you can use the cosh() function.
MathSinh
R eturns the hyperbolic sine of the number.
double MathSinh(
double value // number
);
Parameters
value
[in] Value.
Return Value
Note
Instead of the MathSinh() function you can use the sinh() function.
MathTanh
R eturns the hyperbolic tangent of the number.
double MathTanh(
double value // number
);
Parameters
value
[in] Value.
Return Value
The hyperbolic tangent of the number, value within the range of -1 to +1.
Note
Instead of the MathTanh() function you can use the tanh() function.
See also
R eal types (double, float)
MathSwap
Change the order of bytes in the ushort type value.
ushort MathSwap(
ushort value // value
);
Parameters
value
[in] Value for changing the order of bytes.
Return Value
MathSwap
Change the order of bytes in the uint type value.
uint MathSwap(
uint value // value
);
Parameters
value
[in] Value for changing the order of bytes.
Return Value
MathSwap
Change the order of bytes in the ulong type value.
ulong MathSwap(
ulong value // value
);
Parameters
value
[in] Value for changing the order of bytes.
Return Value
See also
Network functions, Sock etR ead, Sock etSend, Sock etTls R ead, Sock etTls R eadAvailable, Sock etTlsSend
String Functions
This is a group of functions intended for work ing with data of the string type.
Function Action
StringAdd
The function adds a substring to the end of a string.
bool StringAdd(
string& string_var, // string, to which we add
string add_substring // string, which is added
);
Parameters
string_var
[in][out] String, to which another one is added.
add_substring
[in] String that is added to the end of a source string.
Return Value
In case of success returns true, otherwise false. In order to get an error code, the GetLastError()
function should be called.
Example:
void OnStart()
{
long length=1000000;
string a="a",b="b",c;
//--- first method
uint start=GetTickCount(),stop;
long i;
for(i=0;i<length;i++)
{
c=a+b;
}
stop=GetTickCount();
Print("time for 'c = a + b' = ",(stop-start)," milliseconds, i = ",i);
{
StringConcatenate(c,a,b);
}
stop=GetTickCount();
Print("time for 'StringConcatenate(c,a,b)' = ",(stop-start)," milliseconds, i = ",i);
}
See also
StringConcatenate, StringSplit, StringSubstr
StringBufferLen
The function returns the size of buffer allocated for the string.
int StringBufferLen(
string string_var // string
)
Parameters
string_var
[in] String.
Return Value
The value 0 means that the string is constant and buffer size can't be changed. -1 means that the
string belongs to the client terminal, and modification of the buffer contents can have
indeterminate results.
Example:
void OnStart()
{
long length=1000;
string a="a",b="b";
//---
long i;
Print("before: StringBufferLen(a) = ",StringBufferLen(a),
" StringLen(a) = ",StringLen(a));
for(i=0;i<length;i++)
{
StringAdd(a,b);
}
Print("after: StringBufferLen(a) = ",StringBufferLen(a),
" StringLen(a) = ",StringLen(a));
}
See also
String Add, StringInit, StringLen, String Fill
StringCompare
The function compares two strings and returns the comparison result in form of an integer.
int StringCompare(
const string& string1, // the first string in the comparison
const string& string2, // the second string in the comparison
bool case_sensitive=true // case sensitivity mode selection for the comparison
);
Parameters
string1
[in] The first string.
string2
[in] The second string.
case_sensitive=true
[in] Case sensitivity mode selection. If it is true, then "A">" a" . If it is false, then "A"=" a" . By
default the value is equal to true.
Return Value
· -1 (minus one), if string 1<string 2
· 0 (zero), if string 1=string 2
· 1 (one), if string 1>string 2
Note
The strings are compared symbol by symbol, the symbols are compared in the alphabetic order in
accordance with the current code page.
Example:
void OnStart()
{
//--- what is larger - apple or home?
string s1="Apple";
string s2="home";
{
if(result2<0)PrintFormat("Case insensitive comparison: %s < %s",s1,s2);
else PrintFormat("Case insensitive comparison: %s = %s",s1,s2);
}
/* Result:
Case-sensitive comparison: Apple < home
Case insensitive comparison: Apple < home
*/
}
See also
String Type, CharToString(), ShortToString(), StringToCharArray(), StringToShortArray(),
String GetCharacter(), Use of a Codepage
StringConcatenate
The function forms a string of passed parameters and returns the size of the formed string.
Parameters can be of any type. Number of parameters can't be less than 2 or more than 64.
int StringConcatenate(
string& string_var, // string to form
void argument1 // first parameter of any simple type
void argument2 // second parameter of any simple type
... // next parameter of any simple type
);
Parameters
string_var
[out] String that will be formed as a result of concatenation.
argumentN
[in] Any comma separated values. From 2 to 63 parameters of any simple type.
Return Value
R eturns the string length, formed by concatenation of parameters transformed into string type.
Parameters are transformed into strings according to the same rules as in Print() and Comment().
See also
String Add, StringSplit, StringSubstr
StringFill
It fills out a selected string by specified symbols.
bool StringFill(
string& string_var, // string to fill
ushort character // symbol that will fill the string
);
Parameters
string_var
[in][out] String, that will be filled out by the selected symbol.
character
[in] Symbol, by which the string will be filled out.
Return Value
In case of success returns true, otherwise - false. To get the error code call GetLastError().
Note
Filling out a string at place means that symbols are inserted directly to the string without
transitional operations of new string creation or copying. This allows to save the operation time.
Example:
void OnStart()
{
string str;
StringInit(str,20,'_');
Print("str = ",str);
StringFill(str,0);
Print("str = ",str,": StringBufferLen(str) = ", StringBufferLen(str));
}
// Result
// str = ____________________
// str = : StringBufferLen(str) = 20
//
See also
String BufferLen, StringLen, StringInit
StringFind
Search for a substring in a string.
int StringFind(
string string_value, // string in which search is made
string match_substring, // what is searched
int start_pos=0 // from what position search starts
);
Parameters
string_value
[in] String, in which search is made.
match_substring
[in] Searched substring.
start_pos=0
[in] Position in the string from which search is started.
Return Value
R eturns position number in a string, from which the searched substring starts, or -1, if the substring
is not found.
See also
StringSubstr, String GetCharacter, StringLen, StringLen
StringGetCharacter
R eturns value of a symbol, located in the specified position of a string.
ushort StringGetCharacter(
string string_value, // string
int pos // symbol position in the string
);
Parameters
string_value
[in] String.
pos
[in] Position of a symbol in the string. Can be from 0 to StringLen(text) -1.
Return Value
Symbol code or 0 in case of an error. To get the error code call GetLastError().
See also
StringSetCharacter, String BufferLen, StringLen, String Fill, StringInit, StringToCharArray,
StringToShortArray
StringInit
Initializes a string by specified symbols and provides the specified string size.
bool StringInit(
string& string_var, // string to initialize
int new_len=0, // required string length after initialization
ushort character=0 // symbol, by which the string will be filled
);
Parameters
string_var
[in][out] String that should be initialized and deinitialized.
new_len=0
[in] String length after initialization. If length=0, it deinitializes the string, i.e. the string buffer
is cleared and the buffer address is zeroed.
character=0
[in] Symbol to fill the string.
Return Value
In case of success returns true, otherwise - false. To get the error code call GetLastError().
Note
If character=0 and the length new_len>0, the buffer of the string of indicated length will be
distributed and filled by zeroes. The string length will be equal to zero, because the whole buffer is
filled out by string terminators.
Example:
void OnStart()
{
//---
string str;
StringInit(str,200,0);
Print("str = ",str,": StringBufferLen(str) = ",
StringBufferLen(str)," StringLen(str) = ",StringLen(str));
}
/* Result
str = : StringBufferLen(str) = 200 StringLen(str) = 0
*/
See also
String BufferLen, StringLen
StringLen
R eturns the number of symbols in a string.
int StringLen(
string string_value // string
);
Parameters
string_value
[in] String to calculate length.
Return Value
See also
String BufferLen, StringTrimLeft, StringTrimR ight, StringToCharArray, StringToShortArray
StringSetLength
Sets a specified length (in characters) for a string.
bool StringSetLength(
string& string_var, // string
uint new_length // new string length
);
Parameters
string_var
[in][out] String, for which a new length in characters should be set.
new_capacity
[in] R equired string length in characters. If new_length is less than the current size, the excessive
characters are discarded.
Return Value
In case of successful execution, returns true, otherwise - false. To receive an error code, the
GetLastError() function should be called.
Note
TheStringSetLength() function does not change the size of the buffer allocated for a string.
See also
StringLen, String BufferLen, String R eserve StringInit, StringSetCharacter
StringReplace
It replaces all the found substrings of a string by a set sequence of symbols.
int StringReplace(
string& str, // the string in which substrings will be replaced
const string find, // the searched substring
const string replacement // the substring that will be inserted to the found positions
);
Parameters
str
[in][out] The string in which you are going to replace substrings.
find
[in] The desired substring to replace.
replacement
[in] The string that will be inserted instead of the found one.
Return Value
The function returns the number of replacements in case of success, otherwise -1. To get an error
code call the GetLastError() function.
Note
If the function has run successfully but no replacements have been made (the substring to replace
was not found), it returns 0.
The error can result from incorrect str or find parameters (empty or non-initialized string, see
StringInit() ). Besides, the error occurs if there is not enough memory to complete the replacement.
Example:
string text="The quick brown fox jumped over the lazy dog.";
int replaced=StringReplace(text,"quick","slow");
replaced+=StringReplace(text,"brown","black");
replaced+=StringReplace(text,"fox","bear");
Print("Replaced: ", replaced,". Result=",text);
// Result
// Replaced: 3. Result=The slow black bear jumped over the lazy dog.
//
See also
StringSetCharacter(), StringSubstr()
StringReserve
R eserves the buffer of a specified size for a string in memory.
bool StringReserve(
string& string_var, // string
uint new_capacity // buffer size for storing a string
);
Parameters
string_var
[in][out] String the buffer size should change the size for.
new_capacity
[in] Buffer size required for a string. If the new_capacity size is less than the string length, the
size of the current buffer does not change.
Return Value
In case of successful execution, returns true, otherwise - false. To receive an error code, the
GetLastError() function should be called.
Note
Generally, the string size is not equal to the size of the buffer meant for storing the string. W hen
creating a string, the appropriate buffer is usually allocated with a margin. The String R eserve()
function allows managing the buffer size and specify the optimal size for future operations.
Unlik e StringInit(), the String R eserve() function does not change the string contents and does not fill
it with characters.
Example:
void OnStart()
{
string s;
//--- check the operation speed without using StringReserve
ulong t0=GetMicrosecondCount();
for(int i=0; i< 1024; i++)
s+=" "+(string)i;
ulong msc_no_reserve=GetMicrosecondCount()-t0;
s=NULL;
//--- now, let's do the same using StringReserve
StringReserve(s,1024 * 3);
t0=GetMicrosecondCount();
for(int i=0; i< 1024; i++)
s+=" "+(string)i;
ulong msc_reserve=GetMicrosecondCount()-t0;
//--- check the time
Print("Test with StringReserve passed for "+(string)msc_reserve+" msc");
Print("Test without StringReserve passed for "+(string)msc_no_reserve+" msc");
/* Result:
See also
String BufferLen, StringSetLength, StringInit, StringSetCharacter
StringSetCharacter
R eturns copy of a string with a changed character in a specified position.
bool StringSetCharacter(
string& string_var, // string
int pos, // position
ushort character // character
);
Parameters
string_var
[in][out] String.
pos
[in] Position of a character in a string. Can be from 0 to StringLen(text).
character
[in] Symbol code Unicode.
Return Value
In case of success returns true, otherwise false. In order to get an error code, the GetLastError()
function should be called.
Note
If pos is less than string length and the symbol code value = 0, the string is cut off (but the buffer
size, distributed for the string remains unchanged). The string length becomes equal to pos.
If pos is equal to string length, the specified symbol is added at the string end, and the length is
enlarged by one.
Example:
void OnStart()
{
string str="0123456789";
Print("before: str = ",str,",StringBufferLen(str) = ",
StringBufferLen(str)," StringLen(str) = ",StringLen(str));
//--- add zero value in the middle
StringSetCharacter(str,6,0);
Print("after: str = ",str,",StringBufferLen(str) = ",
StringBufferLen(str)," StringLen(str) = ",StringLen(str));
//--- add symbol at the end
int size=StringLen(str);
StringSetCharacter(str,size,'+');
Print("addition: str = ",str,",StringBufferLen(str) = ",
StringBufferLen(str)," StringLen(str) = ",StringLen(str));
}
/* Result
before: str = 0123456789 ,StringBufferLen(str) = 0 StringLen(str) = 10
See also
String BufferLen, StringLen, String Fill, StringInit, CharToString, ShortToString, CharArrayToString,
ShortArrayToString
StringSplit
Gets substrings by a specified separator from the specified string, returns the number of substrings
obtained.
int StringSplit(
const string string_value, // A string to search in
const ushort separator, // A separator using which substrings will be searched
string & result[] // An array passed by reference to get the found substrings
);
Parameters
string_value
[in] The string from which you need to get substrings. The string will not change.
pos
[in] The code of the separator character. To get the code, you can use the String GetCharacter()
function.
result[]
[out] An array of strings where the obtained substrings are located.
Return Value
The number of substrings in the result[] array. If the separator is not found in the passed string,
only one source string will be placed in the array.
If string _value is empty or NULL, the function will return zero. In case of an error the function
returns -1. To get the error code, call the GetLastError() function.
Example:
See also
String R eplace(), StringSubstr(), StringConcatenate()
StringSubstr
Extracts a substring from a text string starting from the specified position.
string StringSubstr(
string string_value, // string
int start_pos, // position to start with
int length=-1 // length of extracted string
);
Parameters
string_value
[in] String to extract a substring from.
start_pos
[in] Initial position of a substring. Can be from 0 to StringLen(text) -1.
length=-1
[in] Length of an extracted substring. If the parameter value is equal to -1 or parameter isn't set,
the substring will be extracted from the indicated position till the string end.
Return Value
See also
StringSplit, String Find, String GetCharacter
StringToLower
Transforms all symbols of a selected string into lowercase.
bool StringToLower(
string& string_var // string to process
);
Parameters
string_var
[in][out] String.
Return Value
In case of success returns true, otherwise - false. To get the error code call GetLastError().
See also
StringToUpper, StringTrimLeft, StringTrimR ight
StringToUpper
Transforms all symbols of a selected string into capitals.
bool StringToUpper(
string& string_var // string to process
);
Parameters
string_var
[in][out] String.
Return Value
In case of success returns true, otherwise - false. To get the error code call GetLastError().
See also
StringToLower, StringTrimLeft, StringTrimR ight
StringTrimLeft
The function cuts line feed characters, spaces and tabs in the left part of the string till the first
meaningful symbol. The string is modified at place.
int StringTrimLeft(
string& string_var // string to cut
);
Parameters
string_var
[in][out] String that will be cut from the left.
Return Value
See also
StringTrimR ight, StringToLower, StringToUpper
StringTrimRight
The function cuts line feed characters, spaces and tabs in the right part of the string after the last
meaningful symbol. The string is modified at place.
int StringTrimRight(
string& string_var // string to cut
);
Parameters
string_var
[in][out] String that will be cut from the right.
Return Value
See also
StringTrimLeft, StringToLower, StringToUpper
To arrange high-resolution counters and timers, use the GetTick Count() function, which produces
values in milliseconds.
Function Action
TimeCurrent
R eturns the last k nown server time, time of the last quote receipt for one of the symbols selected in
the " Mark et W atch" window. In the OnTick () handler, this function returns the time of the received
handled tick . In other cases (for example, call in handlers OnInit(), OnDeinit(), OnTimer() and so on)
this is the time of the last quote receipt for any symbol available in the " Mark et W atch" window, the
time shown in the title of this window. The time value is formed on a trade server and does not
depend on the time settings on your computer. There are 2 variants of the function.
datetime TimeCurrent();
datetime TimeCurrent(
MqlDateTime& dt_struct // structure type variable
);
Parameters
dt_struct
[out] M qlDateTime structure type variable.
Return Value
Note
If the M qlDateTime structure type variable has been passed as a parameter, it is filled accordingly.
To arrange high-resolution counters and timers, use the GetTick Count() function, which produces
values in milliseconds.
During testing in the strategy tester, TimeCurrent() is simulated according to historical data.
TimeTradeServer
R eturns the calculated current time of the trade server. Unlik e TimeCurrent(), the calculation of the
time value is performed in the client terminal and depends on the time settings on your computer.
There are 2 variants of the function.
datetime TimeTradeServer();
datetime TimeTradeServer(
MqlDateTime& dt_struct // Variable of structure type
);
Parameters
dt_struct
[out] Variable of structure type M qlDateTime.
Return Value
Note
If the M qlDateTime structure type variable has been passed as a parameter, it is filled accordingly.
To arrange high-resolution counters and timers, use the GetTick Count() function, which produces
values in milliseconds.
During testing in the strategy tester, TimeTradeServer() is simulated according to historical data
and always equal to TimeCurrent().
TimeLocal
R eturns the local time of a computer, where the client terminal is running. There are 2 variants of the
function.
datetime TimeLocal();
datetime TimeLocal(
MqlDateTime& dt_struct // Variable of structure type
);
Parameters
dt_struct
[out] Variable of structure type M qlDateTime.
Return Value
Note
If the M qlDateTime structure type variable has been passed as a parameter, it is filled accordingly.
To arrange high-resolution counters and timers, use the GetTick Count() function, which produces
values in milliseconds.
During testing in the strategy tester, TimeLocal() is always equal to TimeCurrent() simulated server
time.
TimeGMT
R eturns the GMT, which is calculated tak ing into account the DST switch by the local time on the
computer where the client terminal is running. There are 2 variants of the function.
datetime TimeGMT();
datetime TimeGMT(
MqlDateTime& dt_struct // Variable of structure type
);
Parameters
dt_struct
[out] Variable of structure type M qlDateTime.
Return Value
Note
If the M qlDateTime structure type variable has been passed as a parameter, it is filled accordingly.
To arrange high-resolution counters and timers, use the GetTick Count() function, which produces
values in milliseconds.
During testing in the strategy tester, TimeGMT() is always equal to TimeTradeServer() simulated
server time.
TimeDaylightSavings
R eturns correction for daylight saving time in seconds, if the switch to summer time has been made.
It depends on the time settings of your computer.
int TimeDaylightSavings();
Return Value
TimeGMTOffset
R eturns the current difference between GMT time and the local computer time in seconds, tak ing into
account switch to winter or summer time. Depends on the time settings of your computer.
int TimeGMTOffset();
Return Value
The value of int type, representing the current difference between GMT time and the local time of
the computer TimeLocal in seconds.
TimeToStruct
Converts a value of datetime type (number of seconds since 01.01.1970) into a structure variable
M qlDateTime.
bool TimeToStruct(
datetime dt, // date and time
MqlDateTime& dt_struct // structure for the adoption of values
);
Parameters
dt
[in] Date value to convert.
dt_struct
[out] Variable of structure type M qlDateTime.
Return Value
True if successful, otherwise false. To get information about the error, call the GetLastError()
function.
StructToTime
Converts a structure variable M qlDateTime into a value of datetime type and returns the resulting
value.
datetime StructToTime(
MqlDateTime$ dt_struct // structure of the date and time
);
Parameters
dt_struct
[in] Variable of structure type M qlDateTime.
Return Value
The value of datetime type containing the number of seconds since 01.01.1970.
Account Information
Functions that return parameters of the current account.
Function Action
AccountInfoDouble
R eturns the value of the corresponding account property.
double AccountInfoDouble(
ENUM_ACCOUNT_INFO_DOUBLE property_id // identifier of the property
);
Parameters
property_id
[in] Identifier of the property. The value can be one of the values of
ENUM _ACCOUNT _INFO_DOUBL E.
Return Value
Example:
void OnStart()
{
//--- show all the information available from the function AccountInfoDouble()
printf("ACCOUNT_BALANCE = %G",AccountInfoDouble(ACCOUNT_BALANCE));
printf("ACCOUNT_CREDIT = %G",AccountInfoDouble(ACCOUNT_CREDIT));
printf("ACCOUNT_PROFIT = %G",AccountInfoDouble(ACCOUNT_PROFIT));
printf("ACCOUNT_EQUITY = %G",AccountInfoDouble(ACCOUNT_EQUITY));
printf("ACCOUNT_MARGIN = %G",AccountInfoDouble(ACCOUNT_MARGIN));
printf("ACCOUNT_MARGIN_FREE = %G",AccountInfoDouble(ACCOUNT_MARGIN_FREE));
printf("ACCOUNT_MARGIN_LEVEL = %G",AccountInfoDouble(ACCOUNT_MARGIN_LEVEL));
printf("ACCOUNT_MARGIN_SO_CALL = %G",AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL));
printf("ACCOUNT_MARGIN_SO_SO = %G",AccountInfoDouble(ACCOUNT_MARGIN_SO_SO));
}
See also
SymbolInfoDouble, SymbolInfoString, SymbolInfoInteger, PrintFormat
AccountInfoInteger
R eturns the value of the properties of the account.
long AccountInfoInteger(
ENUM_ACCOUNT_INFO_INTEGER property_id // Identifier of the property
);
Parameters
property_id
[in] Identifier of the property. The value can be one of the values of
ENUM _ACCOUNT _INFO_INT EGER .
Return Value
Note
Example:
void OnStart()
{
//--- show all the information available from the function AccountInfoInteger()
printf("ACCOUNT_LOGIN = %d",AccountInfoInteger(ACCOUNT_LOGIN));
printf("ACCOUNT_LEVERAGE = %d",AccountInfoInteger(ACCOUNT_LEVERAGE));
bool thisAccountTradeAllowed=AccountInfoInteger(ACCOUNT_TRADE_ALLOWED);
bool EATradeAllowed=AccountInfoInteger(ACCOUNT_TRADE_EXPERT);
ENUM_ACCOUNT_TRADE_MODE tradeMode=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE
ENUM_ACCOUNT_STOPOUT_MODE stopOutMode=(ENUM_ACCOUNT_STOPOUT_MODE)AccountInfoInteger(ACCOUNT_MARG
case(ACCOUNT_TRADE_MODE_CONTEST):
Print("This is a competition account");
break;
default:Print("This is a real account!");
}
See also
Account Information
AccountInfoString
R eturns the value of the corresponding account property.
string AccountInfoString(
ENUM_ACCOUNT_INFO_STRING property_id // Identifier of the property
);
Parameters
property_id
[in] Identifier of the property. The value can be one of the values of
ENUM _ACCOUNT _INFO_ST R ING.
Return Value
Example:
void OnStart()
{
//--- Show all the information available from the function AccountInfoString()
Print("The name of the broker = ",AccountInfoString(ACCOUNT_COMPANY));
Print("Deposit currency = ",AccountInfoString(ACCOUNT_CURRENCY));
Print("Client name = ",AccountInfoString(ACCOUNT_NAME));
Print("The name of the trade server = ",AccountInfoString(ACCOUNT_SERVER));
}
See also
Account Information
State Checking
Functions that return parameters of the current state of the client terminal
Function Action
GetLastError
R eturns the contents of the system variable _LastError.
int GetLastError();
Return Value
R eturns the value of the last error that occurred during the execution of an mql5 program.
Note
After the function call, the contents of _LastError are not reset. To reset this variable, you need to
call R esetLastError().
See also
Trade Server R eturn Codes
IsStopped
Check s the forced shutdown of an mql5 program.
bool IsStopped();
Return Value
R eturns true, if the _StopFlag system variable contains a value other than 0. A nonzero value is
written into _StopFlag, if a mql5 program has been commanded to complete its operation. In this
case, you must immediately terminate the program, otherwise the program will be completed
forcibly from the outside after 3 seconds.
UninitializeReason
R eturns the code of a reason for deinitialization.
int UninitializeReason();
Return Value
R eturns the value of _UninitR eason which is formed before OnDeinit() is called. Value depends on
the reasons that led to deinitialization.
TerminalInfoInteger
R eturns the value of a corresponding property of the mql5 program environment.
int TerminalInfoInteger(
int property_id // identifier of a property
);
Parameters
property_id
[in] Identifier of a property. Can be one of the values of the ENUM _T ER MINAL _INFO_INT EGER
enumeration.
Return Value
TerminalInfoDouble
R eturns the value of a corresponding property of the mql5 program environment.
double TerminalInfoDouble(
int property_id // identifier of a property
);
Parameters
property_id
[in] Identifier of a property. Can be one of the values of the ENUM _T ER MINAL _INFO_DOUBL E
enumeration.
Return Value
TerminalInfoString
R eturns the value of a corresponding property of the mql5 program environment. The property must be
of string type.
string TerminalInfoString(
int property_id // identifier of a property
);
Parameters
property_id
[in] Identifier of a property. Can be one of the values of the ENUM _T ER MINAL _INFO_ST R ING
enumeration.
Return Value
MQLInfoInteger
R eturns the value of a corresponding property of a running mql5 program.
int MQLInfoInteger(
int property_id // identifier of a property
);
Parameters
property_id
[in] Identifier of a property. Can be one of values of the ENUM _MQL _INFO_INT EGER enumeration.
Return Value
MQLInfoString
R eturns the value of a corresponding property of a running mql5 program.
string MQLInfoString(
int property_id // Identifier of a property
);
Parameters
property_id
[in] Identifier of a property. Can be one of the ENUM _MQL _INFO_ST R ING enumeration.
Return Value
Symbol
R eturns the name of a symbol of the current chart.
string Symbol();
Return Value
Value of the _Symbol system variable, which stores the name of the current chart symbol.
Note
Unlik e Expert Advisors, indicators and scripts, services are not bound to a specific chart. Therefore,
Symbol() returns an empty string ("" ) for a service.
Period
R eturns the current chart timeframe.
ENUM_TIMEFRAMES Period();
Return Value
The contents of the _Period variable that contains the value of the current chart timeframe. The
value can be one of the values of the ENUM _TIM EFRAM ES enumeration.
Note
Unlik e Expert Advisors, indicators and scripts, services are not bound to a specific chart. Therefore,
Period() returns 0 for a service.
See also
Digits
R eturns the number of decimal digits determining the accuracy of price of the current chart symbol.
int Digits();
Return Value
The value of the _Digits variable which stores the number of decimal digits determining the
accuracy of price of the current chart symbol.
Point
R eturns the point size of the current symbol in the quote currency.
double Point();
Return Value
The value of the _Point variable which stores the point size of the current symbol in the quote
currency.
Event Handling
The MQL5 language provides handling of certain predefined events. The functions for handling these
events should be defined in an MQL5 program: function name, return type, a set of parameters (if
any) and their types should strictly correspond to the description of an event handling function.
The client terminal event handler uses the return and parameter types to identify functions processing
an event. If a certain function has some parameters or a return type not corresponding to the
descriptions below, such a function cannot be used for handling an event.
Function Description
The client terminal sends incoming events to corresponding open charts. Also, events may be
generated by charts (chart events) or mql5 programs (custom events). Generating graphical object
creation/deletion events can be enabled/disabled by setting the CHAR T _EVENT _OBJECT _CREAT E and
CHAR T _EVENT _OBJECT _DEL ET E chart properties. Each mql5 application and chart have their own
queue of events where all newly arrived events are placed.
A program gets events only from the chart it is running on. All events are handled one after another in
the order of their receipt. If the queue already contains the NewTick event or this event is in the
processing stage, then the new NewTick event is not added to mql5 application queue. Similarly, if the
ChartEvent is already in an mql5 program queue or such an event is being handled, then a new event
of this type is not placed into a queue. Timer event handling is processed in the same way – if the
Timer event is already in the queue or is being handled, no new timer event is set into a queue.
Event queues have a limited but sufficient size, so the queue overflow is unlik ely for a correctly
developed program. W hen the queue overflows, new events are discarded without being set into a
queue.
It is strongly recommended not to use infinite loops to handle events. Possible exceptions are scripts
handling a single Start event.
OnStart
The function is called in scripts and services when the Start event occurs. The function is intended for
one-time execution of actions implemented in a program. There are two function types.
Return Value
The entry " script script_name removed (result code N)" is created in the terminal journal after a
script execution is complete. H ere N is a value returned by the OnStart() function.
The entry " service service_name stopped (result code N)" is created in the terminal journal after a
service execution is complete. H ere N is a value returned by the OnStart() function.
The OnStart() call that returns the execution result is recommended for use since it not only allows for
a script or service execution, but also returns an error code or other useful data to analyze the
program execution result.
The version without a result return is left only for compatibility with old codes. It is not
recommended for use
void OnStart(void);
Note
OnStart() is the only function for handling events in scripts and services. No other events are sent to
these programs. In turn, the Start event is not passed to EAs and custom indicators.
Sample script:
See also
Event handling functions, Program running, Client terminal events
OnInit
The function is called in indicators and EAs when the Init event occurs. It is used to initialize a running
MQL5 program. There are two function types.
int OnInit(void);
Return Value
The OnInit() call that returns the execution result is recommended for use since it not only allows for
program initialization, but also returns an error code in case of an early program termination.
The version without a result return is left only for compatibility with old codes. It is not
recommended for use
void OnInit(void);
Note
The Init event is generated immediately after loading an EA or an indicator. The event is not
generated for scripts. The OnInit() function is used to initialize an MQL5 program. If OnInit() has a
return value of int type, the non-zero return code means failed initialization and generates the
Deinit event with the REASON_INIT FAIL ED deinitialization reason code.
OnInit() function of void type always means successful initialization and is not recommended for
use.
For optimizing the EA inputs, it is recommended to use values from the ENUM _INIT _RETCODE
enumeration as a return code. These values are intended for establishing the optimization process
management, including selection of the most suitable test agents. It is possible to request data on
agent configuration and resources (number of cores, free memory amount, etc.) using the
TerminalInfoInteger() function during the EA initialization before launching the test. Based on the
obtained data, you can either allow using the test agent or ban it from optimizing the EA.
ID Description
Using OnInit() returning INIT _FAIL ED/INIT _PARAM ET ER S _INCORRECT in the tester have some
peculiarities that should be considered when optimizing EAs :
· the set of parameters the OnInit() returned I NIT _PARAM ET ER S _I NCORRECT for is considered
unsuitable for testing and is not used to obtain the next population during genetic optimization.
Too many " discarded" parameter sets may lead to incorrect results when searching for optimal EA
parameters. The search algorithm assumes that the optimization criterion function is smooth and
has no gaps on the entire multitude of input parameters.
· if OnInit() returns I NIT _FAIL ED, this means that a test cannot be launched, and the EA is unloaded
from the agent's memory. The EA is loaded again to perform the next pass with a new set of
parameters. Launching the next optimization pass tak es much more time as compared to calling
TesterStop().
{
//--- check available RAM for the agent
int available_memory_mb=TerminalInfoInteger(TERMINAL_MEMORY_TOTAL);
if(available_memory_mb<2000)
{
PrintFormat("Insufficient memory for the test agent: %d MB",
available_memory_mb);
return (INIT_AGENT_NOT_SUITABLE);
}
}
//--- check for the indicator
indicator_handle=iCustom(_Symbol,_Period,"My_Indicator",ma_period);
if(indicator_handle==INVALID_HANDLE)
{
PrintFormat("Failed to generate My_Indicator handle. Error code %d",
GetLastError());
return (INIT_FAILED);
}
//--- EA initialization successful
return(INIT_SUCCEEDED);
}
See also
OnDeinit, Event handling functions, Program running, Client terminal events, Initialization of
variables, Creating and deleting objects
OnDeinit
The function is called in indicators and EAs when the Deinit event occurs. It is used to deinitialize a
running MQL5 program.
void OnDeinit(
const int reason // deinitialization reason code
);
Parameters
reason
[in] Deinitialization reason code.
Return Value
No return value
Note
Deinit event is generated for EAs and indicators in the following cases :
· before a re-initialization due to the change of a symbol or a chart period the mql5 program is
attached to;
· before a re-initialization due to the change of the inputs ;
· before unloading an mql5 program.
EA deinitialization reason codes can be received by the UninitializeR eason() function or from the
predefined _UninitR eason variable.
case REASON_CHARTCLOSE:
text="Chart was closed";break;
case REASON_PARAMETERS:
text="Input-parameter was changed";break;
case REASON_RECOMPILE:
text="Program "+__FILE__+" was recompiled";break;
case REASON_REMOVE:
text="Program "+__FILE__+" was removed from chart";break;
case REASON_TEMPLATE:
text="New template was applied to chart";break;
default:text="Another reason";
}
//---
return text;
}
See also
OnInit, Event handling functions, Program running, Client terminal events, Uninitialization reason
codes, Visibility scope and lifetime of variables, Creating and deleting objects
OnTick
The function is called in EAs when the NewTick event occurs to handle a new quote.
void OnTick(void);
Return Value
No return value
Note
The NewTick event is generated only for EAs upon receiving a new tick for a symbol of the chart the
EA is attached to. There is no point in defining the OnTick () function in a custom indicator or a
script since a NewTick event is not generated for them.
The Tick event is generated only for EAs, but this does not mean that EAs have to feature the
OnTick () function, since Timer, BookEvent and ChartEvent events are also generated for EAs in
addition to NewTick .
All events are handled one after another in the order of their receipt. If the queue already contains
the NewTick event or this event is in the processing stage, then the new NewTick event is not added
to mql5 application queue.
The NewTick event is generated regardless of whether auto trading is enabled (AutoTrading button).
Disabled auto trading means only a ban on sending trade requests from an EA. The EA operation is
not stopped.
Disabling auto trading by pressing the AutoTrading button does not interrupt the current execution
of the OnTick () function.
Example of the EA featuring its entire trading logic in the OnTick () function
//+------------------------------------------------------------------+
//| TradeByATR.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Sample EA trading in the \"explosive\" candle direction"
#property description "\"Explosive\" candle has the body size exceeding k*ATR"
#property description "The \"revers\" parameter reverses the signal direction"
int atr_handle;
//--- here we will store the last ATR values and the candle body
double last_atr,last_body;
datetime lastbar_timeopen;
double trade_lot;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- initialize global variables
last_atr=0;
last_body=0;
//--- set the correct volume
double min_lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
trade_lot=lots>min_lot? lots:min_lot;
//--- create ATR indicator handle
atr_handle=iATR(_Symbol,_Period,ATRperiod);
if(atr_handle==INVALID_HANDLE)
{
PrintFormat("%s: failed to create iATR, error code %d",__FUNCTION__,GetLastError());
return(INIT_FAILED);
}
//--- successful EA initialization
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- inform of the EA operation end code
Print(__FILE__,": Deinitialization reason code = ",reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- trading signal
static int signal=0; // +1 means a buy signal, -1 means a sell signal
//--- check and close old positions opened more than 'holdbars' bars ago
ClosePositionsByBars(holdbars,slippage,EXPERT_MAGIC);
//--- check for a new bar
if(isNewBar())
{
//--- check for a signal presence
signal=CheckSignal();
}
//--- if a netting position is opened, skip the signal - wait till it closes
if(signal!=0 && PositionsTotal()>0 && (ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGI
{
signal=0;
return; // exit the NewTick event handler and do not enter the market before a new bar appear
}
//--- for a hedging account, each position is held and closed separately
if(signal!=0)
{
//--- buy signal
if(signal>0)
{
PrintFormat("%s: Buy signal! Revers=%s",__FUNCTION__,string(revers));
if(Buy(trade_lot,slippage,EXPERT_MAGIC))
signal=0;
}
//--- sell signal
if(signal<0)
{
PrintFormat("%s: Sell signal! Revers=%s",__FUNCTION__,string(revers));
if(Sell(trade_lot,slippage,EXPERT_MAGIC))
signal=0;
}
}
//--- OnTick function end
}
//+------------------------------------------------------------------+
//| Check for a new trading signal |
//+------------------------------------------------------------------+
int CheckSignal()
{
//--- 0 means no signal
int res=0;
//--- get ATR value on a penultimate complete bar (the bar index is 2)
double atr_value[1];
if(CopyBuffer(atr_handle,0,2,1,atr_value)!=-1)
{
last_atr=atr_value[0];
//--- get data on the last closed bar to the MqlRates type array
MqlRates bar[1];
if(CopyRates(_Symbol,_Period,1,1,bar)!=-1)
{
//--- calculate the bar body size on the last complete bar
last_body=bar[0].close-bar[0].open;
//--- if the body of the last bar (with index 1) exceeds the previous ATR value (on the ba
if(MathAbs(last_body)>kATR*last_atr)
res=last_body>0?1:-1; // positive value for the upward candle
}
else
return (MarketOrder(ORDER_TYPE_BUY,volume,deviation,magicnumber));
}
//+------------------------------------------------------------------+
//| Sell at a market price with a specified volume |
//+------------------------------------------------------------------+
bool Sell(double volume,ulong deviation=10,ulong magicnumber=0)
{
//--- sell at a market price
return (MarketOrder(ORDER_TYPE_SELL,volume,deviation,magicnumber));
}
//+------------------------------------------------------------------+
//| Close positions by hold time in bars |
//+------------------------------------------------------------------+
void ClosePositionsByBars(int holdtimebars,ulong deviation=10,ulong magicnumber=0)
{
int total=PositionsTotal(); // number of open positions
//--- iterate over open positions
for(int i=total-1; i>=0; i--)
{
//--- position parameters
ulong position_ticket=PositionGetTicket(i); // position
string position_symbol=PositionGetString(POSITION_SYMBOL); // symbol
ulong magic=PositionGetInteger(POSITION_MAGIC); // position
datetime position_open=(datetime)PositionGetInteger(POSITION_TIME); // position
int bars=iBarShift(_Symbol,PERIOD_CURRENT,position_open)+1; // how many
//--- if a position's lifetime is already large, while MagicNumber and a symbol match
if(bars>holdtimebars && magic==magicnumber && position_symbol==_Symbol)
{
int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // number o
double volume=PositionGetDouble(POSITION_VOLUME); // position
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // position
string str_type=StringSubstr(EnumToString(type),14);
StringToLower(str_type); // lower the text case for correct message formatting
PrintFormat("Close position #%d %s %s %.2f",
position_ticket,position_symbol,str_type,volume);
//--- set an order type and sending a trade request
if(type==POSITION_TYPE_BUY)
MarketOrder(ORDER_TYPE_SELL,volume,deviation,magicnumber,position_ticket);
else
MarketOrder(ORDER_TYPE_BUY,volume,deviation,magicnumber,position_ticket);
}
}
}
//+------------------------------------------------------------------+
//| Prepare and send a trade request |
//+------------------------------------------------------------------+
bool MarketOrder(ENUM_ORDER_TYPE type,double volume,ulong slip,ulong magicnumber,ulong pos_ticket=0
{
See also
Event handling functions, Program running, Client terminal events, OnTimer, OnBookEvent,
OnChartEvent
OnCalculate
The function is called in the indicators when the Calculate event occurs for processing price data
changes. There are two function types. Only one of them can be used within a single indicator.
Parameters
rates_total
[in] Size of the price[] array or input series available to the indicator for calculation. In the second
function type, the parameter value corresponds to the number of bars on the chart it is launched
at.
prev_calculated
[in] Contains the value returned by the OnCalculate() function during the previous call. It is
designed to s k ip the bars that have not changed since the previous launch of this function.
begin
[in] Index value in the price[] array meaningful data starts from. It allows you to s k ip missing or
initial data, for which there are no correct values.
price[]
[in] Array of values for calculations. One of the price timeseries or a calculated indicator buffer
can be passed as the price[] array. Type of data passed for calculation can be defined using the
_AppliedTo predefined variable.
time{}
[in] Array with bar open time values.
open[]
[in] Array with Open price values.
high[]
[in] Array with H igh price values.
low[]
[in] Array with Low price values.
close[]
[in] Array with Close price values.
tick_volume[]
[in] Array with tick volume values.
volume[]
[in] Array with trade volume values.
spread[]
[in] Array with spread values for bars.
Return Value
int type value to be passed as the prev_calculated parameter during the next function call.
Note
If the OnCalculate() function is equal to zero, no indicator values are shown in the DataW indow of
the client terminal.
If the price data have been changed since the last call of the OnCalculate() function (a deeper
history has been loaded or gaps in the history have been filled), the value of the prev_calculated
input parameter is set to zero by the terminal itself.
To define the indexing direction in the time[], open[], high[], low[], close[], tick_volume[],
volume[] and spread[] arrays, call the A rrayGetA sSeries() function. In order not to depend on
defaults, call the ArraySetAsSeries() function for the arrays to work with.
W hen using the first function type, a necessary timeseries or indicator is selected by a user as the
price[] array in the Parameters tab when launching the indicator. To do this, specify the necessary
element in the drop-down list of the "Apply to" field.
To get custom indicator values from other mql5 programs, the iCustom() function is used. It returns
the indicator handle for subsequent operations. It is also possible to specify the required price []
array or the handle of another indicator. This parameter should be passed the last in the list of input
variables of a custom indicator.
It is necessary to use the connection between the value returned by the OnCalculate() function and
the prev_calculated second input parameter. W hen calling the function, the prev_calculated
parameter contains the value returned by the OnCalculate() function during the previous call. This
mak es it possible to implement resource-saving algorithms for calculating a custom indicator in
order to avoid repetitive calculations for the bars that have not changed since the previous launch of
this function.
Sample indicator
//+------------------------------------------------------------------+
//| OnCalculate_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Sample Momentum indicator calculation"
See also
ArrayGetAsSeries, ArraySetAsSeries, iCustom, Event handling functions, Program running, Client
terminal events, Access to timeseries and indicators
OnTimer
The function is called in EAs during the Timer event generated by the terminal at fixed time intervals.
void OnTimer(void);
Return Value
No return value
Note
The Timer event is periodically generated by the client terminal for an EA, which activated the timer
using the EventSetTimer() function. Usually, this function is called in the OnInit() function. W hen
the EA stops work ing, the timer should be eliminated using EventKillTimer(), which is usually called
in the OnDeinit() function.
Each Expert Advisor and each indicator work with its own timer receiving events solely from this
timer. During mql5 application shutdown, the timer is forcibly destroyed in case it has been created
but has not been disabled by EventKillTimer() function.
If you need to receive timer events more frequently than once per second, use
EventSetMillisecondTimer() for creating a high-resolution timer.
The minimum interval of 1000 milliseconds is used in the strategy tester. In general, when the timer
period is reduced, the testing time is increased, as the handler of timer events is called more often.
W hen work ing in real-time mode, timer events are generated no more than 1 time in 10-16
milliseconds due to hardware limitations.
Only one timer can be launched for each program. Each mql5 application and chart have their own
queue of events where all newly arrived events are placed. If the queue already contains Timer
event or this event is in the processing stage, then the new Timer event is not added to mql5
application queue.
//+------------------------------------------------------------------+
//| OnTimer_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Example of using the timer for calculating the trading server time"
#property description "It is recommended to run the EA at the end of a trading week before the week
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create a timer with a 1 second period
EventSetTimer(1);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy the timer after completing the work
EventKillTimer();
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//--- time of the OnTimer() first call
static datetime start_time=TimeCurrent();
//--- trade server time during the first OnTimer() call
static datetime start_tradeserver_time=0;
//--- calculated trade server time
static datetime calculated_server_time=0;
//--- local PC time
datetime local_time=TimeLocal();
//--- current estimated trade server time
datetime trade_server_time=TimeTradeServer();
//--- if a server time is unknown for some reason, exit ahead of time
if(trade_server_time==0)
return;
//--- if the initial trade server value is not set yet
if(start_tradeserver_time==0)
{
start_tradeserver_time=trade_server_time;
//--- set a calculated value of a trade server
Print(trade_server_time);
calculated_server_time=trade_server_time;
}
else
{
See also
EventSetTimer, EventSetMillisecondTimer, EventKillTimer, GetTick Count, GetMicrosecondCount,
Client terminal events
OnTrade
The function is called in EAs when the Trade event occurs. The function is meant for processing
changes in order, position and trade lists.
void OnTrade(void);
Return Value
No return value
Note
OnTrade() is called only for Expert Advisors. It is not used in indicators and scripts even if you add
there a function with the same name and type.
For any trade action (placing a pending order, opening /closing a position, placing stops, activating
pending orders, etc.), the history of orders and trades and/or the list of positions and current orders
is changed appropriately.
W hen handling an order, a trade server sends the terminal a message about the incoming Trade
event. To retrieve relevant data on orders and trades from history, it is necessary to perform a
trading history request using H istorySelect() first.
Each Trade event may appear as a result of one or several trade requests. Trade requests are sent
to the server using OrderSend() or OrderSendAsync(). Each request can lead to several trade events.
You cannot rely on the statement " One request - one Trade event" , since the processing of events
may be performed in several stages, and each operation may change the state of orders, positions
and the trade history.
OnTrade() handler is called after the appropriate OnTradeTransaction() calls. In general, there is no
exact correlation in the number of OnTrade () and OnTradeTransaction () calls. One OnTrade() call
corresponds to one or several OnTradeTransaction calls.
//+------------------------------------------------------------------+
//| OnTrade_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- set the limits of the trade history on the global scope
datetime start; // start date for trade history in cache
datetime end; // end date for trade history in cache
//--- global counters
int orders; // number of active orders
int positions; // number of open positions
int deals; // number of deals in the trade history cache
int history_orders; // number of orders in the trade history cache
bool started=false; // flag of counter relevance
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
end=TimeCurrent();
start=end-days*PeriodSeconds(PERIOD_D1);
PrintFormat("Limits of the history to be loaded: start - %s, end - %s",
TimeToString(start),TimeToString(end));
InitCounters();
//---
return(0);
}
//+------------------------------------------------------------------+
//| initialization of position, order and trade counters |
//+------------------------------------------------------------------+
void InitCounters()
{
ResetLastError();
//--- load history
bool selected=HistorySelect(start,end);
if(!selected)
{
PrintFormat("%s. Failed to load history from %s to %s to cache. Error code: %d",
__FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
return;
}
//--- get the current value
orders=OrdersTotal();
positions=PositionsTotal();
deals=HistoryDealsTotal();
history_orders=HistoryOrdersTotal();
started=true;
Print("Counters of orders, positions and deals successfully initialized");
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(started) SimpleTradeProcessor();
else InitCounters();
}
//+------------------------------------------------------------------+
//| called when a Trade event arrives |
//+------------------------------------------------------------------+
void OnTrade()
{
if(started) SimpleTradeProcessor();
else InitCounters();
}
//+------------------------------------------------------------------+
//| example of processing changes in trade and history |
//+------------------------------------------------------------------+
void SimpleTradeProcessor()
{
end=TimeCurrent();
ResetLastError();
//--- download trading history from the specified interval to the program cache
bool selected=HistorySelect(start,end);
if(!selected)
{
PrintFormat("%s. Failed to load history from %s to %s to cache. Error code: %d",
__FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
return;
}
//--- get the current values
int curr_orders=OrdersTotal();
int curr_positions=PositionsTotal();
int curr_deals=HistoryDealsTotal();
int curr_history_orders=HistoryOrdersTotal();
//--- check if the number of active orders has been changed
if(curr_orders!=orders)
{
//--- number of active orders has been changed
PrintFormat("Number of orders has been changed. Previous value is %d, current value is %d",
orders,curr_orders);
//--- update the value
orders=curr_orders;
}
//--- changes in the number of open positions
if(curr_positions!=positions)
{
//--- number of open positions has been changed
PrintFormat("Number of positions has been changed. Previous value is %d, current value is %d"
positions,curr_positions);
//--- update the value
positions=curr_positions;
}
//--- changes in the number of deals in the trade history cache
if(curr_deals!=deals)
{
//--- number of deals in the trade history cache has been changed
PrintFormat("Number of deals has been changed. Previous value is %d, current value is %d",
deals,curr_deals);
//--- update the value
deals=curr_deals;
}
//--- changes in the number of history orders in the trade history cache
if(curr_history_orders!=history_orders)
{
//--- number of history orders in the trade history cache has been changed
PrintFormat("Number of orders in history has been changed. Previous value is %d, current valu
history_orders,curr_history_orders);
//--- update the value
history_orders=curr_history_orders;
}
//--- checking if it is necessary to change the limits of the trade history to be requested in cach
CheckStartDateInTradeHistory();
}
//+------------------------------------------------------------------+
//| changing the start date for requesting the trade history |
//+------------------------------------------------------------------+
void CheckStartDateInTradeHistory()
{
//--- initial interval, if we were to start working right now
datetime curr_start=TimeCurrent()-days*PeriodSeconds(PERIOD_D1);
//--- make sure that the start limit of the trade history has not gone
//--- more than 1 day over the intended date
if(curr_start-start>PeriodSeconds(PERIOD_D1))
{
//--- correct the start date of history to be loaded in the cache
start=curr_start;
PrintFormat("New start limit of the trade history to be loaded: start => %s",
TimeToString(start));
//--- now reload the trade history for the updated interval
HistorySelect(start,end);
//--- correct the deal and order counters in history for further comparison
history_orders=HistoryOrdersTotal();
deals=HistoryDealsTotal();
}
}
//+------------------------------------------------------------------+
/* Sample output:
Limits of the history to be loaded: start - 2018.07.16 18:11, end - 2018.07.23 18:11
The counters of orders, positions and deals are successfully initialized
See also
OrderSend, OrderSendAsync, OnTradeTransaction, Client terminal events
OnTradeTransaction
The function is called in EAs when the TradeTransaction event occurs. The function is meant for
handling trade request execution results.
void OnTradeTransaction()
const MqlTradeTransaction& trans, // trade transaction structure
const MqlTradeRequest& request, // request structure
const MqlTradeResult& result // response structure
);
Parameters
trans
[in] M qlTradeTransaction type variable describing a transaction made on a trading account.
request
[in] M qlTradeR equest type variable describing a trade request that led to a transaction. It
contains the values for T RADE_T RANS ACTION_REQUEST type transaction only.
result
[in] M qlTradeR esult type variable containing an execution result of a trade request that led to a
transaction. It contains the values for T RADE_T RANS ACTION_REQUEST type transaction only.
Return Value
No return value
Note
OnTradeTransaction() is called to handle the TradeTransaction event sent by the trade server to the
terminal in the following cases :
· sending a trade request from an MQL5 program using the OrderSend()/OrderSendAsync()
functions and its subsequent execution;
· sending a trade request manually via the GUI and its subsequent execution;
· activations of pending and stop orders on the server;
· performing operations on the trade server side.
Data on transaction type is contained in the type field of the trans variable. Types of trade
transactions are described in the ENUM _T RADE_T RANS ACTION_T YPE enumeration:
· T RADE_T RANS ACTION_ORDER_ADD – adding a new active order
· T RADE_T RANS ACTION_ORDER_UPDAT E – changing an existing order
· T RADE_T RANS ACTION_ORDER_DEL ET E – deleting an order from the list of active ones
· T RADE_T RANS ACTION_DEAL _ADD – adding a deal to history
· T RADE_T RANS ACTION_DEAL _UPDAT E – changing a deal in history
· T RADE_T RANS ACTION_DEAL _DEL ET E – deleting a deal from history
· T RADE_T RANS ACTION_H ISTORY_ADD – adding an order to history as a result of execution or
cancelation
· T RADE_T RANS ACTION_H ISTORY_UPDAT E – changing an order in the order history
· T RADE_T RANS ACTION_H ISTORY_DEL ET E – deleting an order from the order history
· T RADE_T RANS ACTION_POSITION – position change not related to a trade execution
· T RADE_T RANS ACTION_REQUEST – notification that a trade request has been processed by the
server and the result of its processing has been received.
W hen handling transactions of T RADE_T RANS ACTION_REQUEST type, it is necessary to analyze the
second and third parameters of the OnTradeTransaction() function – request and result – to receive
additional information.
Sending a buy trade request leads to a chain of trade transactions on a trading account: 1) request
is accepted for processing, 2) an appropriate purchase order is created for the account, 3) the order
is then executed, 4) the executed order is removed from the list of active ones, 5) adding to the
history of orders, 6) the subsequent transaction is added to history and 7) a new position is created.
All these stages are trade transactions. The arrival of each such transaction to the terminal is the
TradeTransaction event. Priority of these transactions ' arrival at the terminal is not guaranteed.
Thus, you should not expect that one group of transactions will arrive after another one when
developing your trading algorithm.
W hen transactions are processed by the EA's OnTradeTransaction() handler, the terminal goes on
handling the incoming trade transactions. Thus, the trading account status may change at the
course of OnTradeTransaction() operation. For example, while an MQL5 program handles adding a
new order, it can be executed, deleted from the list of open orders and moved to history. The
program is notified of all these events.
Transactions queue length comprises 1024 elements. If OnTradeTransaction() handles yet another
transaction for too long, the previous ones can be superseded by new transactions in the queue.
OnTrade() handler is called after the appropriate OnTradeTransaction() calls. In general, there is no
exact correlation in the number of OnTrade () and OnTradeTransaction () calls. One OnTrade() call
corresponds to one or several OnTradeTransaction calls.
Each Trade event may appear as a result of one or several trade requests. Trade requests are sent
to the server using OrderSend() or OrderSendAsync(). Each request can lead to several trade events.
You cannot rely on the statement " One request - one Trade event" , since the processing of events
may be performed in several stages and each operation may change the state of orders, positions
and the trade history.
//+------------------------------------------------------------------+
//| OnTradeTransaction_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Sample listener of TradeTransaction events"
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
PrintFormat("LAST PING=%.f ms",
TerminalInfoInteger(TERMINAL_PING_LAST)/1000.);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//---
static int counter=0; // counter of OnTradeTransaction() calls
static uint lasttime=0; // time of the OnTradeTransaction() last call
//---
uint time=GetTickCount();
//--- if the last transaction was performed more than 1 second ago,
if(time-lasttime>1000)
{
counter=0; // then this is a new trade operation, an the counter can be reset
if(IS_DEBUG_MODE)
Print(" New trade operation");
}
lasttime=time;
counter++;
Print(counter,". ",__FUNCTION__);
//--- result of trade request execution
ulong lastOrderID =trans.order;
ENUM_ORDER_TYPE lastOrderType =trans.order_type;
ENUM_ORDER_STATE lastOrderState=trans.order_state;
//--- the name of the symbol, for which a transaction was performed
string trans_symbol=trans.symbol;
//--- type of transaction
ENUM_TRADE_TRANSACTION_TYPE trans_type=trans.type;
switch(trans.type)
{
case TRADE_TRANSACTION_POSITION: // position modification
{
ulong pos_ID=trans.position;
PrintFormat("MqlTradeTransaction: Position #%d %s modified: SL=%.5f TP=%.5f",
pos_ID,trans_symbol,trans.price_sl,trans.price_tp);
}
break;
case TRADE_TRANSACTION_REQUEST: // sending a trade request
PrintFormat("MqlTradeTransaction: TRADE_TRANSACTION_REQUEST");
break;
case TRADE_TRANSACTION_DEAL_ADD: // adding a trade
{
ulong lastDealID =trans.deal;
ENUM_DEAL_TYPE lastDealType =trans.deal_type;
double lastDealVolume=trans.volume;
//--- Trade ID in an external system - a ticket assigned by an exchange
string Exchange_ticket="";
if(HistoryDealSelect(lastDealID))
Exchange_ticket=HistoryDealGetString(lastDealID,DEAL_EXTERNAL_ID);
if(Exchange_ticket!="")
Exchange_ticket=StringFormat("(Exchange deal=%s)",Exchange_ticket);
}
break;
}
//--- order ticket
ulong orderID_result=result.order;
string retcode_result=GetRetcodeID(result.retcode);
if(orderID_result!=0)
PrintFormat("MqlTradeResult: order #%d retcode=%s ",orderID_result,retcode_result);
//---
}
//+------------------------------------------------------------------+
//| convert numeric response codes to string mnemonics |
//+------------------------------------------------------------------+
string GetRetcodeID(int retcode)
{
switch(retcode)
{
case 10004: return("TRADE_RETCODE_REQUOTE"); break;
case 10006: return("TRADE_RETCODE_REJECT"); break;
case 10007: return("TRADE_RETCODE_CANCEL"); break;
case 10008: return("TRADE_RETCODE_PLACED"); break;
case 10009: return("TRADE_RETCODE_DONE"); break;
case 10010: return("TRADE_RETCODE_DONE_PARTIAL"); break;
case 10011: return("TRADE_RETCODE_ERROR"); break;
case 10012: return("TRADE_RETCODE_TIMEOUT"); break;
case 10013: return("TRADE_RETCODE_INVALID"); break;
case 10014: return("TRADE_RETCODE_INVALID_VOLUME"); break;
case 10015: return("TRADE_RETCODE_INVALID_PRICE"); break;
case 10016: return("TRADE_RETCODE_INVALID_STOPS"); break;
case 10017: return("TRADE_RETCODE_TRADE_DISABLED"); break;
case 10018: return("TRADE_RETCODE_MARKET_CLOSED"); break;
case 10019: return("TRADE_RETCODE_NO_MONEY"); break;
case 10020: return("TRADE_RETCODE_PRICE_CHANGED"); break;
case 10021: return("TRADE_RETCODE_PRICE_OFF"); break;
case 10022: return("TRADE_RETCODE_INVALID_EXPIRATION"); break;
case 10023: return("TRADE_RETCODE_ORDER_CHANGED"); break;
case 10024: return("TRADE_RETCODE_TOO_MANY_REQUESTS"); break;
case 10025: return("TRADE_RETCODE_NO_CHANGES"); break;
case 10026: return("TRADE_RETCODE_SERVER_DISABLES_AT"); break;
case 10027: return("TRADE_RETCODE_CLIENT_DISABLES_AT"); break;
case 10028: return("TRADE_RETCODE_LOCKED"); break;
case 10029: return("TRADE_RETCODE_FROZEN"); break;
case 10030: return("TRADE_RETCODE_INVALID_FILL"); break;
case 10031: return("TRADE_RETCODE_CONNECTION"); break;
case 10032: return("TRADE_RETCODE_ONLY_REAL"); break;
case 10033: return("TRADE_RETCODE_LIMIT_ORDERS"); break;
case 10034: return("TRADE_RETCODE_LIMIT_VOLUME"); break;
case 10035: return("TRADE_RETCODE_INVALID_ORDER"); break;
case 10036: return("TRADE_RETCODE_POSITION_CLOSED"); break;
default:
return("TRADE_RETCODE_UNKNOWN="+IntegerToString(retcode));
break;
}
//---
}
See also
OrderSend, OrderSendAsync, OnTradeTransaction, Trade request structure, Trade transaction
structure, Trade transaction types, Trade operation types, Client terminal events
OnBookEvent
The function is called in indicators and EAs when the BookEvent event occurs. It is meant for handling
Depth of Mark et changes.
void OnBookEvent(
const string& symbol // symbol
);
Parameters
symbol
[in] Name of a symbol the BookEvent has arrived for
Return Value
No return value
Note
To get the BookEvent events for any symbol, simply subscribe to receive them for this symbol using
the Mark etBookAdd() function. To cancel subscription for receiving the BookEvent for a certain
symbol, call the Mark etBookR elease() function.
The BookEvent broadcasts within the entire chart. This means that if one application on a chart
subscribes to the BookEvent using the Mark etBookAdd function, all other indicators and EAs
launched on the same chart and having the OnBookEvent() handler receive this event as well.
Therefore, it is necessary to analyze a symbol name passed to the OnBookEvent() handler as the
symbol parameter.
Separate BookEvent counters sorted by symbols are provided for all applications running on the same
chart. This means that each chart may have multiple subscriptions to different symbols, and a
counter is provided for each symbol. Subscribing and unsubscribing from BookEvent changes the
subscription counter for specified symbols only within one chart. In other words, there may be two
adjacent charts to the BookEvent for the same symbol but different subscription counter values.
The initial subscription counter value is zero. At each Mark etBookAdd() call, the subscription counter
for a specified symbol on the chart is increased by one (chart symbol and symbol in Mark etBookAdd()
do not have to match). W hen calling Mark etBookR elease(), the counter of subscriptions for a
specified symbol within the chart is decreased by one. The BookEvent events for any symbol are
broadcast within the chart till the counter is equal to zero. Therefore, it is important that each
MQL5 program that contains Mark etBookAdd () calls correctly unsubscribes from getting events for
each symbol using Mark etBookR elease () at the end of its work . To achieve this, the number of
Mark etBookAdd() and Mark etBookR elease() calls should be even for each call during the entire MQL5
program lifetime. Using flags or custom subscription counters within the program allows you to
safely work with BookEvent events and prevents disabling subscriptions for getting this event in
third-party programs within the same chart.
BookEvent events are never s k ipped and are always placed into a queue even if handling the
previous BookEvent handling is not over yet.
Example
//+------------------------------------------------------------------+
//| OnBookEvent_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com/en/articles/2635"
#property version "1.00"
#property description "Example of measuring the market depth refresh rate using OnBookEvent()"
#property description "The code is taken from the article https://www.mql5.com/en/articles/2635"
//--- input parameters
input ulong ExtCollectTime =30; // test time in seconds
input ulong ExtSkipFirstTicks=10; // number of ticks skipped at start
//--- flag of subscription to BookEvent events
bool book_subscribed=false;
//--- array for accepting requests from the market depth
MqlBookInfo book[];
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- show the start
Comment(StringFormat("Waiting for the first %I64u ticks to arrive",ExtSkipFirstTicks));
PrintFormat("Waiting for the first %I64u ticks to arrive",ExtSkipFirstTicks);
//--- enable market depth broadcast
if(MarketBookAdd(_Symbol))
{
book_subscribed=true;
PrintFormat("%s: MarketBookAdd(%s) function returned true",__FUNCTION__,_Symbol);
}
else
PrintFormat("%s: MarketBookAdd(%s) function returned false! GetLastError()=%d",__FUNCTION__,_
//--- successful initialization
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialize expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- display deinitialization reason code
Print(__FUNCTION__,": Deinitialization reason code = ",reason);
//--- cancel subscription for getting market depth events
if(book_subscribed)
{
if(!MarketBookRelease(_Symbol))
PrintFormat("%s: MarketBookRelease(%s) returned false! GetLastError()=%d",_Symbol,GetLastE
else
book_subscribed=false;
}
//---
}
//+------------------------------------------------------------------+
//| BookEvent function |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
static ulong starttime=0; // test start time
static ulong tickcounter=0; // market depth update counter
//--- work with depth market events only if we subscribed to them ourselves
if(!book_subscribed)
return;
//--- count updates only for a certain symbol
if(symbol!=_Symbol)
return;
//--- skip first ticks to clear the queue and to prepare
tickcounter++;
if(tickcounter<ExtSkipFirstTicks)
return;
//--- remember the start time
if(tickcounter==ExtSkipFirstTicks)
starttime=GetMicrosecondCount();
//--- request for the market depth data
MarketBookGet(symbol,book);
//--- when to stop?
ulong endtime=GetMicrosecondCount()-starttime;
ulong ticks =1+tickcounter-ExtSkipFirstTicks;
// how much time has passed in microseconds since the start of the test?
if(endtime>ExtCollectTime*1000*1000)
{
PrintFormat("%I64u ticks for %.1f seconds: %.1f ticks/sec ",ticks,endtime/1000.0/1000.0,ticks
ExpertRemove();
return;
}
//--- display the counters in the comment field
if(endtime>0)
Comment(StringFormat("%I64u ticks for %.1f seconds: %.1f ticks/sec ",ticks,endtime/1000.0/100
}
See also
Mark etBookAdd, Mark etBookR elease, Mark etBookGet, OnTrade, OnTradeTransaction, OnTick , Event
handling functions, Program running, Client terminal events
OnChartEvent
The function is called in indicators and EAs when the ChartEvent event occurs. The function is meant
for handling chart changes made by a user or an MQL5 program.
void OnChartEvent()
const int id, // event ID
const long& lparam, // long type event parameter
const double& dparam, // double type event parameter
const string& sparam // string type event parameter
);
Parameters
id
[in] Event ID from the ENUM _CHAR T _EVENT enumeration.
lparam
[in] long type event parameter
dparam
[in] double type event parameter
sparam
[in] string type event parameter
Return Value
No return value
Note
There are 11 types of events that can be handled using the predefined OnChartEvent() function.
65535 IDs from CHAR T EVENT _CUSTOM to CHAR T EVENT _CUSTOM _L AST inclusive are provided for
custom events. To generate a custom event, use the EventChartCustom() function.
· CHAR T EVENT _CUSTOM+n — custom event I D, where n is within the range from 0 to 65535.
CHAR T EVENT _CUSTOM _L AST contains the last acceptable custom event ID
(CHAR T EVENT _CUSTOM+65535).
All MQL5 programs work in threads other than the main thread of the application. The main
application thread is responsible for handling all W indows system messages and, in its turn,
generates W indows messages for its own application as a result of this handling. For example,
moving the mouse on a chart (W M _MOUS E_MOVE event) generates several system messages for
subsequent rendering of the application window, and also sends internal messages to experts and
indicators launched on the chart. A situation may occur, where the main application thread has not
yet processed the W M _PAI NT system message (and therefore has not yet rendered the modified
chart), while an EA or an indicator has already received the mouse movement event. In this case,
the chart property CHAR T _FI R ST _VISI BL E_BAR will be changed only after the chart is rendered.
For each event type, the inputs of the OnChartEvent() function have certain values necessary for
handling that event. The table lists events and values passed via the parameters.
Keystrok e event CHAR T EVENT _KE pressed button The number of String value of
YDOWN code k eypresses the bit mas k ,
generated while which describes
the k ey was held the status of the
in the pressed k eyboard k eys
state
Custom event CHAR T EVENT _C Value defined by Value defined by Value defined by
with N number USTOM+N the the the
EventChartCusto EventChartCusto EventChartCusto
m() function m() function m() function
//+------------------------------------------------------------------+
//| OnChartEvent_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Sample chart event listener and custom events generator"
//--- service keys IDs
#define KEY_NUMPAD_5 12
#define KEY_LEFT 37
#define KEY_UP 38
#define KEY_RIGHT 39
#define KEY_DOWN 40
#define KEY_NUMLOCK_DOWN 98
#define KEY_NUMLOCK_LEFT 100
#define KEY_NUMLOCK_5 101
#define KEY_NUMLOCK_RIGHT 102
#define KEY_NUMLOCK_UP 104
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- display the CHARTEVENT_CUSTOM constant value
Print("CHARTEVENT_CUSTOM=",CHARTEVENT_CUSTOM);
//---
Print("Launched the EA ",MQLInfoString(MQL5_PROGRAM_NAME));
//--- set the flag of receiving chart object creation events
ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_CREATE,true);
//--- set the flag of receiving chart object removal events
ChartSetInteger(ChartID(),CHART_EVENT_OBJECT_DELETE,true);
//--- enabling mouse wheel scrolling messages
ChartSetInteger(0,CHART_EVENT_MOUSE_WHEEL,1);
//--- forced updating of chart properties ensures readiness for event processing
ChartRedraw();
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- tick counter for generating a custom event
static int tick_counter=0;
//--- divide accumulated ticks by this value
int simple_number=113;
//---
tick_counter++;
//--- send a custom event if the tick counter is multiple of simple_number
if(tick_counter%simple_number==0)
{
//--- form custom event ID from 0 to 65535
ushort custom_event_id=ushort(tick_counter%65535);
//--- send a custom event with parameters filling
EventChartCustom(ChartID(),custom_event_id,tick_counter,SymbolInfoDouble(Symbol(),SYMBOL_BID)
//--- add to a log for analyzing the example results
Print(__FUNCTION__,": Sent a custom event ID=",custom_event_id);
}
//---
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- keypress
if(id==CHARTEVENT_KEYDOWN)
{
switch((int)lparam)
{
case KEY_NUMLOCK_LEFT: Print("Pressed KEY_NUMLOCK_LEFT"); break;
case KEY_LEFT: Print("Pressed KEY_LEFT"); break;
case KEY_NUMLOCK_UP: Print("Pressed KEY_NUMLOCK_UP"); break;
case KEY_UP: Print("Pressed KEY_UP"); break;
case KEY_NUMLOCK_RIGHT: Print("Pressed KEY_NUMLOCK_RIGHT"); break;
case KEY_RIGHT: Print("Pressed KEY_RIGHT"); break;
case KEY_NUMLOCK_DOWN: Print("Pressed KEY_NUMLOCK_DOWN"); break;
case KEY_DOWN: Print("Pressed KEY_DOWN"); break;
case KEY_NUMPAD_5: Print("Pressed KEY_NUMPAD_5"); break;
case KEY_NUMLOCK_5: Print("Pressed KEY_NUMLOCK_5"); break;
default: Print("Pressed unlisted key");
}
}
//--- left-clicking on a chart
if(id==CHARTEVENT_CLICK)
Print("Mouse click coordinates on a chart: x = ",lparam," y = ",dparam);
//--- clicking on a graphical object
if(id==CHARTEVENT_OBJECT_CLICK)
Print("Clicking a mouse button on an object named '"+sparam+"'");
//--- object removed
if(id==CHARTEVENT_OBJECT_DELETE)
Print("Removed object named ",sparam);
//--- object created
if(id==CHARTEVENT_OBJECT_CREATE)
Print("Created object named ",sparam);
//--- changed object
if(id==CHARTEVENT_OBJECT_CHANGE)
Print("Changed object named ",sparam);
//--- object moved or anchor point coordinates changed
if(id==CHARTEVENT_OBJECT_DRAG)
Print("Changing anchor points of object named ",sparam);
//--- changed a text in the input field of the Edit graphical object
if(id==CHARTEVENT_OBJECT_ENDEDIT)
if(str_keys!="")
str_keys=", keys='"+StringSubstr(str_keys,0,StringLen(str_keys)-1)+"'";
PrintFormat("%s: X=%d, Y=%d, delta=%d%s",EnumToString(CHARTEVENT_MOUSE_WHEEL),x_cursor,y_curs
}
//--- event of resizing the chart or modifying the chart properties using the properties dialog win
if(id==CHARTEVENT_CHART_CHANGE)
Print("Changing the chart size or properties");
//--- custom event
if(id>CHARTEVENT_CUSTOM)
PrintFormat("Custom event ID=%d, lparam=%d, dparam=%G, sparam=%s",id,lparam,dparam,sparam);
}
//+------------------------------------------------------------------+
//| MouseState |
//+------------------------------------------------------------------+
string MouseState(uint state)
{
string res;
res+="\nML: " +(((state& 1)== 1)?"DN":"UP"); // mouse left
res+="\nMR: " +(((state& 2)== 2)?"DN":"UP"); // mouse right
res+="\nMM: " +(((state&16)==16)?"DN":"UP"); // mouse middle
res+="\nMX: " +(((state&32)==32)?"DN":"UP"); // mouse first X key
See also
EventChartCustom, Types of chart events, Event handling functions, Program running, Client
terminal events
OnTester
The function is called in Expert Advisors when the Tester event occurs to perform necessary actions
after testing.
double OnTester(void);
Return Value
Note
The OnTester() function can be used only when testing EAs and is intended primarily for the
calculation of a value that is used as a 'Custom max ' criterion when optimizing input parameters.
During the genetic optimization, sorting results within one generation is performed in descending
order. This means that the results with the highest value are deemed the best from the optimization
criterion point of view. The worst values f or such sorting are placed at the end and are subsequently
discarded. Therefore, they do not tak e part in forming the next generation.
Thus, the OnTester() function allows you not only to create and save your own test results reports,
but also control the optimization process to find the best parameters of the trading strategy.
Below is an example of calculating the custom criterion optimization. The idea is to calculate the
linear regression of the balance graph. It is described in the article Optimizing a strategy using
balance graph and comparing results with "Balance + max Sharpe R atio" criterion.
//+------------------------------------------------------------------+
//| OnTester_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Sample EA with the OnTester() handler"
#property description "As a custom optimization criterion, "
#property description "the ratio of the balance graph linear regression"
#property description "divided by the deviation mean-square error is returned"
//--- include the class for trading operations
#include <Trade\Trade.mqh>
//--- EA input parameters
input double Lots = 0.1; // Volume
input int Slippage = 10; // Allowable slippage
input int MovingPeriod = 80; // Moving average period
input int MovingShift = 6; // Moving average shift
//--- global variables
int IndicatorHandle=0; // indicator handle
bool IsHedging=false; // flag of the account
CTrade trade; // for performing trading operations
//---
MqlRates rt[2];
//--- trade only at the start of a new bar
if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
{
Print("CopyRates of ",_Symbol," failed, no history");
return;
}
if(rt[1].tick_volume>1)
return;
//--- receive moving average values
double ma[1];
if(CopyBuffer(IndicatorHandle,0,1,1,ma)!=1)
{
Print("CopyBuffer from iMA failed, no data");
return;
}
//--- position has already been selected earlier using PositionSelect()
bool signal=false;
long type=PositionGetInteger(POSITION_TYPE);
//--- candle opened higher but closed below the moving average - close a short position
if(type==(long)POSITION_TYPE_SELL && rt[0].open>ma[0] && rt[0].close<ma[0])
signal=true;
//--- candle opened lower but closed above the moving average - close a long position
if(type==(long)POSITION_TYPE_BUY && rt[0].open<ma[0] && rt[0].close>ma[0])
signal=true;
//--- additional checks
if(signal)
{
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
trade.PositionClose(_Symbol,Slippage);
}
//---
}
//+-------------------------------------------------------------------+
//| Select a position considering an account type: Netting or Hedging |
//+-------------------------------------------------------------------+
bool SelectPosition()
{
bool res=false;
//--- select a position for a Hedging account
if(IsHedging)
{
uint total=PositionsTotal();
for(uint i=0; i<total; i++)
{
string position_symbol=PositionGetSymbol(i);
if(_Symbol==position_symbol && EA_MAGIC==PositionGetInteger(POSITION_MAGIC))
{
res=true;
break;
}
}
}
//--- select a position for a Netting account
else
{
if(!PositionSelect(_Symbol))
return(false);
else
return(PositionGetInteger(POSITION_MAGIC)==EA_MAGIC); //---check Magic number
}
//--- execution result
return(res);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- set a trading type: Netting or Hedging
IsHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MOD
//--- initialize an object for correct position control
trade.SetExpertMagicNumber(EA_MAGIC);
trade.SetMarginMode();
trade.SetTypeFillingBySymbol(Symbol());
trade.SetDeviationInPoints(Slippage);
//--- create Moving Average indicator
IndicatorHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
if(IndicatorHandle==INVALID_HANDLE)
{
printf("Error creating iMA indicator");
return(INIT_FAILED);
}
//--- ok
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick(void)
{
//--- if a position is already opened, check the closing condition
if(SelectPosition())
CheckForClose();
// check the position opening condition
CheckForOpen();
//---
}
//+------------------------------------------------------------------+
//| Tester function |
//+------------------------------------------------------------------+
double OnTester()
{
//--- custom criterion optimization value (the higher, the better)
double ret=0.0;
//--- get trade results to the array
double array[];
double trades_volume;
GetTradeResultsToArray(array,trades_volume);
int trades=ArraySize(array);
//--- if there are less than 10 trades, test yields no positive results
if(trades<10)
return (0);
//--- average result per trade
double average_pl=0;
for(int i=0;i<ArraySize(array);i++)
average_pl+=array[i];
average_pl/=trades;
//--- display the message for the single-test mode
if(MQLInfoInteger(MQL_TESTER) && !MQLInfoInteger(MQL_OPTIMIZATION))
PrintFormat("%s: Trades=%d, Average profit=%.2f",__FUNCTION__,trades,average_pl);
//--- calculate linear regression ratios for the profit graph
double a,b,std_error;
double chart[];
if(!CalculateLinearRegression(array,chart,a,b))
return (0);
//--- calculate the error of the chart deviation from the regression line
if(!CalculateStdError(chart,a,b,std_error))
return (0);
//--- calculate the ratio of trend profits to the standard deviation
ret=a*trades/std_error;
//--- return custom criterion optimization value
return(ret);
}
//+------------------------------------------------------------------+
//| Get the array of profits/losses from deals |
//+------------------------------------------------------------------+
bool GetTradeResultsToArray(double &pl_results[],double &volume)
{
//--- request the complete trading history
if(!HistorySelect(0,TimeCurrent()))
return (false);
uint total_deals=HistoryDealsTotal();
volume=0;
//--- set the initial size of the array with a margin - by the number of deals in history
ArrayResize(pl_results,total_deals);
//--- counter of deals that fix the trading result - profit or loss
int counter=0;
ulong ticket_history_deal=0;
//--- go through all deals
for(uint i=0;i<total_deals;i++)
{
//--- select a deal
if((ticket_history_deal=HistoryDealGetTicket(i))>0)
{
ENUM_DEAL_ENTRY deal_entry =(ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket_history_deal,DE
long deal_type =HistoryDealGetInteger(ticket_history_deal,DEAL_TYPE);
double deal_profit =HistoryDealGetDouble(ticket_history_deal,DEAL_PROFIT);
double deal_volume =HistoryDealGetDouble(ticket_history_deal,DEAL_VOLUME);
//--- we are only interested in trading operations
if((deal_type!=DEAL_TYPE_BUY) && (deal_type!=DEAL_TYPE_SELL))
continue;
//--- only deals that fix profits/losses
if(deal_entry!=DEAL_ENTRY_IN)
{
//--- write the trading result to the array and increase the counter of deals
pl_results[counter]=deal_profit;
volume+=deal_volume;
counter++;
}
}
}
//--- set the final size of the array
ArrayResize(pl_results,counter);
return (true);
}
//+------------------------------------------------------------------+
//| Calculate the linear regression y=a*x+b |
//+------------------------------------------------------------------+
bool CalculateLinearRegression(double &change[],double &chartline[],
double &a_coef,double &b_coef)
{
//--- check for data sufficiency
if(ArraySize(change)<3)
return (false);
//--- create a chart array with an accumulation
int N=ArraySize(change);
ArrayResize(chartline,N);
chartline[0]=change[0];
for(int i=1;i<N;i++)
chartline[i]=chartline[i-1]+change[i];
//--- now, calculate regression ratios
double x=0,y=0,x2=0,xy=0;
for(int i=0;i<N;i++)
{
x=x+i;
y=y+chartline[i];
xy=xy+i*chartline[i];
x2=x2+i*i;
}
a_coef=(N*xy-x*y)/(N*x2-x*x);
b_coef=(y-a_coef*x)/N;
//---
return (true);
}
//+------------------------------------------------------------------+
//| Calculate mean-square deviation error for specified a and b |
//+------------------------------------------------------------------+
bool CalculateStdError(double &data[],double a_coef,double b_coef,double &std_err)
{
//--- sum of error squares
double error=0;
int N=ArraySize(data);
if(N==0)
return (false);
for(int i=0;i<N;i++)
error=MathPow(a_coef*i+b_coef-data[i],2);
std_err=MathSqrt(error/(N-2));
//---
return (true);
}
See also
Testing trading strategies, TesterH ideIndicators, W ork ing with optimization results,
TesterStatistics, OnTesterInit, OnTesterDeinit, OnTesterPass, MQL _T EST ER , MQL _OPTIMI ZATION,
FileOpen, FileW rite, FileLoad, FileSave
OnTesterInit
The function is called in EAs when the TesterInit event occurs to perform necessary actions before
optimization in the strategy tester. There are two function types.
int OnTesterInit(void);
Return Value
int type value, zero means successful initialization of an EA launched on a chart before optimization
starts.
The OnTesterInit() call that returns the execution result is recommended for use since it not only
allows for program initialization, but also returns an error code in case of an early optimization stop.
R eturn of any value other than INIT _S UCCEEDED (0) means an error, no optimization is launched.
The version without a result return is left only for compatibility with old codes. Not recommended
for use
void OnTesterInit(void);
Note
The TesterInit event is generated before EA optimization in the strategy tester starts. At this
event, an EA having OnTesterDeInit() or OnTesterPass() event handler is automatically downloaded
on a separate terminal chart. It has the symbol and the period that have been specified in the
tester.
Such an event receives the TesterInit, TesterDeinit and TesterPass events, but not Init, Deinit and
NewTick ones. Accordingly, all necessary logic for processing the results of each pass during
optimization should be implemented in the OnTesterInit (), OnTesterDeinit () and OnTesterPass ()
handlers.
The result of each single pass during a strategy optimization can be passed via a frame from the
OnTester () handler using the FrameAdd () function.
The OnTesterInit() function is used to initiate an Expert Advisor before start of optimization for
further processing of optimization results. It is always used together with the OnTesterDeinit()
handler.
The time for OnTesterInit() execution is limited. If it is exceeded, the EA is forcibly stopped, while
the optimization itself is canceled. A message is displayed in the tester journal:
The example is tak en from OnTick . The OnTesterInit() handler is added for setting optimization
parameters :
//+------------------------------------------------------------------+
//| OnTesterInit_Sample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
void OnTesterDeinit()
{
//--- optimization duration
string log_message=StringFormat("%s: optimization took %d seconds",
__FUNCTION__,TimeLocal()-optimization_start);
PrintFormat(log_message);
report=report+"\r\n"+log_message;
Comment(report);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- initialize global variables
last_atr=0;
last_body=0;
//--- set the correct volume
double min_lot=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
trade_lot=lots>min_lot? lots:min_lot;
//--- create ATR indicator handle
atr_handle=iATR(_Symbol,_Period,ATRperiod);
if(atr_handle==INVALID_HANDLE)
{
PrintFormat("%s: failed to create iATR, error code %d",__FUNCTION__,GetLastError());
return(INIT_FAILED);
}
//--- successful EA initialization
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- trading signal
static int signal=0; // +1 means a buy signal, -1 means a sell signal
//--- check and close old positions opened more than 'holdbars' bars ago
ClosePositionsByBars(holdbars,slippage,EXPERT_MAGIC);
//--- check for a new bar
if(isNewBar())
{
//--- check for a signal presence
signal=CheckSignal();
}
//--- if a netting position is opened, skip the signal - wait till it closes
if(signal!=0 && PositionsTotal()>0 && (ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGI
{
signal=0;
return; // exit the NewTick event handler and do not enter the market before a new bar appear
}
//--- for a hedging account, each position is held and closed separately
if(signal!=0)
{
//--- buy signal
if(signal>0)
{
PrintFormat("%s: Buy signal! Revers=%s",__FUNCTION__,string(revers));
if(Buy(trade_lot,slippage,EXPERT_MAGIC))
signal=0;
}
//--- sell signal
if(signal<0)
{
PrintFormat("%s: Sell signal! Revers=%s",__FUNCTION__,string(revers));
if(Sell(trade_lot,slippage,EXPERT_MAGIC))
signal=0;
}
}
//--- OnTick function end
}
//+------------------------------------------------------------------+
//| Check for a new trading signal |
//+------------------------------------------------------------------+
int CheckSignal()
{
//--- 0 means no signal
int res=0;
//--- get ATR value on a penultimate complete bar (the bar index is 2)
double atr_value[1];
if(CopyBuffer(atr_handle,0,2,1,atr_value)!=-1)
{
last_atr=atr_value[0];
//--- get data on the last closed bar to the MqlRates type array
MqlRates bar[1];
if(CopyRates(_Symbol,_Period,1,1,bar)!=-1)
{
//--- calculate the bar body size on the last complete bar
last_body=bar[0].close-bar[0].open;
//--- if the body of the last bar (with index 1) exceeds the previous ATR value (on the ba
if(MathAbs(last_body)>kATR*last_atr)
res=last_body>0?1:-1; // positive value for the upward candle
}
else
PrintFormat("%s: Failed to receive the last bar! Error",__FUNCTION__,GetLastError());
}
else
//--- if a position's lifetime is already large, while MagicNumber and a symbol match
if(bars>holdtimebars && magic==magicnumber && position_symbol==_Symbol)
{
int digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // number o
double volume=PositionGetDouble(POSITION_VOLUME); // position
ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // position
string str_type=StringSubstr(EnumToString(type),14);
StringToLower(str_type); // lower the text case for correct message formatting
PrintFormat("Close position #%d %s %s %.2f",
position_ticket,position_symbol,str_type,volume);
//--- set an order type and sending a trade request
if(type==POSITION_TYPE_BUY)
MarketOrder(ORDER_TYPE_SELL,volume,deviation,magicnumber,position_ticket);
else
MarketOrder(ORDER_TYPE_BUY,volume,deviation,magicnumber,position_ticket);
}
}
}
//+------------------------------------------------------------------+
//| Prepare and send a trade request |
//+------------------------------------------------------------------+
bool MarketOrder(ENUM_ORDER_TYPE type,double volume,ulong slip,ulong magicnumber,ulong pos_ticket=0
{
//--- declaring and initializing structures
MqlTradeRequest request={0};
MqlTradeResult result={0};
double price=SymbolInfoDouble(Symbol(),SYMBOL_BID);
if(type==ORDER_TYPE_BUY)
price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
//--- request parameters
request.action =TRADE_ACTION_DEAL; // trading operation type
request.position =pos_ticket; // position ticket if closing
request.symbol =Symbol(); // symbol
request.volume =volume; // volume
request.type =type; // order type
request.price =price; // trade price
request.deviation=slip; // allowable deviation from the price
request.magic =magicnumber; // order MagicNumber
//--- send a request
if(!OrderSend(request,result))
{
//--- display data on failure
PrintFormat("OrderSend %s %s %.2f at %.5f error %d",
request.symbol,EnumToString(type),volume,request.price,GetLastError());
return (false);
}
//--- inform of a successful operation
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
return (true);
}
See also
Testing trading strategies, W ork ing with optimization results, OnTesterDeinit, OnTesterPass,
ParameterGetR ange, ParameterSetR ange
OnTesterDeinit
The function is called in EAs when the TesterDeinit event occurs after EA optimization.
void OnTesterDeinit(void);
Return Value
No return value
Note
The TesterDeinit event is generated after the end of EA optimization in the strategy tester.
Keep in mind that optimization frames sent by test agents using the FrameAdd() function may come
in bundles and tak e time to deliver. Therefore, not all frames, as well as TesterPass events, may
arrive and be processed in OnTesterPass() before the end of optimization. If you want to receive all
belated frames in OnTesterDeinit(), place the code block using the FrameNext() function.
See also
Testing trading strategies, W ork ing with optimization results, TesterStatistics, OnTesterInit,
OnTesterPass, ParameterGetR ange, ParameterSetR ange
OnTesterPass
The function is called in EAs when the TesterPass event occurs for handling a new data frame during
EA optimization.
void OnTesterPass(void);
Return Value
No return value
Note
The TesterPass event is generated automatically when receiving a frame during an Expert Advisor
optimization in the strategy tester.
Keep in mind that optimization frames sent by test agents using the FrameAdd() function may come
in bundles and tak e time to deliver. Therefore, not all frames, as well as TesterPass events, may
arrive and be processed in OnTesterPass() before the end of optimization. If you want to receive all
belated frames in OnTesterDeinit(), place the code block using the FrameNext() function.
After completing OnTesterDeinit() optimization, it is possible to sort all received frames again using
the FrameFirst()/FrameFilter and FrameNext() functions.
See also
Testing trading strategies, W ork ing with optimization results, OnTesterInit, OnTesterDeinit,
FrameFirst, FrameFilter, FrameNext, FrameInputs
Function Action
SymbolsTotal
R eturns the number of available (selected in Mark et W atch or all) symbols.
int SymbolsTotal(
bool selected // True - only symbols in MarketWatch
);
Parameters
selected
[in] R equest mode. Can be true or false.
Return Value
If the 'selected' parameter is true, the function returns the number of symbols selected in
Mark etW atch. If the value is false, it returns the total number of all symbols.
SymbolExist
Check s if a symbol with a specified name exists.
bool SymbolExist(
const string name, // symbol name
bool& is_custom // custom symbol property
);
Parameters
name
[in] Symbol name.
is_custom
[out] Custom symbol property set upon successful execution. If true, the detected symbol is a
custom one.
Return Value
If false, the symbol is not found among standard and custom ones.
See also
SymbolsTotal, SymbolSelect, Custom symbols
SymbolName
R eturns the name of a symbol.
string SymbolName(
int pos, // number in the list
bool selected // true - only symbols in MarketWatch
);
Parameters
pos
[in] Order number of a symbol.
selected
[in] R equest mode. If the value is true, the symbol is tak en from the list of symbols selected in
Mark etW atch. If the value is false, the symbol is tak en from the general list.
Return Value
SymbolSelect
Selects a symbol in the Mark et W atch window or removes a symbol from the window.
bool SymbolSelect(
string name, // symbol name
bool select // add or remove
);
Parameters
name
[in] Symbol name.
select
[in] Switch. If the value is false, a symbol should be removed from Mark etW atch, otherwise a
symbol should be selected in this window. A symbol can't be removed if the symbol chart is open,
or there are open positions for this symbol.
Return Value
SymbolIsSynchronized
The function check s whether data of a selected symbol in the terminal are synchronized with data on
the trade server.
bool SymbolIsSynchronized(
string name, // symbol name
);
Parameters
name
[in] Symbol name.
Return value
See also
SymbolInfoInteger, Organizing Data Access
SymbolInfoDouble
R eturns the corresponding property of a specified symbol. There are 2 variants of the function.
double SymbolInfoDouble(
string name, // symbol
ENUM_SYMBOL_INFO_DOUBLE prop_id // identifier of the property
);
2. R eturns true or false depending on whether a function is successfully performed. In case of success,
the value of the property is placed into a recipient variable, passed by reference by the last
parameter.
bool SymbolInfoDouble(
string name, // symbol
ENUM_SYMBOL_INFO_DOUBLE prop_id, // identifier of the property
double& double_var // here we accept the property value
);
Parameters
name
[in] Symbol name.
prop_id
[in] Identifier of a symbol property. The value can be one of the values of the
ENUM _S YM BOL _INFO_DOUBL E enumeration.
double_var
[out] Variable of double type receiving the value of the requested property.
Return Value
The value of double type. In case of execution failure, information about the error can be obtained
using GetLastError() function:
· 5040 – invalid string parameter for specifying a symbol name,
· 4301 – unk nown symbol (financial instrument),
· 4302 – symbol is not selected in " Mark et W atch" (not found in the list of available ones),
· 4303 – invalid identifier of a symbol property.
Note
It is recommended to use SymbolInfoTick () if the function is used for getting information about the
last tick . It may well be that not a single quote has appeared yet since the terminal is connected to a
trading account. In such a case, the requested value will be indefinite.
In most cases, it is enough to use SymbolInfoTick () function allowing a user to receive the values of
As k , Bid, Last, Volume and the time of the last tick's arrival during a single call.
Example:
void OnTick()
{
//--- obtain spread from the symbol properties
bool spreadfloat=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD_FLOAT);
string comm=StringFormat("Spread %s = %I64d points\r\n",
spreadfloat?"floating":"fixed",
SymbolInfoInteger(Symbol(),SYMBOL_SPREAD));
//--- now let's calculate the spread by ourselves
double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
double spread=ask-bid;
int spread_points=(int)MathRound(spread/SymbolInfoDouble(Symbol(),SYMBOL_POINT));
comm=comm+"Calculated spread = "+(string)spread_points+" points";
Comment(comm);
}
SymbolInfoInteger
R eturns the corresponding property of a specified symbol. There are 2 variants of the function.
long SymbolInfoInteger(
string name, // symbol
ENUM_SYMBOL_INFO_INTEGER prop_id // identifier of a property
);
2. R eturns true or false depending on whether a function is successfully performed. In case of success,
the value of the property is placed into a recipient variable, passed by reference by the last
parameter.
bool SymbolInfoInteger(
string name, // symbol
ENUM_SYMBOL_INFO_INTEGER prop_id, // identifier of a property
long& long_var // here we accept the property value
);
Parameters
name
[in] Symbol name.
prop_id
[in] Identifier of a symbol property. The value can be one of the values of the
ENUM _S YM BOL _INFO_INT EGER enumeration.
long_var
[out] Variable of the long type receiving the value of the requested property.
Return Value
The value of long type. In case of execution failure, information about the error can be obtained
using GetLastError() function:
· 5040 – invalid string parameter for specifying a symbol name,
· 4301 – unk nown symbol (financial instrument),
· 4302 – symbol is not selected in " Mark et W atch" (not found in the list of available ones),
· 4303 – invalid identifier of a symbol property.
Note
It is recommended to use SymbolInfoTick () if the function is used for getting information about the
last tick . It may well be that not a single quote has appeared yet since the terminal is connected to a
trading account. In such a case, the requested value will be indefinite.
In most cases, it is enough to use SymbolInfoTick () function allowing a user to receive the values of
As k , Bid, Last, Volume and the time of the last tick's arrival during a single call.
Example:
void OnTick()
{
//--- obtain spread from the symbol properties
bool spreadfloat=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD_FLOAT);
string comm=StringFormat("Spread %s = %I64d points\r\n",
spreadfloat?"floating":"fixed",
SymbolInfoInteger(Symbol(),SYMBOL_SPREAD));
//--- now let's calculate the spread by ourselves
double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
double spread=ask-bid;
int spread_points=(int)MathRound(spread/SymbolInfoDouble(Symbol(),SYMBOL_POINT));
comm=comm+"Calculated spread = "+(string)spread_points+" points";
Comment(comm);
}
SymbolInfoString
R eturns the corresponding property of a specified symbol. There are 2 variants of the function.
string SymbolInfoString(
string name, // Symbol
ENUM_SYMBOL_INFO_STRING prop_id // Property identifier
);
2. R eturns true or false, depending on the success of a function. If successful, the value of the
property is placed in a placeholder variable passed by reference in the last parameter.
bool SymbolInfoString(
string name, // Symbol
ENUM_SYMBOL_INFO_STRING prop_id, // Property identifier
string& string_var // here we accept the property value
);
Parameters
name
[in] Symbol name.
prop_id
[in] Identifier of a symbol property. The value can be one of the values of the
ENUM _S YM BOL _INFO_ST R ING enumeration.
string_var
[out] Variable of the string type receiving the value of the requested property.
Return Value
The value of string type. In case of execution failure, information about the error can be obtained
using GetLastError() function:
· 5040 – invalid string parameter for specifying a symbol name,
· 4301 – unk nown symbol (financial instrument),
· 4302 – symbol is not selected in " Mark et W atch" (not found in the list of available ones),
· 4303 – invalid identifier of a symbol property.
Note
It is recommended to use SymbolInfoTick () if the function is used for getting information about the
last tick . It may well be that not a single quote has appeared yet since the terminal is connected to a
trading account. In such a case, the requested value will be indefinite.
In most cases, it is enough to use SymbolInfoTick () function allowing a user to receive the values of
As k , Bid, Last, Volume and the time of the last tick's arrival during a single call.
SymbolInfoMarginRate
R eturns the margin rates depending on the order type and direction.
bool SymbolInfoMarginRate(
string name, // symbol name
ENUM_ORDER_TYPE order_type, // order type
double& initial_margin_rate, // initial margin rate
double& maintenance_margin_rate // maintenance margin rate
);
Parameters
name
[in] Symbol name.
order_type
[in] Order type.
initial_margin_rate
[in] A double type variable for receiving an initial margin rate. Initial margin is a security deposit
for 1 lot deal in the appropriate direction. Multiplying the rate by the initial margin, we receive the
amount of funds to be reserved on the account when placing an order of the specified type.
maintenance_margin_rate
[out] A double type variable for receiving a maintenance margin rate. Maintenance margin is a
minimum amount for maintaining an open position of 1 lot in the appropriate direction. Multiplying
the rate by the maintenance margin, we receive the amount of funds to be reserved on the
account after an order of the specified type is activated.
Return Value
SymbolInfoTick
The function returns current prices of a specified symbol in a variable of the M qlTick type.
bool SymbolInfoTick(
string symbol, // symbol name
MqlTick& tick // reference to a structure
);
Parameters
symbol
[in] Symbol name.
tick
[out] Link to the structure of the M qlTick type, to which the current prices and time of the last
price update will be placed.
Return Value
SymbolInfoSessionQuote
Allows receiving time of beginning and end of the specified quoting sessions for a specified symbol
and day of week .
bool SymbolInfoSessionQuote(
string name, // symbol name
ENUM_DAY_OF_WEEK day_of_week, // day of the week
uint session_index, // session index
datetime& from, // time of the session beginning
datetime& to // time of the session end
);
Parameters
name
[in] Symbol name.
ENUM_DAY_OF_WEEK
[in] Day of the week , value of enumeration ENUM _DAY_OF_WEEK.
uint
[in] Ordinal number of a session, whose beginning and end time we want to receive. Indexing of
sessions starts with 0.
from
[out] Session beginning time in seconds from 00 hours 00 minutes, in the returned value date
should be ignored.
to
[out] Session end time in seconds from 00 hours 00 minutes, in the returned value date should be
ignored.
Return Value
If data for the specified session, symbol and day of the week are received, returns true, otherwise
returns false.
See also
Symbol Properties, TimeToStruct, Data Structures
SymbolInfoSessionTrade
Allows receiving time of beginning and end of the specified trading sessions for a specified symbol and
day of week .
bool SymbolInfoSessionTrade(
string name, // symbol name
ENUM_DAY_OF_WEEK day_of_week, // day of the week
uint session_index, // session index
datetime& from, // session beginning time
datetime& to // session end time
);
Parameters
name
[in] Symbol name.
ENUM_DAY_OF_WEEK
[in] Day of the week , value of enumeration ENUM _DAY_OF_WEEK.
uint
[in] Ordinal number of a session, whose beginning and end time we want to receive. Indexing of
sessions starts with 0.
from
[out] Session beginning time in seconds from 00 hours 00 minutes, in the returned value date
should be ignored.
to
[out] Session end time in seconds from 00 hours 00 minutes, in the returned value date should be
ignored.
Return value
If data for the specified session, symbol and day of the week are received, returns true, otherwise
returns false.
See also
Symbol Properties, TimeToStruct, Data Structures
MarketBookAdd
Provides opening of Depth of Mark et for a selected symbol, and subscribes for receiving notifications
of the DOM changes.
bool MarketBookAdd(
string symbol // symbol
);
Parameters
symbol
[in] The name of a symbol, whose Depth of Mark et is to be used in the Expert Advisor or script.
Return Value
Note
Normally, this function must be called from the OnInit() function or in the class constructor. To
handle incoming alerts, in the Expert Advisor program must contain the function void
OnBookEvent(string & symbol).
See also
Structure of Depth of Mark et, Structures and Classes
MarketBookRelease
Provides closing of Depth of Mark et for a selected symbol, and cancels the subscription for receiving
notifications of the DOM changes.
bool MarketBookRelease(
string symbol // symbol
);
Parameters
symbol
[in] Symbol name.
Return Value
Note
Normally, this function must be called from the OnDeinit() function, if the corresponding
Mark etBookAdd() function has been called in the OnInit() function. Or it must be called from the
class destructor, if the corresponding Mark etBookAdd() function has been called from the class
constructor.
See also
Structure of Depth of Mark et, Structures and Classes
MarketBookGet
R eturns a structure array M qlBook Info containing records of the Depth of Mark et of a specified symbol.
bool MarketBookGet(
string symbol, // symbol
MqlBookInfo& book[] // reference to an array
);
Parameters
symbol
[in] Symbol name.
book[]
[in] R eference to an array of Depth of Mark et records. The array can be pre-allocated for a
sufficient number of records. If a dynamic array hasn't been pre-allocated in the operating
memory, the client terminal will distribute the array itself.
Return Value
Note
Example:
MqlBookInfo priceArray[];
bool getBook=MarketBookGet(NULL,priceArray);
if(getBook)
{
int size=ArraySize(priceArray);
Print("MarketBookInfo for ",Symbol());
for(int i=0;i<size;i++)
{
Print(i+":",priceArray[i].price
+" Volume = "+priceArray[i].volume,
" type = ",priceArray[i].type);
}
}
else
{
Print("Could not get contents of the symbol DOM ",Symbol());
}
See also
Structure of Depth of Mark et, Structures and Classes
All functions for work ing with the economic calendar use the trade server time (TimeTradeServer).
This means that the time in the M qlCalendarValue structure and the time inputs in the
CalendarValueH istoryByEvent/CalendarValueH istory functions are set in a trade server timezone,
rather than a user's local time.
Economic calendar functions allow conducting the auto analysis of incoming events according to
custom importance criteria from a perspective of necessary countries /currencies.
Function Action
CalendarValueLast Get the array of values for all events with the
ability to sort by country and/or currency since
the calendar database status with a specified
change_id
CalendarCountryById
Get a country description by its ID.
bool CalendarCountryById(
const long country_id, // country ID
MqlCalendarCountry& country // variable for receiving a country description
);
Parameters
country_id
[in] Country ID (ISO 3166-1).
country
[out] M qlCalendarCountry type variable for receiving a country description.
Return Value
R eturns true if successful, otherwise - false. To get information about an error, call the
GetLastError() function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 5402 – ERR_CAL ENDAR_NO_DAT A (country is not found),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded).
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- get the list of countries from the economic calendar
MqlCalendarCountry countries[];
int count=CalendarCountries(countries);
//--- check the result
if(count==0)
PrintFormat("CalendarCountries() returned 0! Error %d",GetLastError());
//--- if there are two or more countries
if(count>=2)
{
MqlCalendarCountry country;
//--- now get a country description by its ID
if(CalendarCountryById(countries[1].id, country))
{
//--- prepare a country description
string descr="id = "+IntegerToString(country.id)+"\n";
descr+=("name = " + country.name+"\n");
descr+=("code = " + country.code+"\n");
descr+=("currency = " + country.currency+"\n");
descr+=("currency_symbol = " + country.currency_symbol+"\n");
See also
CalendarCountries, CalendarEventByCountry
CalendarEventById
Get an event description by its ID.
bool CalendarEventById(
ulong event_id, // event ID
MqlCalendarEvent& event // variable for receiving an event description
);
Parameters
event_id
[in] Event ID.
event
[out] M qlCalendarEvent type variable for receiving an event description.
Return Value
R eturns true if successful, otherwise - false. To get information about an error, call the
GetLastError() function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 5402 – ERR_CAL ENDAR_NO_DAT A (country is not found),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded).
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- country code for Germany (ISO 3166-1 Alpha-2)
string germany_code="DE";
//--- get Germany events
MqlCalendarEvent events[];
int events_count=CalendarEventByCountry(germany_code,events);
//--- display Germany events in the Journal
if(events_count>0)
{
PrintFormat("Germany events: %d",events_count);
ArrayPrint(events);
}
else
{
PrintFormat("Failed to receive events for the country code %s, error %d",
germany_code,GetLastError());
//--- script early completion
return;
}
//--- get description of the last event from the events[] array
MqlCalendarEvent event;
ulong event_id=events[events_count-1].id;
if(CalendarEventById(event_id,event))
{
MqlCalendarCountry country;
CalendarCountryById(event.country_id,country);
PrintFormat("Event description with event_id=%d received",event_id);
PrintFormat("Country: %s (country code = %d)",country.name,event.country_id);
PrintFormat("Event name: %s",event.name);
PrintFormat("Event code: %s",event.event_code);
PrintFormat("Event importance: %s",EnumToString((ENUM_CALENDAR_EVENT_IMPORTANCE)event.importa
PrintFormat("Event type: %s",EnumToString((ENUM_CALENDAR_EVENT_TYPE)event.type));
PrintFormat("Event sector: %s",EnumToString((ENUM_CALENDAR_EVENT_SECTOR)event.sector));
PrintFormat("Event frequency: %s",EnumToString((ENUM_CALENDAR_EVENT_FREQUENCY)event.frequency
PrintFormat("Event release mode: %s",EnumToString((ENUM_CALENDAR_EVENT_TIMEMODE)event.time_mo
PrintFormat("Event measurement unit: %s",EnumToString((ENUM_CALENDAR_EVENT_UNIT)event.unit));
PrintFormat("Number of decimal places: %d",event.digits);
PrintFormat("Event multiplier: %s",EnumToString((ENUM_CALENDAR_EVENT_MULTIPLIER)event.multipl
PrintFormat("Source URL: %s",event.source_url);
}
else
PrintFormat("Failed to get event description for event_d=%s, error %d",
event_id,GetLastError());
}
/*
Result:
Germany events: 50
[id] [type] [sector] [frequency] [time_mode] [country_id] [unit] [importance] [multipl
[ 0] 276010001 1 6 2 0 276 1 1
[ 1] 276010002 1 6 2 0 276 1 1
[ 2] 276010003 1 4 2 0 276 1 1
[ 3] 276010004 1 4 2 0 276 1 1
....
[47] 276500001 1 8 2 0 276 0 2
[48] 276500002 1 8 2 0 276 0 2
[49] 276500003 1 8 2 0 276 0 2
Event description with event_id=276500003 received
Country: Germany (country code = 276)
Event name: Markit Composite PMI
Event code: markit-composite-pmi
Event importance: CALENDAR_IMPORTANCE_MODERATE
Event type: CALENDAR_TYPE_INDICATOR
Event sector: CALENDAR_SECTOR_BUSINESS
Event frequency: CALENDAR_FREQUENCY_MONTH
Event release mode: CALENDAR_TIMEMODE_DATETIME
Event measurement unit: CALENDAR_UNIT_NONE
Number of decimal places: 1
Value multiplier: CALENDAR_MULTIPLIER_NONE
Source URL: https://www.markiteconomics.com
*/
See also
CalendarEventByCountry, CalendarEventByCurrency, CalendarValueById
CalendarValueById
Get an event value description by its ID.
bool CalendarValueById(
ulong value_id, // event value ID
MqlCalendarValue& value // variable for receiving an event value
);
Parameters
value_id
[in] Event value ID.
value
[out] M qlCalendarValue type variable for receiving an event description.
Return Value
R eturns true if successful, otherwise - false. To get information about an error, call the
GetLastError() function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 5402 – ERR_CAL ENDAR_NO_DAT A (country is not found),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded).
Note
All functions for work ing with the economic calendar use the trade server time (TimeTradeServer).
This means that the time in the M qlCalendarValue structure and the time inputs in the
CalendarValueH istoryByEvent/CalendarValueH istory functions are set in a trade server timezone,
rather than a user's local time.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- country code for Japan (ISO 3166-1 Alpha-2)
string japan_code="JP";
//--- set the boundaries of the interval we take the events from
datetime date_from=D'01.01.2018'; // take all events from 2018
datetime date_to=0; // 0 means all known events, including the ones that have not
//--- get the array of the Japan event values
MqlCalendarValue values[];
int values_count=CalendarValueHistory(values,date_from,date_to,japan_code);
//--- move along the detected event values
if(values_count>0)
{
PrintFormat("Number of values for Japan events: %d",values_count);
//--- delete all "empty" values (actual_value==-9223372036854775808)
for(int i=values_count-1;i>=0;i--)
{
if(values[i].actual_value==-9223372036854775808)
ArrayRemove(values,i,1);
}
PrintFormat("Number of values after deleting empty ones: %d",ArraySize(values));
}
else
{
PrintFormat("Failed to receive events for the country code %s, error %d",
japan_code,GetLastError());
//--- script early completion
return;
}
//--- leave no more than 10 values in the values[] array
if(ArraySize(values)>10)
{
PrintFormat("Reduce the list of values to 10 and display them");
ArrayRemove(values,0,ArraySize(values)-10);
}
ArrayPrint(values);
//--- now let's display how to get an event value description based on the known value_id
for(int i=0;i<ArraySize(values);i++)
{
MqlCalendarValue value;
CalendarValueById(values[i].id,value);
PrintFormat("%d: value_id=%d value=%d impact=%s",
i,values[i].id,value.actual_value,EnumToString(ENUM_CALENDAR_EVENT_IMPACT(value.i
}
//---
}
/*
Result:
Number of values for Japan events: 1734
Number of values after deleting empty ones: 1017
Reduce the list of values to 10 and display them
[id] [event_id] [time] [period] [revision] [actual_value] [prev_val
[0] 56500 392030004 2019.03.28 23:30:00 2019.03.01 00:00:00 0 900000 600
[1] 56501 392030005 2019.03.28 23:30:00 2019.03.01 00:00:00 0 700000 700
[2] 56502 392030006 2019.03.28 23:30:00 2019.03.01 00:00:00 0 1100000 1100
[3] 56544 392030007 2019.03.28 23:30:00 2019.02.01 00:00:00 0 2300000 2500
[4] 56556 392050002 2019.03.28 23:30:00 2019.02.01 00:00:00 0 1630000 1630
[5] 55887 392020003 2019.03.28 23:50:00 2019.02.01 00:00:00 0 400000 600
[6] 55888 392020004 2019.03.28 23:50:00 2019.02.01 00:00:00 0 -1800000 -3300
[7] 55889 392020002 2019.03.28 23:50:00 2019.02.01 00:00:00 0 200000 -2300
[8] 55948 392020006 2019.03.28 23:50:00 2019.02.01 00:00:00 1 1400000 -3400
[9] 55949 392020007 2019.03.28 23:50:00 2019.02.01 00:00:00 1 -1000000 300
Display brief data on event values based on value_id
See also
CalendarValueH istoryByEvent, CalendarValueH istory, CalendarValueLastByEvent, CalendarValueLast
CalendarCountries
Get the array of country names available in the Calendar.
int CalendarCountries(
MqlCalendarCountry& countries[] // array for receiving a list of Calendar countries' de
);
Parameters
countries[]
[out] An array of M qlCalendarCountry type for receiving all Calendar countries ' descriptions.
Return Value
Number of received descriptions. To get information about an error, call the GetLastError()
function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded),
· 5400 – ERR_CAL ENDAR_MORE_DAT A (array size is insufficient for receiving descriptions of all
countries, only the ones that managed to fit in were received).
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- get the list of countries from the economic calendar
MqlCalendarCountry countries[];
int count=CalendarCountries(countries);
//--- display the array in the Journal
if(count>0)
ArrayPrint(countries);
else
PrintFormat("CalendarCountries() returned 0! Error %d",GetLastError());
/*
Result:
[id] [name] [code] [currency] [currency_symbol] [url_name] [reserved]
[ 0] 0 "Worldwide" "WW" "ALL" "" "worldwide" 0
[ 1] 999 "European Union" "EU" "EUR" "€" "european-union" 0
[ 2] 840 "United States" "US" "USD" "$" "united-states" 0
[ 3] 124 "Canada" "CA" "CAD" "$" "canada" 0
[ 4] 36 "Australia" "AU" "AUD" "$" "australia" 0
[ 5] 554 "New Zealand" "NZ" "NZD" "$" "new-zealand" 0
[ 6] 392 "Japan" "JP" "JPY" "Ґ" "japan" 0
[ 7] 156 "China" "CN" "CNY" "Ґ" "china" 0
[ 8] 826 "United Kingdom" "GB" "GBP" "Ј" "united-kingdom" 0
[ 9] 756 "Switzerland" "CH" "CHF" "₣" "switzerland" 0
See also
CalendarEventByCountry, CalendarCountryById
CalendarEventByCountry
Get the array of descriptions of all events available in the Calendar by a specified country code.
int CalendarEventByCountry(
string country_code, // country code name (ISO 3166-1 alpha-2)
MqlCalendarEvent& events[] // variable for receiving the description array
);
Parameters
country_code
[in] Country code name (ISO 3166-1 alpha-2)
events[]
[out] M qlCalendarEvent type array for receiving descriptions of all events for a specified country.
Return Value
Number of received descriptions. To get information about an error, call the GetLastError()
function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 4004 – ERR_NOT _ENOUGH_M EMORY (not enough memory for executing a request),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded),
· errors of failed execution of ArrayR esize()
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- country code for EU (ISO 3166-1 Alpha-2)
string EU_code="EU";
//--- get EU events
MqlCalendarEvent events[];
int events_count=CalendarEventByCountry(EU_code,events);
//--- display EU events in the Journal
if(events_count>0)
{
PrintFormat("EU events: %d",events_count);
ArrayPrint(events);
}
//---
}
/*
Result:
EU events: 56
[id] [type] [country_id] [unit] [importance] [multiplier] [digits] [event_code]
[ 0] 999010001 0 999 0 2 0 0 "ECB Non-monetary
*/
See also
CalendarCountries, CalendarCountryById
CalendarEventByCurrency
Get the array of descriptions of all events available in the Calendar by a specified currency.
int CalendarEventByCurrency(
const string currency, // country currency code name
MqlCalendarEvent& events[] // variable for receiving the description array
);
Parameters
currency
[in] Country currency code name.
events[]
[out] M qlCalendarEvent type array for receiving descriptions of all events for a specified currency.
Return Value
Number of received descriptions. To get information about an error, call the GetLastError()
function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 4004 – ERR_NOT _ENOUGH_M EMORY (not enough memory for executing a request),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded),
· errors of failed execution of ArrayR esize()
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- declare the array for receiving economic calendar events
MqlCalendarEvent events[];
//--- get EU currency events
int count = CalendarEventByCurrency("EUR",events);
Print("count = ", count);
//--- 10 events are sufficient for the current example
if(count>10)
ArrayResize(events,10);
//--- display events in the Journal
ArrayPrint(events);
}
/*
Result:
[id] [type] [country_id] [unit] [importance] [s
[0] 999010001 0 999 0 2 "https://www.ecb.europa.eu/home/html/index
[1] 999010002 0 999 0 2 "https://www.ecb.europa.eu/home/html/index
[2] 999010003 0 999 0 3 "https://www.ecb.europa.eu/home/html/index
See also
CalendarEventById, CalendarEventByCountry
CalendarValueHistoryByEvent
Get the array of values for all events in a specified time range by an event ID.
bool CalendarValueHistoryByEvent(
ulong event_id, // event ID
MqlCalendarValue& values[], // array for value descriptions
datetime datetime_from, // left border of a time range
datetime datetime_to=0 // right border of a time range
);
Parameters
event_id
[in] Event ID.
values[]
[out] M qlCalendarValue type array for receiving event values.
datetime_from
[in] Initial date of a time range events are selected from by a specified ID, while datetime_from <
datetime_to.
datetime_to=0
[in] End date of a time range events are selected from by a specified ID. If the datetime_to is not
set (or is 0), all event values beginning from the specified datetime_from date in the Calendar
database are returned (including the values of future events).
Return Value
R eturns true if successful, otherwise - false. To get information about an error, call the
GetLastError() function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 4004 – ERR_NOT _ENOUGH_M EMORY (not enough memory for executing a request),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded),
· 5400 – ERR_CAL ENDAR_MORE_DAT A (array size is insufficient for receiving descriptions of all
values, only the ones that managed to fit in were received),
· errors of failed execution of ArrayR esize()
If an event value does not have any of the fields specified below
struct MqlCalendarValue
{
...
long actual_value; // event's actual value
long prev_value; // event's previous value
long revised_prev_value; // event's revised previous value
long forecast_value; // event's forecast value
...
};
then the value of the missing field is returned as I NT 64_MI N (-9223372036854775808). See the
revised_prev_value field value in the example below.
Note
All functions for work ing with the economic calendar use the trade server time (TimeTradeServer).
This means that the time in the M qlCalendarValue structure and the time inputs in the
CalendarValueH istoryByEvent/CalendarValueH istory functions are set in a trade server timezone,
rather than a user's local time.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- country code for EU (ISO 3166-1 Alpha-2)
string EU_code="EU";
//--- get EU events
MqlCalendarEvent events[];
int events_count=CalendarEventByCountry(EU_code,events);
//--- display EU events in the Journal
if(events_count>0)
{
PrintFormat("EU events: %d",events_count);
//--- reduce the event list, 10 events are sufficient for analysis
ArrayResize(events,10);
ArrayPrint(events);
}
//--- see that the "ECB Interest Rate Decision" event has event_id=999010007
ulong event_id=events[6].id; // the event's ID may change in the Calendar, so be sure to
string event_name=events[6].name; // name of a Calendar event
PrintFormat("Get values for event_name=%s event_id=%d",event_name,event_id);
//--- get all values of the "ECB Interest Rate Decision" event
MqlCalendarValue values[];
//--- set the boundaries of the interval we take the events from
datetime date_from=0; // take all events from the beginning of the available history
datetime date_to=D'01.01.2016'; // take events not older than 2016
if(CalendarValueHistoryByEvent(event_id,values,date_from,date_to))
{
PrintFormat("Received values for %s: %d",
event_name,ArraySize(values));
//--- reduce the value list, 10 events are sufficient for analysis
ArrayResize(values,10);
ArrayPrint(values);
}
else
{
PrintFormat("Error! Failed to get values for event_id=%d",event_id);
See also
CalendarCountries, CalendarEventByCountry, CalendarValueH istory, CalendarEventById,
CalendarValueById
CalendarValueHistory
Get the array of values for all events in a specified time range with the ability to sort by country
and/or currency.
bool CalendarValueHistory(
MqlCalendarValue& values[], // array for value descriptions
datetime datetime_from, // left border of a time range
datetime datetime_to=0 // right border of a time range
const string country_code=NULL, // country code name (ISO 3166-1 alpha-2)
const string currency=NULL // country currency code name
);
Parameters
values[]
[out] M qlCalendarValue type array for receiving event values.
datetime_from
[in] Initial date of a time range events are selected from by a specified ID, while datetime_from <
datetime_to.
datetime_to=0
[in] End date of a time range events are selected from by a specified ID. If the datetime_to is not
set (or is 0), all event values beginning from the specified datetime_from date in the Calendar
database are returned (including the values of future events).
country_code=NULL
[in] Country code name (ISO 3166-1 alpha-2)
currency=NULL
[in] Country currency code name.
Return Value
R eturns true if successful, otherwise - false. To get information about an error, call the
GetLastError() function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 4004 – ERR_NOT _ENOUGH_M EMORY (not enough memory for executing a request),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded),
· 5400 – ERR_CAL ENDAR_MORE_DAT A (array size is insufficient for receiving descriptions of all
values, only the ones that managed to fit in were received),
· errors of failed execution of ArrayR esize()
Note
All functions for work ing with the economic calendar use the trade server time (TimeTradeServer).
This means that the time in the M qlCalendarValue structure and the time inputs in the
CalendarValueH istoryByEvent/CalendarValueH istory functions are set in a trade server timezone,
rather than a user's local time.
If the events[] array of fixed length was passed to the function and there was not enough space to
save the entire result, the ERR_CAL ENDAR_MORE_DAT A (5400) error is activated.
If the datetime_to is not set (or is 0), all event values beginning from the specified datetime_from
date in the Calendar database are returned (including the values of future events).
For the country_code and currency filters, NULL and "" values are equivalent and mean the absence
of the filter.
For country_code, the code field of the M qlCalendarCountry structure, for example "US " , "RU" or
"EU" , should be used.
For currency, the currency field of the M qlCalendarCountry structure, for example "US D" , "RUB" or
"EUR" , should be used.
The filters are applied by conjunction, i.e. logical 'AND' is used to select only the values of events
both conditions (country and currency) are simultaneously met for.
If an event value does not have any of the fields specified below
struct MqlCalendarValue
{
...
long actual_value; // event's actual value
long prev_value; // event's previous value
long revised_prev_value; // event's revised previous value
long forecast_value; // event's forecast value
...
};
then the value of the missing field is returned as I NT 64_MI N (-9223372036854775808). See the
revised_prev_value field value in the example below.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- country code for EU (ISO 3166-1 Alpha-2)
string EU_code="EU";
//--- get all EU event values
MqlCalendarValue values[];
//--- set the boundaries of the interval we take the events from
datetime date_from=D'01.01.2018'; // take all events from 2018
datetime date_to=0; // 0 means all known events, including the ones that have not
//--- request EU event history since 2018 year
if(CalendarValueHistory(values,date_from,date_to,EU_code))
{
PrintFormat("Received event values for country_code=%s: %d",
EU_code,ArraySize(values));
//--- decrease the size of the array for outputting to the Journal
ArrayResize(values,10);
//--- display event values in the Journal
ArrayPrint(values);
}
else
{
PrintFormat("Error! Failed to receive events for country_code=%s",EU_code);
PrintFormat("Error code: %d",GetLastError());
}
//---
}
/*
Result:
Received event values for country_code=EU: 1384
[id] [event_id] [time] [period] [revision] [actual_value] [prev_v
[0] 54215 999500001 2018.01.02 09:00:00 2017.12.01 00:00:00 3 60600000 60600
[1] 54221 999500002 2018.01.04 09:00:00 2017.12.01 00:00:00 3 56600000 56500
[2] 54222 999500003 2018.01.04 09:00:00 2017.12.01 00:00:00 3 58100000 58000
[3] 45123 999030005 2018.01.05 10:00:00 2017.11.01 00:00:00 0 600000 400
[4] 45124 999030006 2018.01.05 10:00:00 2017.11.01 00:00:00 0 2800000 2500
[5] 45125 999030012 2018.01.05 10:00:00 2017.12.01 00:00:00 1 900000 900
[6] 45126 999030013 2018.01.05 10:00:00 2017.12.01 00:00:00 1 1400000 1500
[7] 54953 999520001 2018.01.05 20:30:00 2018.01.02 00:00:00 0 127900000 92100
[8] 22230 999040003 2018.01.08 10:00:00 2017.12.01 00:00:00 0 9100000 8200
[9] 22231 999040004 2018.01.08 10:00:00 2017.12.01 00:00:00 0 18400000 16300
*/
See also
CalendarCountries, CalendarEventByCountry, CalendarValueH istoryByEvent, CalendarEventById,
CalendarValueById
CalendarValueLastByEvent
Get the array of event values by its ID since the Calendar database status with a specified change_id.
int CalendarValueLastByEvent(
ulong event_id, // event ID
ulong& change_id, // Calendar change ID
MqlCalendarValue& values[] // array for value descriptions
);
Parameters
event_id
[in] Event ID.
change_id
[in][out] Change ID.
values[]
[out] M qlCalendarValue type array for receiving event values.
Return Value
Number of received event values. To get information about an error, call the GetLastError()
function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 4004 – ERR_NOT _ENOUGH_M EMORY (not enough memory for executing a request),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded),
· 5400 – ERR_CAL ENDAR_MORE_DAT A (array size is insufficient for receiving descriptions of all
values, only the ones that managed to fit in were received),
· errors of failed execution of ArrayR esize()
Note
All functions for work ing with the economic calendar use the trade server time (TimeTradeServer).
This means that the time in the M qlCalendarValue structure and the time inputs in the
CalendarValueH istoryByEvent/CalendarValueH istory functions are set in a trade server timezone,
rather than a user's local time.
If the events[] array of fixed length was passed to the function and there was not enough space to
save the entire result, the ERR_CAL ENDAR_MORE_DAT A (5400) error is activated.
If change_id = 0 is passed to the function, the function always returns zero but the current calendar
database is returned to change_id.
The function returns the array for a specified news and a new change_id that can be used for
subsequent calls of the function to receive the new values of the news. Thus, it is possible to update
values for a specified news by calling this function with the last k nown change_id.
If an event value does not have any of the fields specified below
struct MqlCalendarValue
{
...
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//--- Calendar database change ID
static ulong calendar_change_id=0;
//--- first launch attribute
ArrayRemove(events,0,event_pos-9);
ArrayPrint(events);
}
else
{
PrintFormat("%s: CalendarEventByCountry(%s) returned 0 events, error code=%d",
USA_code,__FUNCTION__,GetLastError());
//--- operation completed in a failure, try again during the next call of the timer
return;
}
//--- get the Calendar database change ID for the specified event
if(CalendarValueLastByEvent(event_id,calendar_change_id,values)>0)
{
//--- this code block cannot be executed during the first launch but let's add it anyway
PrintFormat("%s: Received the Calendar database current ID: change_id=%d",
__FUNCTION__,calendar_change_id);
//--- set the flag and exit before the timer's next event
first=false;
return;
}
else
{
//--- data are not received (this is normal for the first launch), check for an error
int error_code=GetLastError();
if(error_code==0)
{
PrintFormat("%s: Received the Calendar database current ID: change_id=%d",
__FUNCTION__,calendar_change_id);
//--- set the flag and exit before the timer's next event
first=false;
//--- now we have the calendar_change_id value
return;
}
else
{
//--- and this is really an error
PrintFormat("%s: Failed to get values for event_id=%d",__FUNCTION__,event_id);
PrintFormat("Error code: %d",error_code);
//--- operation completed in a failure, try again during the next call of the timer
return;
}
}
}
//--- we have the last known value of the Calendar change ID (change_id)
ulong old_change_id=calendar_change_id;
//--- check for a new Nonfarm Payrolls event value
if(CalendarValueLastByEvent(event_id,calendar_change_id,values)>0)
{
PrintFormat("%s: Received new events for \"%s\": %d",
__FUNCTION__,event_name,ArraySize(values));
//--- display data from the 'values' array in the Journal
ArrayPrint(values);
//--- display the values of the previous and new Calendar IDs in the Journal
PrintFormat("%s: Previous change_id=%d, new change_id=%d",
__FUNCTION__,old_change_id,calendar_change_id);
/*
write your code that is to handle "Nonfarm Payrolls" data release here
*/
}
//---
}
/*
Result:
OnTimer: USA events: 202
Event "Nonfarm Payrolls" found: event_id=840030016 event_name=Nonfarm Payrolls
[id] [type] [sector] [frequency] [time_mode] [country_id] [unit] [importance] [multipli
[0] 840030007 1 4 2 0 840 1 1
[1] 840030008 1 4 2 0 840 1 1
[2] 840030009 1 4 2 0 840 0 1
[3] 840030010 1 4 2 0 840 0 1
[4] 840030011 1 4 2 0 840 1 1
[5] 840030012 1 4 2 0 840 1 1
[6] 840030013 1 4 2 0 840 1 1
[7] 840030014 1 4 2 0 840 1 1
[8] 840030015 1 3 2 0 840 1 2
[9] 840030016 1 3 2 0 840 4 3
OnTimer: Received the Calendar database current ID: change_id=33986560
*/
See also
CalendarValueLast, CalendarValueH istory, CalendarValueH istoryByEvent, CalendarValueById
CalendarValueLast
Get the array of values for all events with the ability to sort by country and/or currency since the
calendar database status with a specified change_id.
int CalendarValueLast(
ulong& change_id, // change ID
MqlCalendarValue& values[], // array for value descriptions
const string country_code=NULL, // country code name (ISO 3166-1 alpha-2)
const string currency=NULL // country currency code name
);
Parameters
change_id
[in][out] Change ID.
values[]
[out] M qlCalendarValue type array for receiving event values.
country_code=NULL
[in] Country code name (ISO 3166-1 alpha-2)
currency=NULL
[in] Country currency code name.
Return Value
Number of received event values. To get information about an error, call the GetLastError()
function. Possible errors :
· 4001 – ERR_I NT ERNAL _ERR OR (general runtime error),
· 4004 – ERR_NOT _ENOUGH_M EMORY (not enough memory for executing a request),
· 5401 – ERR_CAL ENDAR_TIM EOUT (request time limit exceeded),
· 5400 – ERR_CAL ENDAR_MORE_DAT A (array size is insufficient for receiving descriptions of all
values, only the ones that managed to fit in were received),
· errors of failed execution of ArrayR esize()
Note
All functions for work ing with the economic calendar use the trade server time (TimeTradeServer).
This means that the time in the M qlCalendarValue structure and the time inputs in the
CalendarValueH istoryByEvent/CalendarValueH istory functions are set in a trade server timezone,
rather than a user's local time.
If the events[] array of fixed length was passed to the function and there was not enough space to
save the entire result, the ERR_CAL ENDAR_MORE_DAT A (5400) error is activated.
If change_id = 0 is passed to the function, you will get the current change_id of the calendar
database to that parameter; and the function returns 0
For the country_code and currency filters, NULL and "" values are equivalent and mean the absence
of the filter.
For country_code, the code field of the M qlCalendarCountry structure, for example "US " , "RU" or
"EU" , should be used.
For currency, the currency field of the M qlCalendarCountry structure, for example "US D" , "RUB" or
"EUR" , should be used.
The filters are applied by conjunction, i.e. logical 'AND' is used to select only the values of events
both conditions (country and currency) are simultaneously met for
The function returns the array for a specified news and a new change_id that can be used for
subsequent calls of the function to receive the new values of the news. Thus, it is possible to update
values for a specified news by calling this function with the last k nown change_id.
If an event value does not have any of the fields specified below
struct MqlCalendarValue
{
...
long actual_value; // event's actual value
long prev_value; // event's previous value
long revised_prev_value; // event's revised previous value
long forecast_value; // event's forecast value
...
};
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//--- Calendar database change ID
static ulong calendar_change_id=0;
//--- first launch attribute
static bool first=true;
//--- event value array
MqlCalendarValue values[];
//--- perform initialization - get the current calendar_change_id
if(first)
{
//--- get the Calendar database change ID
if(CalendarValueLast(calendar_change_id,values)>0)
{
//--- this code block cannot be executed during the first launch but let's add it anyway
PrintFormat("%s: Received the Calendar database current ID: change_id=%d",
__FUNCTION__,calendar_change_id);
//--- set the flag and exit before the timer's next event
first=false;
return;
}
else
{
//--- data are not received (this is normal for the first launch), check for an error
int error_code=GetLastError();
if(error_code==0)
{
PrintFormat("%s: Received the Calendar database current ID: change_id=%d",
__FUNCTION__,calendar_change_id);
//--- set the flag and exit before the timer's next event
first=false;
//--- now we have the calendar_change_id value
return;
}
else
{
//--- and this is really an error
PrintFormat("%s: Failed to get events in CalendarValueLast. Error code: %d",
__FUNCTION__,error_code);
//--- operation completed in a failure, re-initialize during the next call of the timer
return;
}
}
}
//--- we have the last known value of the Calendar change ID (change_id)
ulong old_change_id=calendar_change_id;
//--- check if there are new Calendar events
if(CalendarValueLast(calendar_change_id,values)>0)
{
PrintFormat("%s: Received new Calendar events: %d",
__FUNCTION__,ArraySize(values));
//--- display data from the 'values' array in the Journal
ArrayPrint(values);
//--- display the values of the previous and new Calendar IDs in the Journal
PrintFormat("%s: Previous change_id=%d, new change_id=%d",
__FUNCTION__,old_change_id,calendar_change_id);
//--- display new events in the Journal
ArrayPrint(values);
/*
write your code that is to handle occurrence of events here
*/
}
//---
}
/*
Example of the listener operation:
OnTimer: Received the Calendar database current ID: change_id=33281792
OnTimer: Received new events for the Calendar: 1
[id] [event_id] [time] [period] [revision] [actual_value] [prev_val
[0] 91040 76020013 2019.03.20 15:30:00 1970.01.01 00:00:00 0 -5077000 -1913
OnTimer: Previous change_id=33281792, new change_id=33282048
[id] [event_id] [time] [period] [revision] [actual_value] [prev_val
[0] 91040 76020013 2019.03.20 15:30:00 1970.01.01 00:00:00 0 -5077000 -1913
OnTimer: Received new events for the Calendar: 1
[id] [event_id] [time] [period] [revision] [actual_value] [pr
[0] 91041 76020013 2019.03.27 15:30:00 1970.01.01 00:00:00 0 -9223372036854775808
OnTimer: Previous change_id=33282048, new change_id=33282560
[id] [event_id] [time] [period] [revision] [actual_value] [pr
[0] 91041 76020013 2019.03.27 15:30:00 1970.01.01 00:00:00 0 -9223372036854775808
*/
See also
CalendarValueLast, CalendarValueH istory, CalendarValueH istoryByEvent, CalendarValueById
There is an important exception to this rule: if timeseries and indicator values need to be copied
often, for example at each call of OnTick () in Expert Advisors or at each call of OnCalculate() in
indicators, in this case one should better use statically distributed arrays, because operations of
memory allocation for dynamic arrays require additional time, and this will have effect during
testing and optimization.
W hen using functions accessing timeseries and indicator values, indexing direction should be tak en
into account. This is described in the Indexing Direction in Arrays, Buffers and Timeseries section.
Access to indicator and timeseries data is implemented irrespective of the fact whether the requested
data are ready (the so called asynchronous access). This is critically important for the calculation of
custom indicator, so if there are no data, functions of Copy...() type immediately return an error.
H owever, when accessing form Expert Advisors and scripts, several attempts to receive data are made
in a small pause, which is aimed at providing some time necessary to download required timeseries or
to calculate indicator values.
The Organizing Data Access section describes details of receiving, storing and requesting price data in
the MetaTrader 5 client terminal.
It is historically accepted that an access to the price data in an array is performed from the end of the
data. Physically, the new data are always written at the array end, but the index of the array is always
equal to zero. The 0 index in the timeseries array denotes data of the current bar, i.e. the bar that
corresponds to the unfinished time interval in this timeframe.
A timeframe is the time period, during which a single price bar is formed. There are 21 predefined
standard timeframes.
Function Action
Despite the fact that by using the ArraySetAsSeries() function it is possible to set up in arrays access
to elements lik e that in timeseries, it should be remembered that the array elements are physically
stored in one and the same order - only indexing direction changes. To demonstrate this fact let's
perform an example:
datetime TimeAsSeries[];
//--- set access to the array like to a timeseries
ArraySetAsSeries(TimeAsSeries,true);
ResetLastError();
int copied=CopyTime(NULL,0,0,10,TimeAsSeries);
if(copied<=0)
{
Print("The copy operation of the open time values for last 10 bars has failed");
return;
}
Print("TimeCurrent =",TimeCurrent());
Print("ArraySize(Time) =",ArraySize(TimeAsSeries));
int size=ArraySize(TimeAsSeries);
for(int i=0;i<size;i++)
{
Print("TimeAsSeries["+i+"] =",TimeAsSeries[i]);
}
datetime ArrayNotSeries[];
ArraySetAsSeries(ArrayNotSeries,false);
ResetLastError();
copied=CopyTime(NULL,0,0,10,ArrayNotSeries);
if(copied<=0)
{
Print("The copy operation of the open time values for last 10 bars has failed");
return;
}
size=ArraySize(ArrayNotSeries);
for(int i=size-1;i>=0;i--)
{
Print("ArrayNotSeries["+i+"] =",ArrayNotSeries[i]);
}
As we see from the output, as the index of TimeAsSeries array increases, the time value of the index
decreases, i.e. we move from the present to the past. For the common array ArrayNotSeries the result
is different - as index grows, we move from past to present.
See Also
ArrayIs Dynamic, ArrayGetAsSeries, ArraySetAsSeries, ArrayIsSeries
An indicator buffer is a dynamic array of type double, whose size is managed by the client terminals,
so that it always corresponds to the number of bars the indicator is calculated on. A usual dynamic
array of type double is assigned as an indicator buffer using the SetIndex Buffer() function. Indicator
buffers do not require setting of their size using function ArrayR esize() - this will be done by the
executing system of the terminal.
Timeseries are arrays with reverse indexing, i.e. the first element of a timeseries is in the extreme
right position, and the last element is in the extreme left position. Timeseries being used for storing
history price data and contain the time information, we can say that the newest data are placed in the
extreme right position of the timeseries, while the oldest data are in the extreme left position.
So the timeseries element with index 0 contains the information about the latest quote of a symbol. If
a timeseries contains data on a daily timeframe, data of the current yet uncompleted day are located
on the zero position, and the position with index 1 contains yesterday data.
Function ArraySetAsSeries() allows changing the method of accessing elements of a dynamic array; the
physical order of data storing in the computer memory is not changed at that. This function simply
changes the method of addressing array elements, so when copying one array to another using
function ArrayCopy(), the contents of the recipient array will not depend on the indexing direction in
the source array.
Direction of indexing cannot be changed for statically distributed arrays. Even if an array was passed
as a parameter to a function, attempts to change the indexing direction inside this function will bring
no effect.
For indicator buffers, lik e for usual arrays, indexing direction can also be set as back ward (lik e in
timeseries), i.e. reference to the zero position in the indicator buffer will mean reference to the last
value on the corresponding indicator buffer and this will correspond to the value of the indicator on the
latest bar. Still, the physical location of indicator bars will be unchanged.
Each custom indicator must necessarily contain the OnCalculate() function, to which price data
required for calculating values in indicator buffers are passed. Indexing direction in these passed
arrays can be found out using function ArrayGetAsSeries().
Arrays passed to the function reflect price data, i.e. these arrays have the sign of a timeseries and
function ArrayIsSeries() will return true when check ing these arrays. H owever, in any case indexing
direction should be check ed only by function ArrayGetAsSeries().
In order not to be dependent on default values, ArraySetAsSeries() should be unconditionally called for
the arrays you are going to work with, and set the required direction.
Default indexing direction of all arrays in Expert Advisors, indicators and scripts is left-to-right. If
necessary, in any mql5 program you can request timeseries values on any symbol and timeframe, as
well as values of indicators calculated on any symbol and timeframe.
All these functions work in a similar way. Let's consider the data obtaining mechanism on the example
of CopyBuffer(). It is implied that the indexing direction of requested data is that of timeseries, and
the position with index 0 (zero) stores data of the current yet uncompleted bar. In order to get access
to these data we need to copy the necessary volume of data into the recipient array, e.g. into array
buffer.
W hen copying we need to specify the starting position in the source array, starting from which data
will be copied to the recipient array. In case of success, the specified number of elements will be
copied to the recipient array from the source array (from the indicator buffer in this case).
Irrespective of the indexing value set in the recipient array, copying is always performed as is shown
in the above figure.
If it is expected that price data will be handled in a loop with a large number of iterations, it is
advisable that you check the fact of forced program termination using the IsStopped() function:
);
if(copied<0) return;
int k=0;
while(k<copied && !IsStopped())
{
//--- Get the value for the k index
double value=Buffer[k];
// ...
// work with value
k++;
}
Example:
See also
Organizing Data Access
Before price data become available in the MetaTrader 5 terminal, they must be received and
processed. To receive data, connection to the MetaTrader 5 trade server must be established. Data
are received in the form of pack ed block s of minute bars from the server upon the request of a
terminal.
The mechanism of server reference for data doesn't depend on how the request has been initiated - by
a user when navigating in a chart or in a program way in the MQL5 language.
Data received from a server are automatically unpack ed and saved in the H CC intermediate format.
Data on each symbol are written into a separate folder:
terminal_directory\ bases \ server_name\ history\ symbol_name. For example, data on EURUS D received
Data are written into files with .hcc extension. Each file stores data of minute bars for one year. For
example, the file named 2009.hcc in the EURUS D folder contains minute bars of EURUS D for year 2009.
These files are used for preparing price data for all timeframes and are not intended for direct access.
Intermediate H CC files are used as the data source for building price data for requested timeframes in
the H C format. Data of H C format are timeseries that are maximally prepared for a quick access. They
are created upon a request of a chart or a MQL5 program. The volume of data should not exceed the
value of the " Max bars in charts " parameter. Data are stored for further using in files with hc
extension.
To save resources, data on a timeframe are stored and saved in RAM only if necessary. If not called
for a long time, they are released from RAM and saved into a file. For each timeframe, data are
prepared regardless of whether there are ready data for other timeframes or not. R ules of forming and
accessing data are the same for all timeframes. I.e., despite the fact that the unit data stored in H CC
is one minute (M 1), the availability of H CC data doesn't mean the availability of data on M 1 timeframe
as H C in the same volume.
R eceipt of new data from a server calls automatic update of used price data in H C format of all
timeframes. It also leads to the recalculation of all indicators that implicitly use them as input data for
calculations.
The " Max bars in charts " parameter restricts number of bars in H C format available to charts,
indicators and mql5 programs. This is valid for all available timeframes and serves, first of all, to save
computer resources.
W hen setting a large value of this parameter, it should be remembered, that if deep history price data
for small timeframes are available, memory used for storing timeseries and indicator buffers can
become hundreds of megabytes and reach the RAM restriction for the client terminal program (2Gb for
32-bit applications of MS W indows).
Change of the " Max bars in charts " comes into effect after the client terminal is restarted. Change of
this parameter causes neither automatic referring to a server for additional data, nor forming of
additional bars of timeseries. Additional price data are requested from the server, and timeseries are
updated tak ing into account the new limitation, in case of either chart scroll to the area with no data,
or when data are requested by a mql5 program.
Volume of data requested from the server corresponds to the required number of bars of this
timeframe with the " Max bars in charts " parameter tak en into account. The restriction set by this
parameter is not strict, and in some cases the number of available bars for a timeframe can be a little
more than the current parameter value.
Data Availability
Presence of data on H CC format or even in the prepared for using H C format does not always denote
the absolute availability of these data to be shown in a chart or to be used in MQL5 programs.
W hen accessing to price data or indicator values from a mql5 program it should be remembered that
their availability in a certain moment of time or starting from a certain moment of time is not
guaranteed. It is connected with the fact that with the purpose of saving resources, the full copy of
data necessary for a mql5 program isn't stored in MetaTrader 5; only direct access to the terminal
database is given.
The price history for all timeframes is built from common data of H CC format, and any update of data
from a server leads to the update of data for all timeframes and to the recalculation of indicators. Due
to this access to data can be closed, even if these data were available a moment ago.
Since a mql5 program can call data from any symbol and timeframe, there is a possibility that data of
a necessary timeseries are not formed yet in the terminal or the necessary price data aren't
synchronized with the trade server. In this case it's hard to predict the latency time.
Algorithms using " do-nothing " loops are not the best solution. The only exception in this case are
scripts, because they do not have any alternative algorithm choice due to not having event handling.
For custom indicators such algorithms, as well as any other " do-nothing " loops are strongly not
recommended, because they lead to termination of calculation of all indicators and any other handling
of price data of the symbol.
For Expert Advisors and indicators, it is better to use the event model of handling. If during handling
of OnTick () or OnCalculate() event, data receipt for the required timeseries failed, you should exit the
event handler, relying on the access availability during the next call of the handler.
timeframe doesn't matter, because, as it was mentioned above, price data are received from a trade
server as pack ed one minute data, from which any predefined timeseries is constructed then.
W rite all actions concerning data receipt as a separate function Check LoadH istory(symbol, timeframe,
start_date):
The Check LoadH istory() function is designed as a universal function that can be called from any
program (Expert Advisor, script or indicator); and therefore it requires three input parameters : symbol
name, period and start date to indicate the beginning of price history you need.
Insert necessary check s into the function code before requesting the missing history. First of all, we
should mak e sure that the symbol name and period value are correct:
Then let's mak e sure that the symbol is available in the Mark etW atch window, i.e., the history for the
symbol will be available when sending a request to a trade server. If there is no such a symbol in
Mark etW atch, add it using the SymbolSelect() function.
if(!SymbolInfoInteger(symbol,SYMBOL_SELECT))
{f
if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) return(-1);
SymbolSelect(symbol,true);
}
Now we should receive the start date of the available history for the indicated symbol/period pair.
Perhaps, the value of the input parameter startdate, passed to Check LoadH istory(), is within the
available history; then request to a trade server is not needed. In order to obtain the very first date
for the symbol-period as of the moment, the SeriesInfoInteger() function with the S ER I ES _FI R ST DAT E
modifier is used.
SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date);
if(first_date>0 && first_date<=start_date) return(1);
The next important check is check ing the type of the program, from which the function is called. Note
that it is not desirable to send a request to update the timeseries from indicator with the same
period. The undesirability of requesting data on the same symbol-period as that of the indicator is
conditioned by the fact that update of history data is performed in the same thread where the
indicator operates. So the possibility of deadlock occurrence is high. To check this use the
MQL5InfoInteger() function with the MQL5_PR OGRAM _T YPE modifier.
If all the check s have been passed successfully, mak e the last attempt to do without referring to the
trade server. First let's find out the start date, for which minute data in H CC format are available.
R equest this value using the SeriesInfoInteger() function with the S ER IES _T ER MINAL _FIR ST DAT E
modifier and again compare it to the value of the start_date parameter.
if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date))
{
//--- there is loaded data to build timeseries
if(first_date>0)
{
//--- force timeseries build
CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times);
//--- check date
if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
if(first_date>0 && first_date<=start_date) return(2);
}
}
If after all the check s the execution thread is still in the body of the Check LoadH istory() function, it
means there is a necessity to request the missing price data from a trade server. First, return the
value of " Max bars in chart" using the TerminalInfoInteger() function:
int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS);
W e'll need it to prevent requesting extra data. Then find the very first date in the symbol history on
the trade server (regardless of the period) using already k nown function SeriesInfoInteger() with the
S ER I ES _S ERVER_FI R ST DAT E modifier.
datetime first_server_date=0;
while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopp
Sleep(5);
Since the request is an asynchronous operation, the function is called in the loop with a small delay of
5 milliseconds until the first_server_date variable receives a value, or the loop execution is
terminated by a user (IsStopped() will return true in this case). Let's indicate a correct value of the
start date, starting from which we request price data from a trade server.
if(first_server_date>start_date) start_date=first_server_date;
if(first_date>0 && first_date<first_server_date)
Print("Warning: first server date ",first_server_date," for ",
symbol," does not match to first series date ",first_date);
If the start date first_server_date of the server is lower than the start date first_date of the symbol in
H CC format, the corresponding entry will be output in the journal.
Now we are ready to mak e a request to a trade server as k ing for missing price data. Mak e the request
in the form of a loop and start filling out its body:
while(!IsStopped())
{
//1. wait for synchronization between the re-built timeseries and intermediate history as HHC
//2. receive the current number of bars in this timeseries
// if bars is larger than Max_bars_in_chart, we can exit, work is over
//3. obtain the start date first_date in the re-built timeseries and compare it to start_date
// if first_date is lower than start_date, we can exit, work is over
//4. request from a server a new part of history - 100 bars starting from last available bar
}
while(!IsStopped())
{
//--- 1.wait till timeseries re-build process is over
while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped())
Sleep(5);
//--- 2.request how many bars we have
int bars=Bars(symbol,period);
if(bars>0)
{
//--- bars more than ones that can be drawn in the chart, exit
if(bars>=max_bars) return(-2);
//--- 3. return the current start date in the timeseries
if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
// start date was earlier than that requested, task completed
if(first_date>0 && first_date<=start_date) return(0);
}
//4. Request from a server a new part of history - 100 bars starting from last available bar
}
The last fourth point is left - requesting history. W e can't refer to a server directly, but any Copy-
function automatically initiates request sending to a server, if the history in H CC format is not
enough. Since the time of the very first start date in the first_date variable is the simple and natural
criterion to evaluate the request execution degree, then the easiest way is to use the CopyTime()
function.
W hen calling functions that copy any data from timeseries, it should be noted that the parameter
start
(number of the bar, starting from which price data should be copied) must always be within the
available terminal history. If you have only 100 bars, it meaningless to try copying 300 bars starting
from the bar with the index 500. Such a request will be understood as an erroneous and won't be
handled, i.e. no additional history will be loaded from a trade server.
That's why we'll copy bars in groups of 100 starting from the bar with the bars index. This will provide
the smooth loading of missing history from a trade server. Actually a little more than the requested
100 bars will be loaded, while server sends oversized history.
int copied=CopyTime(symbol,period,bars,100,times);
After the copying operation, we should analyze the number of copied elements. If the attempt fails,
then value of the copied will be equal to null and the value of the fail_cnt counter will be increased by
1. After 100 failing attempts, the operation of the function will be stopped.
int fail_cnt=0;
...
int copied=CopyTime(symbol,period,bars,100,times);
if(copied>0)
{
//--- check data
if(times[0]<=start_date) return(0); // the copied value is smaller, ready
if(bars+copied>=max_bars) return(-2); // bars are more than can be drawn in the chart, ready
fail_cnt=0;
}
else
{
//--- no more than 100 failing attempts in succession
fail_cnt++;
if(fail_cnt>=100) return(-5);
Sleep(10);
}
So, not only correct handling of the current situation at each moment of execution is implemented in
the function, but also the termination code is returned, that can be handled after calling the
Check LoadH istory() function for getting additional information. For example, this way:
int res=CheckLoadHistory(InpLoadedSymbol,InpLoadedPeriod,InpStartDate);
switch(res)
{
case -1 : Print("Unknown symbol ",InpLoadedSymbol); break;
case -2 : Print("More requested bars than can be drawn in the chart"); break;
case -3 : Print("Execution stopped by user"); break;
case -4 : Print("Indicator mustn't load its own data"); break;
case -5 : Print("Loading failed"); break;
case 0 : Print("All data loaded"); break;
case 1 : Print("Already available data in timeseries are enough"); break;
case 2 : Print("Timeseries is built from available terminal data"); break;
default : Print("Execution result undefined");
}
The full code of the function can be found in the example of a script that shows the correct
organization of access to any data with the handling of request's results.
Code:
//+------------------------------------------------------------------+
//| TestLoadHistory.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.02"
#property script_show_inputs
//--- input parameters
input string InpLoadedSymbol="NZDUSD"; // Symbol to be load
input ENUM_TIMEFRAMES InpLoadedPeriod=PERIOD_H1; // Period to be loaded
input datetime InpStartDate=D'2006.01.01'; // Start date
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
Print("Start load",InpLoadedSymbol+","+GetPeriodName(InpLoadedPeriod),"from",InpStartDate);
//---
int res=CheckLoadHistory(InpLoadedSymbol,InpLoadedPeriod,InpStartDate);
switch(res)
{
case -1 : Print("Unknown symbol ",InpLoadedSymbol); break;
case -2 : Print("Requested bars more than max bars in chart"); break;
case -3 : Print("Program was stopped"); break;
case -4 : Print("Indicator shouldn't load its own data"); break;
case -5 : Print("Load failed"); break;
case 0 : Print("Loaded OK"); break;
case 1 : Print("Loaded previously"); break;
case 2 : Print("Loaded previously and built"); break;
default : Print("Unknown result");
}
//---
datetime first_date;
SeriesInfoInteger(InpLoadedSymbol,InpLoadedPeriod,SERIES_FIRSTDATE,first_date);
int bars=Bars(InpLoadedSymbol,InpLoadedPeriod);
Print("First date ",first_date," - ",bars," bars");
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CheckLoadHistory(string symbol,ENUM_TIMEFRAMES period,datetime start_date)
{
datetime first_date=0;
datetime times[100];
//--- check symbol & period
if(symbol==NULL || symbol=="") symbol=Symbol();
if(period==PERIOD_CURRENT) period=Period();
//--- check if symbol is selected in the Market Watch
if(!SymbolInfoInteger(symbol,SYMBOL_SELECT))
{
if(GetLastError()==ERR_MARKET_UNKNOWN_SYMBOL) return(-1);
SymbolSelect(symbol,true);
}
//--- check if data is present
SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date);
if(first_date>0 && first_date<=start_date) return(1);
//--- don't ask for load of its own data if it is an indicator
if(MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR && Period()==period && Symbol()==symbol
return(-4);
//--- second attempt
if(SeriesInfoInteger(symbol,PERIOD_M1,SERIES_TERMINAL_FIRSTDATE,first_date))
{
//--- there is loaded data to build timeseries
if(first_date>0)
{
//--- force timeseries build
CopyTime(symbol,period,first_date+PeriodSeconds(period),1,times);
//--- check date
if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
if(first_date>0 && first_date<=start_date) return(2);
}
}
//--- max bars in chart from terminal options
int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS);
//--- load symbol history info
datetime first_server_date=0;
while(!SeriesInfoInteger(symbol,PERIOD_M1,SERIES_SERVER_FIRSTDATE,first_server_date) && !IsStopp
Sleep(5);
//--- fix start date for loading
if(first_server_date>start_date) start_date=first_server_date;
if(first_date>0 && first_date<first_server_date)
Print("Warning: first server date ",first_server_date," for ",symbol,
" does not match to first series date ",first_date);
//--- load data step by step
int fail_cnt=0;
while(!IsStopped())
{
//--- wait for timeseries build
while(!SeriesInfoInteger(symbol,period,SERIES_SYNCHRONIZED) && !IsStopped())
Sleep(5);
//--- ask for built bars
int bars=Bars(symbol,period);
if(bars>0)
{
if(bars>=max_bars) return(-2);
//--- ask for first date
if(SeriesInfoInteger(symbol,period,SERIES_FIRSTDATE,first_date))
if(first_date>0 && first_date<=start_date) return(0);
}
//--- copying of next part forces data loading
int copied=CopyTime(symbol,period,bars,100,times);
if(copied>0)
{
//--- check for data
if(times[0]<=start_date) return(0);
if(bars+copied>=max_bars) return(-2);
fail_cnt=0;
}
else
{
//--- no more than 100 failed attempts
fail_cnt++;
if(fail_cnt>=100) return(-5);
Sleep(10);
}
}
//--- stopped
return(-3);
}
//+------------------------------------------------------------------+
//| Returns string value of the period |
//+------------------------------------------------------------------+
string GetPeriodName(ENUM_TIMEFRAMES period)
{
if(period==PERIOD_CURRENT) period=Period();
//---
switch(period)
{
case PERIOD_M1: return("M1");
case PERIOD_M2: return("M2");
case PERIOD_M3: return("M3");
case PERIOD_M4: return("M4");
case PERIOD_M5: return("M5");
case PERIOD_M6: return("M6");
case PERIOD_M10: return("M10");
case PERIOD_M12: return("M12");
case PERIOD_M15: return("M15");
case PERIOD_M20: return("M20");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H2: return("H2");
case PERIOD_H3: return("H3");
case PERIOD_H4: return("H4");
case PERIOD_H6: return("H6");
case PERIOD_H8: return("H8");
case PERIOD_H12: return("H12");
case PERIOD_D1: return("Daily");
case PERIOD_W1: return("Weekly");
case PERIOD_MN1: return("Monthly");
}
//---
return("unknown period");
}
SeriesInfoInteger
R eturns information about the state of historical data. There are 2 variants of function calls.
long SeriesInfoInteger(
string symbol_name, // symbol name
ENUM_TIMEFRAMES timeframe, // period
ENUM_SERIES_INFO_INTEGER prop_id, // property identifier
);
bool SeriesInfoInteger(
string symbol_name, // symbol name
ENUM_TIMEFRAMES timeframe, // period
ENUM_SERIES_INFO_INTEGER prop_id, // property ID
long& long_var // variable for getting info
);
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
prop_id
[in] Identifier of the requested property, value of the ENUM _S ER IES _INFO_INT EGER enumeration.
long_var
[out] Variable to which the value of the requested property is placed.
Return Value
For the second case, it returns true, if the specified property is available and its value has been
placed into long _var variable, otherwise it returns false. For more details about an error, call
GetLastError().
Example:
void OnStart()
{
//---
Print("Total number of bars for the symbol-period at this moment = ",
SeriesInfoInteger(Symbol(),Period(),SERIES_BARS_COUNT));
Print("The first date in the history for the symbol-period on the server = ",
(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_SERVER_FIRSTDATE));
Bars
R eturns the number of bars count in the history for a specified symbol and period. There are 2
variants of functions calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_time
[in] Bar time corresponding to the first element.
stop_time
[in] Bar time corresponding to the last element.
Return Value
If the start_time and stop_time parameters are defined, the function returns the number of bars in
the specified time interval, otherwise it returns the total number of bars.
Note
If data for the timeseries with specified parameters are not formed in the terminal by the time of
the Bars() function call, or data of the timeseries are not synchronized with a trade server by the
moment of the function call, the function returns a zero value.
W hen requesting the number of bars in a specified time interval, only bars with an open time falling
within the interval are considered. For example, if the current day of the week is Saturday and the
request is made for the number of W1 bars with start_time=last_tuesday and stop_time=last_friday,
the function will return 0 since the open time of a W1 timeframe is always Sunday and not a single
W1 bar falls within the specified interval.
int bars=Bars(_Symbol,_Period);
if(bars>0)
{
Print("Number of bars in the terminal history for the symbol-period at the moment = ",bars);
}
else //no available bars
{
//--- data on the symbol might be not synchronized with data on the server
bool synchronized=false;
//--- loop counter
int attempts=0;
// make 5 attempts to wait for synchronization
while(attempts<5)
{
if(SeriesInfoInteger(Symbol(),0,SERIES_SYNCHRONIZED))
{
//--- synchronization done, exit
synchronized=true;
break;
}
//--- increase the counter
attempts++;
//--- wait 10 milliseconds till the next iteration
Sleep(10);
}
//--- exit the loop after synchronization
if(synchronized)
{
Print("Number of bars in the terminal history for the symbol-period at the moment = ",bars
Print("The first date in the terminal history for the symbol-period at the moment = ",
(datetime)SeriesInfoInteger(Symbol(),0,SERIES_FIRSTDATE));
Print("The first date in the history for the symbol on the server = ",
(datetime)SeriesInfoInteger(Symbol(),0,SERIES_SERVER_FIRSTDATE));
}
//--- synchronization of data didn't happen
else
{
Print("Failed to get number of bars for ",_Symbol);
}
}
Print("Number of bars: ",n); // Output: "Number of bars: 8", H2 bar is considered in the calcula
n=Bars(_Symbol,PERIOD_D1,date1,date2);
Print("Number of bars: ",n); // Output: "Number of bars: 1", since an open time of a single D1 (
n=Bars(_Symbol,PERIOD_W1,date2,date3);
Print("Number of bars: ",n); // Output: "Number of bars: 0", since not a single W1 bar open time
See also
Event H andling Functions
BarsCalculated
R eturns the number of calculated data for the specified indicator.
int BarsCalculated(
int indicator_handle, // indicator handle
);
Parameters
indicator_handle
[in] The indicator handle, returned by the corresponding indicator function.
Return Value
R eturns the amount of calculated data in the indicator buffer or -1 in the case of error (data not
calculated yet)
Note
The function is useful when it's necessary to get the indicator data immediately after its creation
(indicator handle is available).
Example:
void OnStart()
{
double Ups[];
//--- set timeseries ordering for the arrays
ArraySetAsSeries(Ups,true);
//--- create handle for the Fractal Indicator
int FractalsHandle=iFractals(NULL,0);
//--- reset the error code
ResetLastError();
//--- try to copy the indicator values
int i,copied=CopyBuffer(FractalsHandle,0,0,1000,Ups);
if(copied<=0)
{
Sleep(50);
for(i=0;i<100;i++)
{
if(BarsCalculated(FractalsHandle)>0)
break;
Sleep(50);
}
copied=CopyBuffer(FractalsHandle,0,0,1000,Ups);
if(copied<=0)
{
Print("Failed to copy upper fractals. Error = ",GetLastError(),
"i = ",i," copied = ",copied);
return;
}
else
Print("Upper fractals copied",
"i = ",i," copied = ",copied);
}
else Print("Upper fractals copied. ArraySize = ",ArraySize(Ups));
}
IndicatorCreate
The function returns the handle of a specified technical indicator created based on the array of
parameters of M qlParam type.
int IndicatorCreate(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // timeframe
ENUM_INDICATOR indicator_type, // indicator type from the enumeration ENUM_
int parameters_cnt=0, // number of parameters
const MqlParam& parameters_array[]=NULL, // array of parameters
);
Parameters
symbol
[in] Name of a symbol, on data of which the indicator is calculated. NULL means the current
symbol.
period
[in] The value of the timeframe can be one of values of the ENUM _TIM EFRAM ES enumeration, 0
means the current timeframe.
indicator_type
[in] Indicator type, can be one of values of the ENUM _INDICATOR enumeration.
parameters_cnt
[in] The number of parameters passed in the parameters _array[] array. The array elements have a
special structure type M qlParam. By default, zero - parameters are not passed. If you specify a
non-zero number of parameters, the parameter parameters_array is obligatory. You can pass no
more than 64 parameters.
parameters_array[]=NULL
[in] An array of M qlParam type, whose elements contain the type and value of each input
parameter of a technical indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
Note
If the indicator handle of I ND_CUSTOM type is created, the type field of the first element of the
array of input parameters parameters_array must have the T YPE_ST R I NG value of the
ENUM _DAT AT YPE enumeration, and the string_value field of the first element must contain the
name of the custom indicator. The custom indicator must be compiled (file with EX5 extension) and
located in the directory MQL5/Indicators of the client terminal or in a subdirectory.
Indicators that require testing are defined automatically from the call of the iCustom() function, if
the corresponding parameter is set through a constant string. For all other cases (use of the
IndicatorCreate() function or use of a non-constant string in the parameter that sets the indicator
name) the property #property tester_indicator is required:
If the first form of the call is used in a custom indicator, you can additionally indicate as the last
parameter on what data it will be calculated when passing input parameters. If the "Apply to"
parameter is not specified explicitly, the default calculation is based on the PR ICE_CLOS E values.
Example:
void OnStart()
{
MqlParam params[];
int h_MA,h_MACD;
//--- create iMA("EURUSD",PERIOD_M15,8,0,MODE_EMA,PRICE_CLOSE);
ArrayResize(params,4);
//--- set ma_period
params[0].type =TYPE_INT;
params[0].integer_value=8;
//--- set ma_shift
params[1].type =TYPE_INT;
params[1].integer_value=0;
//--- set ma_method
params[2].type =TYPE_INT;
params[2].integer_value=MODE_EMA;
//--- set applied_price
params[3].type =TYPE_INT;
params[3].integer_value=PRICE_CLOSE;
//--- create MA
h_MA=IndicatorCreate("EURUSD",PERIOD_M15,IND_MA,4,params);
//--- create iMACD("EURUSD",PERIOD_M15,12,26,9,h_MA);
ArrayResize(params,4);
//--- set fast ma_period
params[0].type =TYPE_INT;
params[0].integer_value=12;
//--- set slow ma_period
params[1].type =TYPE_INT;
params[1].integer_value=26;
//--- set smooth period for difference
params[2].type =TYPE_INT;
params[2].integer_value=9;
//--- set indicator handle as applied_price
params[3].type =TYPE_INT;
params[3].integer_value=h_MA;
//--- create MACD based on moving average
h_MACD=IndicatorCreate("EURUSD",PERIOD_M15,IND_MACD,4,params);
//--- use indicators
//--- . . .
//--- release indicators (first h_MACD)
IndicatorRelease(h_MACD);
IndicatorRelease(h_MA);
}
IndicatorParameters
Based on the specified handle, returns the number of input parameters of the indicator, as well as the
values and types of the parameters.
int IndicatorParameters(
int indicator_handle, // indicator handle
ENUM_INDICATOR& indicator_type, // a variable for receiving the indicator type
MqlParam& parameters[] // an array for receiving parameters
);
Parameters
indicator_handle
[in] The handle of the indicator, for which you need to k now the number of parameters its is
calculated on.
indicator_type
[out] A variable if the ENUM _INDICATOR type, into which the indicator type will be written.
parameters[]
[out] A dynamic array for receiving values of the M qlParam type, into which the list of indicator
parameters will be written. The array size is returned by the IndicatorParameters() function.
Return Value
The number of input parameters of the indicator with the specified handle. In case of an error
returns -1. For more details about the error call the GetLastError() function.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- The number of windows on the chart (at least one main window is always present)
int windows=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
//--- Go through the chart windows
for(int w=0;w<windows;w++)
{
//--- The number of indicators in this window/subwindow
int total=ChartIndicatorsTotal(0,w);
//--- Take all indicators in the window
for(int i=0;i<total;i++)
{
//--- Get the short name of the indicator
string name=ChartIndicatorName(0,w,i);
//--- Get the indicator handle
int handle=ChartIndicatorGet(0,w,name);
//--- Add to log
See also
ChartIndicatorGet()
IndicatorRelease
The function removes an indicator handle and releases the calculation block of the indicator, if it's not
used by anyone else.
bool IndicatorRelease(
int indicator_handle // indicator handle
);
Return Value
Note
The function allows removing an indicator handle, if it's no longer needed, thus saving memory. The
handle is removed immediately, the calculation block is deleted in some time (if it's not called
anymore).
W hen work ing in the strategy tester, the IndicatorR elease() function is not executed.
Example:
//+------------------------------------------------------------------+
//| Test_IndicatorRelease.mq5 |
//| Copyright 2010, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2010, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- input parameters
input int MA_Period=15;
input int MA_shift=0;
input ENUM_MA_METHOD MA_smooth=MODE_SMA;
input ENUM_APPLIED_PRICE price=PRICE_CLOSE;
//--- will store indicator handle
int MA_handle=INVALID_HANDLE;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create indicator handle
MA_handle=iMA(Symbol(),0,MA_Period,MA_shift,MA_smooth,PRICE_CLOSE);
//--- delete global variable
if(GlobalVariableCheck("MA_value"))
GlobalVariableDel("MA_value");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
CopyBuffer
Gets data of a specified buffer of a certain indicator in the necessary quantity.
Counting of elements of copied data (indicator buffer with the index buffer_num) from the starting
position is performed from the present to the past, i.e., starting position of 0 means the current bar
(indicator value for the current bar).
W hen copying the yet unk nown amount of data, it is recommended to use a dynamic array as a
buffer[] recipient buffer, because the CopyBuffer() function tries to allocate the size of the receiving
array to the size of the copied data. If an indicator buffer (array that is pre-allocated for storing
indicator values by the SetIndex Bufer() function) is used as the buffer[] recipient array, partial copying
is allowed. An example can be found in the Awesome_Oscillator.mql5 custom indicator in the standard
terminal pack age.
If you need to mak e a partial copy of the indicator values into another array (non-indicator buffer),
you should use an intermediate array, to which the desired number is copied. After that conduct the
element-wise copying of the required number of values into the required places of a receiving array
from this intermediate one.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
indicator_handle
[in] The indicator handle, returned by the corresponding indicator function.
buffer_num
[in] The indicator buffer number.
start_pos
[in] The position of the first element to copy.
count
[in] Data count to copy.
start_time
[in] Bar time, corresponding to the first element.
stop_time
[in] Bar time, corresponding to the last element.
buffer[]
[out] Array of double type.
Return Value
Note
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration.
Example:
//+------------------------------------------------------------------+
//| TestCopyBuffer3.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot MA
#property indicator_label1 "MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input bool AsSeries=true;
input int period=15;
input ENUM_MA_METHOD smootMode=MODE_EMA;
input ENUM_APPLIED_PRICE price=PRICE_CLOSE;
input int shift=0;
//--- indicator buffers
double MABuffer[];
int ma_handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,MABuffer,INDICATOR_DATA);
Print("Parameter AsSeries = ",AsSeries);
Print("Indicator buffer after SetIndexBuffer() is a timeseries = ",
ArrayGetAsSeries(MABuffer));
//--- set short indicator name
IndicatorSetString(INDICATOR_SHORTNAME,"MA("+period+")"+AsSeries);
//--- set AsSeries (depends on input parameter)
ArraySetAsSeries(MABuffer,AsSeries);
Print("Indicator buffer after ArraySetAsSeries(MABuffer,true); is a timeseries = ",
ArrayGetAsSeries(MABuffer));
//---
ma_handle=iMA(Symbol(),0,period,shift,smootMode,price);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- check if all data calculated
if(BarsCalculated(ma_handle)<rates_total) return(0);
//--- we can copy not all data
int to_copy;
if(prev_calculated>rates_total || prev_calculated<=0) to_copy=rates_total;
else
{
to_copy=rates_total-prev_calculated;
//--- last value is always copied
to_copy++;
}
//--- try to copy
if(CopyBuffer(ma_handle,0,0,to_copy,MABuffer)<=0) return(0);
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
The above example illustrates how an indicator buffer is filled out with the values of another indicator
buffer from the indicator on the same symbol/period.
See a detailed example of history requesting data in section Methods of Object Binding. The script
available in that section shows how to get the values of indicator iFractals on the last 1000 bars and
how to display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
See also
CopyRates
Gets history data of M qlR ates structure of a specified symbol-period in specified quantity into the
rates _array array. The elements ordering of the copied data is from present to the past, i.e., starting
position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_time
[in] Bar time for the first element to copy.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
stop_time
[in] Bar time, corresponding to the last element to copy.
rates_array[]
[out] Array of M qlR ates type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
Example:
void OnStart()
{
//---
MqlRates rates[];
ArraySetAsSeries(rates,true);
int copied=CopyRates(Symbol(),0,0,100,rates);
if(copied>0)
{
Print("Bars copied: "+copied);
string format="open = %G, high = %G, low = %G, close = %G, volume = %d";
string out;
int size=fmin(copied,10);
for(int i=0;i<size;i++)
{
out=i+":"+TimeToString(rates[i].time);
out=out+" "+StringFormat(format,
rates[i].open,
rates[i].high,
rates[i].low,
rates[i].close,
rates[i].tick_volume);
Print(out);
}
}
else Print("Failed to get history data for the symbol ",Symbol());
}
See a detailed example of requesting history data in section Methods of Object Binding. The script
available in that section shows how to get the values of indicator iFractals on the last 1000 bars and
how to display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
See also
Structures and Classes, TimeToString, String Format
CopyTime
The function gets to time_array history data of bar opening time for the specified symbol-period pair
in the specified quantity. It should be noted that elements ordering is from present to past, i.e.,
starting position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
start_time
[in] The start time for the first element to copy.
stop_time
[in] Bar time corresponding to the last element to copy.
time_array[]
[out] Array of datetime type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
See a detailed example of requesting history data in section Methods of Object Binding. The script
available in that section shows how to get the values of indicator iFractals on the last 1000 bars and
how to display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
CopyOpen
The function gets into open_array the history data of bar open prices for the selected symbol-period
pair in the specified quantity. It should be noted that elements ordering is from present to past, i.e.,
starting position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
start_time
[in] The start time for the first element to copy.
stop_time
[in] The start time for the last element to copy.
open_array[]
[out] Array of double type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
See a detailed example of requesting history data in section Methods of Object Binding. The script
available in that section shows how to get the values of indicator iFractals on the last 1000 bars and
how to display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
CopyHigh
The function gets into high_array the history data of highest bar prices for the selected symbol-period
pair in the specified quantity. It should be noted that elements ordering is from present to past, i.e.,
starting position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
start_time
[in] The start time for the first element to copy.
stop_time
[in] Bar time, corresponding to the last element to copy.
high_array[]
[out] Array of double type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
Example:
#property description "An example for output of the High[i] and Low[i]"
#property description "for a random chosen bars"
double High[],Low[];
//+------------------------------------------------------------------+
//| Get Low for specified bar index |
//+------------------------------------------------------------------+
double iLow(string symbol,ENUM_TIMEFRAMES timeframe,int index)
{
double low=0;
ArraySetAsSeries(Low,true);
int copied=CopyLow(symbol,timeframe,0,Bars(symbol,timeframe),Low);
if(copied>0 && index<copied) low=Low[index];
return(low);
}
//+------------------------------------------------------------------+
//| Get the High for specified bar index |
//+------------------------------------------------------------------+
double iHigh(string symbol,ENUM_TIMEFRAMES timeframe,int index)
{
double high=0;
ArraySetAsSeries(High,true);
int copied=CopyHigh(symbol,timeframe,0,Bars(symbol,timeframe),High);
if(copied>0 && index<copied) high=High[index];
return(high);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- on every tick we output the High and Low values for the bar with index,
//--- that is equal to the second, on which tick arrived
datetime t=TimeCurrent();
int sec=t%60;
printf("High[%d] = %G Low[%d] = %G",
sec,iHigh(Symbol(),0,sec),
sec,iLow(Symbol(),0,sec));
}
See a detailed example of requesting history data in the Methods of Object Binding section. The script
available in that section shows how to get the values of indicator iFractals on the last 1000 bars and
how to display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
CopyLow
The function gets into low_array the history data of minimal bar prices for the selected symbol-period
pair in the specified quantity. It should be noted that elements ordering is from present to past, i.e.,
starting position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol.
timeframe
[in] Period.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
start_time
[in] Bar time, corresponding to the first element to copy.
stop_time
[in] Bar time, corresponding to the last element to copy.
low_array[]
[out] Array of double type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
See a detailed example of requesting history data in section Methods of Object Binding. The script
available in that section shows how to get the values of indicator iFractals on the last 1000 bars and
how to display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
See also
CopyH igh
CopyClose
The function gets into close_array the history data of bar close prices for the selected symbol-period
pair in the specified quantity. It should be noted that elements ordering is from present to past, i.e.,
starting position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
start_time
[in] The start time for the first element to copy.
stop_time
[in] Bar time, corresponding to the last element to copy.
close_array[]
[out] Array of double type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
See a detailed example of history data requesting in section Methods of Object Binding. The script
available in that section shows how to get the values of indicator iFractals on the last 1000 bars and
how to display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
CopyTickVolume
The function gets into volume_array the history data of tick volumes for the selected symbol-period
pair in the specified quantity. It should be noted that elements ordering is from present to past, i.e.,
starting position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
start_time
[in] The start time for the first element to copy.
stop_time
[in] Bar time, corresponding to the last element to copy.
volume_array[]
[out] Array of long type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
Example:
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot TickVolume
#property indicator_label1 "TickVolume"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 C'143,188,139'
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int bars=3000;
//--- indicator buffers
double TickVolumeBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,TickVolumeBuffer,INDICATOR_DATA);
IndicatorSetInteger(INDICATOR_DIGITS,0);
//---
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
See a detailed example of history data requesting in section Methods of Object Binding. The script
available in that section shows how to get the values of indicator iFractals on the last 1000 bars and
how to display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
CopyRealVolume
The function gets into volume_array the history data of trade volumes for the selected symbol-period
pair in the specified quantity. It should be noted that elements ordering is from present to past, i.e.,
starting position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
start_time
[in] The start time for the first element to copy.
stop_time
[in] Bar time, corresponding to the last element to copy.
volume_array[]
[out] Array of long type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
See an example of history data requesting in section Methods of Object Binding. The script available
in that section shows how to get the values of indicator iFractals on the last 1000 bars and how to
display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
CopySpread
The function gets into spread_array the history data of spread values for the selected symbol-period
pair in the specified quantity. It should be noted that elements ordering is from present to past, i.e.,
starting position of 0 means the current bar.
W hen copying the yet unk nown amount of data, it is recommended to use dynamic array as a target
array, because if the requested data count is less (or more) than the length of the target array,
function tries to reallocate the memory so that the requested data fit entirely.
If you k now the amount of data you need to copy, it should better be done to a statically allocated
buffer, in order to prevent the allocation of excessive memory.
No matter what is the property of the target array - as _series =true or as _series =false. Data will be
copied so that the oldest element will be located at the start of the physical memory allocated for the
array. There are 3 variants of function calls.
Parameters
symbol_name
[in] Symbol name.
timeframe
[in] Period.
start_pos
[in] The start position for the first element to copy.
count
[in] Data count to copy.
start_time
[in] The start time for the first element to copy.
stop_time
[in] Bar time, corresponding to the last element to copy.
spread_array[]
[out] Array of int type.
Return Value
Note
If the whole interval of requested data is out of the available data on the server, the function
returns -1. If data outside T ER MI NAL _M AXBAR S (maximal number of bars on the chart) is requested,
the function will also return -1.
W hen requesting data from the indicator, if requested timeseries are not yet built or they need to
be downloaded from the server, the function will immediately return -1, but the process of
downloading /building will be initiated.
W hen requesting data from an Expert Advisor or script, downloading from the server will be
initiated, if the terminal does not have these data locally, or building of a required timeseries will
start, if data can be built from the local history but they are not ready yet. The function will return
the amount of data that will be ready by the moment of timeout expiration, but history downloading
will continue, and at the next similar request the function will return more data.
W hen requesting data by the start date and the number of required elements, only data whose date
is less than (earlier) or equal to the date specified will be returned. It means, the open time of any
bar, for which value is returned (volume, spread, value on the indicator buffer, prices Open, H igh,
Low, Close or open time Time) is always less or equal to the specified one.
W hen requesting data in a specified range of dates, only data from this interval will be returned.
The interval is set and counted up to seconds. It means, the open time of any bar, for which value is
returned (volume, spread, value on the indicator buffer, prices Open, H igh, Low, Close or open time
Time) is always within the requested interval.
Thus, if the current day is Saturday, at the attempt to copy data on a week timeframe specifying
start_time=Last_Tuesday and stop_time=Last_Friday the function will return 0, because the open
time on a week timeframe is always Sunday, but one week bar does not fall into the specified
interval.
If you need to return value corresponding to the current uncompleted bar, you can use the first form
of call specifying start_pos =0 and count=1.
Example:
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot Spread
#property indicator_label1 "Spread"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int bars=3000;
//--- indicator buffers
double SpreadBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,SpreadBuffer,INDICATOR_DATA);
IndicatorSetInteger(INDICATOR_DIGITS,0);
//---
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
See an example of history data requesting in section Methods of Object Binding. The script available
in that section shows how to get the values of indicator iFractals on the last 1000 bars and how to
display the last 10 up and 10 down fractals on the chart. A similar technique can be used for all
indicators that have missing data and that are usually drawn using the following styles :
· DRAW_S ECTION,
· DRAW_ARR OW ,
· DRAW_ZI GZAG,
· DRAW_COLOR_S ECTION,
· DRAW_COLOR_ARR OW ,
· DRAW_COLOR_ZI GZAG.
CopyTicks
The function receives tick s in the M qlTick format into tick s _array. In this case, tick s are indexed from
the past to the present, i.e. the 0 indexed tick is the oldest one in the array. For tick analysis, check
the flags field, which shows what exactly has changed in the tick .
int CopyTicks(
string symbol_name, // Symbol name
MqlTick& ticks_array[], // Tick receiving array
uint flags=COPY_TICKS_ALL, // The flag that determines the type of received ticks
ulong from=0, // The date from which you want to request ticks
uint count=0 // The number of ticks that you want to receive
);
Parameters
symbol_name
[in] Symbol.
ticks_array
[out] An array of the M qlTick type for receiving tick s.
flags
[in] A flag to define the type of the requested tick s. COPY_TICKS _INFO – tick s with Bid and/or As k
changes, COPY_TICKS _T RADE – tick s with changes in Last and Volume, COPY_TICKS _ALL – all tick s.
For any type of request, the values of the previous tick are added to the remaining fields of the
M qlTick structure.
from
[in] The date from which you want to request tick s. In milliseconds since 1970.01.01. If from =0,
the last count tick s will be returned.
count
[in] The number of requested tick s. If the 'from' and 'count' parameters are not specified, all
available recent tick s (but not more than 2000) will be written to tick s _array[].
Returned value
Note
The CopyTick s() function allows requesting and analyzing all received tick s. The first call of
CopyTick s() initiates synchronization of the symbol's tick database stored on the hard dis k . If the
local database does not provide all the requested tick s, then missing tick s will be automatically
downloaded from the trade server. Tick s beginning with the from date specified in CopyTick s() till
the current moment will be synchronized. After that, all tick s arriving for this symbol will be added
to the tick database thus k eeping it in the synchronized state.
If the from and count parameters are not specified, all available recent tick s (but not more than
2000) will be written to ticks_array[]. The flags parameter allows specifying the type of required
tick s.
COPY_TICKS _I NFO – tick s with Bid and/or As k price changes are returned. Data of other fields will
also be added. For example, if only the Bid has changed, the ask and volume fields will be filled with
last k nown values. To find out exactly what has changed, analyze the flags field, which will have the
value of TICK_FL AG_BI D and/or TICK_FL AG_AS K. If a tick has zero values of the Bid and As k prices,
and the flags show that these data have changed (flags =TICK_FL AG_BI D|TICK_FL AG_AS K), this
means that the order book (Mark et Depth) is empty. In other words, there are no buy and sell
orders.
COPY_TICKS _T RADE – tick s with the Last price and volume changes are returned. Data of other
fields will also be added, i.e. last k nown values of Bid and As k will be specified in the appropriate
fields. To find out exactly what has changed, analyze the flags field, which will have the
TICK_FL AG_L AST and TICK_FL AG_VOL UM E value.
COPY_TICKS _ALL – all tick s with any change are returned. Unchanged fields will be filled with last
k nown values.
Call of CopyTick s() with the COPY_TICKS _ALL flag immediately returns all tick s from the request
interval, while calls in other modes require some time to process and select tick s, therefore they do
not provide significant speed advantage.
W hen requesting tick s (either COPY_TICKS _INFO or COPY_TICKS _T RADE), every tick contains full
price information as of the time of the tick (bid, ask, last and volume). This feature is provided for
an easier analysis of the trade state at the time of each tick , so there is no need to request a deep
tick history and search for the values of other fields.
In indicators, the CopyTicks() function returns the result: when called from an indicator,
CopyTick () immediately returns all available tick s of a symbol, and will launch synchronization of the
tick database, if available data is not enough. All indicators in one symbol operate in one common
thread, so the indicator cannot wait for the completion of synchronization. After synchronization,
CopyTick s() will return all requested tick s during the next call. In indicators, the OnCalculate()
function is called after the arrival of each tick .
CopyTicks() can wait for the result for 45 seconds in Expert Advisors and scripts: as distinct
from indicators, every Expert Advisor and script operate in a separate thread, and therefore can
wait 45 seconds till the completion of synchronization. If the required amount of tick s fails to be
synchronized during this time, CopyTick s() will return available tick s by timeout and will continue
synchronization. OnTick () in Expert Advisor is not a handler of every tick , it only notifies an Expert
Advisor about changes in the mark et. It can be a batch of changes : the terminal can simultaneously
mak e a few tick s, but OnTick () will be called only once to notify the EA of the latest mark et state.
The rate of data return: the terminal stores in the fast access cache 4,096 last tick s for each
instrument (65,536 tick s for symbols with a running Mark et Depth). If requested tick s for the
current trading session are beyond the cache, CopyTick s() calls the tick s stored in the terminal
memory. These requests require more time for execution. The slowest requests are those
requesting tick s for other days, since the data is read from the dis k in this case.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int attempts=0; // Count of attempts
bool success=false; // The flag of a successful copying of ticks
MqlTick tick_array[]; // Tick receiving array
MqlTick lasttick; // To receive last tick data
SymbolInfoTick(_Symbol,lasttick);
//--- Make 3 attempts to receive ticks
while(attempts<3)
{
//--- Measuring start time before receiving the ticks
uint start=GetTickCount();
//--- Requesting the tick history since 1970.01.01 00:00.001 (parameter from=1 ms)
int received=CopyTicks(_Symbol,tick_array,COPY_TICKS_ALL,1,getticks);
if(received!=-1)
{
//--- Showing information about the number of ticks and spent time
PrintFormat("%s: received %d ticks in %d ms",_Symbol,received,GetTickCount()-start);
//--- If the tick history is synchronized, the error code is equal to zero
if(GetLastError()==0)
{
success=true;
break;
}
else
PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d"
_Symbol,received,GetTickCount()-start,_LastError);
}
//--- Counting attempts
attempts++;
//--- A one-second pause to wait for the end of synchronization of the tick database
Sleep(1000);
}
//--- Receiving the requested ticks from the beginning of the tick history failed in three attempts
if(!success)
{
PrintFormat("Error! Failed to receive %d ticks of %s in three attempts",getticks,_Symbol);
return;
}
int ticks=ArraySize(tick_array);
//--- Showing the time of the first tick in the array
datetime firstticktime=tick_array[ticks-1].time;
PrintFormat("Last tick time = %s.%03I64u",
TimeToString(firstticktime,TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick_array[ticks-1].
//--- Show the time of the last tick in the array
datetime lastticktime=tick_array[0].time;
PrintFormat("First tick time = %s.%03I64u",
TimeToString(lastticktime,TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick_array[0].time_ms
//---
MqlDateTime today;
datetime current_time=TimeCurrent();
TimeToStruct(current_time,today);
PrintFormat("current_time=%s",TimeToString(current_time));
today.hour=0;
today.min=0;
today.sec=0;
datetime startday=StructToTime(today);
datetime endday=startday+24*60*60;
if((ticks=CopyTicksRange(_Symbol,tick_array,COPY_TICKS_ALL,startday*1000,endday*1000))==-1)
{
PrintFormat("CopyTicksRange(%s,tick_array,COPY_TICKS_ALL,%s,%s) failed, error %d",
_Symbol,TimeToString(startday),TimeToString(endday),GetLastError());
return;
}
ticks=MathMax(100,ticks);
//--- Showing the first 100 ticks of the last day
int counter=0;
for(int i=0;i<ticks;i++)
{
datetime time=tick_array[i].time;
if((time>=startday) && (time<endday) && counter<100)
{
counter++;
PrintFormat("%d. %s",counter,GetTickDescription(tick_array[i]));
}
}
//--- Showing the first 100 deals of the last day
counter=0;
for(int i=0;i<ticks;i++)
{
datetime time=tick_array[i].time;
if((time>=startday) && (time<endday) && counter<100)
{
if(((tick_array[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) || ((tick_array[i].flags&TICK_FLAG
{
counter++;
PrintFormat("%d. %s",counter,GetTickDescription(tick_array[i]));
}
}
}
}
//+------------------------------------------------------------------+
//| Returns the string description of a tick |
//+------------------------------------------------------------------+
string GetTickDescription(MqlTick &tick)
{
string desc=StringFormat("%s.%03d ",
TimeToString(tick.time),tick.time_msc%1000);
//--- Checking flags
bool buy_tick=((tick.flags&TICK_FLAG_BUY)==TICK_FLAG_BUY);
bool sell_tick=((tick.flags&TICK_FLAG_SELL)==TICK_FLAG_SELL);
bool ask_tick=((tick.flags&TICK_FLAG_ASK)==TICK_FLAG_ASK);
bool bid_tick=((tick.flags&TICK_FLAG_BID)==TICK_FLAG_BID);
bool last_tick=((tick.flags&TICK_FLAG_LAST)==TICK_FLAG_LAST);
bool volume_tick=((tick.flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME);
//--- Checking trading flags in a tick first
if(buy_tick || sell_tick)
{
//--- Forming an output for the trading tick
desc=desc+(buy_tick?StringFormat("Buy Tick: Last=%G Volume=%d ",tick.last,tick.volume):"");
desc=desc+(sell_tick?StringFormat("Sell Tick: Last=%G Volume=%d ",tick.last,tick.volume):"");
desc=desc+(ask_tick?StringFormat("Ask=%G ",tick.ask):"");
desc=desc+(bid_tick?StringFormat("Bid=%G ",tick.ask):"");
desc=desc+"(Trade tick)";
}
else
{
//--- Form a different output for an info tick
desc=desc+(ask_tick?StringFormat("Ask=%G ",tick.ask):"");
desc=desc+(bid_tick?StringFormat("Bid=%G ",tick.ask):"");
desc=desc+(last_tick?StringFormat("Last=%G ",tick.last):"");
desc=desc+(volume_tick?StringFormat("Volume=%d ",tick.volume):"");
desc=desc+"(Info tick)";
}
//--- Returning tick description
return desc;
}
//+------------------------------------------------------------------+
/* Example of the output
Si-12.16: received 11048387 ticks in 4937 ms
Last tick time = 2016.09.26 18:32:59.775
First tick time = 2015.06.18 09:45:01.000
1. 2016.09.26 09:45.249 Ask=65370 Bid=65370 (Info tick)
2. 2016.09.26 09:47.420 Ask=65370 Bid=65370 (Info tick)
3. 2016.09.26 09:50.893 Ask=65370 Bid=65370 (Info tick)
4. 2016.09.26 09:51.827 Ask=65370 Bid=65370 (Info tick)
5. 2016.09.26 09:53.810 Ask=65370 Bid=65370 (Info tick)
6. 2016.09.26 09:54.491 Ask=65370 Bid=65370 (Info tick)
7. 2016.09.26 09:55.913 Ask=65370 Bid=65370 (Info tick)
8. 2016.09.26 09:59.350 Ask=65370 Bid=65370 (Info tick)
9. 2016.09.26 09:59.678 Bid=65370 (Info tick)
10. 2016.09.26 10:00.000 Sell Tick: Last=65367 Volume=3 (Trade tick)
See also
SymbolInfoTick , Structure for Current Prices, OnTick ()
CopyTicksRange
The function receives tick s in the M qlTick format within the specified date range to tick s _array.
Indexing goes from the past to the present meaning that a tick with the index 0 is the oldest one in
the array. For tick analysis, check the flags field, which shows what exactly has changed.
int CopyTicksRange(
const string symbol_name, // symbol name
MqlTick& ticks_array[], // tick receiving array
uint flags=COPY_TICKS_ALL, // flag that defines the type of the ticks that are rece
ulong from_msc=0, // date, starting from which ticks are requested
ulong to_msc=0 // date, up to which ticks are requested
);
Parameters
symbol_name
[in] Symbol.
ticks_array
[out] M qlTick static or dynamic array for receiving tick s. If the static array cannot hold all the
tick s from the requested time interval, the maximum possible amount of tick s is received. In this
case, the function generates the error ERR_H ISTORY_SM ALL _BUFFER (4407) .
flags
[in] A flag to define the type of the requested tick s. COPY_TICKS _INFO – tick s with Bid and/or As k
changes, COPY_TICKS _T RADE – tick s with changes in Last and Volume, COPY_TICKS _ALL – all tick s.
For any type of request, the values of the previous tick are added to the remaining fields of the
M qlTick structure.
from_msc
[in] The date, from which you want to request tick s. In milliseconds since 1970.01.01. If the
from_msc parameter is not specified, tick s from the beginning of the history are sent. Tick s with
the time >= from_msc are sent.
to_msc
[in] The date, up to which you want to request tick s. In milliseconds since 01.01.1970. Tick s with
the time <= to_msc are sent. If the to_msc parameter is not specified, all tick s up to the end of
the history are sent.
Return Value
The number of copied tick or -1 in case of an error. GetLastError() is able to return the following
errors :
· ERR_H ISTORY_TIM EOUT – tick s synchronization waiting time is up, the function has sent all it
had.
· ERR_H ISTORY_SM ALL _BUFFER – static buffer is too small. Only the amount the array can store has
been sent.
· ERR_NOT _ENOUGH_M EMORY – insufficient memory for receiving a history from the specified
range to the dynamic tick array. Failed to allocate enough memory for the tick array.
Note
The CopyTick s R ange() function is used for requesting tick s strictly from a specified range, for
example, from a certain day in history. At the same time, CopyTick s() allows specifying only a start
date, for example – receive all tick s from the beginning of the month till the current moment.
See also
SymbolInfoTick , Structure for Current Prices, OnTick , CopyTick s
iBars
R eturns the number of bars of a corresponding symbol and period, available in history.
int iBars(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe // Period
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
Return Value
The number of bars of a corresponding symbol and period, available in history, but no more than
allowed by the " Max bars in chart" parameter in platform settings.
Example:
See also
Bars
iBarShift
Search bar by time. The function returns the index of the bar corresponding to the specified time.
int iBarShift(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
datetime time, // Time
bool exact=false // Mode
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. PER IOD_CURRENT
means the current chart period.
time
[in] Time value to search for.
exact=false
[in] A return value, in case the bar with the specified time is not found. If
exact=false, iBarShift
returns the index of the nearest bar, the Open time of which is less than the specified time
(time_open<time). If such a bar is not found (history before the specified time is not available),
then the function returns -1. If exact=true, iBarShift does not search for a nearest bar but
immediately returns -1.
Return Value
The index of the bar corresponding to the specified time. If the bar corresponding to the specified
time is not found (there is a gap in the history), the function returns -1 or the index of the nearest
bar (depending on the 'exact' parameter).
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- The date is on Sunday
datetime time=D'2002.04.25 12:00';
string symbol="GBPUSD";
ENUM_TIMEFRAMES tf=PERIOD_H1;
bool exact=false;
//--- If there is no bar at the specified time, iBarShift will return the index of the nearest bar
int bar_index=iBarShift(symbol,tf,time,exact);
//--- Check the error code after the call of iBarShift()
int error=GetLastError();
if(error!=0)
{
PrintFormat("iBarShift(): GetLastError=%d - The requested date %s "+
"for %s %s is not found in the available history",
error,TimeToString(time),symbol,EnumToString(tf));
return;
}
//--- The iBarShift() function was executed successfully, return a result for exact=false
PrintFormat("1. %s %s %s(%s): bar index is %d (exact=%s)",
symbol,EnumToString(tf),TimeToString(time),
DayOfWeek(time),bar_index,string(exact));
datetime bar_time=iTime(symbol,tf,bar_index);
PrintFormat("Time of bar #%d is %s (%s)",
bar_index,TimeToString(bar_time),DayOfWeek(bar_time));
//--- Request the index of the bar with the specified time; if there is no bar -1 will be returned
exact=true;
bar_index=iBarShift(symbol,tf,time,exact);
//--- The iBarShift() function was executed successfully, return a result for exact=true
PrintFormat("2. %s %s %s (%s):bar index is %d (exact=%s)",
symbol,EnumToString(tf),TimeToString(time)
,DayOfWeek(time),bar_index,string(exact));
}
//+------------------------------------------------------------------+
//| Returns the name of the day of the week |
//+------------------------------------------------------------------+
string DayOfWeek(const datetime time)
{
MqlDateTime dt;
string day="";
TimeToStruct(time,dt);
switch(dt.day_of_week)
{
case 0: day=EnumToString(SUNDAY);
break;
case 1: day=EnumToString(MONDAY);
break;
case 2: day=EnumToString(TUESDAY);
break;
case 3: day=EnumToString(WEDNESDAY);
break;
case 4: day=EnumToString(THURSDAY);
break;
case 5: day=EnumToString(FRIDAY);
break;
default:day=EnumToString(SATURDAY);
break;
}
//---
return day;
}
//+------------------------------------------------------------------+
/* Execution result
1. GBPUSD PERIOD_H1 2018.06.10 12:00(SUNDAY): bar index is 64 (exact=false)
Time of bar #64 is 2018.06.08 23:00 (FRIDAY)
2. GBPUSD PERIOD_H1 2018.06.10 12:00 (SUNDAY):bar index is -1 (exact=true)
*/
iClose
R eturns the Close price of the bar (indicated by the 'shift' parameter) on the corresponding chart.
double iClose(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The Close price of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in case
of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
Comment(Symbol(),",",EnumToString(Period()),"\n",
See also
CopyClose, CopyR ates
iHigh
R eturns the H igh price of the bar (indicated by the 'shift' parameter) on the corresponding chart.
double iHigh(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The H igh price of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in case
of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
Comment(Symbol(),",",EnumToString(Period()),"\n",
See also
CopyH igh, CopyR ates
iHighest
R eturns the index of the highest value found on the corresponding chart (shift relative to the current
bar).
int iHighest(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
ENUM_SERIESMODE type, // Timeseries identifier
int count=WHOLE_ARRAY, // Number of elements
int start=0 // Index
);
Parameters
symbol
[in] The symbol, on which the search will be performed. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
type
[in] The identifier of the timeseries, in which the search will be performed. Can be equal to any
value from ENUM _S ER I ESMODE.
count=WHOLE_ARRAY
[in] The number of elements in the timeseries (from the current bar towards index increasing
direction), among which the search should be performed.
start=0
[in] The index (shift relative to the current bar) of the initial bar, from which search for the
highest value begins. Negative values are ignored and replaced with a zero value.
Return Value
The index of the highest value found on the corresponding chart (shift relative to the current bar) or
-1 in case of an error. For error details, call the GetLastError() function.
Example:
double val;
//--- Calculation of the highest Close value among 20 consecutive bars
//--- From index 4 to index 23 inclusive, on the current timeframe
int val_index=iHighest(NULL,0,MODE_CLOSE,20,4);
if(val_index!=-1)
val=High[val_index];
else
PrintFormat("iHighest() call error. Error code=%d",GetLastError());
iLow
R eturns the Low price of the bar (indicated by the 'shift' parameter) on the corresponding chart.
double iLow(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The Low price of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in case
of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
Comment(Symbol(),",",EnumToString(Period()),"\n",
See also
CopyLow, CopyR ates
iLowest
R eturns the index of the smallest value found on the corresponding chart (shift relative to the current
bar).
int iLowest(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
ENUM_SERIESMODE type, // Timeseries identifier
int count=WHOLE_ARRAY, // Number of elements
int start=0 // Index
);
Parameters
symbol
[in] The symbol, on which the search will be performed. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
type
[in] The identifier of the timeseries, in which the search will be performed. Can be equal to any
value from ENUM _S ER I ESMODE.
count=WHOLE_ARRAY
[in] The number of elements in the timeseries (from the current bar towards index increasing
direction), among which the search should be performed.
start=0
[in] The index (shift relative to the current bar) of the initial bar, from which search for the
lowest value begins. Negative values are ignored and replaced with a zero value.
Return Value
The index of the lowest value found on the corresponding chart (shift relative to the current bar) or
-1 in case of an error. For error details, call the GetLastError() function.
Example:
double val;
//--- Search for a bar with the lowest value of the real volume among 15 consecutive bars
//--- From index 10 to index 24 inclusive, on the current timeframe
int val_index=iLowest(NULL,0,MODE_REAL_VOLUME,15,10);
if(val_index!=-1)
val=Low[val_index];
else
PrintFormat("iLowest() call error. Error code=%d",GetLastError());
iOpen
R eturns the Open price of the bar (indicated by the 'shift' parameter) on the corresponding chart.
double iOpen(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The Open price of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in case
of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
Comment(Symbol(),",",EnumToString(Period()),"\n",
See also
CopyOpen, CopyR ates
iTime
R eturns the opening time of the bar (indicated by the 'shift' parameter) on the corresponding chart.
datetime iTime(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The opening time of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in
case of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- The date is on Sunday
datetime time=D'2018.06.10 12:00';
string symbol="GBPUSD";
ENUM_TIMEFRAMES tf=PERIOD_H1;
bool exact=false;
//--- there is no bar at the specified time, iBarShift will return the index of the nearest bar
int bar_index=iBarShift(symbol,tf,time,exact);
PrintFormat("1. %s %s %s(%s): bar index is %d (exact=%s)",
symbol,EnumToString(tf),TimeToString(time),DayOfWeek(time),bar_index,string(exact));
datetime bar_time=iTime(symbol,tf,bar_index);
See also
CopyTime, CopyR ates
iTickVolume
R eturns the tick volume of the bar (indicated by the 'shift' parameter) on the corresponding chart.
long iTickVolume(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The tick volume of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in
case of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
Comment(Symbol(),",",EnumToString(Period()),"\n",
See also
CopyTickVolume, CopyR ates
iRealVolume
R eturns the real volume of the bar (indicated by the 'shift' parameter) on the corresponding chart.
long iRealVolume(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The real volume of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in
case of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
Comment(Symbol(),",",EnumToString(Period()),"\n",
See also
CopyR ealVolume, CopyR ates
iVolume
R eturns the tick volume of the bar (indicated by the 'shift' parameter) on the corresponding chart.
long iVolume(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The tick volume of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in
case of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
Comment(Symbol(),",",EnumToString(Period()),"\n",
See also
CopyTickVolume, CopyR ates
iSpread
R eturns the spread value of the bar (indicated by the 'shift' parameter) on the corresponding chart.
long iSpread(
const string symbol, // Symbol
ENUM_TIMEFRAMES timeframe, // Period
int shift // Shift
);
Parameters
symbol
[in] The symbol name of the financial instrument. NULL means the current symbol.
timeframe
[in] Period. It can be one of the values of the ENUM _TIM EFRAM ES enumeration. 0 means the
current chart period.
shift
[in] The index of the received value from the timeseries (back ward shift by specified number of
bars relative to the current bar).
Return Value
The Spread value of the bar (indicated by the 'shift' parameter) on the corresponding chart or 0 in
case of an error. For error details, call the GetLastError() function.
Note
The function always returns actual data. For this purpose it performs a request to the timeseries for
the specified symbol/period during each call. This means that if there is no ready data during the
first function call, some time may be tak en to prepare the result.
The function does not store previous calls results, and there is no local cache for quick value return.
Example:
Comment(Symbol(),",",EnumToString(Period()),"\n",
See also
CopySpread, CopyR ates
Custom symbols
Functions for creating and editing the custom symbol properties.
W hen connecting the terminal to a certain trade server, a user is able to work with time series of the
financial symbols provided by a brok er. Available financial symbols are displayed as a list in the Mark et
W atch window. A separate group of functions allows receiving data on the symbol properties, trading
sessions and mark et depth updates.
The group of functions described in this section allows creating custom symbols. To do this, users are
able to apply the trade server's existing symbols, text files or external data sources.
Function Action
CustomR ates Delete Delete all bars from the price history of the
custom symbol in the specified time interval
CustomR ates R eplace Fully replace the price history of the custom
symbol within the specified time interval with
the data from the M qlR ates type array
CustomR ates Update Add missing bars to the custom symbol history
and replace existing data with the ones from
the M qlR ates type array
CustomTick s Delete Delete all tick s from the price history of the
custom symbol in the specified time interval
CustomSymbolCreate
Creates a custom symbol with the specified name in the specified group.
bool CustomSymbolCreate(
const string symbol_name, // custom symbol name
const string symbol_path="", // name of a group a symbol is to be created in
const string symbol_origin=NULL // name of a symbol used as a basis to create a custom sym
);
Parameters
symbol_name
[in] Custom symbol name. It should not contain groups or subgroups the symbol is located in.
symbol_path=""
[in] The group name a symbol is located in.
symbol_origin=NULL
[in] Name of a symbol the properties of a created custom symbol are to be copied from. After
creating a custom symbol, any property value can be changed to a necessary one using the
appropriate functions.
Return Value
true – success, otherwise – false. To get information about the error, call the GetLastError()
function.
Note
All custom symbols are created in the special Custom section. If a group name is not specified (the
symbol_path parameter in the CustomSymbolCreate function contains an empty string or NULL), a
custom symbol is generated in the Custom section root. H ere we can draw an analogy with the file
system, where groups and subgroups can be viewed as folders and subfolders
The symbol and group names may only contain Latin letters without punctuation, spaces or special
characters (may only contain " ." , "_" , "&" and "#" ). It is not recommended to use characters <, >, :,
" , /, |, ?, *.
The custom symbol name should be unique regardless of a group name it is created in. If a symbol
with the same name already exists, the CustomSymbolCreate() function returns 'false', while the
subsequent GetLastError() call returns the error 5300 (ERR_NOT _CUSTOM _S YM BOL) or 5304
(ERR_CUSTOM _S YM BOL _EXIST).
The length of the symbol name should not exceed 31 characters. Otherwise, CustomSymbolCreate()
returns 'false' and the error 5302 – ERR_CUSTOM _S YM BOL _NAM E_LONG is activated.
then a custom symbol named " platinum" is created in the " Custom\ CFD\ Metals \ Platinum" group.
The SymbolInfoGetString(" platinum" ,S YM BOL _PAT H ) function returns the
" Custom\CFD\Metals \Platinum\platinum" value.
Note that the S YM BOL _PAT H property returns the path with the symbol name at the end. Therefore,
it cannot be copied without changes if you want to create a custom symbol in the exact same group.
In this case, it is necessary to cut the symbol name in order not to get the result described above.
If a non-existent symbol is set as the symbol_origin parameter, then the custom symbol is created
empty as if the symbol_origin parameter is not set. The error 4301 –
ERR_M ARKET _UNKNOWN_S YM BOL is activated in that case.
The symbol_path parameter length should not exceed 127 characters considering " Custom\\" , "\\"
groups separators and the symbol name if it is specified at the end.
See also
SymbolName, SymbolSelect, CustomSymbolDelete
CustomSymbolDelete
Deletes a custom symbol with the specified name.
bool CustomSymbolDelete(
const string symbol_name // custom symbol name
);
Parameters
symbol
[in] Custom symbol name. It should not match the name of an already existing symbol.
Return Value
true – success, otherwise – false. To get information about the error, call the GetLastError()
function.
Note
The custom symbol displayed in the Mark et W atch or the one a chart is opened for cannot be
deleted.
See also
SymbolName, SymbolSelect, CustomSymbolCreate
CustomSymbolSetInteger
Sets the integer type property value for a custom symbol.
bool CustomSymbolSetInteger(
const string symbol_name, // symbol name
ENUM_SYMBOL_INFO_INTEGER property_id, // property ID
long property_value // property value
);
Parameters
symbol_name
[in] Custom symbol name.
property_id
[in] Symbol property ID. The value can be one of the values of the ENUM _S YM BOL _INFO_INT EGER
enumeration.
property_value
[in] A long type variable containing the property value.
Return Value
true – success, otherwise – false. To get information about the error, call the GetLastError()
function.
Note
The minute and tick history of the custom symbol is completely removed if any of these properties is
changed in the symbol specification:
· S YM BOL _CHAR T _MODE – price type for constructing bars (Bid or Last)
· S YM BOL _DI GITS – number of digits after the decimal point to display the price
After deleting the custom symbol history, the terminal attempts to create a new history using the
updated properties. The same happens when the custom symbol properties are changed manually.
See also
SymbolInfoInteger
CustomSymbolSetDouble
Sets the real type property value for a custom symbol.
bool CustomSymbolSetDouble(
const string symbol_name, // symbol name
ENUM_SYMBOL_INFO_DOUBLE property_id, // property ID
double property_value // property value
);
Parameters
symbol_name
[in] Custom symbol name.
property_id
[in] Symbol property ID. The value can be one of the values of the ENUM _S YM BOL _INFO_DOUBL E
enumeration.
property_value
[in] A double type variable containing the property value.
Return Value
true – success, otherwise – false. To get information about the error, call the GetLastError()
function.
Note
The minute and tick history of the custom symbol is completely removed if any of these properties is
changed in the symbol specification:
· S YM BOL _POI NT – one point value
· S YM BOL _T RADE_TICK_SI ZE – value of a tick that specifies the minimum allowable price change
· S YM BOL _T RADE_TICK_VAL UE – one-tick price change value for a profitable position
After deleting the custom symbol history, the terminal attempts to create a new history using the
updated properties. The same happens when the custom symbol properties are changed manually.
See also
SymbolInfoDouble
CustomSymbolSetString
Sets the string type property value for a custom symbol.
bool CustomSymbolSetString(
const string symbol_name, // symbol name
ENUM_SYMBOL_INFO_STRING property_id, // property ID
string property_value // property value
);
Parameters
symbol_name
[in] Custom symbol name.
property_id
[in] Symbol property ID. The value can be one of the values of the ENUM _S YM BOL _INFO_ST R ING
enumeration.
property_value
[in] A string type variable containing the property value.
Return Value
true – success, otherwise – false. To get information about the error, call the GetLastError()
function.
Note
The minute and tick history of the custom symbol is completely removed if the S YM BOL _FOR M UL A
property (setting the equation for the custom symbol price construction) is changed in the symbol
specification. After deleting the custom symbol history, the terminal attempts to create a new
history using the new equation. The same happens when the custom symbol equation is changed
manually.
See also
SymbolInfoString
CustomSymbolSetMarginRate
Sets the margin rates depending on the order type and direction for a custom symbol.
bool CustomSymbolSetMarginRate(
const string symbol_name, // symbol name
ENUM_ORDER_TYPE order_type, // order type
double initial_margin_rate, // initial margin rate
double maintenance_margin_rate // maintenance margin rate
);
Parameters
symbol_name
[in] Custom symbol name.
order_type
[in] Order type.
initial_margin_rate
[in] A double type variable with an initial margin rate. Initial margin is a security deposit for 1 lot
deal in the appropriate direction. Multiplying the rate by the initial margin, we receive the amount
of funds to be reserved on the account when placing an order of the specified type.
maintenance_margin_rate
[in] A double type variable with a maintenance margin rate. Maintenance margin is a minimum
amount for maintaining an open position of 1 lot in the appropriate direction. Multiplying the rate
by the maintenance margin, we receive the amount of funds to be reserved on the account after
an order of the specified type is activated.
Return Value
true – success, otherwise – false. To get information about the error, call the GetLastError()
function.
See also
SymbolInfoMarginR ate
CustomSymbolSetSessionQuote
Sets the start and end time of the specified quotation session for the specified symbol and week day.
bool CustomSymbolSetSessionQuote(
const string symbol_name, // symbol name
ENUM_DAY_OF_WEEK day_of_week, // week day
uint session_index, // session index
datetime from, // session start time
datetime to // session end time
);
Parameters
symbol_name
[in] Custom symbol name.
ENUM_DAY_OF_WEEK
[in] W eek day, value from the ENUM _DAY_OF_WEEK enumeration.
uint
[in] Index of the session, for which start and end times are to be set. Session indexing starts
from 0.
from
[in] Session start time in seconds from 00:00, data value in the variable is ignored.
to
[in] Session end time in seconds from 00:00, data value in the variable is ignored.
Return Value
true – success, otherwise – false. To get information about the error, call the GetLastError()
function.
Note
If the session with the specified session_index already exists, the function simply edits the
beginning and end of the session.
If zero start and end parameters have been passed for the session (from=0 and to=0), the
appropriate session with the session_index is deleted, while the session indexing is shifted
downwards.
Sessions can be added only sequentially. In other words, you can add session_index=1 only if the
session with the index 0 already exists. If this rule is brok en, a new session is not created, while the
function itself returns 'false'.
See also
SymbolInfoSessionQuote, Symbol info, TimeToStruct, Date structure
CustomSymbolSetSessionTrade
Sets the start and end time of the specified trading session for the specified symbol and week day.
bool CustomSymbolSetSessionTrade(
const string symbol_name, // symbol name
ENUM_DAY_OF_WEEK day_of_week, // week day
uint session_index, // session index
datetime from, // session start time
datetime to // session end time
);
Parameters
symbol_name
[in] Custom symbol name.
ENUM_DAY_OF_WEEK
[in] W eek day, value from the ENUM _DAY_OF_WEEK enumeration.
uint
[in] Index of the session, for which start and end times are to be set. Session indexing starts
from 0.
from
[in] Session start time in seconds from 00:00, data value in the variable is ignored.
to
[in] Session end time in seconds from 00:00, data value in the variable is ignored.
Return Value
true – success, otherwise – false. To get information about the error, call the GetLastError()
function.
Note
If the session with the specified session_index already exists, the function simply edits the
beginning and end of the session.
If zero start and end parameters have been passed for the session (from=0 and to=0), the
appropriate session with the session_index is deleted, while the session indexing is shifted
downwards.
Sessions can be added only sequentially. In other words, you can add session_index=1 only if the
session with the index 0 already exists. If this rule is brok en, a new session is not created, while the
function itself returns 'false'.
See also
SymbolInfoSessionTrade, Symbol info, TimeToStruct, Date structure
CustomRatesDelete
Deletes all bars from the price history of the custom symbol in the specified time interval.
int CustomRatesDelete(
const string symbol, // symbol name
datetime from, // start date
datetime to // end date
);
Parameters
symbol
[in] Custom symbol name.
from
[in] Time of the first bar in the price history within the specified range to be removed.
to
[in] Time of the last bar in the price history within the specified range to be removed.
Return Value
See also
CustomR ates R eplace, CustomR ates Update, CopyR ates
CustomRatesReplace
Fully replaces the price history of the custom symbol within the specified time interval with the data
from the M qlR ates type array.
int CustomRatesReplace(
const string symbol, // symbol name
datetime from, // start date
datetime to, // end date
const MqlRates& rates[], // array for the data to be applied to a custom symbol
uint count=WHOLE_ARRAY // number of the rates[] array elements to be used
);
Parameters
symbol
[in] Custom symbol name.
from
[in] Time of the first bar in the price history within the specified range to be updated.
to
[in] Time of the last bar in the price history within the specified range to be updated.
rates[]
[in] Array of the M qlR ates type history data for M 1.
count=WHOLE_ARRAY
[in] Number of the rates[] array elements to be used for replacement. WH OL E_ARRAY means that
all rates[] array elements should be used for replacement.
Return Value
Note
If the bar from the rates[] array goes beyond the specified range, it is ignored. If such a bar is
already present in the price history and enters the given range, it is replaced. All other bars in the
current price history outside the specified range remain unchanged. The rates[] array data should be
correct regarding OH LC prices, while the bars opening time should correspond to the M 1 timeframe.
See also
CustomR ates Delete, CustomR ates Update, CopyR ates
CustomRatesUpdate
Adds missing bars to the custom symbol history and replaces existing data with the ones from the
M qlR ates type array.
int CustomRatesUpdate(
const string symbol, // custom symbol name
const MqlRates& rates[], // array for the data to be applied to a custom symbol
uint count=WHOLE_ARRAY // number of the rates[] array elements to be used
);
Parameters
symbol
[in] Custom symbol name.
rates[]
[in] Array of the M qlR ates type history data for M 1.
count=WHOLE_ARRAY
[in] Number of the rates[] array elements to be used for update. WH OL E_ARRAY means that all
Return Value
Note
If there is no bar from the rates[] array in the current custom symbol history, it is added. If such a
bar already exists, it is replaced. All other bars in the current price history remain unchanged. The
rates[] array data should be correct regarding O H LC prices, while the bars opening time should
See also
CustomR ates R eplace, CustomR ates Delete, CopyR ates
CustomTicksAdd
Adds data from an array of the M qlTick type to the price history of a custom symbol. The custom
symbol must be selected in the Mark et W atch window.
int CustomTicksAdd(
const string symbol, // Symbol name
const MqlTick& ticks[], // The array with tick data that should be applied to the c
uint count=WHOLE_ARRAY // number of the ticks[] array elements to be used
);
Parameters
symbol
[in] The name of the custom symbol.
ticks[]
[in] An array of tick data of the M qlTick type arranged in order of time from earlier data to more
recent ones, i.e. tick s [k].time_msc <= tick s [n].time_msc, if k<n.
count=WHOLE_ARRAY
[in] Number of the ticks[] array elements to be used for adding. WH OL E_ARRAY means that all
Return Value
Further Note
The CustomTick s Add function only work s for custom symbols opened in the Mark et W atch window. If
the symbol is not selected in Mark et W atch, then you should add tick s using CustomTick s R eplace.
The CustomTick s Add function allows transmitting tick s as if they are delivered from the brok er's
server. Data are sent to the Mark et W atch window instead of being written directly to the tick
database. The terminal then saves tick s from the Mark et W atch to a database. If the amount of
data transmitted during one function call is large, the behavior of the function changes in order to
reduce resource usage. If more than 256 tick s are passed, data is divided into two parts. The first,
i.e. the larger part is written directly to the tick database (as it is done in CustomTick s R eplace).
The second part containing 128 tick s is passed to the Mark et W atch window, from which the
terminal saves the tick s to a database.
The M qlTick structure has two fields with the time value: time (the tick time in seconds) and
time_msc (the tick time in milliseconds), which are counted from January 1, 1970. These fields in
the added tick s are processed in the following order:
1. If tick s [k].time_msc!=0, we use it to fill the tick s [k].time field, i.e.
tick s [k].time=tick s [k].time_msc/1000 (integer division) is set for the tick
2. If tick s [k].time_msc==0 and tick s [k].time!=0, time in milliseconds is obtained by multiplying by
1000, i.e. tick s [k].time_msc=tick s [k].time*1000
3. If tick s [k].time_msc==0 and tick s [k].time==0, the current trade server time up to a millisecond
as of the moment of CustomTick s Add call is written to these fields.
If the value of tick s [k].bid, tick s [k].as k , tick s [k].last or tick s [k].volume is greater than zero, a
combination of appropriate flags is written to the tick s [k].flags field:
· TICK_FL AG_BI D – the tick has changed the bid price
· TICK_FL AG_AS K – the tick has changed the as k price
· TICK_FL AG_L AST – the tick has changed the last deal price
· TICK_FL AG_VOL UM E – the tick has changed the volume
If the value of a field is less than or equal to zero, the corresponding flag is not written to the
tick s [k].flags field.
Flags TICK_FL AG_BUY and TICK_FL AG_S ELL are not added to the history of a custom symbol.
See also
CustomR ates Delete, CustomR ates Update, CustomTick s R eplace, CopyTick s, CopyTick s R ange
CustomTicksDelete
Deletes all tick s from the price history of the custom symbol in the specified time interval.
int CustomTicksDelete(
const string symbol, // symbol name
long from_msc, // start date
long to_msc // end date
);
Parameters
symbol
[in] Custom symbol name.
from_msc
[in] Time of the first tick in the price history within the specified range to be removed. Time in
milliseconds since 01.01.1970.
to_msc
[in] Time of the last tick in the price history within the specified range to be removed. Time in
milliseconds since 01.01.1970.
Return Value
See also
CustomR ates Delete, CustomR ates Update, CustomTick s R eplace, CopyTick s, CopyTick s R ange
CustomTicksReplace
Fully replaces the price history of the custom symbol within the specified time interval with the data
from the M qlTick type array.
int CustomTicksReplace(
const string symbol, // symbol name
long from_msc, // start date
long to_msc, // end date
const MqlTick& ticks[], // array for the data to be applied to a custom symbol
uint count=WHOLE_ARRAY // number of the ticks[] array elements to be used
);
Parameters
symbol
[in] Custom symbol name.
from_msc
[in] Time of the first tick in the price history within the specified range to be removed. Time in
milliseconds since 01.01.1970.
to_msc
[in] Time of the last tick in the price history within the specified range to be removed. Time in
milliseconds since 01.01.1970.
ticks[]
[in] Array of the M qlTick type tick data ordered in time in ascending order.
count=WHOLE_ARRAY
[in] Number of the ticks[] array elements to be used for replacement in the specified time
interval. WH OL E_ARRAY means that all ticks[] array elements should be used.
Return Value
Note
Since several tick s may often have the same time up to a millisecond in a stream of quotes
(accurate tick time is stored in the time_msc field of the M qlTick structure), the
CustomTick s R eplace function does not automatically sort out the ticks[] array elements by time.
Therefore, the array of tick s must be pre-arranged in time ascending order.
The tick s are replaced consecutively, day after day, until the time specified in to_msc or until an
error occurs. The first day from the specified range is processed followed by the next one, etc. As
soon as the mismatch between the tick time and the ascending (non-descending) order is detected,
the tick replacement stops on the current day. All tick s from the previous days are successfully
replaced, while the current day (at the moment of a wrong tick ) and all the remaining days in the
specified interval remain unchanged.
If the ticks[] array contains no tick data for any day (generally, any time interval), a " hole"
corresponding to the missing data appears in the custom symbol history after the tick data from
ticks[] are applied. In other words, the call of CustomTicks Replace with missing ticks is
equivalent to deleting part of the tick history, as if CustomTick s Delete with the " hole" interval is
called.
If the tick database has no data for the specified time interval, CustomTick s R eplace will add to the
database tick s form the tick s [] array.
The CustomTick s R eplace function work s directly with the tick database.
See also
CustomR ates Delete, CustomR ates Update, CustomTick s Delete, CopyTick s, CopyTick s R ange
CustomBookAdd
Passes the status of the Depth of Mark et for a custom symbol. The function allows broadcasting the
Depth of Mark et as if the prices arrive from a brok er's server.
int CustomBookAdd(
const string symbol, // symbol name
const MqlBookInfo& books[] // array with descriptions of the Depth of Market element
uint count=WHOLE_ARRAY // number of elements to be used
);
Parameters
symbol
[in] Custom symbol name.
books[]
[in] The array of M qlBook Info type data fully describing the Depth of Mark et status — all buy and
sell requests. The passed Depth of Mark et status completely replaces the previous one.
count=WHOLE_ARRAY
[in] The number of 'book s ' array elements to be passed to the function. The entire array is used
by default.
Return Value
Note
The CustomBookAdd function work s only for custom symbols the Depth of Mark et is opened for — via
the platform interface or the Mark etBookAdd function.
W hen throwing the Depth of Mark et in, the symbol's Bid and As k prices are not updated. You should
control the change of the best prices and throw in the tick s using CustomTick s Add.
The passed data are check ed for validity: prices and volumes should not be negative, as well as
type, price and volume (M qlBook Info.volume or M qlBook Info.volume_real) should be specified for
each element. If at least one Depth of Mark et element is described incorrectly, the system discards
the passed status entirely.
The M qlBook Info.volume_real extended accuracy volume has a higher priority over the regular
M qlBook Info.volume. If both values are specified for the Depth of Mark et element, the volume_real
one is used.
The order of the M qlBook Info elements in the 'book s ' array does not matter. W hen saving the data,
the terminal sorts them by price on its own.
W hen saving data, the "Book depth" (S YM BOL _TICKS _BOOKDEPT H ) parameter of the recipient
custom symbol is check ed. If the number of sell requests exceeds this value in the passed Depth of
Mark et, the excess levels are discarded. The same is true for buy requests.
books[0].type=BOOK_TYPE_SELL;
books[0].price=1.14337;
books[0].volume=100;
books[1].type=BOOK_TYPE_SELL;
books[1].price=1.14330;
books[1].volume=50;
books[2].type=BOOK_TYPE_SELL;
books[2].price=1.14335;
books[2].volume=40;
books[3].type=BOOK_TYPE_SELL;
books[3].price=1.14333;
books[3].volume=10;
books[4].type=BOOK_TYPE_BUY;
books[4].price=1.14322;
books[4].volume=10;
books[5].type=BOOK_TYPE_BUY;
books[5].price=1.14320;
books[5].volume=90;
books[6].type=BOOK_TYPE_BUY;
books[6].price=1.14319;
books[6].volume=100;
books[7].type=BOOK_TYPE_BUY;
books[7].price=1.14318;
books[7].volume=10;
Example:
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- enable the Depth of Market for a symbol we are to retrieve data from
MarketBookAdd(Symbol());
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Tick function |
//+------------------------------------------------------------------+
void OnTick(void)
{
MqlTick ticks[];
ArrayResize(ticks,1);
//--- copy the current prices from the common symbol to the custom one
if(SymbolInfoTick(Symbol(),ticks[0]))
{
string symbol_name=Symbol()+".SYN";
CustomTicksAdd(symbol_name,ticks);
}
}
//+------------------------------------------------------------------+
//| Book function |
//+------------------------------------------------------------------+
void OnBookEvent(const string &book_symbol)
{
//--- copy the current Depth of Market status from the common symbol to the custom one
if(book_symbol==Symbol())
{
MqlBookInfo book_array[];
if(MarketBookGet(Symbol(),book_array))
{
string symbol_name=Symbol()+".SYN";
CustomBookAdd(symbol_name,book_array);
}
}
}
//+------------------------------------------------------------------+
See also
Mark etBookAdd, CustomTick s Add, OnBookEvent
Chart Operations
Functions for setting chart properties (ChartSetInteger, ChartSetDouble, ChartSetString) are
asynchronous and are used for sending update commands to a chart. If these functions are executed
successfully, the command is included in the common queue of the chart events. Chart property
changes are implemented along with handling of the events queue of this chart.
Thus, do not expect an immediate update of the chart after calling asynchronous functions. Use the
ChartR edraw() function to forcedly update the chart appearance and properties.
Function Action
ChartApplyTemplate
Applies a specific template from a specified file to the chart. The command is added to chart
messages queue and will be executed after processing of all previous commands.
bool ChartApplyTemplate(
long chart_id, // Chart ID
const string filename // Template file name
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
filename
[in] The name of the file containing the template.
Return Value
R eturns true if the command has been added to chart queue, otherwise false. To get an information
about the error, call the GetLastError() function.
Note
The Expert Advisor will be unloaded and will not be able to continue operating in case of successful
loading of a new template to the chart it is attached to.
W hen applying the template to the chart, trade permissions may be limited due to security reasons :
Live trading permission cannot be extended for the Expert Advisors launched by
applying the template using ChartApplyTemplate() function.
If the mql5-program calling ChartApplyTemplate() function has no permission to trade, the Expert
Advisor launched via the template will also not be able to trade regardless of the template settings.
If the mql5-program calling ChartApplyTemplate() function has permission to trade, while there is no
such permission in the template settings, the Expert Advisor launched via the template will not be
able to trade.
Using Templates
The resources of the MQL5 language allow setting multiple chart properties, including colors using the
ChartSetInteger() function:
· Grid color;
· Color of the stop order levels (Stop Loss and Tak e Profit).
Besides, there can be multiple graphical objects and indicators on a chart. You may set up a chart with
all the necessary indicators once and then save it as a template. Such a template can be applied to any
chart.
The ChartApplyTemplate() function is intended for using a previously saved template, and it can be
used in any mql5 program. The path to the file that stores the template is passed as the second
parameter to ChartApplyTemplate(). The template file is searched according to the following rules :
· if the back slash "\" separator (written as "\\" ) is placed at the beginning of the path, the template
is searched for relative to the path _terminal_data_directory\ MQL5,
· if there is no back slash, the template is searched for relative to the executable EX5 file, in which
ChartApplyTemplate() is called;
· if a template is not found in the first two variants, the search is performed in the folder
terminal_directory\ Profiles \ Templates \ .
H ere terminal_directory is the folder from which the MetaTrader 5 Client Terminal is running, and
terminal_data_directory is the folder, in which editable files are stored, its location depends on the
operating system, user name and computer's security settings. Normally they are different folders, but
in some cases they may coincide.
The location of folders terminal_data_directory and terminal_directory can be obtained using the
TerminalInfoString() function.
For example:
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- example of applying template, located in \MQL5\Files
if(FileIsExist("my_template.tpl"))
{
Print("The file my_template.tpl found in \Files'");
//--- apply template
if(ChartApplyTemplate(0,"\\Files\\my_template.tpl"))
{
Print("The template 'my_template.tpl' applied successfully");
//--- redraw chart
ChartRedraw();
}
else
Print("Failed to apply 'my_template.tpl', error code ",GetLastError());
}
else
{
Print("File 'my_template.tpl' not found in "
+TerminalInfoString(TERMINAL_PATH)+"\\MQL5\\Files");
}
}
See also
R esources
ChartSaveTemplate
Saves current chart settings in a template with a specified name.
bool ChartSaveTemplate(
long chart_id, // Chart ID
const string filename // Filename to save the template
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
filename
[in] The filename to save the template. The " .tpl" extension will be added to the filename
automatically; there is no need to specify it. The template is saved in
data_folder \Profiles \Templates \ and can be used for manual application in the terminal. If a
template with the same filename already exists, the contents of this file will be overwritten.
Return Value
If successful, the function returns true, otherwise it returns false. To get information about the
error, call the GetLastError() function.
Note
Using templates, you can save chart settings with all applied indicators and graphical objects, to
then apply it to another chart.
Example:
//+------------------------------------------------------------------+
//| Test_ChartSaveTemplate.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- input parameters
input string symbol="GBPUSD"; // The symbol of a new chart
input ENUM_TIMEFRAMES period=PERIOD_H3; // The timeframe of a new chart
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- First attach indicators to the chart
int handle;
//--- Prepare the indicator for use
ChartApplyTemplate(new_chart,"StdDevChannelOnZigzag");
}
Sleep(10000);
}
//+------------------------------------------------------------------+
//| Creates a zigzag handle and ensures readiness of its data |
//+------------------------------------------------------------------+
bool PrepareZigzag(string sym,ENUM_TIMEFRAMES tf,int &h)
{
ResetLastError();
//--- The Zigzag indicator must be located in terminal_data_folder\MQL5\Examples
h=iCustom(sym,tf,"Examples\\Zigzag");
if(h==INVALID_HANDLE)
{
PrintFormat("%s: Failed to create the handle of the Zigzag indicator. Error code %d",
__FUNCTION__,GetLastError());
return false;
}
//--- When creating an indicator handle, it requires time to calculate values
int k=0; // The number of attempts to wait for the indicator calculation
//--- Wait for the calculation in a loop, pausing to 50 milliseconds if the calculation is not yet
while(BarsCalculated(h)<=0)
{
k++;
//--- Show the number of attempts
PrintFormat("%s: k=%d",__FUNCTION__,k);
//--- Wait 50 milliseconds to wait until the indicator is calculated
Sleep(50);
//--- If more than 100 attempt, then something is wrong
if(k>100)
{
//--- Report a problem
PrintFormat("Failed to calculate the indicator for %d attempts!");
//--- Terminate the program operation
return false;
}
}
//--- Everything is ready, the indicator is created and values are calculated
return true;
}
//+------------------------------------------------------------------+
//| Searches for the last 2 zigzag fractures and places to arrays |
//+------------------------------------------------------------------+
bool GetLastTwoFractures(double &get_values[],datetime &get_times[],int handle)
{
double values[]; // An array for the values of the zigzag
datetime times[]; // An array to get time
int size=100; // Size of the array
ResetLastError();
return true;
}
See also
ChartApplyTemplate(), R esources
ChartWindowFind
The function returns the number of a subwindow where an indicator is drawn. There are 2 variants of
the function.
1. The function searches in the indicated chart for the subwindow with the specified " short name" of
the indicator (the short name is displayed in the left top part of the subwindow), and it returns the
subwindow number in case of success.
int ChartWindowFind(
long chart_id, // chart identifier
string indicator_shortname // short indicator name, see INDICATOR_SHORTNAME
2. The function must be called from a custom indicator. It returns the number of the subwindow where
the indicator is work ing.
int ChartWindowFind();
Parameters
chart_id
[in] Chart ID. 0 denotes the current chart.
indicator_shortname
[in] Short name of the indicator.
Return Value
Subwindow number in case of success. In case of failure the function returns -1.
Note
If the second variant of the function (without parameters) is called from a script or Expert Advisor,
the function returns -1.
Don't mix up the short name of an indicator and a file name, which is specified when an indicator is
created using iCustom() and IndicatorCreate() functions. If the indicator's short name is not set
explicitly, then the name of the file containing the source code of the indicator, is specified in it
during compilation.
It is important to correctly form the short name of an indicator, which is recorded in the
I NDICATOR_S H OR T NAM E property using the IndicatorSetString() function. It is recommended that
the short name contains values of the indicator's input parameters, because the indicator deleted
from a chart in the ChartIndicatorDelete() function is identified by its short name.
Example:
#property script_show_inputs
//--- input parameters
input string shortname="MACD(12,26,9)";
//+------------------------------------------------------------------+
//| Returns number of the chart window with this indicator |
//+------------------------------------------------------------------+
int GetIndicatorSubWindowNumber(long chartID=0,string short_name="")
{
int window=-1;
//---
if((ENUM_PROGRAM_TYPE)MQL5InfoInteger(MQL5_PROGRAM_TYPE)==PROGRAM_INDICATOR)
{
//--- the function is called from the indicator, name is not required
window=ChartWindowFind();
}
else
{
//--- the function is called from an Expert Advisor or script
window=ChartWindowFind(0,short_name);
if(window==-1) Print(__FUNCTION__+"(): Error = ",GetLastError());
}
//---
return(window);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int window=GetIndicatorSubWindowNumber(0,shortname);
if(window!=-1)
Print("Indicator "+shortname+" is in the window #"+(string)window);
else
Print("Indicator "+shortname+" is not found. window = "+(string)window);
}
See also
ObjectCreate(), ObjectFind()
ChartTimePriceToXY
Converts the coordinates of a chart from the time/price representation to the X and Y coordinates.
bool ChartTimePriceToXY(
long chart_id, // Chart ID
int sub_window, // The number of the subwindow
datetime time, // Time on the chart
double price, // Price on the chart
int& x, // The X coordinate for the time on the chart
int& y // The Y coordinates for the price on the chart
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
sub_window
[in] The number of the chart subwindow. 0 means the main chart window.
time
[in] The time value on the chart, for which the value in pixels along the X axis will be received.
The origin is in the upper left corner of the main chart window.
price
[in] The price value on the chart, for which the value in pixels along the Y axis will be received.
The origin is in the upper left corner of the main chart window.
x
[out] The variable, into which the conversion of time to X will be received.
y
[out] The variable, into which the conversion of price to Y will be received.
Return Value
R eturns true if successful, otherwise false. To get information about the error, call the
GetLastError() function.
See also
ChartXYToTimePrice()
ChartXYToTimePrice
Converts the X and Y coordinates on a chart to the time and price values.
bool ChartXYToTimePrice(
long chart_id, // Chart ID
int x, // The X coordinate on the chart
int y, // The Y coordinate on the chart
int& sub_window, // The number of the subwindow
datetime& time, // Time on the chart
double& price // Price on the chart
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
x
[in] The X coordinate.
y
[in] The Y coordinate.
sub_window
[out] The variable, into which the chart subwindow number will be written. 0 means the main
chart window.
time
[out] The time value on the chart, for which the value in pixels along the X axis will be received.
The origin is in the upper left corner of the main chart window.
price
[out] The price value on the chart, for which the value in pixels along the Y axis will be received.
The origin is in the upper left corner of the main chart window.
Return Value
R eturns true if successful, otherwise false. To get information about the error, call the
GetLastError() function.
Example:
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- Show the event parameters on the chart
See also
ChartTimePriceToXY()
ChartOpen
Opens a new chart with the specified symbol and period.
long ChartOpen(
string symbol, // Symbol name
ENUM_TIMEFRAMES period // Period
);
Parameters
symbol
[in] Chart symbol. NULL means the symbol of the current chart (the Expert Advisor is attached
to).
period
[in] Chart period (timeframe). Can be one of the ENUM _TIM EFRAM ES values. 0 means the current
chart period.
Return Value
Note
The maximum possible number of simultaneously open charts in the terminal can't exceed the
CHAR TS _M AX value.
ChartFirst
R eturns the ID of the first chart of the client terminal.
long ChartFirst();
Return Value
Chart I D.
ChartNext
R eturns the chart ID of the chart next to the specified one.
long ChartNext(
long chart_id // Chart ID
);
Parameters
chart_id
[in] Chart ID. 0 does not mean the current chart. 0 means " return the first chart ID" .
Return Value
Example:
ChartClose
Closes the specified chart.
bool ChartClose(
long chart_id=0 // Chart ID
);
Parameters
chart_id=0
[in] Chart ID. 0 means the current chart.
Return Value
ChartSymbol
R eturns the symbol name for the specified chart.
string ChartSymbol(
long chart_id=0 // Chart ID
);
Parameters
chart_id=0
[in] Chart ID. 0 means the current chart.
Return Value
See also
ChartSetSymbolPeriod
ChartPeriod
R eturns the timeframe period of specified chart.
ENUM_TIMEFRAMES ChartPeriod(
long chart_id=0 // Chart ID
);
Parameters
chart_id=0
[in] Chart ID. 0 means the current chart.
Return Value
The function returns one of the ENUM _TIM EFRAM ES values. If chart does not exist, it returns 0.
ChartRedraw
This function calls a forced redrawing of a specified chart.
void ChartRedraw(
long chart_id=0 // Chart ID
);
Parameters
chart_id=0
[in] Chart ID. 0 means the current chart.
Note
See also
Objects functions
ChartSetDouble
Sets a value for a corresponding property of the specified chart. Chart property should be of a double
type. The command is added to chart messages queue and will be executed after processing of all
previous commands.
bool ChartSetDouble(
long chart_id, // Chart ID
int prop_id, // Property ID
double value // Value
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
prop_id
[in] Chart property ID. Can be one of the ENUM _CHAR T _PR OPER T Y_DOUBL E values (except the
read-only properties).
value
[in] Property value.
Return Value
R eturns true if the command has been added to chart queue, otherwise false. To get an information
about the error, call the GetLastError() function.
Note
The function is asynchronous, which means that the function does not wait for the execution of the
command, which has been successfully added to the queue of specified the chart. Instead, it
immediately returns control. The property will only change after the handling of the appropriate
command from the chart queue. To immediately execute commands from the chart queue, call the
ChartR edraw function.
If you want to immediately change several chart properties at once, then the corresponding
functions (ChartSetString, ChartSetDouble, ChartSetString) should be executed in one code block ,
after which you should call ChartR edraw once.
To check the command execution result, you can use a function, which requests the specified chart
property (ChartGetInteger, ChartGetDouble, ChartSetString). H owever, note that these functions
are synchronous and wait for execution results.
ChartSetInteger
Sets a value for a corresponding property of the specified chart. Chart property must be
datetime, int, color, bool or char. The command is added to chart messages queue and will be
executed after processing of all previous commands.
bool ChartSetInteger(
long chart_id, // Chart ID
int prop_id, // Property ID
long value // Value
);
bool ChartSetInteger(
long chart_id, // Chart ID
int prop_id, // Property ID
int sub_window, // Subwindow number
long value // Value
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
prop_id
[in] Chart property ID. It can be one of the ENUM _CHAR T _PR OPER T Y_INT EGER value (except the
read-only properties).
sub_window
[in] Number of the chart subwindow. For the first case, the default value is 0 (main chart
window). The most of the properties do not require a subwindow number.
value
[in] Property value.
Return Value
R eturns true if the command has been added to chart queue, otherwise false. To get an information
about the error, call the GetLastError() function.
Note
The function is asynchronous, which means that the function does not wait for the execution of the
command, which has been successfully added to the queue of specified the chart. Instead, it
immediately returns control. The property will only change after the handling of the appropriate
command from the chart queue. To immediately execute commands from the chart queue, call the
ChartR edraw function.
If you want to immediately change several chart properties at once, then the corresponding
functions (ChartSetString, ChartSetDouble, ChartSetString) should be executed in one code block ,
after which you should call ChartR edraw once.
To check the command execution result, you can use a function, which requests the specified chart
property (ChartGetInteger, ChartGetDouble, ChartSetString). H owever, note that these functions
are synchronous and wait for execution results.
Example:
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- Enabling events of mouse movements on the chart window
ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,1);
//--- Forced updating of chart properties ensures readiness for event processing
ChartRedraw();
}
//+------------------------------------------------------------------+
//| MouseState |
//+------------------------------------------------------------------+
string MouseState(uint state)
{
string res;
res+="\nML: " +(((state& 1)== 1)?"DN":"UP"); // mouse left
res+="\nMR: " +(((state& 2)== 2)?"DN":"UP"); // mouse right
res+="\nMM: " +(((state&16)==16)?"DN":"UP"); // mouse middle
res+="\nMX: " +(((state&32)==32)?"DN":"UP"); // mouse first X key
res+="\nMY: " +(((state&64)==64)?"DN":"UP"); // mouse second X key
res+="\nSHIFT: "+(((state& 4)== 4)?"DN":"UP"); // shift key
res+="\nCTRL: " +(((state& 8)== 8)?"DN":"UP"); // control key
return(res);
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
if(id==CHARTEVENT_MOUSE_MOVE)
Comment("POINT: ",(int)lparam,",",(int)dparam,"\n",MouseState((uint)sparam));
}
ChartSetString
Sets a value for a corresponding property of the specified chart. Chart property must be of the string
type. The command is added to chart messages queue and will be executed after processing of all
previous commands.
bool ChartSetString(
long chart_id, // Chart ID
int prop_id, // Property ID
string str_value // Value
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
prop_id
[in] Chart property I D. Its value can be one of the ENUM _CHAR T _PR OPER T Y_ST R I NG values
(except the read-only properties).
str_value
[in] Property value string. String length cannot exceed 2045 characters (extra characters will be
truncated).
Return Value
R eturns true if the command has been added to chart queue, otherwise false. To get an information
about the error, call the GetLastError() function.
Note
ChartSetString can be used for a comment output on the chart instead of the Comment function.
The function is asynchronous, which means that the function does not wait for the execution of the
command, which has been successfully added to the queue of specified the chart. Instead, it
immediately returns control. The property will only change after the handling of the appropriate
command from the chart queue. To immediately execute commands from the chart queue, call the
ChartR edraw function.
If you want to immediately change several chart properties at once, then the corresponding
functions (ChartSetString, ChartSetDouble, ChartSetString) should be executed in one code block ,
after which you should call ChartR edraw once.
To check the command execution result, you can use a function, which requests the specified chart
property (ChartGetInteger, ChartGetDouble, ChartSetString). H owever, note that these functions
are synchronous and wait for execution results.
Example:
void OnTick()
{
//---
double Ask,Bid;
int Spread;
Ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
Bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
Spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD);
string comment=StringFormat("Printing prices:\nAsk = %G\nBid = %G\nSpread = %d",
Ask,Bid,Spread);
ChartSetString(0,CHART_COMMENT,comment);
}
See also
Comment, ChartGetString
ChartGetDouble
R eturns the value of a corresponding property of the specified chart. Chart property must be of double
type. There are 2 variants of the function calls.
double ChartGetDouble(
long chart_id, // Chart ID
int prop_id, // Property ID
int sub_window=0 // subwindow number, if necessary
);
2. R eturns true or false, depending on the success of a function. If successful, the value of the
property is placed in a target variable double_var passed by reference.
bool ChartGetDouble(
long chart_id, // Chart ID
int prop_id, // Property ID
int sub_window, // Subwindow number
double& double_var // Target variable for the chart property
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
prop_id
[in] Chart property ID. This value can be one of the ENUM _CHAR T _PR OPER T Y_DOUBL E values.
sub_window
[in] Number of the chart subwindow. For the first case, the default value is 0 (main chart
window). The most of the properties do not require a subwindow number.
double_var
[out] Target variable of double type for the requested property.
Return Value
For the second call case it returns true if the specified property is available and its value has been
placed into double_var variable, otherwise returns false. To get an additional information about the
error, it is necessary to call the function GetLastError().
Note
The function is synchronous, which means that it waits for the execution of all the commands that
have been added to the chart queue prior to its call.
Example:
void OnStart()
{
double priceMin=ChartGetDouble(0,CHART_PRICE_MIN,0);
double priceMax=ChartGetDouble(0,CHART_PRICE_MAX,0);
Print("CHART_PRICE_MIN =",priceMin);
Print("CHART_PRICE_MAX =",priceMax);
}
ChartGetInteger
R eturns the value of a corresponding property of the specified chart. Chart property must be of
datetime, int or bool type. There are 2 variants of the function calls.
long ChartGetInteger(
long chart_id, // Chart ID
int prop_id, // Property ID
int sub_window=0 // subwindow number, if necessary
);
2. R eturns true or false, depending on the success of a function. If successful, the value of the
property is placed in a target variable long _var passed by reference.
bool ChartGetInteger(
long chart_id, // Chart ID
int prop_id, // Property ID
int sub_window, // subwindow number
long& long_var // Target variable for the property
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
prop_id
[in] Chart property ID. This value can be one of the ENUM _CHAR T _PR OPER T Y_INT EGER values.
sub_window
[in] Number of the chart subwindow. For the first case, the default value is 0 (main chart
window). The most of the properties do not require a subwindow number.
long_var
[out] Target variable of long type for the requested property.
Return Value
For the second call case it returns true if specified property is available and its value has been
stored into long _var variable, otherwise returns false. To get additional information about the error,
it is necessary to call the function GetLastError().
Note
The function is synchronous, which means that it waits for the execution of all the commands that
have been added to the chart queue prior to its call.
Example:
void OnStart()
{
int height=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
int width=ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
Print("CHART_HEIGHT_IN_PIXELS =",height,"pixels");
Print("CHART_WIDTH_IN_PIXELS =",width,"pixels");
}
ChartGetString
R eturns the value of a corresponding property of the specified chart. Chart property must be of string
type. There are 2 variants of the function call.
string ChartGetString(
long chart_id, // Chart ID
int prop_id // Property ID
);
2. R eturns true or false, depending on the success of a function. If successful, the value of the
property is placed in a target variable string _var passed by reference.
bool ChartGetString(
long chart_id, // Chart ID
int prop_id, // Property ID
string& string_var // Target variable for the property
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
prop_id
[in] Chart property ID. This value can be one of the ENUM _CHAR T _PR OPER T Y_ST R ING values.
string_var
[out] Target variable of string type for the requested property.
Return Value
For the second call case it returns true if the specified property is available and its value has been
stored into string _var variable, otherwise returns false. To get additional information about the
error, it is necessary to call the function GetLastError().
Note
ChartGetString can be used for reading comments plotted on the chart using the Comment or
ChartSetString functions.
The function is synchronous, which means that it waits for the execution of all the commands that
have been added to the chart queue prior to its call.
Example:
void OnStart()
{
ChartSetString(0,CHART_COMMENT,"Test comment.\nSecond line.\nThird!");
ChartRedraw();
Sleep(1000);
string comm=ChartGetString(0,CHART_COMMENT);
Print(comm);
}
See also
Comment, ChartSetString
ChartNavigate
Performs shift of the specified chart by the specified number of bars relative to the specified position
in the chart.
bool ChartNavigate(
long chart_id, // Chart ID
ENUM_CHART_POSITION position, // Position
int shift=0 // Shift value
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
position
[in] Chart position to perform a shift. Can be one of the ENUM _CHAR T _POSITION values.
shift=0
[in] Number of bars to shift the chart. Positive value means the right shift (to the end of chart),
negative value means the left shift (to the beginning of chart). The zero shift can be used to
navigate to the beginning or end of chart.
Return Value
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- get handle of the current chart
long handle=ChartID();
string comm="";
if(handle>0) // if successful, additionally set up the chart
{
//--- disable auto scroll
ChartSetInteger(handle,CHART_AUTOSCROLL,false);
//--- set a shift from the right chart border
ChartSetInteger(handle,CHART_SHIFT,true);
//--- draw candlesticks
ChartSetInteger(handle,CHART_MODE,CHART_CANDLES);
//--- set the display mode for tick volumes
ChartSetInteger(handle,CHART_SHOW_VOLUMES,CHART_VOLUME_TICK);
Comment(comm);
//--- scroll 10 bars to the right of the history start
ChartNavigate(handle,CHART_BEGIN,10);
//--- get the number of the first bar visible on the chart (numeration like in timeseries)
long first_bar=ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR,0);
//--- add line feed character
comm=comm+"\r\n";
//--- add to comment
comm=comm+"The first bar on the chart is number "+IntegerToString(first_bar)+"\r\n";
//--- show comment
Comment(comm);
//--- wait 5 seconds to see how the chart moves
Sleep(5000);
ChartID
R eturns the ID of the current chart.
long ChartID();
Return Value
ChartIndicatorAdd
Adds an indicator with the specified handle into a specified chart window. Indicator and chart should
be generated on the same symbol and time frame.
bool ChartIndicatorAdd(
long chart_id, // chart ID
int sub_window // number of the sub-window
int indicator_handle // handle of the indicator
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
sub_window
[in] The number of the chart sub-window. 0 means the main chart window. To add an indicator in
a new window, the parameter must be one greater than the index of the last existing window, i.e.
equal to CHAR T _W I NDOW S _TOT AL. If the value of the parameter is greater than
CHAR T _W I NDOW S _TOT AL, a new window will not be created, and the indicator will not be added.
indicator_handle
[in] The handle of the indicator.
Return Value
The function returns true in case of success, otherwise it returns false. In order to obtain
information about the error, call the GetLastError() function. Error 4114 means that a chart and an
added indicator differ by their symbol or time frame.
Note
If an indicator that should be drawn in a separate subwindow (for example, built-in iM ACD or a
custom indicator with specified #property indicator_separate_window property) is applied to the
main chart window, it may not be visible though it will still be present in the list of indicators. This
means that the scale of the indicator is different from the scale of the price chart, and applied
indicator's values do not fit in the displayed range of the price chart. In this case, GetLastError()
returns zero code indicating the absence of an error. The values of such " invisible" indicator can be
seen in Data W indow and received from other MQL5 applications.
Example:
#property description "Expert Advisor demonstrating the work with ChartIndicatorAdd() function."
#property description "After launching on the chart (and receiving the error in Journal), open"
#property description "the Expert Advisor's properties and specify correct <symbol> and <period> pa
#property description "MACD indicator will be added on the chart."
int indicator_handle=INVALID_HANDLE;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
indicator_handle=iMACD(symbol,period,fast_ema_period,slow_ema_period,signal_period,apr);
//--- try to add the indicator on the chart
if(!AddIndicator())
{
//--- AddIndicator() function refused to add the indicator on the chart
int answer=MessageBox("Do you want to add MACD on the chart anyway?",
"Incorrect symbol and/or time frame for adding the indicator",
MB_YESNO // "Yes" and "No" selection buttons will be shown
);
//--- if a user still insists on incorrect usage of ChartIndicatorAdd()
if(answer==IDYES)
{
//--- first of all, a Journal entry will be made about that
PrintFormat("Attention! %s: Trying to add MACD(%s/%s) indicator on %s/%s chart. Receiving
__FUNCTION__,symbol,EnumToString(period),_Symbol,EnumToString(_Period));
//--- receive the number of a new subwindow, to which we will try to add the indicator
int subwindow=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
//--- now make an attempt resulting in error
if(!ChartIndicatorAdd(0,subwindow,indicator_handle))
PrintFormat("Failed to add MACD indicator on %d chart window. Error code %d",
subwindow,GetLastError());
}
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Expert Advisor performs nothing
}
//+------------------------------------------------------------------+
//| Function for checking and adding the indicator on the chart |
//+------------------------------------------------------------------+
bool AddIndicator()
{
//--- displayed message
string message;
//--- check if the indicator symbol and chart symbol match each other
if(symbol!=_Symbol)
{
message="Displaying the use of Demo_ChartIndicatorAdd() function:";
message=message+"\r\n";
message=message+"Unable to add the indicator calculated on another symbol on the chart.";
message=message+"\r\n";
message=message+"Specify the chart symbol in Expert Advisor's property - "+_Symbol+".";
Alert(message);
//--- premature exit, the indicator will not be added on the chart
return false;
}
//--- check if the indicator's and chart's time frames match each other
if(period!=_Period)
{
message="Unable to add the indicator calculated on another time frame on the chart.";
message=message+"\r\n";
message=message+"Specify the chart time frame in Expert Advisor properties - "+EnumToString(_
Alert(message);
//--- premature exit, the indicator will not be added on the chart
return false;
}
//--- all checks completed, symbol and indicator time frame match the chart
if(indicator_handle==INVALID_HANDLE)
{
Print(__FUNCTION__," Creating MACD indicator");
indicator_handle=iMACD(symbol,period,fast_ema_period,slow_ema_period,signal_period,apr);
if(indicator_handle==INVALID_HANDLE)
{
Print("Failed to create MACD indicator. Error code ",GetLastError());
}
}
//--- reset the error code
ResetLastError();
//--- apply the indicator to the chart
Print(__FUNCTION__," Adding MACD indicator on the chart");
Print("MACD is generated on ",symbol,"/",EnumToString(period));
//--- receive the number of a new subwindow, to which MACD indicator is added
int subwindow=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
PrintFormat("Adding MACD indicator on %d chart window",subwindow);
if(!ChartIndicatorAdd(0,subwindow,indicator_handle))
{
PrintFormat("Failed to add MACD indicator on %d chart window. Error code %d",
subwindow,GetLastError());
}
//--- Indicator added successfully
return(true);
}
See Also
ChartIndicatorDelete(), ChartIndicatorName(), ChartIndicatorsTotal(), iCustom(), IndicatorCreate()
ChartIndicatorDelete
R emoves an indicator with a specified name from the specified chart window.
bool ChartIndicatorDelete(
long chart_id, // chart id
int sub_window // number of the subwindow
const string indicator_shortname // short name of the indicator
);
Parameters
chart_id
[in] Chart ID. 0 denotes the current chart.
sub_window
[in] Number of the chart subwindow. 0 denotes the main chart subwindow.
const indicator_shortname
[in] The short name of the indicator which is set in the INDICATOR_S H OR T NAM E property with the
IndicatorSetString() function. To get the short name of an indicator use the ChartIndicatorName()
function.
Return Value
R eturns true in case of successful deletion of the indicator. Otherwise it returns false. To get error
details use the GetLastError() function.
Note
If two indicators with identical short names exist in the chart subwindow, the first one in a row will
be deleted.
If other indicators on this chart are based on the values of the indicator that is being deleted, such
indicators will also be deleted.
Do not confuse the indicator short name and the file name that is specified when creating an
indicator using functions iCustom() and IndicatorCreate(). If the short name of an indicator is not
set explicitly, then the name of the file containing the source code of the indicator will be specified
during compilation.
Deletion of an indicator from a chart doesn't mean that its calculation part will be deleted from the
terminal memory. To release the indicator handle use the IndicatorR elease() function.
The indicator's short name should be formed correctly. It will be written to the
I NDICATOR_S H OR T NAM E property using the IndicatorSetString() function. It is recommended that
the short name should contain values of all the input parameters of the indicator, because the
indicator to be deleted from the chart by the ChartIndicatorDelete() function is identified by the
short name.
//+------------------------------------------------------------------+
//| Demo_ChartIndicatorDelete.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Histogram
#property indicator_label1 "Histogram"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int first_param=1;
input int second_param=2;
input int third_param=3;
input bool wrong_init=true;
//--- indicator buffers
double HistogramBuffer[];
string shortname;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
int res=INIT_SUCCEEDED;
//--- Link the HistogramBuffer array to the indicator buffer
SetIndexBuffer(0,HistogramBuffer,INDICATOR_DATA);
//--- Construct a short indicator name based on input parameters
shortname=StringFormat("Demo_ChartIndicatorDelete(%d,%d,%d)",
first_param,second_param,third_param);
IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- If forced completion of an indicator is set, return a non-zero value
if(wrong_init) res=INIT_FAILED;
return(res);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
See also
ChartIndicatorAdd(), ChartIndicatorName(), ChartIndicatorsTotal(), iCustom(), IndicatorCreate(),
IndicatorSetString()
ChartIndicatorGet
R eturns the handle of the indicator with the specified short name in the specified chart window.
int ChartIndicatorGet(
long chart_id, // Chart ID
int sub_window // The number of the subwindow
const string indicator_shortname // Short name of the indicator
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
sub_window
[in] The number of the chart subwindow. 0 means the main chart window.
const indicator_shortname
[in] The short name if the indicator, which is set in the INDICATOR_S H OR T NAM E property using
the IndicatorSetString() function. To get the short name of an indicator, use the
ChartIndicatorName() function.
Return Value
Note
W hen creating an indicator, be careful forming its short name, which is written in the
I NDICATOR_S H OR T NAM E property using the IndicatorSetString() function. It is recommended that a
short name should contain the values of input parameters of the indicator, since the indicator is
identified in the ChartIndicatorGet() function based on its short name.
Another way to identify the indicator is to get a list of its parameters for a given handle using the
IndicatorParameters() function and then to analyze the obtained values.
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- The number of windows on the chart (at least one main window is always present)
int windows=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
//--- Check all windows
for(int w=0;w<windows;w++)
{
//--- the number of indicators in this window/subwindow
int total=ChartIndicatorsTotal(0,w);
//--- Go through all indicators in the window
for(int i=0;i<total;i++)
{
//--- get the short name of an indicator
string name=ChartIndicatorName(0,w,i);
//--- get the handle of an indicator
int handle=ChartIndicatorGet(0,w,name);
//--- Add to log
PrintFormat("Window=%d, index=%d, name=%s, handle=%d",w,i,name,handle);
//--- You should obligatorily release the indicator handle when it is no longer needed
IndicatorRelease(handle);
}
}
}
See also
ChartIndicatorAdd(), ChartIndicatorName(), ChartIndicatorsTotal(), IndicatorParameters()
ChartIndicatorName
R eturns the short name of the indicator by the number in the indicators list on the specified chart
window.
string ChartIndicatorName(
long chart_id, // chart id
int sub_window // number of the subwindow
int index // index of the indicator in the list of indicators added to the chart subw
);
Parameters
chart_id
[in] Chart ID. 0 denotes the current chart.
sub_window
[in] Number of the chart subwindow. 0 denotes the main chart subwindow.
index
[in] the index of the indicator in the list of indicators. The numeration of indicators start with
zero, i.e. the first indicator in the list has the 0 index. To obtain the number of indicators in the
list use the ChartIndicatorsTotal() function.
Return Value
The short name of the indicator which is set in the I NDICATOR_S H OR T NAM E property with the
IndicatorSetString() function. To get error details use the GetLastError() function.
Note
Do not confuse the indicator short name and the file name that is specified when creating an
indicator using functions iCustom() and IndicatorCreate(). If the short name of an indicator is not
set explicitly, then the name of the file containing the source code of the indicator will be specified
during compilation.
The indicator's short name should be formed correctly. It will be written to the
I NDICATOR_S H OR T NAM E property using the IndicatorSetString() function. It is recommended that
the short name should contain values of all the input parameters of the indicator, because the
indicator to be deleted from the chart by the ChartIndicatorDelete() function is identified by the
short name.
See also
ChartIndicatorAdd(), ChartIndicatorDelete(), ChartIndicatorsTotal(), iCustom(), IndicatorCreate(),
IndicatorSetString()
ChartIndicatorsTotal
R eturns the number of all indicators applied to the specified chart window.
int ChartIndicatorsTotal(
long chart_id, // chart id
int sub_window // number of the subwindow
);
Parameters
chart_id
[in] Chart ID. 0 denotes the current chart.
sub_window
[in] Number of the chart subwindow. 0 denotes the main chart subwindow.
Return Value
The number of indicators in the specified chart window. To get error details use the GetLastError()
function.
Note
The function allows going searching through all the indicators attached to the chart. The number of
all the windows of the chart can be obtained from the CHAR T _W I NDOW S _TOT AL property using the
ChartGetInteger() function.
See also
ChartIndicatorAdd(), ChartIndicatorDelete(), iCustom(), IndicatorCreate(), IndicatorSetString()
ChartWindowOnDropped
R eturns the number (index) of the chart subwindow the Expert Advisor or script has been dropped to.
0 means the main chart window.
int ChartWindowOnDropped();
Return Value
Example:
int myWindow=ChartWindowOnDropped();
int windowsTotal=ChartGetInteger(0,CHART_WINDOWS_TOTAL);
Print("Script is running on the window #"+myWindow+
". Total windows on the chart "+ChartSymbol()+":",windowsTotal);
See also
ChartPriceOnDropped, ChartTimeOnDropped, ChartXOnDropped, ChartYOnDropped
ChartPriceOnDropped
R eturns the price coordinate corresponding to the chart point the Expert Advisor or script has been
dropped to.
double ChartPriceOnDropped();
Return Value
Example:
double p=ChartPriceOnDropped();
Print("ChartPriceOnDropped() = ",p);
See also
ChartXOnDropped, ChartYOnDropped
ChartTimeOnDropped
R eturns the time coordinate corresponding to the chart point the Expert Advisor or script has been
dropped to.
datetime ChartTimeOnDropped();
Return Value
Example:
datetime t=ChartTimeOnDropped();
Print("Script was dropped on the "+t);
See also
ChartXOnDropped, ChartYOnDropped
ChartXOnDropped
R eturns the X coordinate of the chart point the Expert Advisor or script has been dropped to.
int ChartXOnDropped();
Return Value
Note
Example:
int X=ChartXOnDropped();
int Y=ChartYOnDropped();
Print("(X,Y) = ("+X+","+Y+")");
See also
ChartW indowOnDropped, ChartPriceOnDropped, ChartTimeOnDropped
ChartYOnDropped
R eturns the Y coordinateof the chart point the Expert Advisor or script has been dropped to.
int ChartYOnDropped();
Return Value
Note
See also
ChartW indowOnDropped, ChartPriceOnDropped, ChartTimeOnDropped
ChartSetSymbolPeriod
Changes the symbol and period of the specified chart. The function is asynchronous, i.e. it sends the
command and does not wait for its execution completion. The command is added to chart messages
queue and will be executed after processing of all previous commands.
bool ChartSetSymbolPeriod(
long chart_id, // Chart ID
string symbol, // Symbol name
ENUM_TIMEFRAMES period // Period
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
symbol
[in] Chart symbol. NULL value means the current chart symbol (Expert Advisor is attached to)
period
[in] Chart period (timeframe). Can be one of the ENUM _TIM EFRAM ES values. 0 means the current
chart period.
Return Value
R eturns true if the command has been added to chart queue, otherwise false. To get an information
about the error, call the GetLastError() function.
Note
The symbol/period change leads to the re-initialization of the Expert Advisor attached to a chart.
The call of ChartSetSymbolPeriod with the same symbol and timeframe can be used to update the
chart (similar to the terminal's R efresh command). In its turn, the chart update triggers re-
calculation of the indicators attached to it. Thus, you are able to calculate an indicator on the chart
even if there are no tick s (e.g., on week ends).
See also
ChartSymbol, ChartPeriod
ChartScreenShot
The function provides a screenshot of the chart in its current state in the GI F, PNG or BMP format
depending on specified extension.
bool ChartScreenShot(
long chart_id, // Chart ID
string filename, // Symbol name
int width, // Width
int height, // Height
ENUM_ALIGN_MODE align_mode=ALIGN_RIGHT // Alignment type
);
Parameters
chart_id
[in] Chart ID. 0 means the current chart.
filename
[in] Screenshot file name. Cannot exceed 63 characters. Screenshot files are placed in the \Files
directory.
width
[in] Screenshot width in pixels.
height
[in] Screenshot height in pixels.
align_mode=ALIGN_RIGHT
[in] Output mode of a narrow screenshot. A value of the ENUM _ALIGN_MODE enumeration.
ALIGN_R IGH T means align to the right margin (the output from the end). ALIGN_L EFT means Left
justify.
Return Value
Note
If you need to tak e a screenshot from a chart from a certain position, first it's necessary to position
the graph using the ChartNavigate() function. If the horizontal size of the screenshot is smaller than
the chart window, either the right part of the chart window, or its left part is output, depending on
the align_mode settings.
Example:
#property description "The Expert Advisor demonstrates how to create a series of screenshots of the
#property description "chart using the ChartScreenShot() function. For convenience, the file name i
#property description "shown on the chart. The height and width of images is defined through macros
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- Show the name of the function, call time and event identifier
Print(__FUNCTION__,TimeCurrent()," id=",id," mode=",mode);
//--- Handle the CHARTEVENT_CLICK event ("A mouse click on the chart")
if(id==CHARTEVENT_CLICK)
{
//--- Initial shift from the chart edge
int pos=0;
//--- Operation with the left chart edge
if(mode>0)
{
//--- Scroll the chart to the left edge
ChartNavigate(0,CHART_BEGIN,pos);
for(int i=0;i<pictures;i++)
{
//--- Prepare a text to show on the chart and a file name
string name="ChartScreenShot"+"CHART_BEGIN"+string(pos)+".gif";
//--- Show the name on the chart as a comment
Comment(name);
//--- Save the chart screenshot in a file in the terminal_directory\MQL5\Files\
if(ChartScreenShot(0,name,WIDTH,HEIGHT,ALIGN_LEFT))
Print("We've saved the screenshot ",name);
//---
pos+=bars_shift;
//--- Give the user time to look at the new part of the chart
Sleep(3000);
//--- Scroll the chart from the current position bars_shift bars to the right
ChartNavigate(0,CHART_CURRENT_POS,bars_shift);
}
//--- Change the mode to the opposite
mode*=-1;
}
else // Operation with the right chart edge
{
//--- Scroll the chart to the right edge
ChartNavigate(0,CHART_END,pos);
for(int i=0;i<pictures;i++)
{
//--- Prepare a text to show on the chart and a file name
string name="ChartScreenShot"+"CHART_END"+string(pos)+".gif";
//--- Show the name on the chart as a comment
Comment(name);
//--- Save the chart screenshot in a file in the terminal_directory\MQL5\Files\
if(ChartScreenShot(0,name,WIDTH,HEIGHT,ALIGN_RIGHT))
Print("We've saved the screenshot ",name);
//---
pos+=bars_shift;
//--- Give the user time to look at the new part of the chart
Sleep(3000);
//--- Scroll the chart from the current position bars_shift bars to the right
ChartNavigate(0,CHART_CURRENT_POS,-bars_shift);
}
//--- Change the mode to the opposite
mode*=-1;
}
} // End of CHARTEVENT_CLICK event handling
//--- End of the OnChartEvent() handler
}
See also
ChartNavigate(), R esources
Trade Functions
This is the group of functions intended for managing trading activities.
Before you proceed to study the trade functions of the platform, you must have a clear understanding
of the basic terms: order, deal and position:
· An order is an instruction given to a brok er to buy or sell a financial instrument. There are two main
types of orders : Mark et and Pending. In addition, there are special Tak e Profit and Stop Loss levels.
· A deal is the commercial exchange (buying or selling) of a financial security. Buying is executed at
the demand price (As k ), and Sell is performed at the supply price (Bid). A deal can be opened as a
result of mark et order execution or pending order triggering. Note that in some cases, execution of
an order can result in several deals.
· A position is a trade obligation, i.e. the number of bought or sold contracts of a financial
instrument. A long position is financial security bought expecting the security price go higher. A
short position is an obligation to supply a security expecting the price will fall in future.
General information about trading operations is available in the client terminal help.
Trading functions can be used in Expert Advisors and scripts. Trading functions can be called only if in
the properties of the Expert Advisor or script the "Allow live trading " check box is enabled.
Trading can be allowed or prohibited depending on various factors described in the Trade Permission
section.
Function Action
OrderCalcMargin
The function calculates the margin required for the specified order type, on the current account, in the
current mark et environment not tak ing into account current pending orders and open positions. It
allows the evaluation of margin for the trade operation planned. The value is returned in the account
currency.
bool OrderCalcMargin(
ENUM_ORDER_TYPE action, // type of order
string symbol, // symbol name
double volume, // volume
double price, // open price
double& margin // variable for obtaining the margin value
);
Parameters
action
[in] The order type, can be one of the values of the ENUM _ORDER_T YPE enumeration.
symbol
[in] Symbol name.
volume
[in] Volume of the trade operation.
price
[in] Open price.
margin
[out] The variable, to which the value of the required margin will be written in case the function
is successfully executed. The calculation is performed as if there were no pending orders and open
positions on the current account. The margin value depends on many factors, and can differ in
different mark et environments.
Return Value
The function returns true in case of success ; otherwise it returns false. In order to obtain
information about the error, call the GetLastError() function.
See also
OrderSend(), Order Properties, Trade Operation Types
OrderCalcProfit
The function calculates the profit for the current account, in the current mark et conditions, based on
the parameters passed. The function is used for pre-evaluation of the result of a trade operation. The
value is returned in the account currency.
bool OrderCalcProfit(
ENUM_ORDER_TYPE action, // type of the order (ORDER_TYPE_BUY or ORDER_TYPE_SELL)
string symbol, // symbol name
double volume, // volume
double price_open, // open price
double price_close, // close price
double& profit // variable for obtaining the profit value
);
Parameters
action
[in] Type of the order, can be one of the two values of the ENUM _ORDER_T YPE enumeration:
ORDER_T YPE_BUY or ORDER_T YPE_S ELL.
symbol
[in] Symbol name.
volume
[in] Volume of the trade operation.
price_open
[in] Open price.
price_close
[in] Close price.
profit
[out] The variable, to which the calculated value of the profit will be written in case the function
is successfully executed. The estimated profit value depends on many factors, and can differ in
different mark et environments.
Return Value
The function returns true in case of success ; otherwise it returns false. If an invalid order type is
specified, the function will return false. In order to obtain information about the error, call
GetLastError().
See also
OrderSend(), Order Properties, Trade Operation Types
OrderCheck
The OrderCheck () function check s if there are enough money to execute a required trade operation.
The check results are placed to the fields of the M qlTradeCheckR esult structure.
bool OrderCheck(
MqlTradeRequest& request, // request structure
MqlTradeCheckResult& result // result structure
);
Parameters
request
[in] Pointer to the structure of the M qlTradeR equest type, which describes the required trade
action.
result
[in,out] Pointer to the structure of the M qlTradeCheckR esult type, to which the check result will
be placed.
Return Value
If funds are not enough for the operation, or parameters are filled out incorrectly, the function
returns false. In case of a successful basic check of structures (check of pointers), it returns true.
However, this is not an indication that the requested trade operation is sure to be successfully
executed . For a more detailed description of the function execution result, analyze the fields of the
result structure.
In order to obtain information about the error, call the GetLastError() function.
See also
OrderSend(), Trade Operation Types, Trade R equest Structure, Structure of R equest Check R esults,
Structure of a Trade R equest R esult
OrderSend
The OrderSend() function is used for executing trade operations by sending requests to a trade server.
bool OrderSend(
MqlTradeRequest& request, // query structure
MqlTradeResult& result // structure of the answer
);
Parameters
request
[in] Pointer to a structure of M qlTradeR equest type describing the trade activity of the client.
result
[in,out] Pointer to a structure of M qlTradeR esult type describing the result of trade operation in
case of a successful completion (if true is returned).
Return Value
In case of a successful basic check of structures (index check ing) returns true. However, this is not
a sign of successful execution of a trade operation. For a more detailed description of the
function execution result, analyze the fields of result structure.
Note
The trade requests go through several stages of check ing on a trade server. First of all, it check s if
all the required fields of the request parameter are filled out correctly. If there are no errors, the
server accepts the order for further processing. If the order is successfully accepted by the trade
server, the OrderSend() function returns true.
It is recommended to check the request before sending it to a trade server. To check requests, use
the OrderCheck () function. It check s if there are enough funds to execute the trade operation, and
returns many useful parameters in the results of trade request check ing :
· return code containing information about errors in the check ed request;
· balance value that will appear after the trade operation is executed;
· equity value that will appear after the trade operation is executed;
· floating point value that will appear after the trade operation is executed;
· margin required for the trade operation;
· amount of free equity that will remain after the execution of the trade operation;
· the margin level that will be set after the trade operation is executed;
· comment to the reply code, error description.
W hen sending a mark et order (M qlTradeR equest.action=T RADE_ACTION_DEAL), the successful result
of the OrderSend() function does not mean that the order has been executed (appropriate trades
have been performed). In this case, 'true' means only that the order has been successfully placed in
the trading system for further execution. The trade server can fill in the deal or order field values in
the returned result structure, if it is aware of these data when forming a response to an OrderSend()
call. Generally, event(s) of executing trades corresponding to an order may happen after sending a
response to the OrderSend() call. Therefore, for any type of a trade request, when receiving the
OrderSend() execution result, we should first check the retcode trade server response code and the
retcode_external external system response code (if necessary) available in the obtained result
structure.
Each accepted order is stored on the trade server awaiting processing until one of the conditions for
its execution occurs :
· expiration,
· appearance of an opposite request,
· order execution when the execution price appears,
· a request to cancel the order is received.
At the moment of the order processing, the trade server sends to the terminal a message about the
occurrence of the Trade event, which can be processed by the OnTrade() function.
The result of executing the trade request on a server sent by OrderSend() function can be track ed by
OnTradeTransaction handler. It should be noted that OnTradeTransaction handler will be called
several times when executing one trade request.
For example, when sending a mark et buy order, it is handled, an appropriate buy order is created
for the account, the order is then executed and removed from the list of the open ones, then it is
added to the orders history, an appropriate deal is added to the history and a new position is
created. OnTradeTransaction function will be called for each of these events.
Example:
See also
Trade Operation Types, Trade R equest Structure, Structure of R equest Check R esults, Structure of a
Trade R equest R esult
OrderSendAsync
The OrderSendAsync() function is used for conducting asynchronous trade operations without waiting
for the trade server's response to a sent request. The function is designed for high-frequency trading,
when under the terms of the trading algorithm it is unacceptable to waste time waiting for a response
from the server.
bool OrderSendAsync(
MqlTradeRequest& request, // Request structure
MqlTradeResult& result // Response structure
);
Parameters
request
[in] A pointer to a structure of the M qlTradeR equest type that describes the trade action of the
client.
result
[in,out] A pointer to a structure of the M qlTradeR esult type that describes the result of a trade
operation in case of successful execution of the function (if true is returned).
Return Value
R eturns true if the request is sent to a trade server. In case the request is not sent, it returns false.
In case the request is sent, in the result variable the response code contains
T RADE_RETCODE_PL ACED value (code 10008) – " order placed" . Successful execution means only the
fact of sending, but does not give any guarantee that the request has reached the trade server and
has been accepted for processing. W hen processing the received request, a trade server sends a
reply to a client terminal notifying of change in the current state of positions, orders and deals,
which leads to the generation of the Trade event.
The result of executing the trade request on a server sent by OrderSendAsync() function can be
track ed by OnTradeTransaction handler. It should be noted that OnTradeTransaction handler will be
called several times when executing one trade request.
For example, when sending a mark et buy order, it is handled, an appropriate buy order is created
for the account, the order is then executed and removed from the list of the open ones, then it is
added to the orders history, an appropriate deal is added to the history and a new position is
created. OnTradeTransaction function will be called for each of these events. To get such a data,
the function parameters should be analyzed:
· trans - this parameter gets M qlTradeTransaction structure describing a trade transaction applied
to a trade account;
· request - this parameter gets M qlTradeR equest structure describing the trade request resulted in
a trade transaction;
· result - this parameter gets M qlTradeR esult structure describing a trade request execution result.
Note
In terms of purposes and parameters, the function is similar to OrderSend(), but unlik e it, it is
asynchronous, i.e. does not hold the program operation while waiting for the function execution
result. You can compare the rate of trade operations of these two functions using the sample Expert
Advisor.
Example:
PrintFormat("Sell %s %G lot",_Symbol,volume_min);
SellAsync(volume_min);
//--- unpress the button
ObjectSetInteger(0,"Sell",OBJPROP_STATE,false);
}
ChartRedraw();
}
//---
}
//+------------------------------------------------------------------+
//| Returns the text description of a transaction |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans,
const bool detailed=true)
{
//--- prepare a string for returning from the function
string desc=EnumToString(trans.type)+"\r\n";
//--- all possible data is added in detailed mode
if(detailed)
{
desc+="Symbol: "+trans.symbol+"\r\n";
desc+="Deal ticket: "+(string)trans.deal+"\r\n";
desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
desc+="Order ticket: "+(string)trans.order+"\r\n";
desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
}
//--- return a received string
return desc;
}
//+------------------------------------------------------------------+
//| Returns the text description of the trade request |
//+------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request,
const bool detailed=true)
{
//--- prepare a string for returning from the function
string desc=EnumToString(request.action)+"\r\n";
//--- add all available data in detailed mode
if(detailed)
{
desc+="Symbol: "+request.symbol+"\r\n";
if(ObjectGetInteger(0,"Buy",OBJPROP_TYPE)!=OBJ_BUTTON)
ObjectDelete(0,"Buy");
}
else
ObjectCreate(0,"Buy",OBJ_BUTTON,0,0,0); // create "Buy" button
//--- configure "Buy" button
ObjectSetInteger(0,"Buy",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetInteger(0,"Buy",OBJPROP_XDISTANCE,100);
ObjectSetInteger(0,"Buy",OBJPROP_YDISTANCE,50);
ObjectSetInteger(0,"Buy",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Buy",OBJPROP_YSIZE,30);
ObjectSetString(0,"Buy",OBJPROP_TEXT,"Buy");
ObjectSetInteger(0,"Buy",OBJPROP_COLOR,clrRed);
//--- check presence of the object named "Sell"
if(ObjectFind(0,"Sell")>=0)
{
//--- if the found object is not a button, delete it
if(ObjectGetInteger(0,"Sell",OBJPROP_TYPE)!=OBJ_BUTTON)
ObjectDelete(0,"Sell");
}
else
ObjectCreate(0,"Sell",OBJ_BUTTON,0,0,0); // create "Sell" button
//--- configure "Sell" button
ObjectSetInteger(0,"Sell",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetInteger(0,"Sell",OBJPROP_XDISTANCE,100);
ObjectSetInteger(0,"Sell",OBJPROP_YDISTANCE,100);
ObjectSetInteger(0,"Sell",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Sell",OBJPROP_YSIZE,30);
ObjectSetString(0,"Sell",OBJPROP_TEXT,"Sell");
ObjectSetInteger(0,"Sell",OBJPROP_COLOR,clrBlue);
//--- perform forced update of the chart to see the buttons immediately
ChartRedraw();
//---
}
//+------------------------------------------------------------------+
//| Buy using OrderSendAsync() asynchronous function |
//+------------------------------------------------------------------+
void BuyAsync(double volume)
{
//--- prepare the request
MqlTradeRequest req={0};
req.action =TRADE_ACTION_DEAL;
req.symbol =_Symbol;
req.magic =MagicNumber;
req.volume =0.1;
req.type =ORDER_TYPE_BUY;
req.price =SymbolInfoDouble(req.symbol,SYMBOL_ASK);
req.deviation =10;
req.comment ="Buy using OrderSendAsync()";
MqlTradeResult res={0};
if(!OrderSendAsync(req,res))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
}
//---
}
//+------------------------------------------------------------------+
//| Sell using OrderSendAsync() asynchronous function |
//+------------------------------------------------------------------+
void SellAsync(double volume)
{
//--- prepare the request
MqlTradeRequest req={0};
req.action =TRADE_ACTION_DEAL;
req.symbol =_Symbol;
req.magic =MagicNumber;
req.volume =0.1;
req.type =ORDER_TYPE_SELL;
req.price =SymbolInfoDouble(req.symbol,SYMBOL_BID);
req.deviation =10;
req.comment ="Sell using OrderSendAsync()";
MqlTradeResult res={0};
if(!OrderSendAsync(req,res))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
}
//---
}
//+------------------------------------------------------------------+
PositionsTotal
R eturns the number of open positions.
int PositionsTotal();
Return Value
Note
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
See also
PositionGetSymbol(), PositionSelect(), Position Properties
PositionGetSymbol
R eturns the symbol corresponding to the open position and automatically selects the position for
further work ing with it using functions PositionGetDouble, PositionGetInteger, PositionGetString.
string PositionGetSymbol(
int index // Number in the list of positions
);
Parameters
index
[in] Number of the position in the list of open positions.
Return Value
Value of the string type. If the position was not found, an empty string will be returned. To get an
error code, call the GetLastError() function.
Note
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
See also
PositionsTotal(), PositionSelect(), Position Properties
PositionSelect
Chooses an open position for further work ing with it. R eturns true if the function is successfully
completed. R eturns false in case of failure. To obtain information about the error, call GetLastError().
bool PositionSelect(
string symbol // Symbol name
);
Parameters
symbol
[in] Name of the financial security.
Return Value
Note
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol. In this case, PositionSelect will select a position with the lowest tick et.
Function PositionSelect() copies data about a position into the program environment, and further
calls of PositionGetDouble(), PositionGetInteger() and PositionGetString() return the earlier copied
data. This means that the position itself may no longer exist (or its volume, direction, etc. has
changed), but data of this position still can be obtained. To ensure receipt of fresh data about a
position, it is recommended to call PositionSelect() right before referring to them.
See also
PositionGetSymbol(), PositionsTotal(), Position Properties
PositionSelectByTicket
Selects an open position to work with based on the tick et number specified in the position. If
successful, returns true. R eturns false if the function failed. Call GetLastError() for error details.
bool PositionSelectByTicket(
ulong ticket // Position ticket
);
Parameters
ticket
[in] Position tick et.
Return Value
Note
The PositionSelectByTick et() function copies position data to the program environment. Further calls
of PositionGetDouble(), PositionGetInteger() and PositionGetString() return the previously copied
data. Even if a position does not exist already (or its size, direction etc. has changed), the data may
still be received sometimes. To mak e sure that you receive valid position data, it is recommended
to call PositionSelectByTick et() before you access the data.
See also
PositionGetSymbol(), PositionsTotal(), Position Properties
PositionGetDouble
The function returns the requested property of an open position, pre-selected using PositionGetSymbol
or PositionSelect. The position property must be of the double type. There are 2 variants of the
function.
double PositionGetDouble(
ENUM_POSITION_PROPERTY_DOUBLE property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function execution. If successful, the value
of the property is placed in a receiving variable passed by reference by the last parameter.
bool PositionGetDouble(
ENUM_POSITION_PROPERTY_DOUBLE property_id, // Property identifier
double& double_var // Here we accept the property value
);
Parameters
property_id
[in] Identifier of a position property. The value can be one of the values of the
ENUM _POSITION_PR OPER T Y_DOUBL E enumeration.
double_var
[out] Variable of the double type, accepting the value of the requested property.
Return Value
Note
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
To ensure receipt of fresh data about a position, it is recommended to call PositionSelect() right
before referring to them.
See also
PositionGetSymbol(), PositionSelect(), Position Properties
PositionGetInteger
The function returns the requested property of an open position, pre-selected using PositionGetSymbol
or PositionSelect. The position property should be of datetime, int type. There are 2 variants of the
function.
long PositionGetInteger(
ENUM_POSITION_PROPERTY_INTEGER property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function execution. If successful, the value
of the property is placed in a receiving variables passed by reference by the last parameter.
bool PositionGetInteger(
ENUM_POSITION_PROPERTY_INTEGER property_id, // Property identifier
long& long_var // Here we accept the property value
);
Parameters
property_id
[in] Identifier of a position property. The value can be one of the values of the
ENUM _POSITION_PR OPER T Y_INT EGER enumeration.
long_var
[out] Variable of the long type accepting the value of the requested property.
Return Value
Note
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
To ensure receipt of fresh data about a position, it is recommended to call PositionSelect() right
before referring to them.
Example:
//+------------------------------------------------------------------+
//| Trade function |
//+------------------------------------------------------------------+
void OnTrade()
{
//--- check if a position is present and display the time of its changing
if(PositionSelect(_Symbol))
{
//--- receive position ID for further work
ulong position_ID=PositionGetInteger(POSITION_IDENTIFIER);
Print(_Symbol," position #",position_ID);
//--- receive the time of position forming in milliseconds since 01.01.1970
long create_time_msc=PositionGetInteger(POSITION_TIME_MSC);
PrintFormat("Position #%d POSITION_TIME_MSC = %i64 milliseconds => %s",position_ID,
create_time_msc,TimeToString(create_time_msc/1000));
//--- receive the time of the position's last change in seconds since 01.01.1970
long update_time_sec=PositionGetInteger(POSITION_TIME_UPDATE);
PrintFormat("Position #%d POSITION_TIME_UPDATE = %i64 seconds => %s",
position_ID,update_time_sec,TimeToString(update_time_sec));
//--- receive the time of the position's last change in milliseconds since 01.01.1970
long update_time_msc=PositionGetInteger(POSITION_TIME_UPDATE_MSC);
PrintFormat("Position #%d POSITION_TIME_UPDATE_MSC = %i64 milliseconds => %s",
position_ID,update_time_msc,TimeToString(update_time_msc/1000));
}
//---
}
See also
PositionGetSymbol(), PositionSelect(), Position Properties
PositionGetString
The function returns the requested property of an open position, pre-selected using PositionGetSymbol
or PositionSelect. The position property should be of the string type. There are 2 variants of the
function.
string PositionGetString(
ENUM_POSITION_PROPERTY_STRING property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function execution. If successful, the value
of the property is placed in a receiving variables passed by reference by the last parameter.
bool PositionGetString(
ENUM_POSITION_PROPERTY_STRING property_id, // Property identifier
string& string_var // Here we accept the property value
);
Parameters
property_id
[in] Identifier of a position property. The value can be one of the values of the
ENUM _POSITION_PR OPER T Y_ST R ING enumeration.
string_var
[out] Variable of the string type accepting the value of the requested property.
Return Value
Value of the string type. If the function fails, an empty string is returned.
Note
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
To ensure receipt of fresh data about a position, it is recommended to call PositionSelect() right
before referring to them.
See also
PositionGetSymbol(), PositionSelect(), Position Properties
PositionGetTicket
The function returns the tick et of a position with the specified index in the list of open positions and
automatically selects the position to work with using functions PositionGetDouble, PositionGetInteger,
PositionGetString.
ulong PositionGetTicket(
int index // The number of a position in the list
);
Parameters
index
[in] The index of a position in the list of open positions, numeration starts with 0.
Return Value
Note
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
To ensure receipt of fresh data about a position, it is recommended to call PositionSelect() right
before referring to them.
See also
PositionGetSymbol(), PositionSelect(), Position Properties
OrdersTotal
R eturns the number of current orders.
int OrdersTotal();
Return Value
Note
Do not confuse current pending orders with positions, which are also displayed on the " Trade" tab of
the " Toolbox " of the client terminal. An order is a request to conduct a transaction, while a position
is a result of one or more deals.
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
See also
OrderSelect(), OrderGetTick et(), Order Properties
OrderGetTicket
R eturns tick et of a corresponding order and automatically selects the order for further work ing with it
using functions.
ulong OrderGetTicket(
int index // Number in the list of orders
);
Parameters
index
[in] Number of an order in the list of current orders.
Return Value
Note
Do not confuse current pending orders with positions, which are also displayed on the " Trade" tab of
the " Toolbox " of the client terminal. An order is a request to conduct a transaction, while a position
is a result of one or more deals.
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
Function OrderGetTick et() copies data about an order into the program environment, and further
calls of OrderGetDouble(), OrderGetInteger(), OrderGetString() return the earlier copied data. This
means that the order itself may no longer exist (or its open price, Stop Loss /Tak e Profit levels or
expiration has changed), but data of this order still can be obtained. To ensure receipt of fresh data
about an order, it is recommended to call OrderGetTick et() right before referring to them.
Example:
void OnStart()
{
//--- variables for returning values from order properties
ulong ticket;
double open_price;
double initial_volume;
datetime time_setup;
string symbol;
string type;
long order_magic;
long positionID;
//--- number of current pending orders
uint total=OrdersTotal();
See also
OrdersTotal(), OrderSelect(), OrderGetInteger()
OrderSelect
Selects an order to work with. R eturns true if the function has been successfully completed. R eturns
false if the function completion has failed. For more information about an error call GetLastError().
bool OrderSelect(
ulong ticket // Order ticket
);
Parameters
ticket
[in] Order tick et.
Return Value
Note
Do not confuse current pending orders with positions, which are also displayed on the " Trade" tab of
the " Toolbox " of the client terminal.
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
Function OrderSelect() copies data about an order into the program environment, and further calls
of OrderGetDouble(), OrderGetInteger(), OrderGetString() return the earlier copied data. This
means that the order itself may no longer exist (or its open price, Stop Loss /Tak e Profit levels or
expiration has changed), but data of this order still can be obtained. To ensure receipt of fresh data
about an order, it is recommended to call OrderSelect() right before referring to them.
See also
OrderGetInteger(), OrderGetDouble(), OrderGetString(), OrderCalcProfit(), OrderGetTick et(), Order
Properties
OrderGetDouble
R eturns the requested property of an order, pre-selected using OrderGetTick et or OrderSelect. The
order property must be of the double type. There are 2 variants of the function.
double OrderGetDouble(
ENUM_ORDER_PROPERTY_DOUBLE property_id // Property identifier
);
2. R eturns true or false, depending on the success of a function. If successful, the value of the
property is placed in a target variable passed by reference by the last parameter.
bool OrderGetDouble(
ENUM _ORDER_PR OPER T Y_DOUBL E property_id, // Property identifier
double& double_var // Here we accept the property value
);
Parameters
property_id
[in] Identifier of the order property. The value can be one of the values of the
ENUM _ORDER_PR OPER T Y_DOUBL E enumeration.
double_var
[out] Variable of the double type that accepts the value of the requested property.
Return Value
Note
Do not confuse current pending orders with positions, which are also displayed on the " Trade" tab of
the " Toolbox " of the client terminal.
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
To ensure receipt of fresh data about an order, it is recommended to call OrderSelect() right before
referring to them.
See also
OrdersTotal(), OrderGetTick et(), Order Properties
OrderGetInteger
R eturns the requested order property, pre-selected using OrderGetTick et or OrderSelect. Order
property must be of the datetime, int type. There are 2 variants of the function.
long OrderGetInteger(
ENUM_ORDER_PROPERTY_INTEGER property_id // Property identifier
);
2. R eturns true or false depending on the success of the function. If successful, the value of the
property is placed into a target variable passed by reference by the last parameter.
bool OrderGetInteger(
ENUM_ORDER_PROPERTY_INTEGER property_id, // Property identifier
long& long_var // Here we accept the property value
);
Parameters
property_id
[in] Identifier of the order property. The value can be one of the values of the
ENUM _ORDER_PR OPER T Y_INT EGER enumeration.
long_var
[out] Variable of the long type that accepts the value of the requested property.
Return Value
Note
Do not confuse current pending orders with positions, which are also displayed on the " Trade" tab of
the " Toolbox " of the client terminal.
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
To ensure receipt of fresh data about an order, it is recommended to call OrderSelect() right before
referring to them.
See also
OrdersTotal(), OrderGetTick et(), Order Properties
OrderGetString
R eturns the requested order property, pre-selected using OrderGetTick et or OrderSelect. The order
property must be of the string type. There are 2 variants of the function.
string OrderGetString(
ENUM_ORDER_PROPERTY_STRING property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function. If successful, the value of the
property is placed into a target variable passed by reference by the last parameter.
bool OrderGetString(
ENUM_ORDER_PROPERTY_STRING property_id, // Property identifier
string& string_var // Here we accept the property value
);
Parameters
property_id
[in] Identifier of the order property. The value can be one of the values of the
ENUM _ORDER_PR OPER T Y_ST R ING enumeration.
string_var
[out] Variable of the string type that accepts the value of the requested property.
Return Value
Note
Do not confuse current pending orders with positions, which are also displayed on the " Trade" tab of
the " Toolbox " of the client terminal.
For the " netting " interpretation of positions (ACCOUNT _M ARGIN_MODE_RET AIL _NETTING and
ACCOUNT _M ARGIN_MODE_EXCHANGE), only one position can exist for a symbol at any moment of
time. This position is a result of one or more deals. Do not confuse positions with valid pending
orders, which are also displayed on the Trading tab of the Toolbox window.
If individual positions are allowed (ACCOUNT _M ARGI N_MODE_RET AIL _HEDGI NG), multiple positions
can be open for one symbol.
To ensure receipt of fresh data about an order, it is recommended to call OrderSelect() right before
referring to them.
See also
OrdersTotal(), OrderGetTick et(), Order Properties
HistorySelect
R etrieves the history of deals and orders for the specified period of server time.
bool HistorySelect(
datetime from_date, // From date
datetime to_date // To date
);
Parameters
from_date
[in] Start date of the request.
to_date
[in] End date of the request.
Return Value
Note
H istorySelect() creates a list of orders and a list of trades in a mql5-program, for further referring
to the list elements using corresponding functions. The deals list size can be returned using the
H istoryDealsTotal() function; the size of the list of orders in the history can be obtained using
H istoryOrdersTotal(). Selection in the list of orders should be better performed by
H istoryOrderGetTick et(), for items in the list of deals H istoryDealGetTick et() suits better.
After using H istoryOrderSelect(), the list of history orders available to the mql5 program is reset and
filled again by the found order, if the search of an order by the tick et has been completed
successfully. The same applies to the list of deals available to the mql5 program - it is reset by
H istoryDealSelect() and filled again in case of a successful receipt of a deal by tick et number.
Example:
void OnStart()
{
color BuyColor =clrBlue;
color SellColor=clrRed;
//--- request trade history
HistorySelect(0,TimeCurrent());
//--- create objects
string name;
uint total=HistoryDealsTotal();
ulong ticket=0;
double price;
double profit;
datetime time;
string symbol;
long type;
long entry;
//--- for all deals
for(uint i=0;i<total;i++)
{
//--- try to get deals ticket
if((ticket=HistoryDealGetTicket(i))>0)
{
//--- get deals properties
price =HistoryDealGetDouble(ticket,DEAL_PRICE);
time =(datetime)HistoryDealGetInteger(ticket,DEAL_TIME);
symbol=HistoryDealGetString(ticket,DEAL_SYMBOL);
type =HistoryDealGetInteger(ticket,DEAL_TYPE);
entry =HistoryDealGetInteger(ticket,DEAL_ENTRY);
profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
//--- only for current symbol
if(price && time && symbol==Symbol())
{
//--- create price object
name="TradeHistory_Deal_"+string(ticket);
if(entry) ObjectCreate(0,name,OBJ_ARROW_RIGHT_PRICE,0,time,price,0,0);
else ObjectCreate(0,name,OBJ_ARROW_LEFT_PRICE,0,time,price,0,0);
//--- set object properties
ObjectSetInteger(0,name,OBJPROP_SELECTABLE,0);
ObjectSetInteger(0,name,OBJPROP_BACK,0);
ObjectSetInteger(0,name,OBJPROP_COLOR,type?BuyColor:SellColor);
if(profit!=0) ObjectSetString(0,name,OBJPROP_TEXT,"Profit: "+string(profit));
}
}
}
//--- apply on chart
ChartRedraw();
}
See also
H istoryOrderSelect(), H istoryDealSelect()
HistorySelectByPosition
R etrieves the history of deals and orders having the specified position identifier.
bool HistorySelectByPosition(
long position_id // position identifier - POSITION_IDENTIFIER
);
Parameters
position_id
[in] Position identifier that is set to every executed order and every deal.
Return Value
Note
Do not confuse orders of a trading history with current pending orders that appear on the " Trade"
tab of the " Toolbox " bar. The list of orders that were canceled or have led to a transaction, can be
viewed in the "H istory" tab of " Toolbox " of the client terminal.
H istorySelectByPosition() creates in a mql5 program a list of orders and a list of deals with a
specified position identifier for further reference to the elements of the list using the appropriate
functions. To k now the size of the list of deals, use function H istoryDealsTotal(), the size of the list
of orders in the history can be obtained using H istoryOrdersTotal(). To run through elements of the
orders list, use H istoryOrderGetTick et(), for elements of the deals list - H istoryDealGetTick et().
After using H istoryOrderSelect(), list of history orders available to the mql5 program is reset and
filled again with the found order, if search of an order by its tick et was successful. The same refers
to the list of deals available to the mql5 program - it is reset by function H istoryDealSelect() and is
filled out again if a deal was found successfully by the tick et number.
See also
H istorySelect(), H istoryOrderGetTick et(), Order Properties
HistoryOrderSelect
Selects an order from the history for further calling it through appropriate functions. It returns true if
the function has been successfully completed. R eturns false if the function has failed. For more details
on error call GetLastError().
bool HistoryOrderSelect(
ulong ticket // Order ticket
);
Parameters
ticket
[in] Order tick et.
Return Value
Note
Do not confuse orders of a trading history with current pending orders that appear on the " Trade"
tab of the " Toolbox " bar. The list of orders that were canceled or have led to a transaction, can be
viewed in the "H istory" tab of " Toolbox " of the client terminal.
H istoryOrderSelect() clears in a mql5-program the list of orders from a history, available for calls,
and copies to it a single order, if the execution of H istoryOrderSelect () has been completed
successfully. If you need to go through all deals selected by H istorySelect(), you should better use
H istoryOrderGetTick et().
See also
H istorySelect(), H istoryOrderGetTick et(), Order Properties
HistoryOrdersTotal
R eturns the number of orders in the history. Prior to calling H istoryOrdersTotal(), first it is necessary
to receive the history of deals and orders using the H istorySelect() or H istorySelectByPosition()
function.
int HistoryOrdersTotal();
Return Value
Note
Do not confuse orders of a trading history with current pending orders that appear on the " Trade"
tab of the " Toolbox " bar. The list of orders that were canceled or have led to a transaction, can be
viewed in the "H istory" tab of " Toolbox " of the client terminal.
See also
H istorySelect(), H istoryOrderSelect(), H istoryOrderGetTick et(), Order Properties
HistoryOrderGetTicket
R eturn the tick et of a corresponding order in the history. Prior to calling H istoryOrderGetTick et(), first
it is necessary to receive the history of deals and orders using the H istorySelect() or
H istorySelectByPosition() function.
ulong HistoryOrderGetTicket(
int index // Number in the list of orders
);
Parameters
index
[in] Number of the order in the list of orders.
Return Value
Note
Do not confuse orders of a trading history with current pending orders that appear on the " Trade"
tab of the " Toolbox " bar. The list of orders that were canceled or have led to a transaction, can be
viewed in the "H istory" tab of " Toolbox " of the client terminal.
Example:
void OnStart()
{
datetime from=0;
datetime to=TimeCurrent();
//--- request the entire history
HistorySelect(from,to);
//--- variables for returning values from order properties
ulong ticket;
double open_price;
double initial_volume;
datetime time_setup;
datetime time_done;
string symbol;
string type;
long order_magic;
long positionID;
//--- number of current pending orders
uint total=HistoryOrdersTotal();
//--- go through orders in a loop
for(uint i=0;i<total;i++)
{
//--- return order ticket by its position in the list
if((ticket=HistoryOrderGetTicket(i))>0)
{
//--- return order properties
open_price =HistoryOrderGetDouble(ticket,ORDER_PRICE_OPEN);
time_setup =(datetime)HistoryOrderGetInteger(ticket,ORDER_TIME_SETUP);
time_done =(datetime)HistoryOrderGetInteger(ticket,ORDER_TIME_DONE);
symbol =HistoryOrderGetString(ticket,ORDER_SYMBOL);
order_magic =HistoryOrderGetInteger(ticket,ORDER_MAGIC);
positionID =HistoryOrderGetInteger(ticket,ORDER_POSITION_ID);
initial_volume=HistoryOrderGetDouble(ticket,ORDER_VOLUME_INITIAL);
type =GetOrderType(HistoryOrderGetInteger(ticket,ORDER_TYPE));
//--- prepare and show information about the order
printf("#ticket %d %s %G %s at %G was set up at %s => done at %s, pos ID=%d",
ticket, // order ticket
type, // type
initial_volume, // placed volume
symbol, // symbol
open_price, // specified open price
TimeToString(time_setup),// time of order placing
TimeToString(time_done), // time of order execution or deletion
positionID // ID of a position , to which the deal of the order is in
);
}
}
//---
}
//+------------------------------------------------------------------+
//| Returns the string name of the order type |
//+------------------------------------------------------------------+
string GetOrderType(long type)
{
string str_type="unknown operation";
switch(type)
{
case (ORDER_TYPE_BUY): return("buy");
case (ORDER_TYPE_SELL): return("sell");
case (ORDER_TYPE_BUY_LIMIT): return("buy limit");
case (ORDER_TYPE_SELL_LIMIT): return("sell limit");
case (ORDER_TYPE_BUY_STOP): return("buy stop");
case (ORDER_TYPE_SELL_STOP): return("sell stop");
case (ORDER_TYPE_BUY_STOP_LIMIT): return("buy stop limit");
case (ORDER_TYPE_SELL_STOP_LIMIT):return("sell stop limit");
}
return(str_type);
}
See also
H istorySelect(), H istoryOrdersTotal(), H istoryOrderSelect(), Order Properties
HistoryOrderGetDouble
R eturns the requested order property. The order property must be of the double type. There are 2
variants of the function.
double HistoryOrderGetDouble(
ulong ticket_number, // Ticket
ENUM_ORDER_PROPERTY_DOUBLE property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function. If successful, the value of the
property is placed into a target variable passed by reference by the last parameter.
bool HistoryOrderGetDouble(
ulong ticket_number, // Ticket
ENUM_ORDER_PROPERTY_DOUBLE property_id, // Property identifier
double& double_var // Here we accept the property value
);
Parameters
ticket_number
[in] Order tick et.
property_id
[in] Identifier of the order property. The value can be one of the values of the
ENUM _ORDER_PR OPER T Y_DOUBL E enumeration.
double_var
[out] Variable of the double type that accepts the value of the requested property.
Return Value
Note
Do not confuse orders of a trading history with current pending orders that appear on the " Trade"
tab of the " Toolbox " bar. The list of orders that were canceled or have led to a transaction, can be
viewed in the "H istory" tab of " Toolbox " of the client terminal.
See also
H istorySelect(), H istoryOrdersTotal(), H istoryOrderSelect(), Order Properties
HistoryOrderGetInteger
R eturns the requested property of an order. The order property must be of datetime, int type. There
are 2 variants of the function.
long HistoryOrderGetInteger(
ulong ticket_number, // Ticket
ENUM_ORDER_PROPERTY_INTEGER property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function. If successful, the value of the
property is placed into a target variable passed by reference by the last parameter.
bool HistoryOrderGetInteger(
ulong ticket_number, // Ticket
ENUM_ORDER_PROPERTY_INTEGER property_id, // Property identifier
long& long_var // Here we accept the property value
);
Parameters
ticket_number
[in] Order tick et.
property_id
[in] Identifier of the order property. The value can be one of the values of the
ENUM _ORDER_PR OPER T Y_INT EGER enumeration.
long_var
[out] Variable of the long type that accepts the value of the requested property.
Return Value
Note
Do not confuse orders of a trading history with current pending orders that appear on the " Trade"
tab of the " Toolbox " bar. The list of orders that were canceled or have led to a transaction, can be
viewed in the "H istory" tab of " Toolbox " of the client terminal.
Example:
//+------------------------------------------------------------------+
//| Trade function |
//+------------------------------------------------------------------+
void OnTrade()
{
//--- receive the last order's ticket from week's trading history
ulong last_order=GetLastOrderTicket();
if(HistoryOrderSelect(last_order))
{
//--- time of placing an order in milliseconds since 01.01.1970
long time_setup_msc=HistoryOrderGetInteger(last_order,ORDER_TIME_SETUP_MSC);
PrintFormat("Order #%d ORDER_TIME_SETUP_MSC=%i64 => %s",
last_order,time_setup_msc,TimeToString(time_setup_msc/1000));
//--- order execution/cancellation time in milliseconds since 01.01.1970
long time_done_msc=HistoryOrderGetInteger(last_order,ORDER_TIME_DONE_MSC);
PrintFormat("Order #%d ORDER_TIME_DONE_MSC=%i64 => %s",
last_order,time_done_msc,TimeToString(time_done_msc/1000));
}
else // notify on failure
PrintFormat("HistoryOrderSelect() failed for #%d. Eror code=%d",
last_order,GetLastError());
//---
}
//+------------------------------------------------------------------+
//| Returns the last order ticket in history or -1 |
//+------------------------------------------------------------------+
ulong GetLastOrderTicket()
{
//--- request history for the last 7 days
if(!GetTradeHistory(7))
{
//--- notify on unsuccessful call and return -1
Print(__FUNCTION__," HistorySelect() returned false");
return -1;
}
//---
ulong first_order,last_order,orders=HistoryOrdersTotal();
//--- work with orders if there are any
if(orders>0)
{
Print("Orders = ",orders);
first_order=HistoryOrderGetTicket(0);
PrintFormat("first_order = %d",first_order);
if(orders>1)
{
last_order=HistoryOrderGetTicket((int)orders-1);
PrintFormat("last_order = %d",last_order);
return last_order;
}
return first_order;
}
//--- no order found, return -1
return -1;
}
//+--------------------------------------------------------------------------+
//| Requests history for the last days and returns false in case of failure |
//+--------------------------------------------------------------------------+
bool GetTradeHistory(int days)
{
//--- set a week period to request trade history
datetime to=TimeCurrent();
datetime from=to-days*PeriodSeconds(PERIOD_D1);
ResetLastError();
//--- make a request and check the result
if(!HistorySelect(from,to))
{
Print(__FUNCTION__," HistorySelect=false. Error code=",GetLastError());
return false;
}
//--- history received successfully
return true;
}
See also
H istorySelect(), H istoryOrdersTotal(), H istoryOrderSelect(), Order Properties
HistoryOrderGetString
R eturns the requested property of an order. The order property must be of the string type. There are 2
variants of the function.
string HistoryOrderGetString(
ulong ticket_number, // Ticket
ENUM_ORDER_PROPERTY_STRING property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function. If successful, the value of the
property is placed into a target variable passed by reference by the last parameter.
bool HistoryOrderGetString(
ulong ticket_number, // Ticket
ENUM_ORDER_PROPERTY_STRING property_id, // Property identifier
string& string_var // Here we accept the property value
);
Parameters
ticket_number
[in] Order tick et.
property_id
[in] Identifier of the order property. The value can be one of the values of the
ENUM _ORDER_PR OPER T Y_ST R ING enumeration.
string_var
[out] Variable of the string type.
Return Value
Note
Do not confuse orders of a trading history with current pending orders that appear on the " Trade"
tab of the " Toolbox " bar. The list of orders that were canceled or have led to a transaction, can be
viewed in the "H istory" tab of " Toolbox " of the client terminal.
See also
H istorySelect(), H istoryOrdersTotal(), H istoryOrderSelect(), Order Properties
HistoryDealSelect
Selects a deal in the history for further calling it through appropriate functions. It returns true if the
function has been successfully completed. R eturns false if the function has failed. For more details on
error call GetLastError().
bool HistoryDealSelect(
ulong ticket // Deal ticket
);
Parameters
ticket
[in] Deal tick et.
Return Value
Note
Do not confuse orders, deals and positions. Each deal is the result of the execution of an order, each
position is the summary result of one or more deals.
H istoryDealSelect() clears in a mql5-program the list of deals available for reference, and copies the
single deal, if the execution of H istoryDealSelect() has been completed successfully. If you need to
go through all deals selected by the H istorySelect() function, you should better use
H istoryDealGetTick et().
See also
H istorySelect(), H istoryDealGetTick et(), Deal Properties
HistoryDealsTotal
R eturns the number of deal in history. Prior to calling H istoryDealsTotal(), first it is necessary to
receive the history of deals and orders using the H istorySelect() or H istorySelectByPosition() function.
int HistoryDealsTotal();
Return Value
Note
Do not confuse orders, deals and positions. Each deal is the result of the execution of an order, each
position is the summary result of one or more deals.
See also
H istorySelect(), H istoryDealGetTick et(), Deal Properties
HistoryDealGetTicket
The function selects a deal for further processing and returns the deal tick et in history. Prior to calling
H istoryDealGetTick et(), first it is necessary to receive the history of deals and orders using the
H istorySelect() or H istorySelectByPosition() function.
ulong HistoryDealGetTicket(
int index // ticket deal
);
Parameters
index
[in] Number of a deal in the list of deals
Return Value
Note
Do not confuse orders, deals and positions. Each deal is the result of the execution of an order, each
position is the summary result of one or more deals.
Example:
void OnStart()
{
ulong deal_ticket; // deal ticket
ulong order_ticket; // ticket of the order the deal was executed on
datetime transaction_time; // time of a deal execution
long deal_type ; // type of a trade operation
long position_ID; // position ID
string deal_description; // operation description
double volume; // operation volume
string symbol; // symbol of the deal
//--- set the start and end date to request the history of deals
datetime from_date=0; // from the very beginning
datetime to_date=TimeCurrent();// till the current moment
//--- request the history of deals in the specified period
HistorySelect(from_date,to_date);
//--- total number in the list of deals
int deals=HistoryDealsTotal();
//--- now process each trade
for(int i=0;i<deals;i++)
{
deal_ticket= HistoryDealGetTicket(i);
volume= HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
transaction_time=(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
order_ticket= HistoryDealGetInteger(deal_ticket,DEAL_ORDER);
deal_type= HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
symbol= HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
position_ID= HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
deal_description= GetDealDescription(deal_type,volume,symbol,order_ticket,position_I
//--- perform fine formatting for the deal number
string print_index=StringFormat("% 3d",i);
//--- show information on the deal
Print(print_index+": deal #",deal_ticket," at ",transaction_time,deal_description);
}
}
//+------------------------------------------------------------------+
//| Returns the string description of the operation |
//+------------------------------------------------------------------+
string GetDealDescription(long deal_type,double volume,string symbol,long ticket,long pos_ID)
{
string descr;
//---
switch(deal_type)
{
case DEAL_TYPE_BALANCE: return ("balance");
case DEAL_TYPE_CREDIT: return ("credit");
case DEAL_TYPE_CHARGE: return ("charge");
case DEAL_TYPE_CORRECTION: return ("correction");
case DEAL_TYPE_BUY: descr="buy"; break;
case DEAL_TYPE_SELL: descr="sell"; break;
case DEAL_TYPE_BONUS: return ("bonus");
case DEAL_TYPE_COMMISSION: return ("additional commission");
case DEAL_TYPE_COMMISSION_DAILY: return ("daily commission");
case DEAL_TYPE_COMMISSION_MONTHLY: return ("monthly commission");
case DEAL_TYPE_COMMISSION_AGENT_DAILY: return ("daily agent commission");
case DEAL_TYPE_COMMISSION_AGENT_MONTHLY: return ("monthly agent commission");
case DEAL_TYPE_INTEREST: return ("interest rate");
case DEAL_TYPE_BUY_CANCELED: descr="cancelled buy deal"; break;
case DEAL_TYPE_SELL_CANCELED: descr="cancelled sell deal"; break;
}
descr=StringFormat("%s %G %s (order #%d, position ID %d)",
descr, // current description
volume, // deal volume
symbol, // deal symbol
ticket, // ticket of the order that caused the deal
pos_ID // ID of a position, in which the deal is included
);
return(descr);
//---
}
See also
H istorySelect(), H istoryDealsTotal(), H istoryDealSelect(), Deal Properties
HistoryDealGetDouble
R eturns the requested property of a deal. The deal property must be of the double type. There are 2
variants of the function.
double HistoryDealGetDouble(
ulong ticket_number, // Ticket
ENUM_DEAL_PROPERTY_DOUBLE property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function. If successful, the value of the
property is placed into a target variable passed by reference by the last parameter.
bool HistoryDealGetDouble(
ulong ticket_number, // Ticket
ENUM_DEAL_PROPERTY_DOUBLE property_id, // Property identifier
double& double_var // Here we accept the property value
);
Parameters
ticket_number
[in] Deal tick et.
property_id
[in] Identifier of a deal property. The value can be one of the values of the
ENUM _DEAL _PR OPER T Y_DOUBL E enumeration.
double_var
[out] Variable of the double type that accepts the value of the requested property.
Return Value
Note
Do not confuse orders, deals and positions. Each deal is the result of the execution of an order, each
position is the summary result of one or more deals.
See also
H istorySelect(), H istoryDealsTotal(), H istoryDealGetTick et(), Deal Properties
HistoryDealGetInteger
R eturns the requested property of a deal. The deal property must be of the datetime, int type. There
are 2 variants of the function.
long HistoryDealGetInteger(
ulong ticket_number, // Ticket
ENUM_DEAL_PROPERTY_INTEGER property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function. If successful, the value of the
property is placed into a target variable passed by reference by the last parameter.
bool HistoryDealGetInteger(
ulong ticket_number, // Ticket
ENUM_DEAL_PROPERTY_INTEGER property_id, // Property identifier
long& long_var // Here we accept the property value
);
Parameters
ticket_number
[in] Trade tick et.
property_id
[in] Identifier of the deal property. The value can be one of the values of the
ENUM _DEAL _PR OPER T Y_INT EGER enumeration.
long_var
[out] Variable of the long type that accepts the value of the requested property.
Return Value
Note
Do not confuse orders, deals and positions. Each deal is the result of the execution of an order, each
position is the summary result of one or more deals.
Example:
//+------------------------------------------------------------------+
//| Trade function |
//+------------------------------------------------------------------+
void OnTrade()
{
//--- receive the last deal's ticket from week's trading history
ulong last_deal=GetLastDealTicket();
if(HistoryDealSelect(last_deal))
{
ResetLastError();
//--- make a request and check the result
if(!HistorySelect(from,to))
{
Print(__FUNCTION__," HistorySelect=false. Error code=",GetLastError());
return false;
}
//--- history received successfully
return true;
}
See also
H istoryDealsTotal(), H istorySelect(), H istoryDealGetTick et(), Deal Properties
HistoryDealGetString
R eturns the requested property of a deal. The deal property must be of the string type. There are 2
variants of the function.
string HistoryDealGetString(
ulong ticket_number, // Ticket
ENUM_DEAL_PROPERTY_STRING property_id // Property identifier
);
2. R eturns true or false, depending on the success of the function. If successful, the value of the
property is placed into a target variable passed by reference by the last parameter.
bool HistoryDealGetString(
ulong ticket_number, // Ticket
ENUM_DEAL_PROPERTY_STRING property_id, // Property identifier
string& string_var // Here we accept the property value
);
Parameters
ticket_number
[in] Deal tick et.
property_id
[in] Identifier of the deal property. The value can be one of the values of the
ENUM _DEAL _PR OPER T Y_ST R ING enumeration.
string_var
[out] Variable of the string type that accepts the value of the requested property.
Return Value
Note
Do not confuse orders, deals and positions. Each deal is the result of the execution of an order, each
position is the summary result of one or more deals.
See also
H istoryDealsTotal(), H istorySelect(), H istoryDealGetTick et(), Deal Properties
Trade Signals
This is the group of functions intended for managing trade signals. The functions allow:
· subscribe and unsubscribe to the signal copying using MQL5 language functions.
Function Action
SignalBaseGetDouble
R eturns the value of double type property for selected signal.
double SignalBaseGetDouble(
ENUM_SIGNAL_BASE_DOUBLE property_id, // property identifier
);
Parameters
property_id
[in] Signal property identifier. The value can be one of the values of the
ENUM _SIGNAL _BAS E_DOUBL E enumeration.
Return Value
SignalBaseGetInteger
R eturns the value of integer type property for selected signal.
long SignalBaseGetInteger(
ENUM_SIGNAL_BASE_INTEGER property_id, // property identifier
);
Parameters
property_id
[in] Signal property identifier. The value can be one of the values of the
ENUM _SIGNAL _BAS E_INT EGER enumeration.
Return Value
SignalBaseGetString
R eturns the value of string type property for selected signal.
string SignalBaseGetString(
ENUM_SIGNAL_BASE_STRING property_id, // property identifier
);
Parameters
property_id
[in] Signal property identifier. The value can be one of the values of the
ENUM _SIGNAL _BAS E_ST R ING enumeration.
Return Value
SignalBaseSelect
Selects a signal from signals, available in terminal for further work ing with it.
bool SignalBaseSelect(
int index // signal index
);
Parameters
index
[in] Signal index in base of trading signals.
Return Value
R eturns true if successful, otherwise returns false. To read more about the error call GetLastError().
Example:
void OnStart()
{
//--- get total amount of signals in the terminal
int total=SignalBaseTotal();
//--- process all signals
for(int i=0;i<total;i++)
{
//--- select the signal by index
if(SignalBaseSelect(i))
{
//--- get signal properties
long id =SignalBaseGetInteger(SIGNAL_BASE_ID); // signal id
long pips =SignalBaseGetInteger(SIGNAL_BASE_PIPS); // profit in pips
long subscr=SignalBaseGetInteger(SIGNAL_BASE_SUBSCRIBERS); // number of subscribers
string name =SignalBaseGetString(SIGNAL_BASE_NAME); // signal name
double price =SignalBaseGetDouble(SIGNAL_BASE_PRICE); // signal price
string curr =SignalBaseGetString(SIGNAL_BASE_CURRENCY); // signal currency
//--- print all profitable free signals with subscribers
if(price==0.0 && pips>0 && subscr>0)
PrintFormat("id=%d, name=\"%s\", currency=%s, pips=%d, subscribers=%d",id,name,curr,pip
}
else PrintFormat("Error in call of SignalBaseSelect. Error code=%d",GetLastError());
}
}
SignalBaseTotal
R eturns the total amount of signals, available in terminal.
int SignalBaseTotal();
Return Value
SignalInfoGetDouble
R eturns the value of double type property of signal copy settings.
double SignalInfoGetDouble(
ENUM_SIGNAL_INFO_DOUBLE property_id, // property identifier
);
Parameters
property_id
[in] Signal copy settings property identifier. The value can be one of the values of the
ENUM _SIGNAL _INFO_DOUBL E enumeration.
Return Value
SignalInfoGetInteger
R eturns the value of integer type property of signal copy settings.
long SignalInfoGetInteger(
ENUM_SIGNAL_INFO_INTEGER property_id, // property identifier
);
Parameters
property_id
[in] Signal copy settings property identifier. The value can be one of the values of the
ENUM _SIGNAL _INFO_INT EGER enumeration.
Return Value
SignalInfoGetString
R eturns the value of string type property of signal copy settings.
string SignalInfoGetString(
ENUM_SIGNAL_INFO_STRING property_id, // property identifier
);
Parameters
property_id
[in] Signal copy settings property identifier. The value can be one of the values of the
ENUM _SIGNAL _INFO_ST R ING enumeration.
Return Value
SignalInfoSetDouble
Sets the value of double type property of signal copy settings.
bool SignalInfoSetDouble(
ENUM_SIGNAL_INFO_DOUBLE property_id, // property identifier
double value // new value
);
Parameters
property_id
[in] Signal copy settings property identifier. The value can be one of the values of the
ENUM _SIGNAL _INFO_DOUBL E enumeration.
value
[in] The value of signal copy settings property.
Return Value
R eturns true if property has been changed, otherwise returns false. To read more about the error
call GetLastError().
SignalInfoSetInteger
Sets the value of integer type property of signal copy settings.
bool SignalInfoSetInteger(
ENUM_SIGNAL_INFO_INTEGER property_id, // property identifier
long value // new value
);
Parameters
property_id
[in] Signal copy settings property identifier. The value can be one of the values of the
ENUM _SIGNAL _INFO_INT EGER enumeration.
value
[in] The value of signal copy settings property.
Return Value
R eturns true if property has been changed, otherwise returns false. To read more about the error
call GetLastError().
SignalSubscribe
Subscribes to the trading signal.
bool SignalSubscribe(
long signal_id // signal id
);
Parameters
signal_id
[in] Signal identifier.
Return Value
R eturns true if subscription was successful, otherwise returns false. To read more about the error
call GetLastError().
SignalUnsubscribe
Cancels subscription.
bool SignalUnsubscribe();
Return Value
R eturns true if subscription has been canceled successfully, otherwise returns false. To read more
about the error call GetLastError().
Network functions
MQL5 programs can exchange data with remote servers, as well as send push notifications, emails and
data via FTP.
· The Sock et* group of functions allows establishing a TCP connection (including a secure TLS) with a
remote host via system sock ets. The operation principle is simple: create a sock et, connect to the
server and start reading and writing data.
· The W ebR equest function is designed to work with web resources and allows sending H TTP requests
(including GET and POST) easily.
· SendFTP, SendMail and SendNotification are more simple functions for sending files, emails and
mobile notifications.
For end-user security, the list of allowed IP addresses is implemented on the client terminal side. The
list contains IP addresses the MQL5 program is allowed to connect to via the Sock et* and W ebR equest
functions. For example, if the program needs to connect to https ://www.someserver.com, this
address should be explicitly indicated by a terminal user in the list. An address cannot be added
programmatically.
Add an explicit message to the MQL5 program to notify a user of the need for additional configuration.
You can do that via #property description, Alert or Print.
Function Action
Sock etIs R eadable Get a number of bytes that can be read from a
sock et
Sock etTimeouts Set timeouts for receiving and sending data for
a sock et system object
Sock etTls R eadAvailable R ead all available data from secure TLS
connection
SocketCreate
Create a sock et with specified flags and return its handle.
int SocketCreate(
uint flags // flags
);
Parameters
flags
[in] Combination of flags defining the mode of work ing with a sock et. Currently, only one flag is
supported — SOCKET _DEFAULT.
Return Value
In case of a successful sock et creation, return its handle, otherwise I NVALI D_HANDL E.
Notes
To free up computer memory from an unused sock et, call Sock etClose for it.
You can create a maximum of 128 sock ets from one MQL5 program. If the limit is exceeded, the
error 5271 (ERR_NETSOCKET _TOO_M ANY_OPENED) is written to _LastError.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
Example:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the
#property script_show_inputs
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
SocketClose
Close a sock et.
bool SocketClose(
const int socket // socket handle
);
Parameters
socket
[in] H andle of a sock et to be closed. The handle is returned by the Sock etCreate function. W hen
an incorrect handle is passed, the error 5270 (ERR_NETSOCKET _I NVALI DHANDL E) is written to
_LastError.
Return Value
Note
If a connection via Sock etConnect was previously created for a sock et, it is discontinued.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
Example:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the
#property script_show_inputs
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
SocketConnect
Connect to the server with timeout control.
bool SocketConnect(
int socket, // socket
const string server, // connection address
uint port, // connection port
uint timeout_receive_ms // connection timeout
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed, the
error 5270 (ERR_NETSOCKET _I NVALI DHANDL E) is written to _LastError.
server
[in] Domain name of the server you want to connect to or its IP address.
port
[in] Connection port number.
timeout_receive_ms
[in] Connection timeout in milliseconds. If connection is not established within that time interval,
attempts are stopped.
Return Value
Note
Connection address should be added to the list of allowed ones on the client terminal side (Tools \
Options \ Expert Advisors).
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
Example:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the
#property script_show_inputs
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
SocketIsConnected
Check s if the sock et is currently connected.
bool SocketIsConnected(
const int socket // socket handle
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate() function. W hen an incorrect handle is passed to
_LastError, the error 5270 (ERR_NETSOCKET _INVALIDHANDL E) is activated.
Return Value
Note
The Sock etIsConnected() function allows check ing the current sock et connection status.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
See also
Sock etConnect, Sock etIs W ritable, Sock etCreate, Sock etClose
SocketIsReadable
Get a number of bytes that can be read from a sock et.
uint SocketIsReadable(
const int socket // socket handle
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed to
_LastError, the error 5270 (ERR_NETSOCKET _INVALIDHANDL E) is activated.
Return Value
Note
If an error occurs on a system sock et when executing the function, connection established via
Sock etConnect is discontinued.
Before calling Sock etR ead, check if the sock et features data for reading. Otherwise, if there are no
data, the Sock etR ead function waits for data within timeout_ms delaying the program execution.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
Example:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the
#property script_show_inputs
if(len<0)
return(false);
//--- if secure TLS connection is used via the port 443
if(ExtTLS)
return(SocketTlsSend(socket,req,len)==len);
//--- if standard TCP connection is used
return(SocketSend(socket,req,len)==len);
}
//+------------------------------------------------------------------+
//| Read server response |
//+------------------------------------------------------------------+
bool HTTPRecv(int socket,uint timeout)
{
char rsp[];
string result;
uint timeout_check=GetTickCount()+timeout;
//--- read data from sockets till they are still present but not longer than timeout
do
{
uint len=SocketIsReadable(socket);
if(len)
{
int rsp_len;
//--- various reading commands depending on whether the connection is secure or not
if(ExtTLS)
rsp_len=SocketTlsRead(socket,rsp,len);
else
rsp_len=SocketRead(socket,rsp,len,timeout);
//--- analyze the response
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
SocketIsWritable
Check whether data can be written to a sock et at the current time.
bool SocketIsWritable(
const int socket // socket handle
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed, the
error 5270 (ERR_NETSOCKET _I NVALI DHANDL E) is written to _LastError.
Return Value
Note
This function allows you to check whether it is possible to write data to a sock et right now.
If an error occurs on a system sock et when executing the function, connection established via
Sock etConnect is discontinued.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
SocketTimeouts
Set timeouts for receiving and sending data for a sock et system object.
bool SocketTimeouts(
int socket, // socket
uint timeout_send_ms, // data sending timeout
uint timeout_receive_ms // data obtaining timeout
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed, the
error 5270 (ERR_NETSOCKET _I NVALI DHANDL E) is written to _LastError.
timeout_send_ms
[in] Data sending timeout in milliseconds.
timeout_receive_ms
[in] Data obtaining timeout in milliseconds.
Return Value
Note
Do not confuse system object timeouts with the ones set when reading data via Sock etR ead.
Sock etTimeout sets timeouts once for a sock et object in the operating system. These timeouts are
to be applied to all functions for reading and sending data via this sock et. In Sock etR ead, the
timeout is set for a certain data reading operation.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
SocketRead
R ead data from a sock et.
int SocketRead(
int socket, // socket
uchar& buffer[], // buffer for reading data from socket
uint buffer_maxlen, // number of bytes to read
uint timeout_ms // reading timeout
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed to
_LastError, the error 5270 (ERR_NETSOCKET _INVALIDHANDL E) is activated.
buffer
[out] R eference to the uchar type array the data is read in. Dynamic array size is increased by the
number of read bytes. The array size cannot exceed I NT _M AX (2147483647).
buffer_maxlen
[in] Number of bytes to read to the buffer[] array. Data not fitting into the array remain in the
sock et. They can be received by the next Sock etR ead call. buffer_maxlen cannot exceed I NT _M AX
(2147483647).
timeout_ms
[in] Data reading timeout in milliseconds. If data is not obtained within this time, attempts are
stopped and the function returns -1.
Return Value
Note
If an error occurs on a system sock et when executing the function, connection established via
Sock etConnect is discontinued.
In case of a data reading error, the error 5273 (ERR_NETSOCKET _IO_ERR OR ) is written in
_LastError.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
Example:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
See also
Sock etTimeouts, MathSwap
SocketSend
W rite data to a sock et.
int SocketSend(
int socket, // socket
const uchar& buffer[], // data buffer
uint buffer_len // buffer size
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed, the
error 5270 (ERR_NETSOCKET _I NVALI DHANDL E) is written to _LastError.
buffer
[in] R eference to the uchar type array with the data to be sent to the sock et.
buffer_len
[in] 'buffer' array size.
Return Value
If successful, return the number of bytes written to a sock et. In case of an error, -1 is returned.
Note
If an error occurs on a system sock et when executing the function, connection established via
Sock etConnect is discontinued.
In case of a data writing error, the error 5273 (ERR_NETSOCKET _IO_ERR OR ) is written to
_LastError.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
Example:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the
#property script_show_inputs
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
See also
Sock etTimeouts, MathSwap, StringToCharArray
SocketTlsHandshake
Initiate secure TLS (SSL) connection to a specified host via TLS H andshak e protocol. During
H andshak e, a client and a server agree on connection parameters : applied protocol version and data
encryption method.
bool SocketTlsHandshake(
int socket, // socket
const string host // host address
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed, the
error 5270 (ERR_NETSOCKET _I NVALI DHANDL E) is written to _LastError.
host
[in] Address of a host a secure connection is established with.
Return Value
Notes
Before a secure connection, the program should establish a standard TCP connection with the host
using Sock etConnect.
If secure connection fails, the error 5274 (ERR_NETSOCKET _HANDS HAKE_FAIL ED) is written to
_LastError.
There is no need to call the function when connecting to the port 443. This is a standard TCP port
used for secure TLS (SSL) connections.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
SocketTlsCertificate
Get data on the certificate used to secure network connection.
int SocketTlsCertificate(
int socket, // socket
string& subject, // certificate owner
string& issuer, // certificate issuer
string& serial, // certificate serial number
string& thumbprint, // certificate print
datetime& expiration // certificate expiration
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed, the
error 5270 (ERR_NETSOCKET _I NVALI DHANDL E) is written to _LastError.
subject
[in] Certificate owner name. Corresponds to the Subject field.
issuer
[in] Certificate issuer name. Corresponds to the Issuer field.
serial
[in] Certificate serial number. Corresponds to the SerialNumber field.
thumbprint
[in] Certificate print. Corresponds to the S HA-1 hash from the entire certificate file (all fields
including the issuer signature).
expiration
[in] Certificate expiration date in the datetime format.
Return Value
Note
Certificate data can be requested only after establishing a secure connection using
Sock etTls H andshak e.
In case of a certificate obtaining error, the error 5275 (ERR_NETSOCKET _NO_CER TI FICAT E) is
written to _LastError.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
Example:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the
#property script_show_inputs
if(rsp_len>0)
{
result+=CharArrayToString(rsp,0,rsp_len);
//--- print only the response header
int header_end=StringFind(result,"\r\n\r\n");
if(header_end>0)
{
Print("HTTP answer header received:");
Print(StringSubstr(result,0,header_end));
return(true);
}
}
}
}
while(GetTickCount()<timeout_check && !IsStopped());
return(false);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int socket=SocketCreate();
//--- check the handle
if(socket!=INVALID_HANDLE)
{
//--- connect if all is well
if(SocketConnect(socket,Address,Port,1000))
{
Print("Established connection to ",Address,":",Port);
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
SocketTlsRead
R ead data from secure TLS connection.
int SocketTlsRead(
int socket, // socket
uchar& buffer[], // buffer for reading data from socket
uint buffer_maxlen // number of bytes to read
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed to
_LastError, the error 5270 (ERR_NETSOCKET _INVALIDHANDL E) is activated.
buffer
[out] R eference to the uchar type array the data is read in. Dynamic array size is increased by the
number of read bytes. The array size cannot exceed I NT _M AX (2147483647).
buffer_maxlen
[in] Number of bytes to read to the buffer[] array. Data not fitting into the array remain in the
sock et. They can be received by the next Sock etTLS R ead call. buffer_maxlen cannot exceed
I NT _M AX (2147483647).
Return Value
Note
If an error occurs on a system sock et when executing the function, connection established via
Sock etConnect is discontinued.
The function is executed till it receives the specified amount of data or the timeout is reached
(Sock etTimeouts).
In case of a data reading error, the error 5273 (ERR_NETSOCKET _IO_ERR OR ) is written in
_LastError.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
Example:
//+------------------------------------------------------------------+
//| SocketExample.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "Add Address to the list of allowed ones in the terminal settings to let the
#property script_show_inputs
string subject,issuer,serial,thumbprint;
datetime expiration;
//--- if connection is secured by the certificate, display its data
if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration))
{
Print("TLS certificate:");
Print(" Owner: ",subject);
Print(" Issuer: ",issuer);
Print(" Number: ",serial);
Print(" Print: ",thumbprint);
Print(" Expiration: ",expiration);
ExtTLS=true;
}
//--- send GET request to the server
if(HTTPSend(socket,"GET / HTTP/1.1\r\nHost: www.mql5.com\r\n\r\n"))
{
Print("GET request sent");
//--- read the response
if(!HTTPRecv(socket,1000))
Print("Failed to get a response, error ",GetLastError());
}
else
Print("Failed to send GET request, error ",GetLastError());
}
else
{
Print("Connection to ",Address,":",Port," failed, error ",GetLastError());
}
//--- close a socket after using
SocketClose(socket);
}
else
Print("Failed to create a socket, error ",GetLastError());
}
//+------------------------------------------------------------------+
See also
Sock etTimeouts, MathSwap
SocketTlsReadAvailable
R ead all available data from secure TLS connection.
int SocketTlsReadAvailable(
int socket, // socket
uchar& buffer[], // buffer for reading data from socket
const uint buffer_maxlen // number of bytes to read
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed to
_LastError, the error 5270 (ERR_NETSOCKET _INVALIDHANDL E) is activated.
buffer
[out] R eference to the uchar type array the data is read in. Dynamic array size is increased by the
number of read bytes. The array size cannot exceed I NT _M AX (2147483647).
buffer_maxlen
[in] Number of bytes to read to the buffer[] array. Data not fitting into the array remain in the
sock et. They can be received by the next Sock etTls R eadAvailable or Sock etTls R ead call.
buffer_maxlen cannot exceed I NT _M AX (2147483647).
Return Value
Note
If an error occurs on a system sock et when executing the function, connection established via
Sock etConnect is discontinued.
In case of a data reading error, the error 5273 (ERR_NETSOCKET _IO_ERR OR ) is written in
_LastError.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
See also
Sock etTimeouts, MathSwap
SocketTlsSend
Send data via secure TLS connection.
int SocketTlsSend(
int socket, // socket
const uchar& buffer[], // data buffer
uint buffer_len // buffer size
);
Parameters
socket
[in] Sock et handle returned by the Sock etCreate function. W hen an incorrect handle is passed, the
error 5270 (ERR_NETSOCKET _I NVALI DHANDL E) is written to _LastError.
buffer
[in] R eference to the uchar type array with the data to be sent.
buffer_len
[in] 'buffer' array size.
Return Value
If successful, return the number of bytes written to a sock et. In case of an error, -1 is returned.
Note
If an error occurs on a system sock et when executing the function, connection established via
Sock etConnect is discontinued.
In case of a data writing error, the error 5273 (ERR_NETSOCKET _IO_ERR OR ) is written to
_LastError.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If calling from an indicator, GetLastError() returns the error 4014 – "Function is not allowed
for call" .
See also
Sock etTimeouts, MathSwap, StringToCharArray
WebRequest
The function sends an H TTP request to a specified server. The function has two versions :
1. Sending simple requests of type "k ey=value" using the header Content-Type: application/x-www-
form-urlencoded.
int WebRequest(
const string method, // HTTP method
const string url, // URL
const string cookie, // cookie
const string referer, // referer
int timeout, // timeout
const char &data[], // the array of the HTTP message body
int data_size, // data[] array size in bytes
char &result[], // an array containing server response data
string &result_headers // headers of server response
);
2. Sending a request of any type specifying the custom set of headers for a more flexible interaction
with various W eb services.
int WebRequest(
const string method, // HTTP method
const string url, // URL
const string headers, // headers
int timeout, // timeout
const char &data[], // the array of the HTTP message body
char &result[], // an array containing server response data
string &result_headers // headers of server response
);
Parameters
method
[in] H TTP method.
url
[in] UR L.
headers
[in] R equest headers of type "k ey: value" , separated by a line break "\r\n" .
cookie
[in] Cook ie value.
referer
[in] Value of the R eferer header of the H TTP request.
timeout
[in] Timeout in milliseconds.
data[]
[in] Data array of the H TTP message body.
data_size
[in] Size of the data[] array.
result[]
[out] An array containing server response data.
result_headers
[out] Server response headers.
Return Value
Note
To use the W ebR equest() function, add the addresses of the required servers in the list of allowed
UR Ls in the "Expert Advisors " tab of the " Options " window. Server port is automatically selected on
the basis of the specified protocol - 80 for " http://" and 443 for " https ://" .
The W ebR equest() function is synchronous, which means its break s the program execution and waits
for the response from the requested server. Since the delays in receiving a response can be large,
the function is not available for calls from indicators, because indicators run in a common thread
shared by all indicators and charts on one symbol. Indicator performance delay on one of the charts
of a symbol may stop updating of all charts of the same symbol.
The function can be called only from Expert Advisors and scripts, as they run in their own execution
threads. If you try to call the function from an indicator, GetLastError() will return error 4014 –
"Function is not allowed for call" .
Example:
void OnStart()
{
string cookie=NULL,headers;
char post[],result[];
string url="https://finance.yahoo.com";
//--- To enable access to the server, you should add URL "https://finance.yahoo.com"
//--- to the list of allowed URLs (Main Menu->Tools->Options, tab "Expert Advisors"):
//--- Resetting the last error code
ResetLastError();
//--- Downloading a html page from Yahoo Finance
int res=WebRequest("GET",url,cookie,NULL,500,post,0,result,headers);
if(res==-1)
{
Print("Error in WebRequest. Error code =",GetLastError());
//--- Perhaps the URL is not listed, display a message about the necessity to add the address
MessageBox("Add the address '"+url+"' to the list of allowed URLs on tab 'Expert Advisors'","
}
else
{
if(res==200)
{
//--- Successful download
PrintFormat("The file has been successfully downloaded, File size %d byte.",ArraySize(resu
//PrintFormat("Server headers: %s",headers);
//--- Saving the data to a file
int filehandle=FileOpen("url.htm",FILE_WRITE|FILE_BIN);
if(filehandle!=INVALID_HANDLE)
{
//--- Saving the contents of the result[] array to a file
FileWriteArray(filehandle,result,0,ArraySize(result));
//--- Closing the file
FileClose(filehandle);
}
else
Print("Error in FileOpen. Error code =",GetLastError());
}
else
PrintFormat("Downloading '%s' failed, error code %d",url,res);
}
}
SendFTP
Sends a file at the address, specified in the setting window of the "FTP" tab.
bool SendFTP(
string filename, // file to be send by ftp
string ftp_path=NULL // ftp catalog
);
Parameters
filename
[in] Name of sent file.
ftp_path=NULL
[in] FTP catalog. If a directory is not specified, directory described in settings is used.
Return Value
Note
Sent file must be located in the folder terminal_directory\MQL5\files or its subfolders. Sending isn't
performed if FTP address and/or access password are not specified in settings.
SendMail
Sends an email at the address specified in the settings window of the "Email" tab.
bool SendMail(
string subject, // header
string some_text // email text
);
Parameters
subject
[in] Email header.
some_text
[in] Email body.
Return Value
Note
Sending can be prohibited in settings, email address can be omitted as well. For the error
information call GetLastError().
SendNotification
Sends push notifications to the mobile terminals, whose MetaQuotes I Ds are specified in the
"Notifications " tab.
bool SendNotification(
string text // Text of the notification
);
Parameters
text
[in] The text of the notification. The message length should not exceed 255 characters.
Return Value
true if a notification has been successfully sent from the terminal; in case of failure returns false.
W hen check ing after a failed push of notification, GetLastError () may return one of the following
errors :
· 4515 – ERR_NOTI FICATION_S END_FAIL ED,
· 4516 – ERR_NOTI FICATION_WR ONG_PARAM ET ER ,
· 4517 – ERR_NOTI FICATION_WR ONG_S ETTI NGS,
· 4518 – ERR_NOTI FICATION_TOO_FREQUENT.
Note
Strict use restrictions are set for the SendNotification() function: no more than 2 calls per second
and not more than 10 calls per minute. Monitoring the frequency of use is dynamic. The function can
be disabled in case of the restriction violation.
Global variables of the client terminal should not be mixed up with variables declared in the global
scope of the mql5 program.
Global variables are k ept in the client terminal for 4 week s since the last access, then they will be
deleted automatically. An access to a global variable is not only setting of a new value, but reading of
the global variable value, as well.
Global variables of the client terminal are accessible simultaneously from all mql5 programs launched
in the client terminal.
Function Action
GlobalVariableCheck
Check s the existence of a global variable with the specified name
bool GlobalVariableCheck(
string name // Global variable name
);
Parameters
name
[in] Global variable name.
Return Value
Global variables exist in the client terminal during 4 week s since their last use, then they are
automatically deleted.
See also
GlobalVariableTime()
GlobalVariableTime
R eturns the time when the global variable was last accessed.
datetime GlobalVariableTime(
string name // name
);
Parameters
name
[in] Name of the global variable.
Return Value
The function returns time of last accessing the specified global variable. Addressing a variable for
its value, for example using the GlobalVariableGet() and GlobalVariableCheck () functions, also
modifies the time of last access. In order to obtain error details, call the GetLastError() function.
Note
Global variables exist in the client terminal during 4 week s since they were called last. After that
they are automatically deleted.
See also
GlobalVariableCheck ()
GlobalVariableDel
Deletes a global variable from the client terminal.
bool GlobalVariableDel(
string name // Global variable name
);
Parameters
name
[in] Global variable name.
Return Value
If successful, the function returns true, otherwise it returns false. To obtain an information about
the error it is necessary to call the function GetLastError().
Note
Global variables exist in the client terminal during 4 week s since their last use, then they are
automatically deleted.
GlobalVariableGet
R eturns the value of an existing global variable of the client terminal. There are 2 variants of the
function.
double GlobalVariableGet(
string name // Global variable name
);
2. R eturns true or false depending on the success of the function run. If successful, the global variable
of the client terminal is placed in a variable passed by reference in the second parameter.
bool GlobalVariableGet(
string name, // Global variable name
double& double_var // This variable will contain the value of the global variable
);
Parameters
name
[in] Global variable name.
double_var
[out] Target variable of the double type, which accepts the value stored in a the global variable of
the client terminal.
Return Value
The value of the existing global variable or 0 in case of an error. For more details about the error,
call GetLastError().
Note
Global variables exist in the client terminal during 4 week s since their last use, then they are
automatically deleted.
GlobalVariableName
R eturns the name of a global variable by its ordinal number.
string GlobalVariableName(
int index // Global variable number in the list of global variables
);
Parameters
index
[in] Sequence number in the list of global variables. It should be greater than or equal to 0 and
less than GlobalVariablesTotal().
Return Value
Global variable name by its ordinal number in the list of global variables. For more details about the
error, call GetLastError().
Note
Global variables exist in the client terminal during 4 week s since their last use, then they are
automatically deleted.
GlobalVariableSet
Sets a new value for a global variable. If the variable does not exist, the system creates a new global
variable.
datetime GlobalVariableSet(
string name, // Global variable name
double value // Value to set
);
Parameters
name
[in] Global variable name.
value
[in] The new numerical value.
Return Value
If successful, the function returns the last modification time, otherwise 0. For more details about
the error, call GetLastError().
Note
A global variable name should not exceed 63 characters. Global variables exist in the client terminal
during 4 week s since their last use, then they are automatically deleted.
GlobalVariablesFlush
Forcibly saves contents of all global variables to a dis k .
void GlobalVariablesFlush();
Return Value
No return value.
Note
The terminal writes all the global variables when the work is over, but data can be lost at a sudden
computer operation failure. This function allows independently controlling the process of saving
global variables in case of contingency.
GlobalVariableTemp
The function attempts to create a temporary global variable. If the variable doesn't exist, the system
creates a new temporary global variable.
bool GlobalVariableTemp(
string name // Global variable name
);
Parameters
name
[in] The name of a temporary global variable.
Return Value
If successful, the function returns true, otherwise - false. To get details about the error, you should
call the GetLastError() function.
Note
Temporary global variables exist only while the client terminal is running ; after the terminal
shutdown they are automatically deleted. Note that during the execution of GlobalVariables Flush()
temporary global variables are not written to a dis k .
After a temporary global variable has been created, it can be accessed and modified the same as
global variable of the client terminal.
GlobalVariableSetOnCondition
Sets the new value of the existing global variable if the current value equals to the third parameter
check_value. If there is no global variable, the function will generate an error
ERR_GLOBAL VAR IABL E_NOT _FOUND (4501) and return false.
bool GlobalVariableSetOnCondition(
string name, // Global variable name
double value, // New value for variable if condition is true
double check_value // Check value condition
);
Parameters
name
[in] The name of a global variable.
value
[in] New value.
check_value
[in] The value to check the current value of the global variable.
Return Value
If successful, the function returns true, otherwise it returns false. For details about the error call
GetLastError(). If the current value of the global variable is different from check_value, the function
returns false.
Note
Function provides atomic access to the global variable, so it can be used for providing of a mutex at
interaction of several Expert Advisors work ing simultaneously within one client terminal.
GlobalVariablesDeleteAll
Deletes global variables of the client terminal.
int GlobalVariablesDeleteAll(
string prefix_name=NULL, // All global variables with names beginning with the prefix
datetime limit_data=0 // All global variables that were changed before this date
);
Parameters
prefix_name=NULL
[in] Name prefix global variables to remove. If you specify a prefix NULL or empty string, then all
variables that meet the data criterion will be deleted.
limit_data=0
[in] Date to select global variables by the time of their last modification. The function removes
global variables, which were changed before this date. If the parameter is zero, then all variables
that meet the first criterion (prefix) are deleted.
Return Value
Note
If both options are equal to zero (prefix _name = NULL and limit_data = 0), then function deletes all
global variables of the terminal. If both parameters are specified, then it deletes global variables
corresponding to both parameters.
Global variables exist in the client terminal during 4 week s since their last use, then they are
automatically deleted.
GlobalVariablesTotal
R eturns the total number of global variables of the client terminal.
int GlobalVariablesTotal();
Return Value
Note
Global variables exist in the client terminal during 4 week s since their last use, then they are
automatically deleted. Call of a global variable is not only setting a new value, but also reading the
value of the global variable.
File Functions
This is a group of functions for work ing with files.
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means cannot be outside the file sandbox.
There are two directories (with subdirectories) in which work ing files can be located:
· terminal_data_folder\ MQL5\FIL ES \ (in the terminal menu select to view "File" - " Open the data
directory" );
· the common folder for all the terminals installed on a computer - usually located in the directory C:
\Documents and Settings \All Users \Application Data\MetaQuotes \Terminal\Common\Files.
There is a program method to obtain names of these catalogs using the TerminalInfoString() function,
using the ENUM _T ER MI NAL _I NFO_ST R I NG enumeration:
File functions allow work ing with so-called " named pipes " . To do this, simply call FileOpen() function
with appropriate parameters.
Function Action
FileR eadArray R eads arrays of any type except for string from
the file of the BI N type
FileR eadInteger R eads int, short or char value from the current
position of the file pointer
FileW riteArray W rites arrays of any type except for string into
a file of BI N type
FileW riteFloat W rites value of the float type from the current
position of a file pointer into a binary file
FileW riteInteger W rites value of the int type from the current
position of a file pointer into a binary file
FileW riteLong W rites value of the long type from the current
position of a file pointer into a binary file
If the file is opened for writing using FileOpen(), all subfolders specified in the path will be created if
there are no such ones.
FileFindFirst
The function starts the search of files or subdirectories in a directory in accordance with the specified
filter.
long FileFindFirst(
const string file_filter, // String - search filter
string& returned_filename, // Name of the file or subdirectory found
int common_flag=0 // Defines the search
);
Parameters
file_filter
[in] Search filter. A subdirectory (or sequence of nested subdirectories) relative to the \Files
directory, in which files should be searched for, can be specified in the filter.
returned_filename
[out] The returned parameter, where, in case of success, the name of the first found file or
subdirectory is placed. Only the file name is returned (including the extension), the directories and
subdirectories are not included no matter if they are specified or not in the search filter.
common_flag
[in] Flag determining the location of the file. If common_flag = FIL E_COMMON, then the file is
located in a shared folder for all client terminals \ Terminal\ Common\Files. Otherwise, the file is
located in a local folder.
Return Value
R eturns handle of the object searched, which should be used for further sorting of files and
subdirectories by the FileFindNext() function, or I NVALI D_HANDL E when there is no file and
subdirectory corresponding to the filter (in the particular case - when the directory is empty). After
searching, the handle must be closed using the FileFindClose() function.
Note
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means, cannot be outside the file sandbox.
Example:
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- filter
input string InpFilter="Dir1\\*";
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name;
string int_dir="";
int i=1,pos=0,last_pos=-1;
//--- search for the last backslash
while(!IsStopped())
{
pos=StringFind(InpFilter,"\\",pos+1);
if(pos>=0)
last_pos=pos;
else
break;
}
//--- the filter contains the folder name
if(last_pos>=0)
int_dir=StringSubstr(InpFilter,0,last_pos+1);
//--- get the search handle in the root of the local folder
long search_handle=FileFindFirst(InpFilter,file_name);
//--- check if the FileFindFirst() is executed successfully
if(search_handle!=INVALID_HANDLE)
{
//--- in a loop, check if the passed strings are the names of files or directories
do
{
ResetLastError();
//--- if it's a file, the function returns true, and if it's a directory, it returns error
FileIsExist(int_dir+file_name);
PrintFormat("%d : %s name = %s",i,GetLastError()==ERR_FILE_IS_DIRECTORY ? "Directory" : "F
i++;
}
while(FileFindNext(search_handle,file_name));
//--- close the search handle
FileFindClose(search_handle);
}
else
Print("Files not found!");
}
See also
FileFindNext, FileFindClose
FileFindNext
The function continues the search started by FileFindFirst().
bool FileFindNext(
long search_handle, // Search handle
string& returned_filename // Name of the file or subdirectory found
);
Parameters
search_handle
[in] Search handle, retrieved by FileFindFirst().
returned_filename
[out] The name of the next file or subdirectory found. Only the file name is returned (including the
extension), the directories and subdirectories are not included no matter if they are specified or
not in the search filter.
Return Value
Example:
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- filter
input string InpFilter="*";
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name;
int i=1;
//--- receive search handle in local folder's root
long search_handle=FileFindFirst(InpFilter,file_name);
//--- check if FileFindFirst() function executed successfully
if(search_handle!=INVALID_HANDLE)
{
//--- check if the passed strings are file or directory names in the loop
do
{
ResetLastError();
//--- if this is a file, the function will return true, if it is a directory, the function
FileIsExist(file_name);
PrintFormat("%d : %s name = %s",i,GetLastError()==ERR_FILE_IS_DIRECTORY ? "Directory" : "F
i++;
}
while(FileFindNext(search_handle,file_name));
See also
FileFindFirst, FileFindClose
FileFindClose
The function closes the search handle.
void FileFindClose(
long search_handle // Search handle
);
Parameters
search_handle
[in] Search handle, retrieved by FileFindFirst().
Return Value
No value returned.
Note
Example:
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- filter
input string InpFilter="*";
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name;
int i=1;
//--- receive search handle in local folder's root
long search_handle=FileFindFirst(InpFilter,file_name);
//--- check if FileFindFirst() function executed successfully
if(search_handle!=INVALID_HANDLE)
{
//--- check if the passed strings are file or directory names in the loop
do
{
ResetLastError();
//--- if this is a file, the function will return true, if it is a directory, the function
FileIsExist(file_name);
PrintFormat("%d : %s name = %s",i,GetLastError()==5018 ? "Directory" : "File",file_name);
i++;
}
while(FileFindNext(search_handle,file_name));
//--- close search handle
FileFindClose(search_handle);
}
else
Print("Files not found!");
}
See also
FileFindFirst, FileFindNext
FileIsExist
Check s the existence of a file.
bool FileIsExist(
const string file_name, // File name
int common_flag=0 // Search area
);
Parameters
file_name
[in] The name of the file being check ed
common_flag=0
[in] Flag determining the location of the file. If common_flag = FIL E_COMMON, then the file is
located in a shared folder for all client terminals \ Terminal\ Common\Files. Otherwise, the file is
located in a local folder.
Return Value
Note
Check ed file can turn out to be a subdirectory. In this case, FileIs Exist() function will return false,
while error 5018 will be logged in _LastError variable - " This is a directory, not a file" (see example
for FileFindFirst function).
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means, cannot be outside the file sandbox.
If common_flag = FIL E_COMMON, then the function look s for the file in a shared folder for all client
terminals \ Terminal\ Common\Files, otherwise the function look s for a file in a local folder
(MQL5\Files or MQL5\ Tester\Files in the case of testing).
Example:
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- date for old files
input datetime InpFilesDate=D'2013.01.01 00:00';
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name; // variable for storing file names
string filter="*.txt"; // filter for searching the files
datetime create_date; // file creation date
string files[]; // list of file names
int def_size=25; // array size by default
int size=0; // number of files
See also
FileFindFirst
FileOpen
The function opens the file with the specified name and flag.
int FileOpen(
string file_name, // File name
int open_flags, // Combination of flags
short delimiter='\t', // Delimiter
uint codepage=CP_ACP // Code page
);
Parameters
file_name
[in] The name of the file can contain subfolders. If the file is opened for writing, these subfolders
will be created if there are no such ones.
open_flags
[in] combination of flags determining the operation mode for the file. The flags are defined as
follows :
FIL E_READ file is opened for reading
FIL E_WR IT E file is opened for writing
FIL E_BIN binary read-write mode (no conversion from a string and to a string)
FIL E_CS V file of csv type (all recorded items are converted to the strings of unicode or ansi type,
and are separated by a delimiter)
FIL E_T XT a simple text file (the same as csv, but the delimiter is not tak en into account)
FIL E_ANSI lines of ANSI type (single-byte symbols)
FIL E_UNICODE lines of UNICODE type (double-byte characters)
FIL E_S HARE_READ shared reading from several programs
FIL E_S HARE_WR IT E shared writing from several programs
FIL E_COMMON location of the file in a shared folder for all client terminals
\Terminal\Common\Files
delimiter='\t'
[in] value to be used as a separator in txt or csv-file. If the csv-file delimiter is not specified, it
defaults to a tab. If the txt-file delimiter is not specified, then no separator is used. If the
separator is clearly set to 0, then no separator is used.
codepage=CP_ACP
[in] The value of the code page. For the most-used code pages provide appropriate constants.
Return Value
If a file has been opened successfully, the function returns the file handle, which is then used to
access the file data. In case of failure returns I NVALI D_HANDL E.
Note
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means, cannot be outside the file sandbox.
Mak e sure to set the FIL E_ANSI flag if the file should be read in a specific encoding (the codepage
parameter with a code page value is specified). If there is no specified FIL E_ANSI flag, the text file
is read in Unicode without any conversion.
The file is opened in the folder of the client terminal in the subfolder MQL5\ files (or
testing _agent_directory\ MQL5\ files in case of testing). If FIL E_COMMON is specified among flags,
the file is opened in a shared folder for all MetaTrader 5 client terminals.
A special symbol '\' is used in shown strings. Therefore, '\' should be doubled when writing a name in
MQL5 application. It means that the above example should have the following look in the code: "\\\
\servername\\pipe\\pipename" .
More information about work ing with named pipes can be found in the article " Communicating W ith
MetaTrader 5 Using Named Pipes W ithout Using DLLs " .
Example:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- incorrect file opening method
string terminal_data_path=TerminalInfoString(TERMINAL_DATA_PATH);
string filename=terminal_data_path+"\\MQL5\\Files\\"+"fractals.csv";
int filehandle=FileOpen(filename,FILE_WRITE|FILE_CSV);
if(filehandle<0)
{
Print("Failed to open the file by the absolute path ");
Print("Error code ",GetLastError());
}
string subfolder="Research";
filehandle=FileOpen(subfolder+"\\fractals.txt",FILE_WRITE|FILE_CSV);
if(filehandle!=INVALID_HANDLE)
{
FileWrite(filehandle,TimeCurrent(),Symbol(), EnumToString(_Period));
FileClose(filehandle);
Print("The file must be created in the folder "+terminal_data_path+"\\"+subfolder);
}
else Print("File open failed, error ",GetLastError());
}
See also
Use of a Codepage, FileFindFirst, FolderCreate, File opening flags
FileClose
Close the file previously opened by FileOpen().
void FileClose(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
No value returned.
Example:
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input string InpFileName="file.txt"; // file name
input string InpDirectoryName="Data"; // directory name
input int InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- print the path to the file we are going to use
PrintFormat("Working %s\\Files\\ folder",TerminalInfoString(TERMINAL_DATA_PATH));
//--- reset the error value
ResetLastError();
//--- open the file for reading (if the file does not exist, the error will occur)
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
//--- print the file contents
while(!FileIsEnding(file_handle))
Print(FileReadString(file_handle));
//--- close the file
FileClose(file_handle);
}
else
PrintFormat("Error, code = %d",GetLastError());
}
FileCopy
The function copies the original file from a local or shared folder to another file.
bool FileCopy(
const string src_file_name, // Name of a source file
int common_flag, // Location
const string dst_file_name, // Name of the destination file
int mode_flags // Access mode
);
Parameters
src_file_name
[in] File name to copy.
common_flag
[in] Flag determining the location of the file. If common_flag = FIL E_COMMON, then the file is
located in a shared folder for all client terminals \ Terminal\ Common\Files. Otherwise, the file is
located in a local folder (for example, common_flag=0).
dst_file_name
[in] R esult file name.
mode_flags
[in] Access flags. The parameter can contain only 2 flags : FIL E_REWR IT E and/or FIL E_COMMON -
other flags are ignored. If the file already exists, and the FIL E_REWR IT E flag hasn't been
specified, then the file will not be rewritten, and the function will return false.
Return Value
Note
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means, cannot be outside the file sandbox.
If the new file already exists, the copy will be made depending on the availability of the
FIL E_REWR IT E flag in the mode_flags parameter.
Example:
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input string InpSrc="source.txt"; // source
input string InpDst="destination.txt"; // copy
input int InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- display the source contents (it must exist)
if(!FileDisplay(InpSrc))
return;
//--- check if the copy file already exists (may not be created)
if(!FileDisplay(InpDst))
{
//--- the copy file does not exist, copying without FILE_REWRITE flag (correct copying)
if(FileCopy(InpSrc,0,InpDst,0))
Print("File is copied!");
else
Print("File is not copied!");
}
else
{
//--- the copy file already exists, try to copy without FILE_REWRITE flag (incorrect copying)
if(FileCopy(InpSrc,0,InpDst,0))
Print("File is copied!");
else
Print("File is not copied!");
//--- InpDst file's contents remains the same
FileDisplay(InpDst);
//--- copy once more with FILE_REWRITE flag (correct copying if the file exists)
if(FileCopy(InpSrc,0,InpDst,FILE_REWRITE))
Print("File is copied!");
else
Print("File is not copied!");
}
//--- receive InpSrc file copy
FileDisplay(InpDst);
}
//+------------------------------------------------------------------+
//| Read the file contents |
//+------------------------------------------------------------------+
bool FileDisplay(const string file_name)
{
//--- reset the error value
ResetLastError();
//--- open the file
int file_handle=FileOpen(file_name,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
//--- display the file contents in the loop
Print("+---------------------+");
PrintFormat("File name = %s",file_name);
while(!FileIsEnding(file_handle))
Print(FileReadString(file_handle));
Print("+---------------------+");
//--- close the file
FileClose(file_handle);
return(true);
}
//--- failed to open the file
PrintFormat("%s is not opened, error = %d",file_name,GetLastError());
return(false);
}
FileDelete
Deletes the specified file in a local folder of the client terminal.
bool FileDelete(
const string file_name, // File name to delete
int common_flag=0 // Location of the file to delete
);
Parameters
file_name
[in] File name.
common_flag=0
[in] Flag determining the file location. If common_flag = FIL E_COMMON, then the file is located in
a shared folder for all client terminals \ Terminal\ Common\Files. Otherwise, the file is located in a
local folder.
Return Value
Note
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means, cannot be outside the file sandbox.
Deletes the specified file from a local folder of the client terminal (MQL5\Files or MQL5\Tester\Files
in case of testing). If common_flag = FIL E_COMMON, then the function removes the file from the
shared folder for all client terminals \ Terminal\ Common\Files.
Example:
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- date for old files
input datetime InpFilesDate=D'2013.01.01 00:00';
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name; // variable for storing file names
string filter="*.txt"; // filter for searching the files
datetime create_date; // file creation date
string files[]; // list of file names
int def_size=25; // array size by default
int size=0; // number of files
//--- allocate memory for the array
ArrayResize(files,def_size);
//--- receive the search handle in the local folder's root
long search_handle=FileFindFirst(filter,file_name);
FileMove
Moves a file from a local or shared folder to another folder.
bool FileMove(
const string src_file_name, // File name for the move operation
int common_flag, // Location
const string dst_file_name, // Name of the destination file
int mode_flags // Access mode
);
Parameters
src_file_name
[in] File name to move/rename.
common_flag
[in] Flag determining the location of the file. If common_flag = FIL E_COMMON, then the file is
located in a shared folder for all client terminals \ Terminal\ Common\Files. Otherwise, the file is
located in a local folder (common_flag=0).
dst_file_name
[in] File name after operation
mode_flags
[in] Access flags. The parameter can contain only 2 flags : FIL E_REWR IT E and/or FIL E_COMMON -
other flags are ignored. If the file already exists and the FIL E_REWR IT E flag isn't specified, the file
will not be rewritten, and the function will return false.
Return Value
Note
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means, cannot be outside the file sandbox.
If the new file already exists, the copy will be made depending on the availability of the
FIL E_REWR IT E flag in the mode_flags parameter.
Example:
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input string InpSrcName="data.txt";
input string InpDstName="newdata.txt";
input string InpSrcDirectory="SomeFolder";
input string InpDstDirectory="OtherFolder";
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string local=TerminalInfoString(TERMINAL_DATA_PATH);
string common=TerminalInfoString(TERMINAL_COMMONDATA_PATH);
//--- receive file paths
string src_path;
string dst_path;
StringConcatenate(src_path,InpSrcDirectory,"//",InpSrcName);
StringConcatenate(dst_path,InpDstDirectory,"//",InpDstName);
//--- check if the source file exists (if not - exit)
if(FileIsExist(src_path))
PrintFormat("%s file exists in the %s\\Files\\%s folder",InpSrcName,local,InpSrcDirectory);
else
{
PrintFormat("Error, %s source file not found",InpSrcName);
return;
}
//--- check if the result file already exists
if(FileIsExist(dst_path,FILE_COMMON))
{
PrintFormat("%s file exists in the %s\\Files\\%s folder",InpDstName,common,InpDstDirectory);
//--- file exists, moving should be performed with FILE_REWRITE flag
ResetLastError();
if(FileMove(src_path,0,dst_path,FILE_COMMON|FILE_REWRITE))
PrintFormat("%s file moved",InpSrcName);
else
PrintFormat("Error! Code = %d",GetLastError());
}
else
{
PrintFormat("%s file does not exist in the %s\\Files\\%s folder",InpDstName,common,InpDstDire
//--- the file does not exist, moving should be performed without FILE_REWRITE flag
ResetLastError();
if(FileMove(src_path,0,dst_path,FILE_COMMON))
PrintFormat("%s file moved",InpSrcName);
else
PrintFormat("Error! Code = %d",GetLastError());
}
//--- the file is moved; let's check it out
if(FileIsExist(dst_path,FILE_COMMON) && !FileIsExist(src_path,0))
Print("Success!");
else
Print("Error!");
}
See also
FileIs Exist
FileFlush
W rites to a dis k all data remaining in the input/output file buffer.
void FileFlush(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
No value returned.
Note
W hen writing to a file, the data may be actually found there only after some time. To save the data
in the file instantly, use FileFlush() function. If the function is not used, part of the data that has
not been stored in the dis k yet, will be forcibly written there only when the file is closed using
FileClose() function.
The function should be used when written data is of a certain value. It should be k ept in mind that
frequent function call may affect the program operation speed.
Function FileFlush () must be called between the operations of reading from a file and writing to it.
Example:
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- file name for writing
input string InpFileName="example.csv"; // file name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- reset error value
ResetLastError();
//--- open the file
int file_handle=FileOpen(InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
if(file_handle!=INVALID_HANDLE)
{
//--- write data to the file
for(int i=0;i<1000;i++)
{
//--- call write function
FileWrite(file_handle,TimeCurrent(),SymbolInfoDouble(Symbol(),SYMBOL_BID),SymbolInfoDouble
//--- save data on the disk at each 128th iteration
if((i & 127)==127)
{
//--- now, data will be located in the file and will not be lost in case of a critical
FileFlush(file_handle);
PrintFormat("i = %d, OK",i);
}
//--- 0.01 second pause
Sleep(10);
}
//--- close the file
FileClose(file_handle);
}
else
PrintFormat("Error, code = %d",GetLastError());
}
See also
FileClose
FileGetInteger
Gets an integer property of a file. There are two variants of the function.
long FileGetInteger(
int file_handle, // File handle
ENUM_FILE_PROPERTY_INTEGER property_id // Property ID
);
long FileGetInteger(
const string file_name, // File name
ENUM_FILE_PROPERTY_INTEGER property_id, // Property ID
bool common_folder=false // The file is viewed in a local folder (false
); // or a common folder of all terminals (true)
Parameters
file_handle
[in] File descriptor returned by FileOpen().
file_name
[in] File name.
property_id
[in] File property ID. The value can be one of the values of the ENUM _FIL E_PR OPER T Y_INT EGER
enumeration. If the second variant of the function is used, you can receive only the values of the
following properties : FIL E_EXISTS, FIL E_CREAT E_DAT E, FIL E_MODI FY_DAT E, FIL E_ACCESS _DAT E
and FIL E_SI ZE.
common_folder=false
[in] Points to the file location. If the parameter is false, terminal data folder is viewed. Otherwise
it is assumed that the file is in the shared folder of all terminals \ Terminal\ Common\Files
(FIL E_COMMON).
Return Value
The value of the property. In case of an error, -1 is returned. To get an error code use the
GetLastError() function.
If a folder is specified when getting properties by the name, the function will have error 5018
(ERR_MQL _FIL E_IS _DI RECTORY) in any case, though the return value will be correct.
Note
The function always changes the error code. In case of successful completion the error code is reset
to NULL.
Example:
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input string InpFileName="data.csv";
input string InpDirectoryName="SomeFolder";
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string path=InpDirectoryName+"//"+InpFileName;
long l=0;
//--- open the file
ResetLastError();
int handle=FileOpen(path,FILE_READ|FILE_CSV);
if(handle!=INVALID_HANDLE)
{
//--- print all information about the file
Print(InpFileName," file info:");
FileInfo(handle,FILE_EXISTS,l,"bool");
FileInfo(handle,FILE_CREATE_DATE,l,"date");
FileInfo(handle,FILE_MODIFY_DATE,l,"date");
FileInfo(handle,FILE_ACCESS_DATE,l,"date");
FileInfo(handle,FILE_SIZE,l,"other");
FileInfo(handle,FILE_POSITION,l,"other");
FileInfo(handle,FILE_END,l,"bool");
FileInfo(handle,FILE_IS_COMMON,l,"bool");
FileInfo(handle,FILE_IS_TEXT,l,"bool");
FileInfo(handle,FILE_IS_BINARY,l,"bool");
FileInfo(handle,FILE_IS_CSV,l,"bool");
FileInfo(handle,FILE_IS_ANSI,l,"bool");
FileInfo(handle,FILE_IS_READABLE,l,"bool");
FileInfo(handle,FILE_IS_WRITABLE,l,"bool");
//--- close the file
FileClose(handle);
}
else
PrintFormat("%s file is not opened, ErrorCode = %d",InpFileName,GetLastError());
}
//+------------------------------------------------------------------+
//| Display the value of the file property |
//+------------------------------------------------------------------+
void FileInfo(const int handle,const ENUM_FILE_PROPERTY_INTEGER id,
long l,const string type)
{
//--- receive the property value
ResetLastError();
if((l=FileGetInteger(handle,id))!=-1)
{
//--- the value received, display it in the correct format
if(!StringCompare(type,"bool"))
Print(EnumToString(id)," = ",l ? "true" : "false");
if(!StringCompare(type,"date"))
Print(EnumToString(id)," = ",(datetime)l);
if(!StringCompare(type,"other"))
Print(EnumToString(id)," = ",l);
}
else
Print("Error, Code = ",GetLastError());
}
See also
File Operations, File Properties
FileIsEnding
Defines the end of a file in the process of reading.
bool FileIsEnding(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
The function returns true if the file end has been reached in the process of reading or moving of the
file pointer.
Note
To define the end of the file, the function tries to read the next string from it. If the string does not
exist, the function returns true, otherwise it returns false.
Example:
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input string InpFileName="file.txt"; // file name
input string InpDirectoryName="Data"; // directory name
input int InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- print the path to the file we are going to use
PrintFormat("Working %s\\Files\\ folder",TerminalInfoString(TERMINAL_DATA_PATH));
//--- reset the error value
ResetLastError();
//--- open the file for reading (if the file does not exist, the error will occur)
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
//--- print the file contents
while(!FileIsEnding(file_handle))
Print(FileReadString(file_handle));
//--- close the file
FileClose(file_handle);
}
else
PrintFormat("Error, code = %d",GetLastError());
FileIsLineEnding
Defines the line end in a text file in the process of reading.
bool FileIsLineEnding(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
R eturns true if in the process of reading txt or csv-file reached the end of the line (the characters
CR -L F).
Example (the file obtained during the execution of an example for FileW riteString function is used
here)
//+------------------------------------------------------------------+
//| Demo_FileIsLineEnding.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "Overbought & Oversold"
#property indicator_type1 DRAW_COLOR_BARS
#property indicator_color1 clrRed, clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- parameters for data reading
input string InpFileName="RSI.csv"; // file name
input string InpDirectoryName="Data"; // directory name
//--- indicator buffers
double open_buff[];
double high_buff[];
double low_buff[];
double close_buff[];
double color_buff[];
//--- overbought variables
int ovb_ind=0;
int ovb_size=0;
datetime ovb_time[];
//---- set the indicator values that will not be visible on the chart
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Read the file's string data |
//+------------------------------------------------------------------+
void ReadData(const int file_handle,datetime &arr[],int &size,int &def_size)
{
bool flag=false;
//--- read till the end of the string or of the file is reached
while(!FileIsLineEnding(file_handle) && !FileIsEnding(file_handle))
{
//--- shift the position by reading the number
if(flag)
FileReadNumber(file_handle);
//--- store the current date
arr[size]=FileReadDatetime(file_handle);
size++;
//--- increase the array size if necessary
if(size==def_size)
{
def_size+=100;
ArrayResize(arr,def_size);
}
//--- slip past the first iteration
flag=true;
}
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- the loop for the bars that have not been handled yet
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 0 by default
open_buff[i]=0;
high_buff[i]=0;
low_buff[i]=0;
close_buff[i]=0;
color_buff[i]=0;
//--- check if any data is still present
if(ovb_ind<ovb_size)
for(int j=ovb_ind;j<ovb_size;j++)
{
//--- if the dates coincide, the bar is in the overbought area
if(time[i]==ovb_time[j])
{
open_buff[i]=open[i];
high_buff[i]=high[i];
low_buff[i]=low[i];
close_buff[i]=close[i];
//--- 0 - red color
color_buff[i]=0;
//--- increase the counter
ovb_ind=j+1;
break;
}
}
//--- check if any data still exists
if(ovs_ind<ovs_size)
for(int j=ovs_ind;j<ovs_size;j++)
{
//--- if the dates coincide, the bar is in the oversold area
if(time[i]==ovs_time[j])
{
open_buff[i]=open[i];
high_buff[i]=high[i];
low_buff[i]=low[i];
close_buff[i]=close[i];
//--- 1 - blue color
color_buff[i]=1;
//--- increase the counter
ovs_ind=j+1;
break;
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent event handler |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam
)
{
//--- change the indicator width according to the scale
if(ChartGetInteger(0,CHART_SCALE)>3)
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);
else
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);
}
See also
FileW riteString
FileReadArray
R eads from a file of BIN type arrays of any type except string (may be an array of structures, not
containing strings, and dynamic arrays ).
uint FileReadArray(
int file_handle, // File handle
void& array[], // Array to record
int start=0, // start array position to write
int count=WHOLE_ARRAY // count to read
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
array[]
[out] An array where the data will be loaded.
start=0
[in] Start position to read from the array.
count=WHOLE_ARRAY
[in] Number of elements to read. By default, reads the entire array (count=WH OL E_ARRAY).
Return Value
Note
String array can be read only from the file of T XT type. If necessary, the function tries to increase
the size of the array.
Example (the file obtained after execution of the example for FileW riteArray function is used here)
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input string InpFileName="data.bin";
input string InpDirectoryName="SomeFolder";
//+------------------------------------------------------------------+
//| Structure for storing price data |
//+------------------------------------------------------------------+
struct prices
{
datetime date; // date
double bid; // bid price
double ask; // ask price
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- structure array
prices arr[];
//--- file path
string path=InpDirectoryName+"//"+InpFileName;
//--- open the file
ResetLastError();
int file_handle=FileOpen(path,FILE_READ|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
//--- read all data from the file to the array
FileReadArray(file_handle,arr);
//--- receive the array size
int size=ArraySize(arr);
//--- print data from the array
for(int i=0;i<size;i++)
Print("Date = ",arr[i].date," Bid = ",arr[i].bid," Ask = ",arr[i].ask);
Print("Total data = ",size);
//--- close the file
FileClose(file_handle);
}
else
Print("File open failed, error ",GetLastError());
}
See also
Variables, FileW riteArray
FileReadBool
R eads from the file of CS V type string from the current position to a delimiter (or till the end of the
text line) and converts the read string to a bool type value.
bool FileReadBool(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
Line read may be set to " true" , " false" or the symbolic representation of integers "0" or "1" . A
nonzero value is converted to a logical true. The function returns the converted value.
Example (the file obtained after executing the example for FileW rite function is used here)
//+------------------------------------------------------------------+
//| Demo_FileReadBool.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//---- plot Label1
#property indicator_label1 "UpSignal"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 4
//---- plot Label2
#property indicator_label2 "DownSignal"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 4
//--- parameters for data reading
input string InpFileName="MACD.csv"; // file name
input string InpDirectoryName="Data"; // directory name
//--- global variables
int ind=0; // index
double upbuff[]; // indicator buffers of up arrows
double downbuff[]; // indicator buffer of down arrows
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(high,false);
//--- the loop for the bars that have not been handled yet
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 0 by default
upbuff[i]=0;
downbuff[i]=0;
//--- check if any data is still present
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- if dates coincide, use the value from the file
if(time[i]==time_buff[j])
{
//--- draw the arrow according to the signal
if(sign_buff[j])
upbuff[i]=high[i];
else
downbuff[i]=low[i];
//--- increase the counter
ind=j+1;
break;
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
See also
Type bool, FileW rite
FileReadDatetime
R eads from the file of CS V type a string of one of the formats : "YYYY.MM.DD HH:MI:SS " ,
"YYYY.MM.DD" or "HH:MI:SS " - and converts it into a value of datetime type.
datetime FileReadDatetime(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
Example (the file obtained after executing the example for FileW rite function is used here)
//+------------------------------------------------------------------+
//| Demo_FileReadDateTime.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//---- plot Label1
#property indicator_label1 "UpSignal"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 4
//---- plot Label2
#property indicator_label2 "DownSignal"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 4
//--- parameters for data reading
input string InpFileName="MACD.csv"; // file name
input string InpDirectoryName="Data"; // directory name
//--- global variables
int ind=0; // index
double upbuff[]; // indicator buffers of up arrows
double downbuff[]; // indicator buffer of down arrows
bool sign_buff[]; // signal array (true - buy, false - sell)
See also
Type datetime, StringToTime, TimeToString, FileW rite
FileReadDouble
R eads a double-precision floating point number (double) from the current position of the binary file.
double FileReadDouble(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
Note
Example (the file obtained after executing the example for FileW riteDouble function is used here)
//+------------------------------------------------------------------+
//| Demo_FileReadDouble.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
#property indicator_separate_window
//--- data reading parameters
input string InpFileName="MA.csv"; // file name
input string InpDirectoryName="Data"; // directory name
//--- global variables
int ind=0;
int size=0;
double ma_buff[];
datetime time_buff[];
//--- indicator buffer
double buff[];
//+------------------------------------------------------------------+
See also
R eal types (double, float), StringToDouble, DoubleToString, FileW riteDouble
FileReadFloat
R eads the single-precision floating point number (float) from the current position of the binary file.
float FileReadFloat(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
Note
Example (the file obtained after executing the example for FileW riteFloat function is used here)
//+------------------------------------------------------------------+
//| Demo_FileReadFloat.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "CloseLine"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 clrRed,clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- parameters for data reading
input string InpFileName="Close.bin"; // file name
input string InpDirectoryName="Data"; // directory name
//--- global variables
int ind=0;
int size=0;
double close_buff[];
datetime time_buff[];
//--- indicator buffers
double buff[];
double color_buff[];
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
ArraySetAsSeries(time,false);
//--- the loop for the bars that have not been handled yet
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 0 by default
buff[i]=0;
color_buff[i]=0; // red color by default
//--- check if any data is still present
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- if the dates coincide, the value from the file is used
if(time[i]==time_buff[j])
{
//--- receive the price
buff[i]=close_buff[j];
//--- if the current price exceeds the previous one, the color is blue
if(buff[i-1]>buff[i])
color_buff[i]=1;
//--- increase the counter
ind=j+1;
break;
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
See also
R eal types (double, float), FileR eadDouble, FileW riteFloat
FileReadInteger
The function reads int, short or char value from the current position of the file pointer depending on
the length specified in bytes.
int FileReadInteger(
int file_handle, // File handle
int size=INT_VALUE // Size of an integer in bytes
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
size=INT_VALUE
[in] Number of bytes (up to 4 inclusive) that should be read. The corresponding constants are
provided: CHAR_VAL UE = 1, S H OR T _VAL UE = 2 and I NT _VAL UE = 4, so the function can read the
whole value of char, short or int type.
Return Value
A value of the int type. The result of this function must be explicitly cast to a target type, i.e. to the
type of data that you need to read. Since a value of the int type is returned, it can be easily
converted to any integer value. The file pointer is shifted by the number of bytes read.
Note
W hen reading less than 4 bytes, the received result is always positive. If one or two bytes are read,
the sign of the number can be determined by explicit casting to type char (1 byte) or short (2 bytes).
Getting the sign for a three-byte number is not trivial, since there is no corresponding underlying
type.
Example (the file obtained after executing the example for FileW riteInteger function is used here)
//+------------------------------------------------------------------+
//| Demo_FileReadInteger.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "Trends"
#property indicator_type1 DRAW_SECTION
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- bind the array to the indicator buffer
SetIndexBuffer(0,buff,INDICATOR_DATA);
//---- set the indicator values that will not be visible on the chart
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(close,false);
//--- the loop for the bars that have not been handled yet
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 0 by default
buff[i]=0;
//--- check if any data is still present
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- if dates coincide, the value from the file is used
if(time[i]==time_buff[j])
{
//--- receive the price
buff[i]=close[i];
//--- increase the counter
ind=j+1;
break;
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
See also
IntegerToString, StringToInteger, Integer types, FileW riteInteger
FileReadLong
The function reads an integer of long type (8 bytes) from the current position of the binary file.
long FileReadLong(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
Example (the file obtained during the execution of an example for FileW riteLong function is used
here)
//+------------------------------------------------------------------+
//| Demo_FileReadLong.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_buffers 1
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "Volume"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrYellow
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
#property indicator_separate_window
//--- parameters for data reading
input string InpFileName="Volume.bin"; // file name
input string InpDirectoryName="Data"; // directory name
//--- global variables
int ind=0;
int size=0;
long volume_buff[];
datetime time_buff[];
//--- indicator buffers
double buff[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- open the file
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is open for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- first, read the amount of data in the file
size=(int)FileReadLong(file_handle);
//--- allocate memory for the arrays
ArrayResize(volume_buff,size);
ArrayResize(time_buff,size);
//--- read data from the file
for(int i=0;i<size;i++)
{
time_buff[i]=(datetime)FileReadLong(file_handle);
volume_buff[i]=FileReadLong(file_handle);
}
//--- close the file
FileClose(file_handle);
PrintFormat("Data is read, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- bind the array to the indicator buffer with 0 index
SetIndexBuffer(0,buff,INDICATOR_DATA);
//---- set the indicator values that will be visible on the chart
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
ArraySetAsSeries(time,false);
//--- the loop for the bars that have not been handled yet
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 0 by default
buff[i]=0;
//--- check if any data is still present
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- if dates coincide, the value from the file is used
if(time[i]==time_buff[j])
{
buff[i]=(double)volume_buff[j];
ind=j+1;
break;
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
See also
Integer types, FileR eadInteger, FileW riteLong
FileReadNumber
The function reads from the CS V file a string from the current position till a separator (or till the end
of a text string) and converts the read string to a value of double type.
double FileReadNumber(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
Example (the file obtained during the execution of an example for FileW riteString function is used
here)
//+------------------------------------------------------------------+
//| Demo_FileReadNumber.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "Overbought & Oversold"
#property indicator_type1 DRAW_COLOR_BARS
#property indicator_color1 clrRed, clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- parameters for data reading
input string InpFileName="RSI.csv"; // file name
input string InpDirectoryName="Data"; // directory name
//--- indicator buffers
double open_buff[];
double high_buff[];
double low_buff[];
double close_buff[];
double color_buff[];
//--- overbought variables
int ovb_ind=0;
int ovb_size=0;
datetime ovb_time[];
//---- set the indicator values that will not be visible on the chart
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Read the file's string data |
//+------------------------------------------------------------------+
void ReadData(const int file_handle,datetime &arr[],int &size,int &def_size)
{
bool flag=false;
//--- read till the end of the string or of the file is reached
while(!FileIsLineEnding(file_handle) && !FileIsEnding(file_handle))
{
//--- shift the carriage after reading the number
if(flag)
FileReadNumber(file_handle);
//--- store the current date
arr[size]=FileReadDatetime(file_handle);
size++;
//--- increase the array size if necessary
if(size==def_size)
{
def_size+=100;
ArrayResize(arr,def_size);
}
//--- slip past the first iteration
flag=true;
}
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
ArraySetAsSeries(time,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- the loop for the bars that have not been handled yet
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 0 by default
open_buff[i]=0;
high_buff[i]=0;
low_buff[i]=0;
close_buff[i]=0;
color_buff[i]=0;
//--- check if any date is still present
if(ovb_ind<ovb_size)
for(int j=ovb_ind;j<ovb_size;j++)
{
//--- if the dates coincide, the bar is in the overbought area
if(time[i]==ovb_time[j])
{
open_buff[i]=open[i];
high_buff[i]=high[i];
low_buff[i]=low[i];
close_buff[i]=close[i];
//--- 0 - red color
color_buff[i]=0;
//--- increase the counter
ovb_ind=j+1;
break;
}
}
//--- check if any data still exists
if(ovs_ind<ovs_size)
for(int j=ovs_ind;j<ovs_size;j++)
{
//--- if the dates coincide, the bar is in the oversold area
if(time[i]==ovs_time[j])
{
open_buff[i]=open[i];
high_buff[i]=high[i];
low_buff[i]=low[i];
close_buff[i]=close[i];
//--- 1 - blue color
color_buff[i]=1;
//--- increase the counter
ovs_ind=j+1;
break;
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent event handler |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam
)
{
//--- change the indicator width according to the scale
if(ChartGetInteger(0,CHART_SCALE)>3)
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2);
else
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,1);
}
See also
FileW riteString
FileReadString
The function reads a string from the current position of a file pointer in a file.
string FileReadString(
int file_handle, // File handle
int length=-1 // Length of the string
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
length=-1
[in] Number of characters to read.
Return Value
Note
W hen reading from a bin-file. the length of a string to read must be specified. W hen reading from a
txt-file the string length is not required, and the string will be read from the current position to the
line feed character "\ r\ n" . W hen reading from a csv-file, the string length isn't required also, the
string will be read from the current position till the nearest delimiter or till the text string end
character.
If the file is opened with FIL E_ANSI flag, then the line read is converted to Unicode.
Example (the file obtained after executing the example for FileW riteInteger function is used here)
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for data reading
input string InpFileName="Trend.bin"; // file name
input string InpDirectoryName="Data"; // directory name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- open the file
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN|FILE_ANSI);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- additional variables
int str_size;
string str;
See also
String Type, Conversion Functions, FileW riteInteger
FileReadStruct
The function reads contents into a structure passed as a parameter from a binary-file, starting with
the current position of the file pointer.
uint FileReadStruct(
int file_handle, // file handle
const void& struct_object, // target structure to which the contents are read
int size=-1 // structure size in bytes
);
Parameters
file_handle
[in] File descriptor of an open bin-file.
struct_object
[out] The object of this structure. The structure should not contain strings, dynamic arrays or
virtual functions.
size=-1
[in] Number of bytes that should be read. If size is not specified or the indicated value is greater
than the size of the structure, the exact size of the specified structure is used.
Return Value
If successful the function returns the number of bytes read. File pointer is moved by the same
number of bytes.
Example (the file obtained after using the example for FileW riteStruct function is used here)
//+------------------------------------------------------------------+
//| Demo_FileReadStruct.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "Candles"
#property indicator_type1 DRAW_CANDLES
#property indicator_color1 clrOrange
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_separate_window
//--- parameters for receiving data
input string InpFileName="EURUSD.txt"; // file name
input string InpDirectoryName="Data"; // directory name
//+------------------------------------------------------------------+
//| Structure for storing candlestick data |
//+------------------------------------------------------------------+
struct candlesticks
{
double open; // open price
double close; // close price
double high; // high price
double low; // low price
datetime date; // date
};
//--- indicator buffers
double open_buff[];
double close_buff[];
double high_buff[];
double low_buff[];
//--- global variables
candlesticks cand_buff[];
int size=0;
int ind=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
int default_size=100;
ArrayResize(cand_buff,default_size);
//--- open the file
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN|FILE_COMMON);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
//--- read data from the file
while(!FileIsEnding(file_handle))
{
//--- write data to the array
FileReadStruct(file_handle,cand_buff[size]);
size++;
//--- check if the array is overflown
if(size==default_size)
{
//--- increase the array size
default_size+=100;
ArrayResize(cand_buff,default_size);
}
}
//--- close the file
FileClose(file_handle);
PrintFormat("Data is read, %s file is closed",InpFileName);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
return(INIT_FAILED);
}
//--- indicator buffers mapping
SetIndexBuffer(0,open_buff,INDICATOR_DATA);
SetIndexBuffer(1,high_buff,INDICATOR_DATA);
SetIndexBuffer(2,low_buff,INDICATOR_DATA);
SetIndexBuffer(3,close_buff,INDICATOR_DATA);
//--- empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
ArraySetAsSeries(time,false);
//--- the loop for the candlesticks that have not been handled yet
for(int i=prev_calculated;i<rates_total;i++)
{
//--- 0 by default
open_buff[i]=0;
close_buff[i]=0;
high_buff[i]=0;
low_buff[i]=0;
//--- check if any data is still present
if(ind<size)
{
for(int j=ind;j<size;j++)
{
//--- if dates coincide, the value from the file is used
if(time[i]==cand_buff[j].date)
{
open_buff[i]=cand_buff[j].open;
close_buff[i]=cand_buff[j].close;
high_buff[i]=cand_buff[j].high;
low_buff[i]=cand_buff[j].low;
//--- increase the counter
ind=j+1;
break;
}
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
See also
Structures and classes, FileW riteStruct
FileSeek
The function moves the position of the file pointer by a specified number of bytes relative to the
specified position.
bool FileSeek(
int file_handle, // File handle
long offset, // In bytes
ENUM_FILE_POSITION origin // Position for reference
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
offset
[in] The shift in bytes (may tak e a negative value).
origin
[in] The starting point for the displacement. Can be one of values of ENUM _FIL E_POSITION.
Return Value
If successful the function returns true, otherwise false. To obtain information about the error call
the GetLastError() function.
Note
If the execution of the FileSeek () function results in a negative shift (going beyond the " level
boundary" of the file), the file pointer will be set to the file beginning.
If a position is set beyond the " right boundary" of the file (larger than the file size), the next writing
to the file will be performed not from the end of the file, but from the position set. In this case
indefinite values will be written for the previous file end and the position set.
Example:
//+------------------------------------------------------------------+
//| Demo_FileSeek.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input string InpFileName="file.txt"; // file name
input string InpDirectoryName="Data"; // directory name
input int InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64
//+------------------------------------------------------------------+
int def_size=127;
//--- allocate memory for the array
ArrayResize(arr,def_size);
//--- string counter
int i=0;
//--- if this is not the file's end, then there is at least one string
if(!FileIsEnding(handle))
{
arr[i]=FileTell(handle);
i++;
}
else
return; // the file is empty, exit
//--- define the shift in bytes depending on encoding
int shift;
if(FileGetInteger(handle,FILE_IS_ANSI))
shift=1;
else
shift=2;
//--- go through the strings in the loop
while(1)
{
//--- read the string
FileReadString(handle);
//--- check for the file end
if(!FileIsEnding(handle))
{
//--- store the next string's position
arr[i]=FileTell(handle)+shift;
i++;
//--- increase the size of the array if it is overflown
if(i==def_size)
{
def_size+=def_size+1;
ArrayResize(arr,def_size);
}
}
else
break; // end of the file, exit
}
//--- define the actual size of the array
ArrayResize(arr,i);
}
FileSize
The function returns the file size in bytes.
ulong FileSize(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
Note
Example:
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input ulong InpThresholdSize=20; // file threshold size in kilobytes
input string InpBigFolderName="big"; // folder for large files
input string InpSmallFolderName="small"; // folder for small files
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string file_name; // variable for storing file names
string filter="*.csv"; // filter for searching the files
ulong file_size=0; // file size in bytes
int size=0; // number of files
//--- print the path to the file we are going to work with
PrintFormat("Working in %s\\Files\\ folder",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
//--- receive the search handle in common folder's root of all terminals
long search_handle=FileFindFirst(filter,file_name,FILE_COMMON);
//--- check if FileFindFirst() has been executed successfully
if(search_handle!=INVALID_HANDLE)
{
//--- move files in the loop according to their size
do
{
//--- open the file
ResetLastError();
int file_handle=FileOpen(file_name,FILE_READ|FILE_CSV|FILE_COMMON);
if(file_handle!=INVALID_HANDLE)
{
//--- receive the file size
file_size=FileSize(file_handle);
//--- close the file
FileClose(file_handle);
}
else
{
PrintFormat("Failed to open %s file, Error code = %d",file_name,GetLastError());
continue;
}
//--- print the file size
PrintFormat("Size of %s file is equal to %d bytes",file_name,file_size);
//--- define the path for moving the file
string path;
if(file_size>InpThresholdSize*1024)
path=InpBigFolderName+"//"+file_name;
else
path=InpSmallFolderName+"//"+file_name;
//--- move the file
ResetLastError();
if(FileMove(file_name,FILE_COMMON,path,FILE_REWRITE|FILE_COMMON))
PrintFormat("%s file is moved",file_name);
else
PrintFormat("Error, code = %d",GetLastError());
}
while(FileFindNext(search_handle,file_name));
//--- close the search handle
FileFindClose(search_handle);
}
else
Print("Files not found!");
}
FileTell
The file returns the current position of the file pointer of an open file.
ulong FileTell(
int file_handle // File handle
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
Return Value
Current position of the file descriptor in bytes from the beginning of the file.
Note
Example:
//+------------------------------------------------------------------+
//| Demo_FileTell.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- display the window of input parameters when launching the script
#property script_show_inputs
//--- input parameters
input string InpFileName="file.txt"; // file name
input string InpDirectoryName="Data"; // directory name
input int InpEncodingType=FILE_ANSI; // ANSI=32 or UNICODE=64
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- specify the value of the variable for generating random numbers
_RandomSeed=GetTickCount();
//--- variables for positions of the strings' start points
ulong pos[];
int size;
//--- reset the error value
ResetLastError();
//--- open the file
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_TXT|InpEncodingType);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for reading",InpFileName);
//--- receive start position for each string in the file
GetStringPositions(file_handle,pos);
//--- define the number of strings in the file
size=ArraySize(pos);
if(!size)
{
//--- stop if the file does not have strings
PrintFormat("%s file is empty!",InpFileName);
FileClose(file_handle);
return;
}
//--- make a random selection of a string number
int ind=MathRand()%size;
//--- shift position to the starting point of the string
FileSeek(file_handle,pos[ind],SEEK_SET);
//--- read and print the string with ind number
PrintFormat("String text with %d number: \"%s\"",ind,FileReadString(file_handle));
//--- close the file
FileClose(file_handle);
PrintFormat("%s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
//+-------------------------------------------------------------------------------+
//| The function defines starting points for each of the strings in the file and |
//| places them in arr array |
//+-------------------------------------------------------------------------------+
void GetStringPositions(const int handle,ulong &arr[])
{
//--- default array size
int def_size=127;
//--- allocate memory for the array
ArrayResize(arr,def_size);
//--- string counter
int i=0;
//--- if this is not the file's end, then there is at least one string
if(!FileIsEnding(handle))
{
arr[i]=FileTell(handle);
i++;
}
else
return; // the file is empty, exit
//--- define the shift in bytes depending on encoding
int shift;
if(FileGetInteger(handle,FILE_IS_ANSI))
shift=1;
else
shift=2;
//--- go through the strings in the loop
while(1)
{
//--- read the string
FileReadString(handle);
//--- check for the file end
if(!FileIsEnding(handle))
{
//--- store the next string's position
arr[i]=FileTell(handle)+shift;
i++;
//--- increase the size of the array if it is overflown
if(i==def_size)
{
def_size+=def_size+1;
ArrayResize(arr,def_size);
}
}
else
break; // end of the file, exit
}
//--- define the actual size of the array
ArrayResize(arr,i);
}
FileWrite
The function is intended for writing of data into a CS V file, delimiter being inserted automatically
unless it is equal to 0. After writing into the file, the line end character "\ r\ n" will be added.
uint FileWrite(
int file_handle, // File handle
... // List of recorded parameters
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
...
[in] The list of parameters separated by commas, to write to the file. The number of written
parameters can be up to 63.
Return Value
Note
Numbers will be converted into a text at output (see the Print() function). Data of the double type
are output with the accuracy of 16 digits after the decimal point, and the data can be displayed
either in traditional or in scientific format - depending on which format will be the most compact.
The data of the float type are shown with 5 digits after the decimal point. To output real numbers
with different precision or in a clearly specified format, use DoubleToString().
Numbers of the bool type are displayed as " true" or " false" strings. Numbers of the datetime type are
displayed as "YYYY.MM.DD HH:MI :SS " .
Example:
//+------------------------------------------------------------------+
//| Demo_FileWrite.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
input string InpSymbolName="EURUSD"; // currency pair
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // time frame
input int InpFastEMAPeriod=12; // fast EMA period
input int InpSlowEMAPeriod=26; // slow EMA period
input int InpSignalPeriod=9; // difference averaging period
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE; // price type
ArrayResize(sign_buff,macd_size-1);
ArrayResize(time_buff,macd_size-1);
for(int i=1;i<macd_size;i++)
{
//--- buy signal
if(macd_buff[i-1]<0 && macd_buff[i]>=0)
{
sign_buff[sign_size]=true;
time_buff[sign_size]=date_buff[i];
sign_size++;
}
//--- sell signal
if(macd_buff[i-1]>0 && macd_buff[i]<=0)
{
sign_buff[sign_size]=false;
time_buff[sign_size]=date_buff[i];
sign_size++;
}
}
//--- open the file for writing the indicator values (if the file is absent, it will be created aut
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- first, write the number of signals
FileWrite(file_handle,sign_size);
//--- write the time and values of signals to the file
for(int i=0;i<sign_size;i++)
FileWrite(file_handle,time_buff[i],sign_buff[i]);
//--- close the file
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
See also
Comment, Print, String Format
FileWriteArray
The function writes arrays of any type except for string to a BI N file (can be an array of structures not
containing strings or dynamic arrays).
uint FileWriteArray(
int file_handle, // File handle
const void& array[], // Array
int start=0, // Start index in the array
int count=WHOLE_ARRAY // Number of elements
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
array[]
[out] Array for recording.
start=0
[in] Initial index in the array (number of the first recorded element).
count=WHOLE_ARRAY
[in] Number of items to write (WH OL E_ARRAY means that all items starting with the number start
until the end of the array will be written).
Return Value
Note
String array can be recorded in a T XT file. In this case, strings are automatically ended by the line
end characters "\ r\ n" . Depending on the file type ANSI or UNICODE, strings are either converted to
ansi-encoding or not.
Example:
//+------------------------------------------------------------------+
//| Demo_FileWriteArray.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- input parameters
input string InpFileName="data.bin";
input string InpDirectoryName="SomeFolder";
//+------------------------------------------------------------------+
//| Structure for storing price data |
//+------------------------------------------------------------------+
struct prices
{
datetime date; // date
double bid; // bid price
double ask; // ask price
};
//--- global variables
int count=0;
int size=20;
string path=InpDirectoryName+"//"+InpFileName;
prices arr[];
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- allocate memory for the array
ArrayResize(arr,size);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- write the remaining count strings if count<n
WriteData(count);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- save data to array
arr[count].date=TimeCurrent();
arr[count].bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
arr[count].ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
//--- show current data
Print("Date = ",arr[count].date," Bid = ",arr[count].bid," Ask = ",arr[count].ask);
//--- increase the counter
count++;
//--- if the array is filled, write data to the file and zero it out
if(count==size)
{
WriteData(size);
count=0;
}
}
//+------------------------------------------------------------------+
//| Write n elements of the array to file |
//+------------------------------------------------------------------+
void WriteData(const int n)
{
//--- open the file
ResetLastError();
int handle=FileOpen(path,FILE_READ|FILE_WRITE|FILE_BIN);
if(handle!=INVALID_HANDLE)
{
//--- write array data to the end of the file
FileSeek(handle,0,SEEK_END);
FileWriteArray(handle,arr,0,n);
//--- close the file
FileClose(handle);
}
else
Print("Failed to open the file, error ",GetLastError());
}
See also
Variables, FileSeek
FileWriteDouble
The function writes the value of a double parameter to a a bin-file, starting from the current position
of the file pointer.
uint FileWriteDouble(
int file_handle, // File handle
double value // Value to write
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
value
[in] The value of double type.
Return Value
If successful the function returns the number of bytes written (in this case sizeof(double)=8). The
file pointer is shifted by the same number of bytes.
Example:
//+------------------------------------------------------------------+
//| Demo_FileWriteDouble.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
input string InpSymbolName="EURJPY"; // currency pair
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_M15; // time frame
input int InpMAPeriod=10; // smoothing period
input int InpMAShift=0; // indicator shift
input ENUM_MA_METHOD InpMAMethod=MODE_SMA; // smoothing type
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE; // price type
input datetime InpDateStart=D'2013.01.01 00:00'; // data copying start date
//--- parameters for writing data to the file
input string InpFileName="MA.csv"; // file name
input string InpDirectoryName="Data"; // directory name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
double ma_buff[];
datetime time_buff[];
int size;
//--- receive MA indicator handle
ResetLastError();
int ma_handle=iMA(InpSymbolName,InpSymbolPeriod,InpMAPeriod,InpMAShift,InpMAMethod,InpAppliedPri
if(ma_handle==INVALID_HANDLE)
{
//--- failed to receive the indicator handle
PrintFormat("Error when receiving indicator handle. Error code = %d",GetLastError());
return;
}
//--- being in the loop until the indicator calculates all its values
while(BarsCalculated(ma_handle)==-1)
Sleep(20); // a pause to allow the indicator to calculate all its values
PrintFormat("Indicator values starting from %s will be written to the file",TimeToString(InpDate
//--- copy the indicator values
ResetLastError();
if(CopyBuffer(ma_handle,0,InpDateStart,date_finish,ma_buff)==-1)
{
PrintFormat("Failed to copy the indicator values. Error code = %d",GetLastError());
return;
}
//--- copy the time of the appropriate bars' arrival
ResetLastError();
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- receive the buffer size
size=ArraySize(ma_buff);
//--- free the memory occupied by the indicator
IndicatorRelease(ma_handle);
//--- open the file for writing the indicator values (if the file is absent, it will be created aut
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- first, write the size of data sample
FileWriteDouble(file_handle,(double)size);
//--- write the indicator time and value to the file
for(int i=0;i<size;i++)
{
FileWriteDouble(file_handle,(double)time_buff[i]);
FileWriteDouble(file_handle,ma_buff[i]);
}
//--- close the file
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
See also
R eal types (double, float)
FileWriteFloat
The function writes the value of the float parameter to a bin-file, starting from the current position of
the file pointer.
uint FileWriteFloat(
int file_handle, // File handle
float value // Value to be written
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
value
[in] The value of float type.
Return Value
If successful the function returns the number of bytes written (in this case sizeof(float)=4). The file
pointer is shifted by the same number of bytes.
Example:
//+------------------------------------------------------------------+
//| Demo_FileWriteFloat.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
input string InpSymbolName="EURUSD"; // currency pair
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_M15; // time frame
input datetime InpDateStart=D'2013.01.01 00:00'; // data copying start date
//--- parameters for writing data to the file
input string InpFileName="Close.bin"; // file name
input string InpDirectoryName="Data"; // directory name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
double close_buff[];
datetime time_buff[];
int size;
See also
R eal types (double, float), FileW riteDouble
FileWriteInteger
The function writes the value of the int parameter to a bin-file, starting from the current position of
the file pointer.
uint FileWriteInteger(
int file_handle, // File handle
int value, // Value to be written
int size=INT_VALUE // Size in bytes
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
value
[in] Integer value.
size=INT_VALUE
[in] Number of bytes (up to 4 inclusive), that should be written. The corresponding constants are
provided: CHAR_VAL UE=1, S H OR T _VAL UE=2 and I NT _VAL UE=4, so the function can write the
integer value of char, uchar, short, ushort, int, or uint type.
Return Value
If successful the function returns the number of bytes written. The file pointer is shifted by the
same number of bytes.
Example:
//+------------------------------------------------------------------+
//| Demo_FileWriteInteger.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
input string InpSymbolName="EURUSD"; // currency pair
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // time frame
input datetime InpDateStart=D'2013.01.01 00:00'; // data copying start date
//--- parameters for writing data to the file
input string InpFileName="Trend.bin"; // file name
input string InpDirectoryName="Data"; // directory name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
double close_buff[];
datetime time_buff[];
int size;
//--- reset the error value
ResetLastError();
//--- copy the close price for each bar
if(CopyClose(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,close_buff)==-1)
{
PrintFormat("Failed to copy the values of close prices. Error code = %d",GetLastError());
return;
}
//--- copy the time for each bar
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- receive the buffer size
size=ArraySize(close_buff);
//--- open the file for writing the values (if the file is absent, it will be created automatically
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//---
int up_down=0; // trend flag
int arr_size; // arr array size
uchar arr[]; // uchar type array
//--- write time values to the file
for(int i=0;i<size-1;i++)
{
//--- compare close prices of the current and next bars
if(close_buff[i]<=close_buff[i+1])
{
if(up_down!=1)
{
//--- write date value to the file using FileWriteInteger
StringToCharArray(TimeToString(time_buff[i]),arr);
arr_size=ArraySize(arr);
//--- first, write the number of symbols in the array
FileWriteInteger(file_handle,arr_size,INT_VALUE);
//--- write the symbols
for(int j=0;j<arr_size;j++)
FileWriteInteger(file_handle,arr[j],CHAR_VALUE);
//--- change the trend flag
up_down=1;
}
}
else
{
if(up_down!=-1)
{
//--- write the date value to the file using FileWriteInteger
StringToCharArray(TimeToString(time_buff[i]),arr);
arr_size=ArraySize(arr);
//--- first, write the number of symbols in the array
FileWriteInteger(file_handle,arr_size,INT_VALUE);
//--- write the symbols
for(int j=0;j<arr_size;j++)
FileWriteInteger(file_handle,arr[j],CHAR_VALUE);
//--- change the trend flag
up_down=-1;
}
}
}
//--- close the file
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
See also
IntegerToString, StringToInteger, Integer types
FileWriteLong
The function writes the value of the long-type parameter to a bin-file, starting from the current
position of the file pointer.
uint FileWriteLong(
int file_handle, // File handle
long value // Value to be written
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
value
[in] Value of type long.
Return Value
If successful the function returns the number of bytes written (in this case sizeof(long)=8). The file
pointer is shifted by the same number of bytes.
Example:
//+------------------------------------------------------------------+
//| Demo_FileWriteLong.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
input string InpSymbolName="EURUSD"; // currency pair
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // time frame
input datetime InpDateStart=D'2013.01.01 00:00'; // data copying start date
//--- parameters for writing data to the file
input string InpFileName="Volume.bin"; // file name
input string InpDirectoryName="Data"; // directory name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
long volume_buff[];
datetime time_buff[];
int size;
See also
Integer types, FileW riteInteger
FileWriteString
The function writes the value of a string-type parameter into a BI N, CS V or T XT file starting from the
current position of the file pointer. W hen writing to a CS V or T XT file: if there is a symbol in the string
'\n' (L F) without previous character '\r' (CR ), then before '\n' the missing '\r' is added.
uint FileWriteString(
int file_handle, // File handle
const string text_string, // string to write
int length=-1 // number of symbols
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
text_string
[in] String.
length=-1
[in] The number of characters that you want to write. This option is needed for writing a string
into a BI N file. If the size is not specified, then the entire string without the trailer 0 is written. If
you specify a size smaller than the length of the string, then a part of the string without the trailer
0 is written. If you specify a size greater than the length of the string, the string is filled by the
appropriate number of zeros. For files of CS V and T XT type, this parameter is ignored and the
string is written entirely.
Return Value
If successful the function returns the number of bytes written. The file pointer is shifted by the
same number of bytes.
Note
Note that when writing to a file opened by the FIL E_UNICODE flag (or without a flag FIL E_ANSI), then
the number of bytes written will be twice as large as the number of string characters written. W hen
recording to a file opened with the FIL E_ANSI flag, the number of bytes written will coincide with the
number of string characters written.
Example:
//+------------------------------------------------------------------+
//| Demo_FileWriteString.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
//--- open the file for writing the indicator values (if the file is absent, it will be created aut
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV|FILE_AN
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- prepare additional variables
string str="";
bool is_formed=false;
//--- write dates of forming overbought and oversold areas
for(int i=0;i<rsi_size;i++)
{
//--- check the indicator values
if(rsi_buff[i]>=70 || rsi_buff[i]<=30)
{
//--- if the value is the first one in this area
if(!is_formed)
{
//--- add the value and the date
str=(string)rsi_buff[i]+"\t"+(string)date_buff[i];
is_formed=true;
}
else
str+="\t"+(string)rsi_buff[i]+"\t"+(string)date_buff[i];
//--- move to the next loop iteration
continue;
}
//--- check the flag
if(is_formed)
{
//--- the string is formed, write it to the file
FileWriteString(file_handle,str+"\r\n");
is_formed=false;
}
}
//--- close the file
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
See also
String Type, String Format
FileWriteStruct
The function writes into a bin-file contents of a structure passed as a parameter, starting from the
current position of the file pointer.
uint FileWriteStruct(
int file_handle, // File handle
const void& struct_object, // link to an object
int size=-1 // size to be written in bytes
);
Parameters
file_handle
[in] File descriptor returned by FileOpen().
struct_object
[in] R eference to the object of this structure. The structure should not contain strings, dynamic
arrays or virtual functions.
size=-1
[in] Number of bytes that you want to record. If size is not specified or the specified number of
bytes is greater than the size of the structure, the entire structure is written.
Return Value
If successful the function returns the number of bytes written. The file pointer is shifted by the
same number of bytes.
Example:
//+------------------------------------------------------------------+
//| Demo_FileWiteStruct.mq5 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for receiving data from the terminal
input string InpSymbolName="EURUSD"; // currency pair
input ENUM_TIMEFRAMES InpSymbolPeriod=PERIOD_H1; // time frame
input datetime InpDateStart=D'2013.01.01 00:00'; // data copying start date
//--- parameters for writing data to the file
input string InpFileName="EURUSD.txt"; // file name
input string InpDirectoryName="Data"; // directory name
//+------------------------------------------------------------------+
//| Structure for storing candlestick data |
//+------------------------------------------------------------------+
struct candlesticks
{
double open; // open price
double close; // close price
double high; // high price
double low; // low price
datetime date; // date
};
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
datetime date_finish=TimeCurrent();
int size;
datetime time_buff[];
double open_buff[];
double close_buff[];
double high_buff[];
double low_buff[];
candlesticks cand_buff[];
//--- reset the error value
ResetLastError();
//--- receive the time of the arrival of the bars from the range
if(CopyTime(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,time_buff)==-1)
{
PrintFormat("Failed to copy time values. Error code = %d",GetLastError());
return;
}
//--- receive high prices of the bars from the range
if(CopyHigh(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,high_buff)==-1)
{
PrintFormat("Failed to copy values of high prices. Error code = %d",GetLastError());
return;
}
//--- receive low prices of the bars from the range
if(CopyLow(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,low_buff)==-1)
{
PrintFormat("Failed to copy values of low prices. Error code = %d",GetLastError());
return;
}
//--- receive open prices of the bars from the range
if(CopyOpen(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,open_buff)==-1)
{
PrintFormat("Failed to copy values of open prices. Error code = %d",GetLastError());
return;
}
//--- receive close prices of the bars from the range
if(CopyClose(InpSymbolName,InpSymbolPeriod,InpDateStart,date_finish,close_buff)==-1)
{
//--- open the file for writing the structure array to the file (if the file is absent, it will be
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_BIN|FILE_CO
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is open for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_COMMONDATA_PATH));
//--- prepare the counter of the number of bytes
uint counter=0;
//--- write array values in the loop
for(int i=0;i<size;i++)
counter+=FileWriteStruct(file_handle,cand_buff[i]);
PrintFormat("%d bytes of information is written to %s file",InpFileName,counter);
PrintFormat("Total number of bytes: %d * %d * %d = %d, %s",size,5,8,size*5*8,size*5*8==counte
//--- close the file
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
See also
Structures and classes
FileLoad
R eads all data of a specified binary file into a passed array of numeric types or simple structures. The
function allows you to quick ly read data of a k nown type into the appropriate array.
long FileLoad(
const string file_name, // File name
void& buffer[], // An array of numeric types or simple structures
int common_flag=0 // A file flag, is searched in <data_folder>\MQL5\Files\ by def
);
Parameters
file_name
[in] The name of the file from which data will be read.
buffer
[out] An array of numeric types or simple structures.
common_flag=0
[in] A file flag indicating the operation mode. If the parameter is not specified, the file is
searched in the subfolder MQL5\Files (or in <testing _agent_directory>\ MQL5\Files in case of
testing).
Return Value
Note
The FileLoad() function reads from a file the number of bytes multiple of the array element size.
Suppose the file size is 10 bytes, and the function reads data into an array of type double
(sizeof(double)=8). In this case the function will read only 8 bytes, the remaining 2 bytes at the end
of the file will be dropped, and the function FileLoad() will return 1 (1 element read).
Example:
//+------------------------------------------------------------------+
//| Demo_FileLoad.mq5 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- input parameters
input int bars_to_save=10; // Number of bars
//+------------------------------------------------------------------+
See also
Structures and Classes, FileR eadArray, FileR eadStruct, FileSave
FileSave
W rites to a binary file all elements of an array passed as a parameter. The function allows you to
quick ly write arrays of numeric types or simple structures as one string.
bool FileSave(
const string file_name, // File name
void& buffer[], // An array of numeric types or simple structures
int common_flag=0 // A file flag, by default files are written to <data_folder>\M
);
Parameters
file_name
[in] The name of the file, to the data array will be written.
buffer
[in] An array of numeric types or simple structures.
common_flag=0
[in] A file flag indicating the operation mode. If the parameter is not specified, the file will be
written to the subfolder MQL5\Files (or to <testing _agent_directory>\ MQL5\Files in case of
testing).
Return Value
Example:
//+------------------------------------------------------------------+
//| Demo_FileSave.mq5 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property script_show_inputs
//--- input parameters
input int ticks_to_save=1000; // Number of ticks
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string filename=_Symbol+"_ticks.bin";
MqlTick ticks[];
u//---
int copied=CopyTicks(_Symbol,ticks,COPY_TICKS_ALL,0,ticks_to_save);
if(copied!=-1)
{
See also
Structures and Classes, FileW riteArray, FileW riteStruct, FileLoad, FileW rite
FolderCreate
Creates a directory in the Files folder (depending on the common_flag value)
bool FolderCreate(
string folder_name, // line with the created folder name
int common_flag=0 // action area
);
Parameters
folder_name
[in] Name of the directory to be created. Contains the relative path to the folder.
common_flag=0
[in] Flag defining the directory location. If common_flag =FIL E_COMMON, the directory is located
in the common folder of all client terminals \ Terminal\ Common\Files. Otherwise, the directory is in
the local folder (MQL5\Files or MQL5\ Tester\Files when testing).
Return Value
Note
For reasons of security, work ing with files is strictly controlled in MQL5 language. Files used in file
operations by means of MQL5 language cannot be located outside the file sandbox.
Example:
//--- display window of the input parameters during the script's launch
#property script_show_inputs
//--- the input parameter defines the folder, in which the script works
input bool common_folder=false; // common folder for all terminals
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- folder to be created in MQL5\Files
string root_folder="Folder_A";
if(CreateFolder(root_folder,common_folder))
{
//--- create the Child_Folder_B1 sub-folder in it
string folder_B1="Child_Folder_B1";
string path=root_folder+"\\"+folder_B1; // create the folder name considering the st
if(CreateFolder(path,common_folder))
{
//--- create 3 more sub-directories in this folder
string folder_C11="Child_Folder_C11";
string child_path=root_folder+"\\"+folder_C11;// create the folder name considering the st
CreateFolder(child_path,common_folder);
//--- second sub-directory
string folder_C12="Child_Folder_C12";
child_path=root_folder+"\\"+folder_C12;
CreateFolder(child_path,common_folder);
See also
FileOpen(), FolderClean(), FileCopy()
FolderDelete
The function removes the specified directory. If the folder is not empty, then it can't be removed.
bool FolderDelete(
string folder_name, // String with the name of the folder to delete
int common_flag=0 // Scope
);
Parameters
folder_name
[in] The name of the directory you want to delete. Contains the full path to the folder.
common_flag=0
[in] Flag determining the location of the directory. If common_flag =FIL E_COMMON, then the
directory is in the shared folder for all client terminals \ Terminal\ Common\Files. Otherwise, the
directory is in a local folder (MQL5\Files or MQL5\ Tester\Files in the case of testing).
Return Value
Note
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means, cannot be outside the file sandbox.
If the directory contains at least one file and/or subdirectory, then this directory can't be deleted, it
must be cleared first. FolderClean() is used to clear a folder of all its files or subfolders.
Example:
//+------------------------------------------------------------------+
//| Demo_FolderDelete.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- Description
#property description "The script shows a sample use of FolderDelete()."
#property description "First two folders are created; one of them is empty, the second one contains
#property description "When trying to delete a non-empty folder, an error is returned and a warning
//--- Show the dialog of input parameters when starting the script
#property script_show_inputs
//--- Input parameters
input string firstFolder="empty"; // An empty folder
input string secondFolder="nonempty";// The folder, in which one file will be created
string filename="delete_me.txt"; // The name of the file that will be created in folder secon
//+------------------------------------------------------------------+
else
PrintFormat("Failed to delete folder %s. Error code=%d", firstFolder, GetLastError());
ResetLastError();
//--- Delete the folder that contains a file
if(FolderDelete(secondFolder))
PrintFormat("Folder %s has been successfully deleted", secondFolder);
else
//--- The following message should appear since the folder contains a file
PrintFormat("Failed to delete folder %s. Error code=%d", secondFolder, GetLastError());
}
else
Print("Deletion canceled");
//---
}
See also
FileOpen(), FolderClean(), FileMove()
FolderClean
The function deletes all files in a specified folder.
bool FolderClean(
string folder_name, // String with the name of the deleted folder
int common_flag=0 // Scope
);
Parameters
folder_name
[in] The name of the directory where you want to delete all files. Contains the full path to the
folder.
common_flag=0
[in] Flag determining the location of the directory. If common_flag = FIL E_COMMON, then the
directory is in the shared folder for all client terminals \ Terminal\ Common\Files. Otherwise, the
directory is in a local folder(MQL5\Files or MQL5\ Tester\Files in case of testing).
Return Value
Note
For security reasons, work with files is strictly controlled in the MQL5 language. Files with which file
operations are conducted using MQL5 means, cannot be outside the file sandbox.
This function should be used with caution, since all the files and all subdirectories are deleted
irretrievably.
Example:
//+------------------------------------------------------------------+
//| Demo_FolderClean.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- Description
#property description "The script shows a sample use of FolderClean()."
#property description "First, files are created in the specified folder using the FileOpen() functi
#property description "Then, before the files are deleted, a warning is shown using MessageBox()."
//--- Show the dialog of input parameters when starting the script
#property script_show_inputs
//--- Input parameters
input string foldername="demo_folder"; // Create a folder in MQL5/Files/
input int files=5; // The number of files to create and delete
//+------------------------------------------------------------------+
//---
}
//+------------------------------------------------------------------+
//| Returns the number of files in the specified folder |
//+------------------------------------------------------------------+
int FilesInFolder(string path,int flag)
{
int count=0;
long handle;
string filename;
//---
handle=FileFindFirst(path,filename,flag);
//--- If at least one file found, search for more files
if(handle!=INVALID_HANDLE)
{
//--- Show the name of the file
PrintFormat("File %s found",filename);
//--- Increase the counter of found files/folders
count++;
//--- Start search in all files/folders
while(FileFindNext(handle,filename))
{
PrintFormat("File %s found",filename);
count++;
}
//--- Do not forget to close the search handle upon completion
FileFindClose(handle);
}
else // Failed to get the handle
{
PrintFormat("Files search in folder %s failed",path);
}
//--- Return the result
return count;
}
See also
FileFindFirst, FileFindNext, FileFindClose
Custom Indicators
This is the group functions used in the creation of custom indicators. These functions can't be used
when writing Expert Advisors and Scripts.
Function Action
Indicator properties can be set using the compiler directives or using functions. To better understand
this, it is recommended that you study indicator styles in examples.
All the necessary calculations of a custom indicator must be placed in the predetermined function
OnCalculate(). If you use a short form of the OnCalculate() function call, lik e
int OnCalculate (const int rates_total, const int prev_calculated, const int begin, const double& p
then the rates_total variable contains the value of the total number of elements of the price[] array,
passed as an input parameter for calculating indicator values.
Parameter prev_calculated is the result of the execution of OnCalculate() at the previous call; it allows
organizing a saving algorithm for calculating indicator values. For example, if the current value
rates _total = 1000, prev _calculated = 999, then perhaps it's enough to mak e calculations only for one
value of each indicator buffer.
If the information about the size of the input array price would have been unavailable, then it would
lead to the necessity to mak e calculations for 1000 values of each indicator buffer. At the first call of
OnCalculate() value prev _calculated = 0. If the price[] array has changed somehow, then in this case
prev _calculated is also equal to 0.
The begin parameter shows the number of initial values of the price array, which don't contain data for
calculation. For example, if values of Accelerator Oscillator (for which the first 37 values aren't
calculated) were used as an input parameter, then begin = 37. For example, let's consider a simple
indicator:
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "Label1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- indicator buffers
double Label1Buffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
//---
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
//---
Print("begin = ",begin," prev_calculated = ",prev_calculated," rates_total = ",rates_total);
//--- return value of prev_calculated for next call
return(rates_total);
}
Drag it from the "Navigator" window to the window of the Accelerator Oscillator indicator and we
indicate that calculations will be made based on the values of the previous indicator:
As a result, the first call of OnCalculate() the value of prev _calculated will be equal to zero, and in
further calls it will be equal to the rates _total value (until the number of bars on the price chart
increases).
The value of the begin parameter will be exactly equal to the number of initial bars, for which the
values of the Accelerator indicator aren't calculated according to the logic of this indicator. If we look
at the source code of the custom indicator Accelerator.mq5, we'll see the following lines in the OnInit()
function:
1. set the number of initial values of an indicator, which shouldn't be used for calculations in another
custom indicator;
2. get information on the number of first values to be ignored when you call another custom indicator,
without going into the logic of its calculations.
The entire set of indicators can be derived from several base drawing styles, k nown as plotting.
Plotting denotes a way of displaying data, which the indicator calculates, stores and provides on
request. There are seven such basic plotting types :
1. A line
2. A section (segment)
3. H istogram
4. Arrow (symbol)
5. A painted area (filled channel)
6. Bars
7. Japanese candlestick s
Each plotting requires one to five arrays of the double type, in which indicator values are stored. For
the purpose of convenience, these arrays are associated with the indicator buffers. The number of
buffers in an indicator must be declared in advance using compiler directives, for example:
The number of buffers in the indicator is always greater than or equal to the number of plots in the
indicator.
Since each basic plotting type can have color variation or construction specifics, the actual number of
plotting types in the MQL5 is 18:
In each indicator, on its global level, you should declare one or more arrays of the double type, which
then must be used as an indicator buffer using the SetIndex Buffer() function. To draw indicator plots,
only the values of the indicator buffers are used, any other arrays cannot be used for this purpose. In
addition, buffer values are displayed in the Data W indow.
An indicator buffer should be dynamic and does not require specification of the size – the size of the
array used as the indicator buffer is set by the terminal execution subsystem automatically.
After the array is bound to the indicator buffer, the indexing direction is set by default lik e in ordinary
arrays, but you can use the ArraySetAsSeries() function to change the way of access to the array
elements. By default, the indicator buffer is used to store data used for plotting (I NDICATOR_DAT A).
If the calculation of indicator values requires holding intermediate calculations and storing the
additional values for each bar, then such an array can be declared as a calculation buffer during
binding (I NDICATOR_CALCUL ATIONS). For the intermediate values, you can also use a regular array,
but in this case, the programmer has to manage the size of the array.
Some plots allow setting a color for each bar. To store the information about color, color buffers are
used (I NDICATOR_COLOR_I NDEX). The color is an integer type color, but all indicator buffers must be
of type double. Values of color and auxiliary (I NDICATOR_CALCUL ATIONS) buffers cannot be obtained
by using CopyBuffer().
The number of indicator buffers must be specified using the compiler directive #property
indicator_buffers number_of_buffers :
Each plotting is based on one or more indicator buffers. So, for displaying simple candlestick s, four
values are required - Open, H igh, Low and Close prices. Accordingly, to display an indicator in the
form of candlestick s, it is necessary to declare 4 indicator buffers and 4 arrays of the double type for
them. For example:
Graphical plots automatically use indicator buffers in accordance with the plot number. Numbering of
plots starts with 1, numbering of buffers starts with zero. If the first plotting requires 4 indicator
buffers, then the first 4 indicator buffers will be used to draw it. These four buffers should be link ed
with the appropriate arrays with correct indexing using the SetIndex Buffer() function.
The plotting candlestick s, the indicator will use just the first four buffers, because plotting of
" candlestick s " was announced under the first number.
Change the example, and add plotting of a simple line - DRAW_LI NE. Now suppose that the line is
numbered 1, and the candlestick s are number 2. The number of buffers and the number of plots has
increased.
The order of the plots has changed, and now the line comes first, followed by Japanese candlestick s.
Therefore, the order of the buffers is appropriate - first we announce a buffer for the line with the
zero index, and then four buffers for the candlestick s.
The number of buffers and plots can be set only by using compiler directives, it is impossible to
change these properties dynamically using functions.
As can be seen in the table, the styles are divided into two groups. The first group includes styles in
whose name there is no word COLOR, we call these styles basic:
· DRAW_LI NE
· DRAW_S ECTION
· DRAW_H ISTOGRAM
· DRAW_H ISTOGRAM 2
· DRAW_ARR OW
· DRAW_ZI GZAG
· DRAW_FILLI NG
· DRAW_BAR S
· DRAW_CANDL ES
In the second group, the style names contain the word COLOR, let's call them color versions :
· DRAW_COLOR_LI NE
· DRAW_COLOR_S ECTION
· DRAW_COLOR_H ISTOGRAM
· DRAW_COLOR_H ISTOGRAM 2
· DRAW_COLOR_ARR OW
· DRAW_COLOR_ZI GZAG
· DRAW_COLOR_BAR S
· DRAW_COLOR_CANDL ES
All color versions of styles differ from the basic ones in that they allow specifying a color for each part
of the plotting. The minimal part of plotting is a bar, so we can say that the color versions allow
setting the color on each bar.
Exceptions are styles DRAW_NONE and DRAW_FILLING, they do not have color versions.
To set the plotting color on each bar, an additional buffer for storing the color index has been added to
the color version. These indices indicate the number of a color in a special array, which contains a
predefined set of colors. The size of the array of colors is 64. This means that each color version of a
style allows painting a plot in 64 different colors.
The set and the number of colors in the special array of colors can be set via a compiler directive
#property indicator_color, where you can specify all the necessary colors separated by commas. For
example, such an entry in an indicator:
//--- Define 8 colors for coloring candlesticks (they are stored in the special array)
#property indicator_color1 clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan,clrLime,clrOrange
It states that for plotting 1, 8 colors are set, which will be placed in a special array. Further in the
program we will not specify the color of the plotting, but only its index. If we want to set red color for
the bar number K, the color index value from an array should be set in the color buffer of the
indicator. The red color is specified first in the directive, it corresponds to the index number 0.
The set of colors is not given once and for all, it can be changed dynamically using
PlotIndexSetInteger(). Example:
//--- Set the color for each index as the property PLOT_LINE_COLOR
PlotIndexSetInteger(0, // The number of a graphical style
PLOT_LINE_COLOR, // Property identifier
plot_color_ind, // The index of the color, where we write the colo
color_array[i]); // A new color
For indicator plots, properties can be set by means of compiler directives and using the appropriate
functions. R ead more information about this in Connection between Indicator Properties and
Functions. Dynamic change of indicator properties using special functions allows creating more flexible
custom indicators.
In many cases, according to the conditions of the algorithm, it is impossible to start calculating the
indicator values immediately with the current bar, since it is necessary to provide a minimum number
of previous bars available in history. For example, many types of smoothing imply using an array of
prices over the previous N bars, and on the basis of these values, the indicator value on the current
bar is calculated.
In such cases, either there is no way to calculate the indicator values for the first N bars, or these
values are not intended to be displayed on the chart and are only subsidiary for calculating further
values. To avoid plotting of the indicator on the first N bars of the history, set the N value to the
PLOT _DRAW_BEGI N property for the corresponding plot:
H ere:
· number_of_plot – a value from zero to indicator_plots-1 (numbering of plots starts with zero).
· N - the number of first bars in the history, on which the indicator should not be displayed on the
chart.
DRAW_NONE
The DRAW_NONE style is designed for use in cases where it is necessary to calculate the values of a
buffer and show them in the Data W indow, but plotting on the chart is not required. To set up the
accuracy use the expression IndicatorSetInteger(I NDICATOR_DI GITS,num_chars) in the OnInit()
function:
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,InvisibleBuffer,INDICATOR_DATA);
//--- Set the accuracy of values to be displayed in the Data Window
IndicatorSetInteger(INDICATOR_DIGITS,0);
//---
return(INIT_SUCCEEDED);
}
An example of the indicator that shows the number of the bar on which the mouse currently hovers in
the Data W indow. The numbering corresponds to the timeseries, meaning the current unfinished bar
has the zero index, and the oldest bar has the largest index.
Note that despite the fact that, for red color is set plotting #1, the indicator does not draw anything
on the chart.
//+------------------------------------------------------------------+
//| DRAW_NONE.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Invisible
#property indicator_label1 "Bar Index"
#property indicator_type1 DRAW_NONE
#property indicator_style1 STYLE_SOLID
#property indicator_color1 clrRed
#property indicator_width1 1
//--- indicator buffers
double InvisibleBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Binding an array and an indicator buffer
SetIndexBuffer(0,InvisibleBuffer,INDICATOR_DATA);
//--- Set the accuracy of values to be displayed in the Data Window
IndicatorSetInteger(INDICATOR_DIGITS,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static datetime lastbar=0;
//--- If this is the first calculation of the indicator
if(prev_calculated==0)
{
//--- Renumber the bars for the first time
CalcValues(rates_total,close);
//--- Remember the opening time of the current bar in lastbar
lastbar=(datetime)SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
}
else
{
//--- If a new bar has appeared, its open time differs from lastbar
if(lastbar!=SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE))
{
//--- Renumber the bars once again
CalcValues(rates_total,close);
//--- Update the opening time of the current bar in lastbar
lastbar=(datetime)SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Number the bars like in a timeseries |
//+------------------------------------------------------------------+
void CalcValues(int total,double const &array[])
{
//--- Set indexing of the indicator buffer like in a timeseries
ArraySetAsSeries(InvisibleBuffer,true);
//--- Fill in each bar with its number
for(int i=0;i<total;i++) InvisibleBuffer[i]=i;
}
DRAW_LINE
DRAW_LINE draws a line of the specified color by the values of the indicator buffer. The width, style
and color of the line can be set using the compiler directives and dynamically using the
PlotIndexSetInteger() function. Dynamic changes of the plotting properties allows " to enliven"
indicators, so that their appearance changes depending on the current situation.
An example of the indicator that draws a line using Close prices of bars. The line color, width and style
change randomly every N=5 tick s.
Note that initially for plot1 with DRAW_LINE the properties are set using the compiler directive
#property, and then in the OnCalculate() function these three properties are set randomly. The N
parameter is set in external parameters of the indicator for the possibility of manual configuration
(the Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_LINE.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- Line properties are set using the compiler directives
#property indicator_label1 "Line" // Name of a plot for the Data Window
#property indicator_type1 DRAW_LINE // Type of plotting is line
#property indicator_color1 clrRed // Line color
#property indicator_style1 STYLE_SOLID // Line style
#property indicator_width1 1 // Line Width
//--- input parameter
input int N=5; // Number of ticks to change
//--- An indicator buffer for the plot
double LineBuffer[];
//--- An array to store colors
color colors[]={clrRed,clrBlue,clrGreen};
//--- An array to store the line styles
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Binding an array and an indicator buffer
SetIndexBuffer(0,LineBuffer,INDICATOR_DATA);
//--- Initializing the generator of pseudo-random numbers
MathSrand(GetTickCount());
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int ticks=0;
//--- Calculate ticks to change the style, color and width of the line
ticks++;
//--- If a critical number of ticks has been accumulated
if(ticks>=N)
{
//--- Return the prev_calculated value for the next call of the function
return(rates_total);
}
//+------------------------------------------------------------------+
//| Changes the appearance of the drawn line in the indicator |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the line properties
string comm="";
//--- A block for changing the color of the line
//--- Get a random number
int number=MathRand();
//--- The divisor is equal to the size of the colors[] array
int size=ArraySize(colors);
//--- Get the index to select a new color as the remainder of integer division
int color_index=number%size;
//--- Set the color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_COLOR,colors[color_index]);
//--- Write the line color
comm=comm+(string)colors[color_index];
DRAW_SECTION
DRAW_S ECTION draws sections of the specified color by the values of the indicator buffer. The width,
color and style of the line can be specified lik e for the DRAW_LI NE style - using compiler directives or
dynamically using the PlotIndexSetInteger() function. Dynamic changes of the plotting properties allows
" to enliven" indicators, so that their appearance changes depending on the current situation.
Sections are drawn from one non-empty value to another non-empty value of the indicator buffer,
empty values are ignored. To specify what value should be considered as " empty" , set this value in the
PLOT _EMPT Y_VAL UE property: For example, if the indicator should be drawn as a sequence of sections
on non-zero values, then you need to set the zero value as an empty one:
Always explicitly fill in the values of the indicator buffers, set an empty value in a buffer to the
elements that should not be plotted.
An example of the indicator that draws sections between the H igh and Low prices. The color, width
and style of all sections change randomly every N tick s.
Note that initially for plot1 with DRAW_S ECTION the properties are set using the compiler directive
#property, and then in the OnCalculate() function these three properties are set randomly. The N
parameter is set in external parameters of the indicator for the possibility of manual configuration
(the Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_SECTION.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Section
#property indicator_label1 "Section"
#property indicator_type1 DRAW_SECTION
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameter
input int bars=5; // The length of sections in bars
input int N=5; // The number of ticks to change the style of sections
//--- An indicator buffer for the plot
double SectionBuffer[];
//--- An auxiliary variable to calculate ends of sections
int divider;
//--- An array to store colors
color colors[]={clrRed,clrBlue,clrGreen};
//--- An array to store the line styles
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Binding an array and an indicator buffer
SetIndexBuffer(0,SectionBuffer,INDICATOR_DATA);
//--- The 0 (empty) value will mot participate in drawing
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- Check the indicator parameter
if(bars<=0)
{
PrintFormat("Invalid value of parameter bar=%d",bars);
return(INIT_PARAMETERS_INCORRECT);
}
else divider=2*bars;
//---+
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int ticks=0;
//--- Calculate ticks to change the style, color and width of the line
ticks++;
//--- If a critical number of ticks has been accumulated
if(ticks>=N)
{
//--- Change the line properties
ChangeLineAppearance();
//--- Reset the counter of ticks to zero
ticks=0;
}
//--- The number of the bar from which the calculation of indicator values starts
int start=0;
//--- If the indicator has been calculated before, then set start on the previous bar
if(prev_calculated>0) start=prev_calculated-1;
//--- Here are all the calculations of the indicator values
for(int i=start;i<rates_total;i++)
{
//--- Get a remainder of the division of the bar number by 2*bars
int rest=i%divider;
//--- If the bar number is divisible by 2*bars
if(rest==0)
{
//--- Set the end of the section at the High price of this bar
SectionBuffer[i]=high[i];
}
//---If the remainder of the division is equal to bars,
else
{
//--- Set the end of the section at the High price of this bar
if(rest==bars) SectionBuffer[i]=low[i];
//--- If nothing happened, ignore the bar - set 0
else SectionBuffer[i]=0;
}
}
//--- Return the prev_calculated value for the next call of the function
return(rates_total);
}
//+------------------------------------------------------------------+
//| Changes the appearance of sections in the indicator |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the line properties
string comm="";
//--- A block of line color change
int number=MathRand(); // Get a random number
//--- The divisor is equal to the size of the colors[] array
int size=ArraySize(colors);
//--- Get the index to select a new color as the remainder of integer division
int color_index=number%size;
//--- Set the color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_COLOR,colors[color_index]);
//--- Write the line color
comm=comm+"\r\n"+(string)colors[color_index];
DRAW_HISTOGRAM
The DRAW_H ISTOGRAM style draws a histogram as a sequence of columns of a specified color from
zero to a specified value. Values are tak en from the indicator buffer. The width, color and style of the
column can be specified lik e for the DRAW_LI NE style - using compiler directives or dynamically using
the PlotIndexSetInteger() function. Dynamic changes of the plotting properties allows changing the
look of the histogram based on the current situation.
Since a column from the zero level is drawn on each bar, DRAW_H ISTOGRAM should better be used in
a separate chart window. Most often this type of plotting is used to create indicators of the oscillator
type, for example, Bears Power or OsM A. For the empty non-displayable values the zero value should
be specified.
An example of the indicator that draws a sinusoid of a specified color based on the MathSin() function.
The color, width and style of all histogram columns change randomly each N tick s. The bars parameter
specifies the period of the sinusoid, that is after the specified number of bars the sinusoid will repeat
the cycle.
Note that initially for plot1 with DRAW_H ISTOGRAM the properties are set using the compiler
directive #property, and then in the OnCalculate() function these three properties are set randomly.
The N parameter is set in external parameters of the indicator for the possibility of manual
configuration (the Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_HISTOGRAM.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Histogram
#property indicator_label1 "Histogram"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int bars=30; // The period of a sinusoid in bars
input int N=5; // The number of ticks to change the histogram
//--- indicator buffers
double HistogramBuffer[];
//--- A factor to get the 2Pi angle in radians, when multiplied by the bars parameter
double multiplier;
//--- An array to store colors
color colors[]={clrRed,clrBlue,clrGreen};
//--- An array to store the line styles
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,HistogramBuffer,INDICATOR_DATA);
//--- Calculate the multiplier
if(bars>1)multiplier=2.*M_PI/bars;
else
{
PrintFormat("Set the value of bars=%d greater than 1",bars);
//--- Early termination of the indicator
return(INIT_PARAMETERS_INCORRECT);
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int ticks=0;
//--- Calculate ticks to change the style, color and width of the line
ticks++;
//--- If a critical number of ticks has been accumulated
if(ticks>=N)
{
//--- Change the line properties
ChangeLineAppearance();
//--- Reset the counter of ticks to zero
ticks=0;
}
DRAW_HISTOGRAM2
The DRAW_H ISTOGRAM 2 style draws a histogram of a specified color – vertical segments using the
values of two indicator buffers. The width, color and style of the segments can be specified lik e for
the DRAW_LI NE style - using compiler directives or dynamically using the PlotIndexSetInteger()
function. Dynamic changes of the plotting properties allows changing the look of the histogram based
on the current situation.
The DRAW_H ISTOGRAM 2 style can be used in a separate subwindow of a chart and in its main window.
For empty values nothing is drawn, all the values in the indicator buffers need to be set explicitly.
Buffers are not initialized with a zero value.
An example of the indicator that plots a vertical segment of the specified color and width between the
Open and Close prices of each bar. The color, width and style of all histogram columns change
randomly each N tick s. During the start of the indicator, in the OnInit() function, the number of the
day of week for which the histogram will not be drawn - invisible_day - is set randomly. For this
purpose an empty value is set PLOT _EMPT Y_VAL UE=0:
Note that initially for plot1 with DRAW_H ISTOGRAM 2 the properties are set using the compiler
directive #property, and then in the OnCalculate() function these three properties are set randomly.
The N parameter is set in external parameters of the indicator for the possibility of manual
configuration (the Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_HISTOGRAM2.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 1
//--- plot Histogram_2
#property indicator_label1 "Histogram_2"
#property indicator_type1 DRAW_HISTOGRAM2
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int N=5; // The number of ticks to change the histogram
//--- indicator buffers
double Histogram_2Buffer1[];
double Histogram_2Buffer2[];
//--- The day of the week for which the indicator is not plotted
int invisible_day;
//--- An array to store colors
color colors[]={clrRed,clrBlue,clrGreen};
//--- An array to store the line styles
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Histogram_2Buffer1,INDICATOR_DATA);
SetIndexBuffer(1,Histogram_2Buffer2,INDICATOR_DATA);
//--- Set an empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- Get a random number from 0 to 5
invisible_day=MathRand()%6;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
void ChangeLineAppearance()
{
//--- A string for the formation of information about the line properties
string comm="";
//--- A block of line color change
int number=MathRand(); // Get a random number
//--- The divisor is equal to the size of the colors[] array
int size=ArraySize(colors);
//--- Get the index to select a new color as the remainder of integer division
int color_index=number%size;
//--- Set the color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_COLOR,colors[color_index]);
//--- Write the line color
comm=comm+"\r\n"+(string)colors[color_index];
DRAW_ARROW
The DRAW_ARR OW style draws arrows of the specified color (symbols of the set W ingdings) based on
the value of the indicator buffer. The width and color of the symbols can be specified lik e for the
DRAW_LINE style - using compiler directives or dynamically using the PlotIndexSetInteger() function.
Dynamic changes of the plotting properties allows changing the look of an indicator based on the
current situation.
//--- Define the symbol code from the Wingdings font to draw in PLOT_ARROW
PlotIndexSetInteger(0,PLOT_ARROW,code);
Each arrow is actually a symbol that has the height and the anchor point, and can cover some
important information on a chart (for example, the closing price at the bar). Therefore, we can
additionally specify the vertical shift in pixels, which does not depend on the scale of the chart. The
arrows will be shifted down by the specified number of pixels, although the values of the indicator will
remain the same:
A negative value of PLOT _ARR OW_S H IFT means the shift of arrows upwards, a positive values shifts
the arrow down.
The DRAW_ARR OW style can be used in a separate subwindow of a chart and in its main window.
Empty values are not drawn and do not appear in the "Data W indow" , all the values in the indicator
buffers should be set explicitly. Buffers are not initialized with a zero value.
An example of the indicator, which draws arrows on each bar with the close price higher than the close
price of the previous bar. The color, width, shift and symbol code of all arrows are changed randomly
every N tick s.
In the example, for plot1 with the DRAW_ARR OW style, the properties, color and size are specified
using the compiler directive #property, and then in the OnCalculate() function the properties are set
randomly. The N parameter is set in external parameters of the indicator for the possibility of manual
configuration (the Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_ARROW.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot Arrows
#property indicator_label1 "Arrows"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrGreen
#property indicator_width1 1
//--- input parameters
input int N=5; // Number of ticks to change
if(prev_calculated>0) start=prev_calculated-1;
//--- Calculation loop
for(int i=1;i<rates_total;i++)
{
//--- If the current Close price is higher than the previous one, draw an arrow
if(close[i]>close[i-1])
ArrowsBuffer[i]=close[i];
//--- Otherwise specify the zero value
else
ArrowsBuffer[i]=0;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Change the appearance of symbols in the indicator |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the indicator properties
string comm="";
//--- A block for changing the arrow color
int number=MathRand(); // Get a random number
//--- The divisor is equal to the size of the colors[] array
int size=ArraySize(colors);
//--- Get the index to select a new color as the remainder of integer division
int color_index=number%size;
//--- Set the color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_COLOR,colors[color_index]);
//--- Write the line color
comm=comm+"\r\n"+(string)colors[color_index];
DRAW_ZIGZAG
The DRAW_ZI GZAG style draws segments of a specified color based on the values of two indicator
buffers. This style is very similar to DRAW_S ECTION, but unlik e the latter, it allows drawing vertical
segments within one bar, if values of both indicator buffers are set for this bar. The segments are
plotted from a value in the first buffer to a value in the second indicator buffer. None of the buffers
can contain only empty values, since in this case nothing is plotted.
The width, color and style of the line can be specified lik e for the DRAW_S ECTION style - using
compiler directives or dynamically using the PlotIndexSetInteger() function. Dynamic changes of the
plotting properties allows " to enliven" indicators, so that their appearance changes depending on the
current situation.
Sections are drawn from a non-empty value of one buffer to a non-empty value of another indicator
buffer. To specify what value should be considered as " empty" , set this value in the
PLOT _EMPT Y_VAL UE property:
Always explicitly fill in the values of the indicator buffers, set an empty value in a buffer to s k ip bars.
An example of the indicator that plots a saw based on the H igh and Low prices. The color, width and
style of the zig zag lines change randomly every N tick s.
Note that initially for plot1 with DRAW_ZIGZAG the properties are set using the compiler directive
#property, and then in the OnCalculate() function these properties are set randomly. The N parameter
is set in external parameters of the indicator for the possibility of manual configuration (the
Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_ZIGZAG.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//--- plot ZigZag
#property indicator_label1 "ZigZag"
#property indicator_type1 DRAW_ZIGZAG
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int N=5; // Number of ticks to change
//--- indicator buffers
double ZigZagBuffer1[];
double ZigZagBuffer2[];
//--- The day of the week for which the indicator is not plotted
int invisible_day;
//--- An array to store colors
color colors[]={clrRed,clrBlue,clrGreen};
//--- An array to store the line styles
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Binding arrays and indicator buffers
SetIndexBuffer(0,ZigZagBuffer1,INDICATOR_DATA);
SetIndexBuffer(1,ZigZagBuffer2,INDICATOR_DATA);
//--- Get a random value from 0 to 6, for this day the indicator is not plotted
invisible_day=MathRand()%6;
//--- The 0 (empty) value will mot participate in drawing
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//--- The 0 (empty) value will mot participate in drawing
PlotIndexSetString(0,PLOT_LABEL,"ZigZag1;ZigZag2");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int ticks=0;
//--- Calculate ticks to change the style, color and width of the line
ticks++;
//--- If a sufficient number of ticks has been accumulated
if(ticks>=N)
{
//--- Change the line properties
ChangeLineAppearance();
//--- Reset the counter of ticks to zero
ticks=0;
}
//--- The structure of time is required to get the day of week of each bar
MqlDateTime dt;
else
{
//--- If the bar number if even
if(i%2==0)
{
//--- Write High in the 1st buffer and Low in the 2nd one
ZigZagBuffer1[i]=high[i];
ZigZagBuffer2[i]=low[i];
}
//--- The bar number is odd
else
{
//--- Fill in the bar in a reverse order
ZigZagBuffer1[i]=low[i];
ZigZagBuffer2[i]=high[i];
}
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Changes the appearance of the zigzag segments |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the ZigZag properties
string comm="";
//--- A block for changing the color of the ZigZag
int number=MathRand(); // Get a random number
//--- The divisor is equal to the size of the colors[] array
int size=ArraySize(colors);
//--- Get the index to select a new color as the remainder of integer division
int color_index=number%size;
//--- Set the color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_COLOR,colors[color_index]);
//--- Write the line color
comm=comm+"\r\n"+(string)colors[color_index];
number=MathRand();
//--- The divisor is equal to the size of the styles array
size=ArraySize(styles);
//--- Get the index to select a new style as the remainder of integer division
int style_index=number%size;
//--- Set the color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_STYLE,styles[style_index]);
//--- Write the line style
comm="\r\n"+EnumToString(styles[style_index])+""+comm;
//--- Add information about the day that is omitted in calculations
comm="\r\nNot plotted day - "+EnumToString((ENUM_DAY_OF_WEEK)invisible_day)+comm;
//--- Show the information on the chart using a comment
Comment(comm);
}
DRAW_FILLING
The DRAW_FILLI NG style plots a colored area between the values of two indicator buffers. In fact, this
style draws two lines and fills the space between them with one of two specified colors. It is used for
creating indicators that draw channels. None of the buffers can contain only empty values, since in this
case nothing is plotted.
· the first color is used for the areas where values in the first buffer are greater than the values in
the second indicator buffer;
· the second color is used for the areas where values in the second buffer are greater than the values
in the first indicator buffer.
The fill color can be set using the compiler directives or dynamically using the PlotIndexSetInteger()
function. Dynamic changes of the plotting properties allows " to enliven" indicators, so that their
appearance changes depending on the current situation.
The indicator is calculated for all bars, for which the values of the both indicator buffers are equal
neither to 0 nor to the empty value. To specify what value should be considered as " empty" , set this
value in PLOT _EMPT Y_VAL UE property:
Drawing on the bars that do not participate in the indicator calculation will depend on the values in the
indicator buffers :
· Bars, for which the values of both indicator buffers are equal to 0, do not participate in drawing the
indicator. It means that the area with zero values is not filled out.
· Bars, for which the values of the indicator buffers are equal to the " empty value" , participate in
drawing the indicator. The area with empty values will be filled out so that to connect the areas with
significant values.
It should be noted that if the " empty value" is equal to zero, the bars that do not participate in the
indicator calculation are also filled out.
An example of the indicator that draws a channel between two M As with different averaging periods in
a separate window. The change of the colors at the crossing of moving averages visually shows the
change of the upward and downward trends. The colors change randomly every N tick s. The N
parameter is set in external parameters of the indicator for the possibility of manual configuration
(the Parameters tab in the indicator's Properties window).
Note that initially for plot1 with DRAW_FILLING the properties are set using the compiler directive
#property, and then in the OnCalculate() function new colors are set randomly.
//+------------------------------------------------------------------+
//| DRAW_FILLING.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//--- plot Intersection
#property indicator_label1 "Intersection"
#property indicator_type1 DRAW_FILLING
#property indicator_color1 clrRed,clrBlue
#property indicator_width1 1
//--- input parameters
input int Fast=13; // The period of a fast MA
input int Slow=21; // The period of a slow MA
input int shift=1; // A shift of MAs towards the future (positive)
input int N=5; // Number of ticks to change
//--- Indicator buffers
double IntersectionBuffer1[];
double IntersectionBuffer2[];
int fast_handle;
int slow_handle;
//--- An array to store colors
color colors[]={clrRed,clrBlue,clrGreen,clrAquamarine,clrBlanchedAlmond,clrBrown,clrCoral,clrDarkSl
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,IntersectionBuffer1,INDICATOR_DATA);
SetIndexBuffer(1,IntersectionBuffer2,INDICATOR_DATA);
//---
PlotIndexSetInteger(0,PLOT_SHIFT,shift);
//---
fast_handle=iMA(_Symbol,_Period,Fast,0,MODE_SMA,PRICE_CLOSE);
slow_handle=iMA(_Symbol,_Period,Slow,0,MODE_SMA,PRICE_CLOSE);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
//--- Make the first calculation of the indicator, or data has changed and requires a complete reca
if(prev_calculated==0)
{
//--- Copy all the values of the indicators to the appropriate buffers
int copied1=CopyBuffer(fast_handle,0,0,rates_total,IntersectionBuffer1);
int copied2=CopyBuffer(slow_handle,0,0,rates_total,IntersectionBuffer2);
}
else // Fill only those data that are updated
{
//--- Get the difference in bars between the current and previous start of OnCalculate()
int to_copy=rates_total-prev_calculated;
//--- If there is no difference, we still copy one value - on the zero bar
if(to_copy==0) to_copy=1;
//--- copy to_copy values to the very end of indicator buffers
int copied1=CopyBuffer(fast_handle,0,0,to_copy,IntersectionBuffer1);
int copied2=CopyBuffer(slow_handle,0,0,to_copy,IntersectionBuffer2);
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Changes the colors of the channel filling |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the line properties
string comm="";
//--- A block for changing the color of the line
//--- Get the index to select a new color as the remainder of integer division
int color_index1=number%size;
//--- Set the first color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,colors[color_index1]);
//--- Write the first color
comm=comm+"\r\nColor1 "+(string)colors[color_index1];
//--- Get the index to select a new color as the remainder of integer division
number=MathRand(); // Get a random number
int color_index2=number%size;
//--- Set the second color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,colors[color_index2]);
//--- Write the second color
comm=comm+"\r\nColor2 "+(string)colors[color_index2];
//--- Show the information on the chart using a comment
Comment(comm);
}
DRAW_BARS
The DRAW_BAR S style draws bars on the values of four indicator buffers, which contain the Open,
H igh, Low and Close prices. It is used for creating custom indicators as bars, including those in a
separate subwindow of a chart and on other financial instruments.
The color of bars can be set using the compiler directives or dynamically using the
PlotIndexSetInteger() function. Dynamic changes of the plotting properties allows " to enliven"
indicators, so that their appearance changes depending on the current situation.
The indicator is drawn only to those bars, for which non-empty values of all four indicator buffers are
set. To specify what value should be considered as " empty" , set this value in the PLOT _EMPT Y_VAL UE
property:
Always explicitly fill in the values of the indicator buffers, set an empty value in a buffer to s k ip bars.
The number of required buffers for plotting DRAW_BAR S is 4. All buffers for the plotting should go one
after the other in the given order: Open, H igh, Low and Close. None of the buffers can contain only
empty values, since in this case nothing is plotted.
An example of the indicator that draws bars on a selected financial instrument in a separate window.
The color of bars changes randomly every N tick s. The N parameter is set in external parameters of
the indicator for the possibility of manual configuration (the Parameters tab in the indicator's
Properties window).
Please note that for plot1 with the DRAW_BAR S style, the color is set using the compiler directive
#property, and then in the OnCalculate() function the color is set randomly from an earlier prepared
list.
//+------------------------------------------------------------------+
//| DRAW_BARS.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 1
//--- plot Bars
#property indicator_label1 "Bars"
#property indicator_type1 DRAW_BARS
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int N=5; // The number of ticks to change the type
input int bars=500; // The number of bars to show
input bool messages=false; // Show messages in the "Expert Advisors" log
//--- Indicator buffers
double BarsBuffer1[];
double BarsBuffer2[];
double BarsBuffer3[];
double BarsBuffer4[];
//--- Symbol name
string symbol;
//--- An array to store colors
color colors[]={clrRed,clrBlue,clrGreen,clrPurple,clrBrown,clrIndianRed};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- If bars is very small - complete the work ahead of time
if(bars<50)
{
Comment("Please specify a larger number of bars! The operation of the indicator has been term
return(INIT_PARAMETERS_INCORRECT);
}
//--- indicator buffers mapping
SetIndexBuffer(0,BarsBuffer1,INDICATOR_DATA);
SetIndexBuffer(1,BarsBuffer2,INDICATOR_DATA);
SetIndexBuffer(2,BarsBuffer3,INDICATOR_DATA);
SetIndexBuffer(3,BarsBuffer4,INDICATOR_DATA);
//--- The name of the symbol, for which the bars are drawn
symbol=_Symbol;
//--- Set the display of the symbol
PlotIndexSetString(0,PLOT_LABEL,symbol+" Open;"+symbol+" High;"+symbol+" Low;"+symbol+" Close");
IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_BARS("+symbol+")");
//--- An empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int ticks=0;
//--- Calculate ticks to change the style, color and width of the line
ticks++;
//--- If a sufficient number of ticks has been accumulated
if(ticks>=N)
{
//--- Select a new symbol from the Market watch window
symbol=GetRandomSymbolName();
//--- Change the line properties
ChangeLineAppearance();
int tries=0;
//--- Make 5 attempts to fill in the buffers with the prices from symbol
while(!CopyFromSymbolToBuffers(symbol,rates_total) && tries<5)
{
//--- A counter of calls of the CopyFromSymbolToBuffers() function
tries++;
}
//--- Reset the counter of ticks to zero
ticks=0;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Fill in the indicator buffers with prices |
//+------------------------------------------------------------------+
bool CopyFromSymbolToBuffers(string name,int total)
{
//--- In the rates[] array, we will copy Open, High, Low and Close
MqlRates rates[];
//--- The counter of attempts
int attempts=0;
//--- How much has been copied
int copied=0;
//--- Make 25 attempts to get a timeseries on the desired symbol
while(attempts<25 && (copied=CopyRates(name,_Period,0,bars,rates))<0)
{
Sleep(100);
attempts++;
if(messages) PrintFormat("%s CopyRates(%s) attempts=%d",__FUNCTION__,name,attempts);
}
//--- If failed to copy a sufficient number of bars
if(copied!=bars)
{
//--- Form a message string
string comm=StringFormat("For the symbol %s, managed to receive only %d bars of %d requested
name,
copied,
bars
);
//--- Show a message in a comment in the main chart window
Comment(comm);
//--- Show the message
if(messages) Print(comm);
return(false);
}
else
{
//--- Set the display of the symbol
PlotIndexSetString(0,PLOT_LABEL,name+" Open;"+name+" High;"+name+" Low;"+name+" Close");
IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_BARS("+name+")");
}
//--- Initialize buffers with empty values
ArrayInitialize(BarsBuffer1,0.0);
ArrayInitialize(BarsBuffer2,0.0);
ArrayInitialize(BarsBuffer3,0.0);
ArrayInitialize(BarsBuffer4,0.0);
//--- Copy prices to the buffers
for(int i=0;i<copied;i++)
{
DRAW_CANDLES
The DRAW_CANDL ES style draws candlestick s on the values of four indicator buffers, which contain the
Open, H igh, Low and Close prices. It is used for creating custom indicators as a sequence of
candlestick s, including those in a separate subwindow of a chart and on other financial instruments.
The color of candlestick s can be set using the compiler directives or dynamically using the
PlotIndexSetInteger() function. Dynamic changes of the plotting properties allows " to enliven"
indicators, so that their appearance changes depending on the current situation.
The indicator is drawn only to those bars, for which non-empty values of all four indicator buffers are
set. To specify what value should be considered as " empty" , set this value in the PLOT _EMPT Y_VAL UE
property:
Always explicitly fill in the values of the indicator buffers, set an empty value in a buffer to s k ip bars.
The number of required buffers for plotting DRAW_CANDL ES is 4. All buffers for the plotting should go
one after the other in the given order: Open, H igh, Low and Close. None of the buffers can contain
only empty values, since in this case nothing is plotted.
You can set up to three colors for the DRAW_CANDL ES style affecting the candle look . If only one color
is set, it is applied to all candles on a chart.
If two comma-separated colors are specified, the first one is applied to candle outlines, while the
second one is applied to the body.
Specify three comma-separated colors so that rising and falling candles are displayed differently. In
that case, the first color is applied to the candle outlines, while the second and third ones – to bullish
and bearish candles.
Thus, the DRAW_CANDL ES style allows you to create custom candle coloring options. Besides, all colors
can be changed dynamically during the indicator operation using the PlotIndexSetInteger function
An example of the indicator that draws candlestick s for a selected financial instrument in a separate
window. The color of candlestick s changes randomly every N tick s. The N parameter is set in external
parameters of the indicator for the possibility of manual configuration (the Parameters tab in the
indicator's Properties window).
Please note that for plot1 , the color is set using the compiler directive #property, and then in the
OnCalculate() function the color is set randomly from an earlier prepared list.
//+------------------------------------------------------------------+
//| DRAW_CANDLES.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 1
//--- plot Bars
#property indicator_label1 "DRAW_CANDLES1"
#property indicator_type1 DRAW_CANDLES
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
{
//--- Calculate the appropriate index for the buffers
int buffer_index=total-copied+i;
//--- Write the prices to the buffers
buff1[buffer_index]=rates[i].open;
buff2[buffer_index]=rates[i].high;
buff3[buffer_index]=rates[i].low;
buff4[buffer_index]=rates[i].close;
}
return(true);
}
//+------------------------------------------------------------------+
//| Randomly returns a symbol from the Market Watch |
//+------------------------------------------------------------------+
string GetRandomSymbolName()
{
//--- The number of symbols shown in the Market watch window
int symbols=SymbolsTotal(true);
//--- The position of a symbol in the list - a random number from 0 to symbols
int number=MathRand()%symbols;
//--- Return the name of a symbol at the specified position
return SymbolName(number,true);
}
//+------------------------------------------------------------------+
//| Changes the appearance of bars |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the bar properties
string comm="";
//--- A block for changing the color of bars
int number=MathRand(); // Get a random number
//--- The divisor is equal to the size of the colors[] array
int size=ArraySize(colors);
//--- Get the index to select a new color as the remainder of integer division
int color_index=number%size;
//--- Set the color as the PLOT_LINE_COLOR property
PlotIndexSetInteger(0,PLOT_LINE_COLOR,colors[color_index]);
//--- Write the color
comm=comm+"\r\n"+(string)colors[color_index];
//--- Write the symbol name
comm="\r\n"+symbol+comm;
//--- Show the information on the chart using a comment
Comment(comm);
}
DRAW_COLOR_LINE
The DRAW_COLOR_LI NE value is a colored variant of the DRAW_LI NE style; it also draws a line using
the values of the indicator buffer. But this style, lik e all color styles with the word COLOR in their title
has an additional special indicator buffer that stores the color index (number) from a specially set
array of colors. Thus, the color of each line segment can be defined by specifying the color index of
the index to draw the line at this bar.
The width, style and colors of lines can be set using the compiler directives and dynamically using the
PlotIndexSetInteger() function. Dynamic changes of the plotting properties allows " to enliven"
indicators, so that their appearance changes depending on the current situation.
· one buffer to store the indicator values used for drawing a line;
· one buffer to store the index of the color of the line on each bar.
Colors can be specified by the compiler directive #property indicator_color1 separated by a comma.
The number of colors cannot exceed 64.
//--- Define 5 colors for coloring each bar (they are stored in the special array)
#property indicator_color1 clrRed,clrBlue,clrGreen,clrOrange,clrDeepPink // (Up to 64 colors can b
An example of the indicator that draws a line using Close prices of bars. The line width and style
change randomly every N=5 tick s.
The colors of the line segments also change randomly in the custom function ChangeColors().
//+------------------------------------------------------------------+
//| Changes the color of line segments |
//+------------------------------------------------------------------+
void ChangeColors(color &cols[],int plot_colors)
{
//--- The number of colors
int size=ArraySize(cols);
//---
string comm=ChartGetString(0,CHART_COMMENT)+"\r\n\r\n";
The example shows the feature of the " color" versions of indicators - to change the color of a line
segment, you do not need to change values in the ColorLineColors [] buffer (which contains the color
indexes). All you need to do is set new colors in a special array. This allows you to quick ly change the
color once for the entire plotting, changing only a small array of colors using the PlotIndexSetInteger()
function.
Note that initially for plot1 with DRAW_COLOR_LINE the properties are set using the compiler
directive #property, and then in the OnCalculate() function these three properties are set randomly.
The N and Length (the length of color segments in bars) parameters are set in external parameters of
the indicator for the possibility of manual configuration (the Parameters tab in the indicator's
Properties window).
//+------------------------------------------------------------------+
//| DRAW_COLOR_LINE.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 1
//--- plot ColorLine
#property indicator_label1 "ColorLine"
#property indicator_type1 DRAW_COLOR_LINE
//--- Define 5 colors for coloring each bar (they are stored in the special array)
#property indicator_color1 clrRed,clrBlue,clrGreen,clrOrange,clrDeepPink // (Up to 64 colors can b
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int N=5; //Number of ticks to change
input int Length=20; // The length of each color part in bars
int line_colors=5; // The number of set colors is 5 - see #property indicator_color1
//--- A buffer for plotting
double ColorLineBuffer[];
//--- A buffer for storing the line color on each bar
double ColorLineColors[];
//--- Return the prev_calculated value for the next call of the function
return(rates_total);
}
//+------------------------------------------------------------------+
//| Changes the color of line segments |
//+------------------------------------------------------------------+
void ChangeColors(color &cols[],int plot_colors)
{
//--- The number of colors
int size=ArraySize(cols);
//---
string comm=ChartGetString(0,CHART_COMMENT)+"\r\n\r\n";
//--- Set the color for each index as the property PLOT_LINE_COLOR
PlotIndexSetInteger(0, // The number of a graphical style
PLOT_LINE_COLOR, // Property identifier
plot_color_ind, // The index of the color, where we write the colo
cols[i]); // A new color
//--- Write the colors
comm=comm+StringFormat("LineColorIndex[%d]=%s \r\n",plot_color_ind,ColorToString(cols[i],true
ChartSetString(0,CHART_COMMENT,comm);
}
//---
}
//+------------------------------------------------------------------+
//| Changes the appearance of a displayed line in the indicator |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the line properties
string comm="";
//--- A block for changing the width of the line
int number=MathRand();
//--- Get the width of the remainder of integer division
int width=number%5; // The width is set from 0 to 4
//--- Set the color as the PLOT_LINE_WIDTH property
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,width);
//--- Write the line width
comm=comm+" Width="+IntegerToString(width);
DRAW_COLOR_SECTION
The DRAW_COLOR_S ECTION style is a color version of DRAW_S ECTION, but unlik e the latter, it allows
drawing sections of different colors. The DRAW_COLOR_S ECTION style, lik e all color styles with the
word COLOR in their title, contains an additional special indicator buffer that stores the color index
(number) from a specially set array of colors. Thus, the color of each section can be defined by
specifying the color index of the index of the bar that corresponds to the section end.
The width, color and style of the sections can be specified lik e for the DRAW_S ECTION style - using
compiler directives or dynamically using the PlotIndexSetInteger() function. Dynamic changes of the
plotting properties allows " to enliven" indicators, so that their appearance changes depending on the
current situation.
Sections are drawn from one non-empty value to another non-empty value of the indicator buffer,
empty values are ignored. To specify what value should be considered as " empty" , set this value in the
PLOT _EMPT Y_VAL UE property: For example, if the indicator should be drawn as a sequence of sections
on non-zero values, then you need to set the zero value as an empty one:
Always explicitly fill in the values of the indicator buffers, set an empty value in a buffer to the
elements that should not be plotted.
· one buffer to store the indicator values used for drawing a line;
· one buffer to store the color index, which is used to draw the section (it mak es sense to set only
non-empty values).
Colors can be specified by the compiler directive #property indicator_color1 separated by a comma.
The number of colors cannot exceed 64.
An example of the indicator that draws colored sections each 5 bars long, using the H igh price values.
The color, width and style of sections change randomly every N tick s.
Note that initially for plot1 with DRAW_COLOR_S ECTION 8 colors are set using the compiler directive
#property. Then in the OnCalculate() function, colors are set randomly from the array of colors
colors [].
The N parameter is set in external parameters of the indicator for the possibility of manual
configuration (the Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_COLOR_SECTION.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 1
//--- plot ColorSection
#property indicator_label1 "ColorSection"
#property indicator_type1 DRAW_COLOR_SECTION
//--- Define 8 colors for coloring sections (they are stored in a special array)
#property indicator_color1 clrRed,clrGold,clrMediumBlue,clrLime,clrMagenta,clrBrown,clrTan,clrMedi
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int N=5; // Number of ticks to change
input int bars_in_section=5; // The length of sections in bars
//--- An auxiliary variable to calculate ends of sections
int divider;
int color_sections;
//--- A buffer for plotting
double ColorSectionBuffer[];
//--- A buffer for storing the line color on each bar
double ColorSectionColors[];
//--- An array for storing colors contains 14 elements
color colors[]=
{
clrRed,clrBlue,clrGreen,clrChocolate,clrMagenta,clrDodgerBlue,clrGoldenrod,
clrIndigo,clrLightBlue,clrAliceBlue,clrMoccasin,clrWhiteSmoke,clrCyan,clrMediumPurple
};
//--- An array to store the line styles
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ColorSectionBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ColorSectionColors,INDICATOR_COLOR_INDEX);
//--- The 0 (empty) value will mot participate in drawing
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---- The number of colors to color the sections
int color_sections=8; // see A comment to #property indicator_color1
//--- Check the indicator parameter
if(bars_in_section<=0)
{
PrintFormat("Invalid section length=%d",bars_in_section);
return(INIT_PARAMETERS_INCORRECT);
}
else divider=color_sections*bars_in_section;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
//--- The number of the bar from which the calculation of indicator values starts
int start=0;
//--- If the indicator has been calculated before, then set start on the previous bar
if(prev_calculated>0) start=prev_calculated-1;
//--- Here are all the calculations of the indicator values
for(int i=start;i<rates_total;i++)
{
//--- If the bar number is divisible by the section_length, it means this is the end of the s
if(i%bars_in_section==0)
{
//--- Set the end of the section at the High price of this bar
ColorSectionBuffer[i]=high[i];
//--- A remainder of the division of the bar number by scetion_length*number_of_colors
int rest=i%divider;
//Get the number of the color = from 0 to number_of_colors-1
int color_indext=rest/bars_in_section;
ColorSectionColors[i]=color_indext;
}
//---If the remainder of the division is equal to bars,
else
{
//--- If nothing happened, ignore the bar - set 0
else ColorSectionBuffer[i]=0;
}
}
//--- Return the prev_calculated value for the next call of the function
return(rates_total);
}
//+------------------------------------------------------------------+
DRAW_COLOR_HISTOGRAM
The DRAW_COLOR_H ISTOGRAM style draws a histogram as a sequence of colored columns from zero
to a specified value. Values are tak en from the indicator buffer. Each column can have its own color
from a predefined set of colors.
The width, color and style of the histogram can be specified lik e for the DRAW_H ISTOGRAM style -
using compiler directives or dynamically using the PlotIndexSetInteger() function. Dynamic changes of
the plotting properties allows changing the look of the histogram based on the current situation.
Since a column from the zero level is drawn on each bar, DRAW_COLOR_H ISTOGRAM should better be
used in a separate chart window. Most often this type of plotting is used to create indicators of the
oscillator type, for example, Awesome Oscillator or Mark et Facilitation Index. For the empty non-
displayable values the zero value should be specified.
· one buffer for storing a non-zero value of the vertical segment on each bar, the second end of the
segment is always on the zero line of the indicator;
· one buffer to store the color index, which is used to draw the section (it mak es sense to set only
non-empty values).
Colors can be specified using the compiler directive #property indicator_color1 separated by a comma.
The number of colors cannot exceed 64.
An example of the indicator that draws a sinusoid of a specified color based on the MathSin() function.
The color, width and style of all histogram columns change randomly each N tick s. The bars parameter
specifies the period of the sinusoid, that is after the specified number of bars the sinusoid will repeat
the cycle.
Please note that for plot1 with the DRAW_COLOR_H ISTOGRAM style, 5 colors are set using the
compiler directive #property, and then in the OnCalculate() function the colors are selected randomly
from the 14 colors stored in the colors [] array. The N parameter is set in external parameters of the
indicator for the possibility of manual configuration (the Parameters tab in the indicator's Properties
window).
//+------------------------------------------------------------------+
//| DRAW_COLOR_HISTOGRAM.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//--- input parameters
input int bars=30; // The period of a sinusoid in bars
input int N=5; // The number of ticks to change the histogram
//--- plot Color_Histogram
#property indicator_label1 "Color_Histogram"
#property indicator_type1 DRAW_COLOR_HISTOGRAM
//--- Define 8 colors for coloring sections (they are stored in a special array)
#property indicator_color1 clrRed,clrGreen,clrBlue,clrYellow,clrMagenta,clrCyan,clrMediumSeaGreen,
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- A buffer of values
double Color_HistogramBuffer[];
//--- A buffer of color indexes
double Color_HistogramColors[];
//--- A factor to get the 2Pi angle in radians, when multiplied by the bars parameter
double multiplier;
int color_sections;
//--- An array for storing colors contains 14 elements
color colors[]=
{
clrRed,clrBlue,clrGreen,clrChocolate,clrMagenta,clrDodgerBlue,clrGoldenrod,
clrIndigo,clrLightBlue,clrAliceBlue,clrMoccasin,clrWhiteSmoke,clrCyan,clrMediumPurple
};
//--- An array to store the line styles
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Color_HistogramBuffer,INDICATOR_DATA);
SetIndexBuffer(1,Color_HistogramColors,INDICATOR_COLOR_INDEX);
//---- The number of colors to color the sinusoid
color_sections=8; // see A comment to #property indicator_color1
//--- Calculate the multiplier
if(bars>1)multiplier=2.*M_PI/bars;
else
{
PrintFormat("Set the value of bars=%d greater than 1",bars);
//--- Early termination of the indicator
return(INIT_PARAMETERS_INCORRECT);
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int ticks=0;
//--- Calculate ticks to change the style, color and width of the line
ticks++;
//--- If a critical number of ticks has been accumulated
if(ticks>=N)
{
//--- Change the line properties
ChangeLineAppearance();
//--- Change colors used for the histogram
ChangeColors(colors,color_sections);
//--- Reset the counter of ticks to zero
ticks=0;
}
string comm="";
//--- A block for changing the width of the line
int number=MathRand();
//--- Get the width of the remainder of integer division
int width=number%5; // The width is set from 0 to 4
//--- Set the color as the PLOT_LINE_WIDTH property
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,width);
//--- Write the line width
comm=comm+" Width="+IntegerToString(width);
DRAW_COLOR_HISTOGRAM2
The DRAW_COLOR_H ISTOGRAM 2 style draws a histogram of a specified color – vertical segments
using the values of two indicator buffers. But unlik e the one-color DRAW_H ISTOGRAM 2, in this style
each column of the histogram can have its own color from a predefined set. The values of all the
segments are tak en from the indicator buffer.
The width, style and color of the histogram can be specified lik e for theDRAW_H ISTOGRAM 2 style –
using compiler directives or dynamically using the PlotIndexSetInteger() function. Dynamic changes of
the plotting properties allows changing the look of the histogram based on the current situation.
The DRAW_COLOR_H ISTOGRAM 2 style can be used in a separate subwindow of a chart and in its main
window. For empty values nothing is drawn, all the values in the indicator buffers need to be set
explicitly. Buffers are not initialized with empty values.
· two buffers to store the upper and lower end of the vertical segment on each bar;
· one buffer to store the color index, which is used to draw the segment (it mak es sense to set only
non-empty values).
An example of the indicator that draws a histogram of a specified color between the H igh and Low
prices. For each day of week , the histogram lines have a different color. The color of the day, width
and style of the histogram change randomly each N tick s.
Please note that for plot1 with the DRAW_COLOR_H ISTOGRAM 2 style, 5 colors are set using the
compiler directive #property, and then in the OnCalculate() function the colors are selected randomly
from the 14 colors stored in the colors [] array.
The N parameter is set in external parameters of the indicator for the possibility of manual
configuration (the Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_COLOR_HISTOGRAM2.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 1
//--- plot ColorHistogram_2
#property indicator_label1 "ColorHistogram_2"
#property indicator_type1 DRAW_COLOR_HISTOGRAM2
//--- Define 5 colors for coloring the histogram based on the days of week (they are stored in the
#property indicator_color1 clrRed,clrBlue,clrGreen,clrYellow,clrMagenta
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
SetIndexBuffer(2,ColorHistogram_2Colors,INDICATOR_COLOR_INDEX);
//--- Set an empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0);
//---- The number of colors to color the sinusoid
color_sections=8; // See a comment to #property indicator_color1
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int ticks=0;
//--- Calculate ticks to change the style, color and width of the line
ticks++;
//--- If a critical number of ticks has been accumulated
if(ticks>=N)
{
//--- Change the line properties
ChangeLineAppearance();
//--- Change the colors used to draw the histogram
ChangeColors(colors,color_sections);
//--- Reset the counter of ticks to zero
ticks=0;
}
comm=comm+" Width="+IntegerToString(width);
DRAW_COLOR_ARROW
The DRAW_COLOR_ARR OW style draws colored arrows (symbols of the set W ingdings) based on the
value of the indicator buffer. In contrast to DRAW_ARR OW , in this style it is possible to set a color
from a predefined set of colors specified by the indicator_color1 property for each symbol.
The width and color of the symbols can be specified lik e for theDRAW_ARR OW style – using compiler
directives or dynamically using the PlotIndexSetInteger() function. Dynamic changes of the plotting
properties allows changing the look of an indicator based on the current situation.
//--- Define the symbol code from the Wingdings font to draw in PLOT_ARROW
PlotIndexSetInteger(0,PLOT_ARROW,code);
Each arrow is actually a symbol that has the height and the anchor point, and can cover some
important information on a chart (for example, the closing price at the bar). Therefore, we can
additionally specify the vertical shift in pixels, which does not depend on the scale of the chart. The
arrows will be shifted down by the specified number of pixels, although the values of the indicator will
remain the same:
A negative value of PLOT _ARR OW_S H IFT means the shift of arrows upwards, a positive values shifts
the arrow down.
The DRAW_COLOR_ARR OW style can be used in a separate subwindow of a chart and in its main
window. Empty values are not drawn and do not appear in the "Data W indow" , all the values in the
indicator buffers should be set explicitly. Buffers are not initialized with a zero value.
· a buffer to store the value of the price which is used to draw the symbol (plus a shift in pixels, given
in the PLOT _ARR OW_S H I FT property);
· a buffer to store the color index, which is used to draw an arrow (it mak es sense to set only non-
empty values).
An example of the indicator, which draws arrows on each bar with the close price higher than the close
price of the previous bar. The width, shift and symbol code of all arrows are changed randomly every
N tick s. The color of the symbol depends on the number of the bar on which it is drawn.
In the example, for plot1 with the DRAW_COLOR_ARR OW style, the properties, color and size are
specified using the compiler directive #property, and then in the OnCalculate() function the properties
are set randomly. The N parameter is set in external parameters of the indicator for the possibility of
manual configuration (the Parameters tab in the indicator's Properties window).
Please note that initially 8 colors are set using the compiler directive #property, and then in the
OnCalculate() function, the color is set randomly from the 14 colors that are stored in the colors []
array.
//+------------------------------------------------------------------+
//| DRAW_COLOR_ARROW.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 1
//--- plot ColorArrow
#property indicator_label1 "ColorArrow"
#property indicator_type1 DRAW_COLOR_ARROW
//--- Define 8 colors for coloring the histogram (they are stored in the special array)
#property indicator_color1 clrRed,clrBlue,clrSeaGreen,clrGold,clrDarkOrange,clrMagenta,clrYellowGr
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
DRAW_COLOR_ZIGZAG
The DRAW_COLOR_ZI GZAG style draws segments of different colors, using the values of two indicator
buffers. This style is a colored version of DRAW_ZI GZAG, i.e. allows specifying for each segment an
individual color from the predefined set of colors. The segments are plotted from a value in the first
buffer to a value in the second indicator buffer. None of the buffers can contain only empty values,
since in this case nothing is plotted.
The width, color and style of the line can be specified lik e for the DRAW_ZI GZAG style - using compiler
directives or dynamically using the PlotIndexSetInteger() function. Dynamic changes of the plotting
properties allows " to enliven" indicators, so that their appearance changes depending on the current
situation.
Sections are drawn from a non-empty value of one buffer to a non-empty value of another indicator
buffer. To specify what value should be considered as " empty" , set this value in the
PLOT _EMPT Y_VAL UE property:
Always explicitly fill in the of the indicator buffers, set an empty value in a buffer to s k ip bars.
· two buffers to store the values of ends of the zig zag sections ;
· one buffer to store the color index, which is used to draw the section (it mak es sense to set only
non-empty values).
An example of the indicator that plots a saw based on the H igh and Low prices. The color, width and
style of the zig zag lines change randomly every N tick s.
Please note that for plot1 with the DRAW_COLOR_ZI GZAG style, 8 colors are set using the compiler
directive #property, and then in the OnCalculate() function the color is selected randomly from the 14
colors stored in the colors [] array.
The N parameter is set in external parameters of the indicator for the possibility of manual
configuration (the Parameters tab in the indicator's Properties window).
//+------------------------------------------------------------------+
//| DRAW_COLOR_ZIGZAG.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 1
//--- plot Color_Zigzag
#property indicator_label1 "Color_Zigzag"
#property indicator_type1 DRAW_COLOR_ZIGZAG
//--- Define 8 colors for coloring sections (they are stored in a special array)
#property indicator_color1 clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan,clrLime,clrOrange
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameter
input int N=5; // Number of ticks to change
int color_sections;
//--- Buffers of values of segment ends
double Color_ZigzagBuffer1[];
double Color_ZigzagBuffer2[];
//--- Buffers of color indexes of segment ends
double Color_ZigzagColors[];
//--- An array for storing colors contains 14 elements
color colors[]=
{
clrRed,clrBlue,clrGreen,clrChocolate,clrMagenta,clrDodgerBlue,clrGoldenrod,
clrIndigo,clrLightBlue,clrAliceBlue,clrMoccasin,clrWhiteSmoke,clrCyan,clrMediumPurple
};
//--- An array to store the line styles
ENUM_LINE_STYLE styles[]={STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Color_ZigzagBuffer1,INDICATOR_DATA);
SetIndexBuffer(1,Color_ZigzagBuffer2,INDICATOR_DATA);
SetIndexBuffer(2,Color_ZigzagColors,INDICATOR_COLOR_INDEX);
//----Number of color for coloring the zigzag
color_sections=8; // see a comment to the #property indicator_color1 property
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int ticks=0;
//--- Calculate ticks to change the style, color and width of the line
ticks++;
//--- If a sufficient number of ticks has been accumulated
if(ticks>=N)
{
//--- Change the line properties
ChangeLineAppearance();
//--- Change colors used to plot the sections
ChangeColors(colors,color_sections);
//--- Reset the counter of ticks to zero
ticks=0;
}
//--- The structure of time is required to get the day of week of each bar
MqlDateTime dt;
{
//--- Write the bar open time in the structure
TimeToStruct(time[i],dt);
comm=comm+StringFormat("ZigzagColorIndex[%d]=%s \r\n",plot_color_ind,ColorToString(cols[i],tr
ChartSetString(0,CHART_COMMENT,comm);
}
//---
}
//+------------------------------------------------------------------+
//| Changes the appearance of the zigzag segments |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the properties of Color_ZigZag
string comm="";
//--- A block for changing the width of the line
int number=MathRand();
//--- Get the width of the remainder of integer division
int width=number%5; // The width is set from 0 to 4
//--- Set the color as the PLOT_LINE_WIDTH property
PlotIndexSetInteger(0,PLOT_LINE_WIDTH,width);
//--- Write the line width
comm=comm+"\r\nWidth="+IntegerToString(width);
DRAW_COLOR_BARS
The DRAW_COLOR_BAR S style draws bars on the values of four indicator buffers, which contain the
Open, H igh, Low and Close prices. This style is an advanced version of DRAW_BAR S and allows
specifying for each bar an individual color from the predefined set of colors. It used for creating
custom indicators as bars, including those in a separate subwindow of a chart and on other financial
instruments.
The color of bars can be set using the compiler directives or dynamically using the
PlotIndexSetInteger() function. Dynamic changes of the plotting properties allows " to enliven"
indicators, so that their appearance changes depending on the current situation.
The indicator is drawn only to those bars, for which non-empty values of all four indicator buffers are
set. To specify what value should be considered as " empty" , set this value in the PLOT _EMPT Y_VAL UE
property:
Always explicitly fill in the values of the indicator buffers, set an empty value in a buffer to s k ip bars.
· four buffer to store the values of Open, H igh, Low and Close;
· one buffer to store the color index, which is used to draw a bar (it mak es sense to set it only for the
bars that will be drawn).
All buffers for the plotting should go one after the other in the given order: Open, H igh, Low, Close
and the color buffer. None of the price buffers can contain only null values, since in this case nothing
is plotted.
An example of the indicator that draws bars on a selected financial instrument in a separate window.
The color of bars changes randomly every N tick s. The N parameter is set in external parameters of
the indicator for the possibility of manual configuration (the Parameters tab in the indicator's
Properties window).
Please note that for plot1 with the DRAW_COLOR_BAR S style, 8 colors are set using the compiler
directive #property, and then in the OnCalculate() function the color is selected randomly from the 14
colors stored in the colors [] array.
//+------------------------------------------------------------------+
//| DRAW_COLOR_BARS.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots 1
//--- plot ColorBars
#property indicator_label1 "ColorBars"
#property indicator_type1 DRAW_COLOR_BARS
//--- Define 8 colors for coloring bars (they are stored in the special array)
#property indicator_color1 clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan,clrLime,clrOrange
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int N=5; // The number of ticks to change the type
ticks++;
//--- If a sufficient number of ticks has been accumulated
if(ticks>=N)
{
//--- Select a new symbol from the Market watch window
symbol=GetRandomSymbolName();
//--- Change the line properties
ChangeLineAppearance();
//--- Change the colors used to draw the candlesticks
ChangeColors(colors,bars_colors);
int tries=0;
//--- Make 5 attempts to fill in the buffers with the prices from symbol
while(!CopyFromSymbolToBuffers(symbol,rates_total,bars_colors) && tries<5)
{
//--- A counter of calls of the CopyFromSymbolToBuffers() function
tries++;
}
//--- Reset the counter of ticks to zero
ticks=0;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Fill in the indicator buffers with prices |
//+------------------------------------------------------------------+
bool CopyFromSymbolToBuffers(string name,int total,int bar_colors)
{
//--- In the rates[] array, we will copy Open, High, Low and Close
MqlRates rates[];
//--- The counter of attempts
int attempts=0;
//--- How much has been copied
int copied=0;
//--- Make 25 attempts to get a timeseries on the desired symbol
while(attempts<25 && (copied=CopyRates(name,_Period,0,bars,rates))<0)
{
Sleep(100);
attempts++;
if(messages) PrintFormat("%s CopyRates(%s) attempts=%d",__FUNCTION__,name,attempts);
}
//--- If failed to copy a sufficient number of bars
if(copied!=bars)
{
//--- Form a message string
string comm=StringFormat("For the symbol %s, managed to receive only %d bars of %d requested
name,
copied,
bars
);
//--- Show a message in a comment in the main chart window
Comment(comm);
//--- Show the message
if(messages) Print(comm);
return(false);
}
else
{
//--- Set the display of the symbol
PlotIndexSetString(0,PLOT_LABEL,name+" Open;"+name+" High;"+name+" Low;"+name+" Close");
IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_COLOR_BARS("+name+")");
}
//--- Initialize buffers with empty values
ArrayInitialize(ColorBarsBuffer1,0.0);
ArrayInitialize(ColorBarsBuffer2,0.0);
ArrayInitialize(ColorBarsBuffer3,0.0);
ArrayInitialize(ColorBarsBuffer4,0.0);
DRAW_COLOR_CANDLES
The DRAW_COLOR_CANDL ES style, lik e DRAW_CANDL ES, draws candlestick s using the values of four
indicator buffers, which contain Open, H igh, Low and Close prices. In addition, it allows specifying a
color for each candlestick from a given set. For this purpose, the style has a special color buffer that
stores color indexes for each bar. It used for creating custom indicators as a sequence of candlestick s,
including those in a separate subwindow of a chart and on other financial instruments.
The number of colors of candlestick s can be set using the compiler directives or dynamically using the
PlotIndexSetInteger() function. Dynamic changes of the plotting properties allows " to enliven"
indicators, so that their appearance changes depending on the current situation.
The indicator is drawn only to those bars, for which non-empty values of four price buffers of the
indicator are set. To specify what value should be considered as " empty" , set this value in the
PLOT _EMPT Y_VAL UE property:
Always explicitly fill in the values of the indicator buffers, set an empty value in a buffer to s k ip bars.
· four buffer to store the values of Open, H igh, Low and Close;
· one buffer to store the color index, which is used to draw a candlestick (it mak es sense to set it only
for the candlestick s that will be drawn).
All buffers for the plotting should go one after the other in the given order: Open, H igh, Low, Close
and the color buffer. None of the price buffers can contain only empty values, since in this case
nothing is plotted.
An example of the indicator that draws candlestick s for a selected financial instrument in a separate
window. The color of candlestick s changes randomly every N tick s. The N parameter is set in external
parameters of the indicator for the possibility of manual configuration (the Parameters tab in the
indicator's Properties window).
Please note that for plot1 , the color is set using the compiler directive #property, and then in the
OnCalculate() function the color is set randomly from an earlier prepared list.
//+------------------------------------------------------------------+
//| DRAW_COLOR_CANDLES.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots 1
//--- plot ColorCandles
#property indicator_label1 "ColorCandles"
#property indicator_type1 DRAW_COLOR_CANDLES
//--- Define 8 colors for coloring candlesticks (they are stored in the special array)
#property indicator_color1 clrRed,clrBlue,clrGreen,clrYellow,clrMagenta,clrCyan,clrLime,clrOrange
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
int tries=0;
//--- Make 5 attempts to fill in the buffers of plot1 with the prices from symbol
while(!CopyFromSymbolToBuffers(symbol,rates_total,0,
ColorCandlesBuffer1,ColorCandlesBuffer2,ColorCandlesBuffer3,
ColorCandlesBuffer4,ColorCandlesColors,candles_colors)
&& tries<5)
{
//--- A counter of calls of the CopyFromSymbolToBuffers() function
tries++;
}
//--- Reset the counter of ticks to zero
ticks=0;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Fills in the specified candlestick |
//+------------------------------------------------------------------+
bool CopyFromSymbolToBuffers(string name,
int total,
int plot_index,
double &buff1[],
double &buff2[],
double &buff3[],
double &buff4[],
double &col_buffer[],
int cndl_colors
)
{
//--- In the rates[] array, we will copy Open, High, Low and Close
MqlRates rates[];
//--- The counter of attempts
int attempts=0;
//--- How much has been copied
int copied=0;
//--- Make 25 attempts to get a timeseries on the desired symbol
while(attempts<25 && (copied=CopyRates(name,_Period,0,bars,rates))<0)
{
Sleep(100);
attempts++;
if(messages) PrintFormat("%s CopyRates(%s) attempts=%d",__FUNCTION__,name,attempts);
}
//--- If failed to copy a sufficient number of bars
if(copied!=bars)
{
//--- Form a message string
string comm=StringFormat("For the symbol %s, managed to receive only %d bars of %d requested
name,
copied,
bars
);
//--- Show a message in a comment in the main chart window
Comment(comm);
//--- Show the message
if(messages) Print(comm);
return(false);
}
else
{
//--- Set the display of the symbol
PlotIndexSetString(plot_index,PLOT_LABEL,name+" Open;"+name+" High;"+name+" Low;"+name+" Clos
IndicatorSetString(INDICATOR_SHORTNAME,"DRAW_COLOR_CANDLES("+symbol+")");
}
//--- Initialize buffers with empty values
ArrayInitialize(buff1,0.0);
ArrayInitialize(buff2,0.0);
ArrayInitialize(buff3,0.0);
ArrayInitialize(buff4,0.0);
//--- On each tick copy prices to buffers
for(int i=0;i<copied;i++)
{
ChartSetString(0,CHART_COMMENT,comm);
}
//---
}
//+------------------------------------------------------------------+
//| Changes the appearance of candlesticks |
//+------------------------------------------------------------------+
void ChangeLineAppearance()
{
//--- A string for the formation of information about the candlestick properties
string comm="";
//--- Write the symbol name
comm="\r\n"+symbol+comm;
//--- Show the information on the chart using a comment
Comment(comm);
}
Also there are other properties that can be set both through preprocessor directives and through
functions intended for custom indicator creation. These properties and corresponding functions are
described in the following table.
indicator_applied_price No function, the property can Default price type used for the
be set only by the preprocessor indicator calculation. It is
directive. specified when necessary, only
if OnCalculate() of the first
type is used.
The property value can also be
set from the dialog of
indicator properties in the
" Parameters " tab - "Apply to" .
It should be noted that numeration of levels and plots in preprocessor terms starts with one, while
numeration of the same properties at using functions starts with zero, i.e. the indicated value must
be by 1 less than that indicated for #property.
There are several directives, for which there are no corresponding functions :
Directive Description
SetIndexBuffer
The function binds a specified indicator buffer with one-dimensional dynamic array of the double type.
bool SetIndexBuffer(
int index, // buffer index
double buffer[], // array
ENUM_INDEXBUFFER_TYPE data_type // what will be stored
);
Parameters
index
[in] Number of the indicator buffer. The numbering starts with 0. The number must be less than
the value declared in #property indicator_buffers.
buffer[]
[in] An array declared in the custom indicator program.
data_type
[in] Type of data stored in the indicator array. By default it is INDICATOR_DAT A (values of the
calculated indicator). It may also tak e the value of I NDICATOR_COLOR_I NDEX; in this case this
buffer is used for storing color indexes for the previous indicator buffer. You can specify up to 64
colors in the #property indicator_colorN line. The I NDICATOR_CALCUL ATIONS value means that the
buffer is used in intermediate calculations of the indicator and is not intended for drawing.
Return Value
Note
After binding, the dynamic array buffer[] will be indexed as in common arrays, even if the indexing
of timeseries is pre-installed for the bound array. If you want to change the order of access to
elements of the indicator array, use the ArraySetAsSeries() function after binding the array using
the SetIndexBuffer() function. Please note that you can't change the size for dynamic arrays set as
indicator buffers by the function SetIndex Buffer(). For indicator buffers, all operations of size
changes are performed by the executing sub-system of the terminal.
Example:
//+------------------------------------------------------------------+
//| TestCopyBuffer1.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot MA
#property indicator_label1 "MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input bool AsSeries=true;
input int period=15;
input ENUM_MA_METHOD smootMode=MODE_EMA;
input ENUM_APPLIED_PRICE price=PRICE_CLOSE;
input int shift=0;
//--- indicator buffers
double MABuffer[];
int ma_handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
if(AsSeries) ArraySetAsSeries(MABuffer,true);
Print("Indicator buffer is timeseries = ",ArrayGetAsSeries(MABuffer));
SetIndexBuffer(0,MABuffer,INDICATOR_DATA);
Print("Indicator buffer after SetIndexBuffer() is timeseries = ",
ArrayGetAsSeries(MABuffer));
IndicatorSetString(INDICATOR_SHORTNAME,"MA("+period+")"+AsSeries);
//---
ma_handle=iMA(Symbol(),0,period,shift,smootMode,price);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- Copy the values of the moving average in the buffer MABuffer
int copied=CopyBuffer(ma_handle,0,0,rates_total,MABuffer);
See also
IndicatorSetDouble
The function sets the value of the corresponding indicator property. Indicator property must be of the
double type. There are two variants of the function.
bool IndicatorSetDouble(
int prop_id, // identifier
double prop_value // value to be set
);
bool IndicatorSetDouble(
int prop_id, // identifier
int prop_modifier, // modifier
double prop_value // value to be set
)
Parameters
prop_id
[in] Identifier of the indicator property. The value can be one of the values of the
ENUM _CUSTOMIND_PR OPER T Y_DOUBL E enumeration.
prop_modifier
[in] Modifier of the specified property. Only level properties require a modifier. Numbering of
levels starts from 0. It means that in order to set property for the second level you need to specify
1 (1 less than when using compiler directive).
prop_value
[in] Value of property.
Return Value
Note
Numbering of properties (modifiers) starts from 1 (one) when using the #property directive, while
the function uses numbering from 0 (zero). In case the level number is set incorrectly, indicator
display can differ from the intended one.
For example, the first level value for the indicator in a separate subwindow can be set in two ways :
· property indicator_level1 50 - the value of 1 is used for specifying the level number,
· IndicatorSetDouble(I NDICATOR_L EVEL VAL UE, 0, 50) - 0 is used for specifying the first level.
Example: indicator that turns upside down the maximum and minimum values of the indicator window
f levels on which the horizontal lines are placed.
and values o
#property indicator_separate_window
//--- set the maximum and minimum values for the indicator window
#property indicator_minimum 0
#property indicator_maximum 100
//--- display three horizontal levels in a separate indicator window
#property indicator_level1 25
#property indicator_level2 50
#property indicator_level3 75
//--- set thickness of horizontal levels
#property indicator_levelwidth 1
//--- set style of horizontal levels
#property indicator_levelstyle STYLE_DOT
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- set descriptions of horizontal levels
IndicatorSetString(INDICATOR_LEVELTEXT,0,"First Level (index 0)");
IndicatorSetString(INDICATOR_LEVELTEXT,1,"Second Level (index 1)");
IndicatorSetString(INDICATOR_LEVELTEXT,2,"Third Level (index 2)");
//--- set the short name for indicator
IndicatorSetString(INDICATOR_SHORTNAME,"IndicatorSetDouble() Demo");
//--- set color for each level
IndicatorSetInteger(INDICATOR_LEVELCOLOR,0,clrBlue);
IndicatorSetInteger(INDICATOR_LEVELCOLOR,1,clrGreen);
IndicatorSetInteger(INDICATOR_LEVELCOLOR,2,clrRed);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
static int tick_counter=0;
static double level1=25,level2=50,level3=75;
static double max=100,min=0, shift=100;
//--- calculate ticks
tick_counter++;
//--- turn levels upside down on every 10th tick
if(tick_counter%10==0)
{
//--- invert sign for the level values
level1=-level1;
level2=-level2;
level3=-level3;
//--- invert sign for the maximum and minimum values
max-=shift;
min-=shift;
//--- invert the shift value
shift=-shift;
//--- set new level values
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,level1);
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,level2);
IndicatorSetDouble(INDICATOR_LEVELVALUE,2,level3);
//--- set new values of maximum and minimum in the indicator window
Print("Set up max = ",max,", min = ",min);
IndicatorSetDouble(INDICATOR_MAXIMUM,max);
IndicatorSetDouble(INDICATOR_MINIMUM,min);
}
//--- return value of prev_calculated for next call
return(rates_total);
}
See also
Indicator Styles in Examples, Connection between Indicator Properties and Functions, Drawing Styles
IndicatorSetInteger
The function sets the value of the corresponding indicator property. Indicator property must be of the
int or color type. There are two variants of the function.
bool IndicatorSetInteger(
int prop_id, // identifier
int prop_value // value to be set
);
bool IndicatorSetInteger(
int prop_id, // identifier
int prop_modifier, // modifier
int prop_value // value to be set
)
Parameters
prop_id
[in] Identifier of the indicator property. The value can be one of the values of the
ENUM _CUSTOMIND_PR OPER T Y_INT EGER enumeration.
prop_modifier
[in] Modifier of the specified property. Only level properties require a modifier.
prop_value
[in] Value of property.
Return Value
Note
Numbering of properties (modifiers) starts from 1 (one) when using the #property directive, while
the function uses numbering from 0 (zero). In case the level number is set incorrectly, indicator
display can differ from the intended one.
For example, in order to set thick ness of the first horizontal line use zeroth index :
· IndicatorSetInteger(I NDICATOR_L EVEL W I DT H , 0, 5) - index 0 is used to set thickness of the first
level.
Example: indicator that sets color, style and thick ness of the indicator horizontal lines.
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
//--- display three horizontal levels in a separate indicator window
#property indicator_level1 20
#property indicator_level2 50
#property indicator_level3 80
//--- set thickness of horizontal levels
#property indicator_levelwidth 5
//--- set color of horizontal levels
#property indicator_levelcolor clrAliceBlue
//--- set style of horizontal levels
#property indicator_levelstyle STYLE_DOT
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- set descriptions of horizontal levels
IndicatorSetString(INDICATOR_LEVELTEXT,0,"First Level (index 0)");
IndicatorSetString(INDICATOR_LEVELTEXT,1,"Second Level (index 1)");
IndicatorSetString(INDICATOR_LEVELTEXT,2,"Third Level (index 2)");
//--- set the short name for indicator
IndicatorSetString(INDICATOR_SHORTNAME,"IndicatorSetInteger() Demo");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
if(tick_number%t_trigger==0)
index=2; // if tick_number is divided by t_trigger without the remainder
//--- if color is defined, set it
if(index!=-1)
IndicatorSetInteger(INDICATOR_LEVELCOLOR,level,colors[index]);
//---
}
//+------------------------------------------------------------------+
//| Set style of horizontal line in the separate indicator window |
//+------------------------------------------------------------------+
void ChangeLevelStyle(int level, // number of horizontal line
int tick_number// number to get the remainder of division
)
{
//--- array to store styles
static ENUM_LINE_STYLE styles[5]=
{STYLE_SOLID,STYLE_DASH,STYLE_DOT,STYLE_DASHDOT,STYLE_DASHDOTDOT};
//--- index of style from the styles[] array
int index=-1;
//--- calculate the number from the styles[] array to set style of horizontal line
if(tick_number%50==0)
index=5; // if tick_number is divided by 50 without the remainder, then style is STYLE_DASH
if(tick_number%40==0)
index=4; // ... style is STYLE_DASHDOT
if(tick_number%30==0)
index=3; // ... STYLE_DOT
if(tick_number%20==0)
index=2; // ... STYLE_DASH
if(tick_number%10==0)
index=1; // ... STYLE_SOLID
//--- if style is defined, set it
if(index!=-1)
IndicatorSetInteger(INDICATOR_LEVELSTYLE,level,styles[index]);
}
See also
IndicatorSetString
The function sets the value of the corresponding indicator property. Indicator property must be of the
string type. There are two variants of the function.
bool IndicatorSetString(
int prop_id, // identifier
string prop_value // value to be set
);
bool IndicatorSetString(
int prop_id, // identifier
int prop_modifier, // modifier
string prop_value // value to be set
)
Parameters
prop_id
[in] Identifier of the indicator property. The value can be one of the values of the
ENUM _CUSTOMIND_PR OPER T Y_ST R ING enumeration.
prop_modifier
[in] Modifier of the specified property. Only level properties require a modifier.
prop_value
[in] Value of property.
Return Value
Note
Numbering of properties (modifiers) starts from 1 (one) when using the #property directive, while
the function uses numbering from 0 (zero). In case the level number is set incorrectly, indicator
display can differ from the intended one.
For example, in order to set description of the first horizontal line use zeroth index :
· IndicatorSetString(I NDICATOR_L EVELT EXT, 0, "First Level" ) - index 0 is used to set text
description of the first level.
Example: indicator that sets text labels to the indicator horizontal lines.
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
//--- display three horizontal levels in a separate indicator window
#property indicator_level1 30
#property indicator_level2 50
#property indicator_level3 70
//--- set color of horizontal levels
#property indicator_levelcolor clrRed
//--- set style of horizontal levels
#property indicator_levelstyle STYLE_SOLID
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- set descriptions of horizontal levels
IndicatorSetString(INDICATOR_LEVELTEXT,0,"First Level (index 0)");
IndicatorSetString(INDICATOR_LEVELTEXT,1,"Second Level (index 1)");
IndicatorSetString(INDICATOR_LEVELTEXT,2,"Third Level (index 2)");
//--- set the short name for indicator
IndicatorSetString(INDICATOR_SHORTNAME,"IndicatorSetString() Demo");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
See also
PlotIndexSetDouble
The function sets the value of the corresponding property of the corresponding indicator line. The
indicator property must be of the double type.
bool PlotIndexSetDouble(
int plot_index, // plotting style index
int prop_id, // property identifier
double prop_value // value to be set
);
Parameters
plot_index
[in] Index of the graphical plotting
prop_id
[in] The value can be one of the values of the ENUM _PLOT _PR OPER T Y_DOUBL E enumeration.
prop_value
[in] The value of the property.
Return Value
PlotIndexSetInteger
The function sets the value of the corresponding property of the corresponding indicator line. The
indicator property must be of the int, char, bool or color type. There are 2 variants of the function.
bool PlotIndexSetInteger(
int plot_index, // plotting style index
int prop_id, // property identifier
int prop_value // value to be set
);
bool PlotIndexSetInteger(
int plot_index, // plotting style index
int prop_id, // property identifier
int prop_modifier, // property modifier
int prop_value // value to be set
)
Parameters
plot_index
[in] Index of the graphical plotting
prop_id
[in] The value can be one of the values of the ENUM _PLOT _PR OPER T Y_INT EGER enumeration.
prop_modifier
[in] Modifier of the specified property. Only color index properties require a modifier.
prop_value
[in] The value of the property.
Return Value
Example: an indicator that draws a three-color line. The color scheme changes every 5 tick s.
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 1
//---- plot ColorLine
#property indicator_label1 "ColorLine"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 clrRed,clrGreen,clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 3
//--- indicator buffers
double ColorLineBuffer[];
double ColorBuffer[];
int MA_handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ColorLineBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ColorBuffer,INDICATOR_COLOR_INDEX);
//--- get MA handle
MA_handle=iMA(Symbol(),0,10,0,MODE_EMA,PRICE_CLOSE);
//---
}
//+------------------------------------------------------------------+
//| get color index |
//+------------------------------------------------------------------+
int getIndexOfColor(int i)
{
int j=i%300;
if(j<100) return(0);// first index
if(j<200) return(1);// second index
return(2); // third index
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
static int ticks=0,modified=0;
int limit;
//--- first calculation or number of bars was changed
if(prev_calculated==0)
{
//--- copy values of MA into indicator buffer ColorLineBuffer
int copied=CopyBuffer(MA_handle,0,0,rates_total,ColorLineBuffer);
if(copied<=0) return(0);// copying failed - throw away
//--- now set line color for every bar
for(int i=0;i<rates_total;i++)
ColorBuffer[i]=getIndexOfColor(i);
}
else
{
//--- copy values of MA into indicator buffer ColorLineBuffer
int copied=CopyBuffer(MA_handle,0,0,rates_total,ColorLineBuffer);
if(copied<=0) return(0);
PlotIndexSetString
The function sets the value of the corresponding property of the corresponding indicator line. The
indicator property must be of the string type.
bool PlotIndexSetString(
int plot_index, // plotting style index
int prop_id, // property identifier
string prop_value // value to be set
);
Parameters
plot_index
[in] Index of graphical plot
prop_id
[in] The value can be one of the values of the ENUM _PLOT _PR OPER T Y_ST R ING enumeration.
prop_value
[in] The value of the property.
Return Value
PlotIndexGetInteger
The function sets the value of the corresponding property of the corresponding indicator line. The
indicator property must be of the int, color, bool or char type. There are 2 variants of the function.
int PlotIndexGetInteger(
int plot_index, // plotting style index
int prop_id, // property identifier
);
int PlotIndexGetInteger(
int plot_index, // plotting index
int prop_id, // property identifier
int prop_modifier // property modifier
)
Parameters
plot_index
[in] Index of the graphical plotting
prop_id
[in] The value can be one of the values of the ENUM _PLOT _PR OPER T Y_INT EGER enumeration.
prop_modifier
[in] Modifier of the specified property. Only color index properties require a modifier.
Note
Function is designed to extract the settings of drawing of the appropriate indicator line. The
function work s in tandem with the function PlotIndexSetInteger to copy the drawing properties of
one line to another.
Example: an indicator that colors candles depending on the day of the week . Colors for each day are
set in a programmatically.
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots 1
//---- plot ColorCandles
#property indicator_label1 "ColorCandles"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- indicator buffers
double OpenBuffer[];
double HighBuffer[];
double LowBuffer[];
double CloseBuffer[];
double ColorCandlesColors[];
color ColorOfDay[6]={CLR_NONE,clrMediumSlateBlue,
clrDarkGoldenrod,clrForestGreen,clrBlueViolet,clrRed};
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,OpenBuffer,INDICATOR_DATA);
SetIndexBuffer(1,HighBuffer,INDICATOR_DATA);
SetIndexBuffer(2,LowBuffer,INDICATOR_DATA);
SetIndexBuffer(3,CloseBuffer,INDICATOR_DATA);
SetIndexBuffer(4,ColorCandlesColors,INDICATOR_COLOR_INDEX);
//--- set number of colors in color buffer
PlotIndexSetInteger(0,PLOT_COLOR_INDEXES,6);
//--- set colors for color buffer
for(int i=1;i<6;i++)
PlotIndexSetInteger(0,PLOT_LINE_COLOR,i,ColorOfDay[i]);
//--- set accuracy
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
printf("We have %u colors of days",PlotIndexGetInteger(0,PLOT_COLOR_INDEXES));
//---
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
int i;
MqlDateTime t;
//----
if(prev_calculated==0) i=0;
else i=prev_calculated-1;
//----
while(i<rates_total)
{
OpenBuffer[i]=open[i];
HighBuffer[i]=high[i];
LowBuffer[i]=low[i];
CloseBuffer[i]=close[i];
//--- set color for every candle
TimeToStruct(time[i],t);
ColorCandlesColors[i]=t.day_of_week;
//---
i++;
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
Object Functions
This is the group of functions intended for work ing with graphic objects relating to any specified
chart.
The functions defining the properties of graphical objects, as well as ObjectCreate() and ObjectMove()
operations for creating and moving objects along the chart are actually used for sending commands to
the chart. If these functions are executed successfully, the command is included in the common queue
of the chart events. Visual changes in the properties of graphical objects are implemented when
handling the queue of the chart events.
Thus, do not expect an immediate visual update of graphical objects after calling these functions.
Generally, the graphical objects on the chart are updated automatically by the terminal following the
change events - a new quote arrival, resizing the chart window, etc. Use ChartR edraw() function to
forcefully update the graphical objects.
Function Action
Every graphical object should have a name unique within one chart, including its subwindows.
Changing of a name of a graphic object generates two events : event of deletion of an object with the
old name, and event of creation of an object with a new name.
ObjectCreate
The function creates an object with the specified name, type, and the initial coordinates in the
specified chart subwindow. During creation up to 30 coordinates can be specified.
bool ObjectCreate(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT type, // object type
sub_window nwin, // window index
datetime time1, // time of the first anchor point
double price1, // price of the first anchor point
...
datetime timeN=0, // time of the N-th anchor point
double priceN=0, // price of the N-th anchor point
...
datetime time30=0, // time of the 30th anchor point
double price30=0 // price of the 30th anchor point
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object. The name must be unique within a chart, including its subwindows.
type
[in] Object type. The value can be one of the values of the ENUM _OBJECT enumeration.
sub_window
[in] Number of the chart subwindow. 0 means the main chart window. The specified subwindow
must exist, otherwise the function returns false.
time1
[in] The time coordinate of the first anchor.
price1
[in] The price coordinate of the first anchor point.
timeN=0
[in] The time coordinate of the N-th anchor point.
priceN=0
[in] The price coordinate of the N-th anchor point.
time30=0
[in] The time coordinate of the thirtieth anchor point.
price30=0
[in] The price coordinate of the thirtieth anchor point.
Return Value
The function returns true if the command has been successfully added to the queue of the specified
chart, or false otherwise. If an object has already been created, an attempt is made to change its
coordinates.
Note
An asynchronous call is always used for ObjectCreate(), that is why the function only returns the
results of adding the command to a chart queue. In this case, true only means that the command
has been successfully enqueued, but the result of its execution is unk nown.
To check the command execution result, you can use the ObjectFind() function or any other function
that requests object properties, such as ObjectGetXXX. H owever, you should k eep in mind that such
functions are added to the end of the queue of that chart, and they wait for the execution result
(due to the synchronous call), and can therefore be time consuming. This feature should be tak en
into account when work ing with a large number of objects on a chart.
The numbering of the chart subwindows (if there are subwindows with indicators in the chart) starts
with 1. The main chart window of the chart is and always has index 0.
The large number of anchor points (up to 30) is implemented for future use. At the same time, the
limit of 30 possible anchor points for graphical objects is determined by the limit on the number of
parameters (not more than 64) that can be used when calling a function.
W hen an object is renamed, two events are formed simultaneously. These events can be handled in
an Expert Advisor or indicator by the OnChartEvent() function:
· an event of deletion of an object with the old name;
· an event of creation of an object with a new name.
There is a certain number of anchor points that must be specified when creating each object type:
OBJ_ARR OW_L EFT _PR ICE Left Price Label One anchor point.
OBJ_ARR OW_R I GH T _PR ICE R ight Price Label One anchor point.
OBJ_RECT ANGL E_L ABEL The "R ectangle label" object Position is set using the
for creating and designing the OBJPR OP_XDIST ANCE and
custom graphical interface. OBJPR OP_YDIST ANCE
properties.
ObjectName
The function returns the name of the corresponding object in the specified chart, in the specified
subwindow, of the specified type.
string ObjectName(
long chart_id, // chart identifier
int pos, // number in the list of objects
int sub_window=-1, // window index
int type=-1 // object type
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
pos
[in] Ordinal number of the object according to the specified filter by the number and type of the
subwindow.
sub_window=-1
[in] Number of the chart subwindow. 0 means the main chart window, -1 means all the
subwindows of the chart, including the main window.
type=-1
[in] Type of the object. The value can be one of the values of the ENUM _OBJECT enumeration. -1
means all types.
Return Value
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
W hen an object is renamed, two events are formed simultaneously. These events can be handled in
an Expert Advisor or indicator by the OnChartEvent() function:
· an event of deletion of an object with the old name;
· an event of creation of an object with a new name.
ObjectDelete
The function removes the object with the specified name from the specified chart.
bool ObjectDelete(
long chart_id, // chart identifier
string name // object name
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of object to be deleted.
Return Value
The function returns true if the command has been successfully added to the queue of the specified
chart, or false otherwise.
Note
An asynchronous call is always used for ObjectDelete(), that is why the function only returns the
results of adding the command to a chart queue. In this case, true only means that the command
has been successfully enqueued, but the result of its execution is unk nown.
To check the command execution result, you can use the ObjectFind() function or any other function
that requests object properties, such as ObjectGetXXX. H owever, you should k eep in mind that such
functions are added to the end of the queue of that chart, and they wait for the execution result
(due to the synchronous call), and can therefore be time consuming. This feature should be tak en
into account when work ing with a large number of objects on a chart.
W hen an object is renamed, two events are formed simultaneously. These events can be handled in
an Expert Advisor or indicator by the OnChartEvent() function:
· an event of deletion of an object with the old name;
· an event of creation of an object with a new name.
ObjectsDeleteAll
R emoves all objects from the specified chart, specified chart subwindow, of the specified type.
int ObjectsDeleteAll(
long chart_id, // chart identifier
int sub_window=-1, // window index
int type=-1 // object type
);
R emoves all objects of the specified type using prefix in object names.
int ObjectsDeleteAll(
long chart_id, // chart ID
const string prefix, // prefix in object name
int sub_window=-1, // window index
int object_type=-1 // object type
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
prefix
[in] Prefix in object names. All objects whose names start with this set of characters will be
removed from chart. You can specify prefix as 'name' or 'name*' – both variants will work the same.
If an empty string is specified as the prefix, objects with all possible names will be removed.
sub_window=-1
[in] Number of the chart subwindow. 0 means the main chart window, -1 means all the subwindows
of the chart, including the main window.
type=-1
[in] Type of the object. The value can be one of the values of the ENUM _OBJECT enumeration. -1
means all types.
Return Value
R eturns the number of deleted objects. To read more about the error call GetLastError().
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
ObjectFind
The function searches for an object with the specified name in the chart with the specified I D.
int ObjectFind(
long chart_id, // chart identifier
string name // object name
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] The name of the searched object.
Return Value
If successful the function returns the number of the subwindow (0 means the main window of the
chart), in which the object is found. If the object is not found, the function returns a negative
number. To read more about the error call GetLastError().
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
W hen an object is renamed, two events are formed simultaneously. These events can be handled in
an Expert Advisor or indicator by the OnChartEvent() function:
· an event of deletion of an object with the old name;
· an event of creation of an object with a new name.
ObjectGetTimeByValue
The function returns the time value for the specified price value of the specified object.
datetime ObjectGetTimeByValue(
long chart_id, // chart identifier
string name, // object name
double value, // Price
int line_id // Line number
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
value
[in] Price value.
line_id
[in] Line identifier.
Return Value
The time value for the specified price value of the specified object.
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
An object can have several values in one price coordinate, therefore it is necessary to specify the
line number. This function applies only to the following objects :
· Trendline (OBJ_T REND)
· Trendline by angle (OBJ_T RENDBYANGL E)
· Gann line (OBJ_GANNLI NE)
· Equidistant channel (OBJ_CHANNEL) - 2 lines
· Linear regression channel (OBJ_REGRESSION) - 3 lines
· Standard deviation channel (OBJ_ST DDEVCHANNEL) - 3 lines
· Arrowed line (OBJ_ARR OWED_LI NE)
See also
Object Types
ObjectGetValueByTime
The function returns the price value for the specified time value of the specified object.
double ObjectGetValueByTime(
long chart_id, // chart identifier
string name, // object name
datetime time, // Time
int line_id // Line number
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
time
[in] Time value.
line_id
[in] Line ID.
Return Value
The price value for the specified time value of the specified object.
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
An object can have several values in one price coordinate, therefore it is necessary to specify the
line number. This function applies only to the following objects :
· Trendline (OBJ_T REND)
· Trendline by angle (OBJ_T RENDBYANGL E)
· Gann line (OBJ_GANNLI NE)
· Equidistant channel (OBJ_CHANNEL) - 2 lines
· Linear regression channel (OBJ_REGRESSION) - 3 lines
· Standard deviation channel (OBJ_ST DDEVCHANNEL) - 3 lines
· Arrowed line (OBJ_ARR OWED_LI NE)
See also
Object Types
ObjectMove
The function changes coordinates of the specified anchor point of the object.
bool ObjectMove(
long chart_id, // chart identifier
string name, // object name
int point_index, // anchor point number
datetime time, // Time
double price // Price
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
point_index
[in] Index of the anchor point. The number of anchor points depends on the type of object.
time
[in] Time coordinate of the selected anchor point.
price
[in] Price coordinate of the selected anchor point.
Return Value
The function returns true if the command has been successfully added to the queue of the specified
chart, or false otherwise.
Note
An asynchronous call is always used for ObjectMove(), that is why the function only returns the
results of adding the command to a chart queue. In this case, true only means that the command
has been successfully enqueued, but the result of its execution is unk nown.
To check the command execution result, you can use a function that requests object properties,
such as ObjectGetXXX. H owever, you should k eep in mind that such functions are added to the end
of the queue of that chart, and they wait for the execution result (due to the synchronous call), and
can therefore be time consuming. This feature should be tak en into account when work ing with a
large number of objects on a chart.
ObjectsTotal
The function returns the number of objects in the specified chart, specified subwindow, of the
specified type.
int ObjectsTotal(
long chart_id, // chart identifier
int sub_window=-1, // window index
int type=-1 // object type
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
sub_window=-1
[in] Number of the chart subwindow. 0 means the main chart window, -1 means all the
subwindows of the chart, including the main window.
type=-1
[in] Type of the object. The value can be one of the values of the ENUM _OBJECT enumeration. -1
means all types.
Return Value
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
ObjectSetDouble
The function sets the value of the corresponding object property. The object property must be of the
double type. There are 2 variants of the function.
bool ObjectSetDouble(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_DOUBLE prop_id, // property
double prop_value // value
);
bool ObjectSetDouble(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_DOUBLE prop_id, // property
int prop_modifier, // modifier
double prop_value // value
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
prop_id
[in] I D of the object property. The value can be one of the values of the
ENUM _OBJECT _PR OPER T Y_DOUBL E enumeration.
prop_modifier
[in] Modifier of the specified property. It denotes the number of the level in Fibonacci tools and in
the graphical object Andrew's pitchfork . The numeration of levels starts from zero.
prop_value
[in] The value of the property.
Return Value
The function returns true only if the command to change properties of a graphical object has been
sent to a chart successfully. Otherwise it returns false. To read more about the error call
GetLastError().
Note
The function uses an asynchronous call, which means that the function does not wait for the
execution of the command that has been added to the queue of the specified chart. Instead, it
immediately returns control.
To check the command execution result, you can use a function that requests the specified object
property. H owever, you should k eep in mind that such functions are added to the end of the queue
of that chart, and they wait for the execution result, and can therefore be time consuming. This
feature should be tak en into account when work ing with a large number of objects on a chart.
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- auxiliary arrays
double high[],low[],price1,price2;
datetime time[],time1,time2;
//--- Copy the open prices - 100 latest bars are enough
int copied=CopyHigh(Symbol(),0,0,100,high);
if(copied<=0)
{
Print("Failed to copy the values of the High price series");
return;
}
//--- Copy the close price - 100 latest bars are enough
copied=CopyLow(Symbol(),0,0,100,low);
if(copied<=0)
{
Print("Failed to copy the values of the Low price series");
return;
}
//--- Copy the open time for the last 100 bars
copied=CopyTime(Symbol(),0,0,100,time);
if(copied<=0)
{
Print("Failed to copy the values of the price series of Time");
return;
}
//--- Organize access to the copied data as to timeseries - backwards
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArraySetAsSeries(time,true);
time2=time[50];
See also
Object Types, Object Properties
ObjectSetInteger
The function sets the value of the corresponding object property. The object property must be of the
datetime, int, color, bool or char type. There are 2 variants of the function.
bool ObjectSetInteger(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_INTEGER prop_id, // property
long prop_value // value
);
bool ObjectSetInteger(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_INTEGER prop_id, // property
int prop_modifier, // modifier
long prop_value // value
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
prop_id
[in] I D of the object property. The value can be one of the values of the
ENUM _OBJECT _PR OPER T Y_INT EGER enumeration.
prop_modifier
[in] Modifier of the specified property. It denotes the number of the level in Fibonacci tools and
in the graphical object Andrew's pitchfork . The numeration of levels starts from zero.
prop_value
[in] The value of the property.
Return Value
The function returns true only if the command to change properties of a graphical object has been
sent to a chart successfully. Otherwise it returns false. To read more about the error call
GetLastError().
Note
The function uses an asynchronous call, which means that the function does not wait for the
execution of the command that has been added to the queue of the specified chart. Instead, it
immediately returns control.
To check the command execution result, you can use a function that requests the specified object
property. H owever, you should k eep in mind that such functions are added to the end of the queue
of that chart, and they wait for the execution result, and can therefore be time consuming. This
feature should be tak en into account when work ing with a large number of objects on a chart.
//+------------------------------------------------------------------+
//| Table of Web Colors|
//| Copyright 2011, MetaQuotes Software Corp |
//| https://www.metaquotes.net |
//+------------------------------------------------------------------+
#define X_SIZE 140 // width of an edit object
#define Y_SIZE 33 // height of an edit object
//+------------------------------------------------------------------+
//| Array of web colors |
//+------------------------------------------------------------------+
color ExtClr[140]=
{
clrAliceBlue,clrAntiqueWhite,clrAqua,clrAquamarine,clrAzure,clrBeige,clrBisque,clrBlack,clrBlanc
clrBlue,clrBlueViolet,clrBrown,clrBurlyWood,clrCadetBlue,clrChartreuse,clrChocolate,clrCoral,clr
clrCornsilk,clrCrimson,clrCyan,clrDarkBlue,clrDarkCyan,clrDarkGoldenrod,clrDarkGray,clrDarkGreen
clrDarkMagenta,clrDarkOliveGreen,clrDarkOrange,clrDarkOrchid,clrDarkRed,clrDarkSalmon,clrDarkSea
clrDarkSlateBlue,clrDarkSlateGray,clrDarkTurquoise,clrDarkViolet,clrDeepPink,clrDeepSkyBlue,clrD
clrDodgerBlue,clrFireBrick,clrFloralWhite,clrForestGreen,clrFuchsia,clrGainsboro,clrGhostWhite,c
clrGoldenrod,clrGray,clrGreen,clrGreenYellow,clrHoneydew,clrHotPink,clrIndianRed,clrIndigo,clrIv
clrLavender,clrLavenderBlush,clrLawnGreen,clrLemonChiffon,clrLightBlue,clrLightCoral,clrLightCya
clrLightGoldenrod,clrLightGreen,clrLightGray,clrLightPink,clrLightSalmon,clrLightSeaGreen,clrLig
clrLightSlateGray,clrLightSteelBlue,clrLightYellow,clrLime,clrLimeGreen,clrLinen,clrMagenta,clrM
clrMediumAquamarine,clrMediumBlue,clrMediumOrchid,clrMediumPurple,clrMediumSeaGreen,clrMediumSla
clrMediumSpringGreen,clrMediumTurquoise,clrMediumVioletRed,clrMidnightBlue,clrMintCream,clrMisty
clrNavajoWhite,clrNavy,clrOldLace,clrOlive,clrOliveDrab,clrOrange,clrOrangeRed,clrOrchid,clrPale
clrPaleGreen,clrPaleTurquoise,clrPaleVioletRed,clrPapayaWhip,clrPeachPuff,clrPeru,clrPink,clrPlu
clrPurple,clrRed,clrRosyBrown,clrRoyalBlue,clrSaddleBrown,clrSalmon,clrSandyBrown,clrSeaGreen,cl
clrSienna,clrSilver,clrSkyBlue,clrSlateBlue,clrSlateGray,clrSnow,clrSpringGreen,clrSteelBlue,clr
clrThistle,clrTomato,clrTurquoise,clrViolet,clrWheat,clrWhite,clrWhiteSmoke,clrYellow,clrYellowG
};
//+------------------------------------------------------------------+
//| Creating and initializing an edit object |
//+------------------------------------------------------------------+
void CreateColorBox(int x,int y,color c)
{
//--- generate a name for a new edit object
string name="ColorBox_"+(string)x+"_"+(string)y;
//--- create a new edit object
if(!ObjectCreate(0,name,OBJ_EDIT,0,0,0))
{
Print("Cannot create: '",name,"'");
return;
}
//--- set coordinates, width and height
ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x*X_SIZE);
ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y*Y_SIZE);
ObjectSetInteger(0,name,OBJPROP_XSIZE,X_SIZE);
ObjectSetInteger(0,name,OBJPROP_YSIZE,Y_SIZE);
//--- set text color
if(clrBlack==c) ObjectSetInteger(0,name,OBJPROP_COLOR,clrWhite);
else ObjectSetInteger(0,name,OBJPROP_COLOR,clrBlack);
//--- set background color
ObjectSetInteger(0,name,OBJPROP_BGCOLOR,c);
//--- set text
ObjectSetString(0,name,OBJPROP_TEXT,(string)c);
}
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- create 7x20 table of colored edit objects
for(uint i=0;i<140;i++)
CreateColorBox(i%7,i/7,ExtClr[i]);
}
See also
Object Types, Object Properties
ObjectSetString
The function sets the value of the corresponding object property. The object property must be of the
string type. There are 2 variants of the function.
bool ObjectSetString(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_STRING prop_id, // property
string prop_value // value
);
bool ObjectSetString(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_STRING prop_id, // property
int prop_modifier, // modifier
string prop_value // value
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
prop_id
[in] I D of the object property. The value can be one of the values of the
ENUM _OBJECT _PR OPER T Y_ST R ING enumeration.
prop_modifier
[in] Modifier of the specified property. It denotes the number of the level in Fibonacci tools and
in the graphical object Andrew's pitchfork . The numeration of levels starts from zero.
prop_value
[in] The value of the property.
Return Value
The function returns true only if the command to change properties of a graphical object has been
sent to a chart successfully. Otherwise it returns false. To read more about the error call
GetLastError().
Note
The function uses an asynchronous call, which means that the function does not wait for the
execution of the command that has been added to the queue of the specified chart. Instead, it
immediately returns control.
To check the command execution result, you can use a function that requests the specified object
property. H owever, you should k eep in mind that such functions are added to the end of the queue
of that chart, and they wait for the execution result, and can therefore be time consuming. This
feature should be tak en into account when work ing with a large number of objects on a chart.
W hen an object is renamed, two events are formed simultaneously. These events can be handled in
an Expert Advisor or indicator by the OnChartEvent() function:
· an event of deletion of an object with the old name;
· an event of creation of an object with a new name.
ObjectGetDouble
The function returns the value of the corresponding object property. The object property must be of
the double type. There are 2 variants of the function.
2. Returns true or false, depending on the success of the function. If successful, the property value
is placed to a receiving variable passed by reference by the last parameter.
bool ObjectGetDouble(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_DOUBLE prop_id, // property identifier
int prop_modifier, // property modifier
double& double_var // here we accept the property value
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
prop_id
[in] I D of the object property. The value can be one of the values of the
ENUM _OBJECT _PR OPER T Y_DOUBL E enumeration.
prop_modifier
[in] Modifier of the specified property. For the first variant, the default modifier value is equal to
0. Most properties do not require a modifier. It denotes the number of the level in Fibonacci tools
and in the graphical object Andrew's pitchfork . The numeration of levels starts from zero.
double_var
[out] Variable of the double type that received the value of the requested property.
Return Value
For the second variant the function returns true, if this property is maintained and the value has
been placed into the double_var variable, otherwise returns false. To read more about the error call
GetLastError().
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
ObjectGetInteger
The function returns the value of the corresponding object property. The object property must be of
the datetime, int, color, bool or char type. There are 2 variants of the function.
2. Returns true or false, depending on the success of the function. If successful, the property value
is placed to a receiving variable passed by reference by the last parameter.
bool ObjectGetInteger(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_INTEGER prop_id, // property identifier
int prop_modifier, // property modifier
long& long_var // here we accept the property value
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
prop_id
[in] I D of the object property. The value can be one of the values of the
ENUM _OBJECT _PR OPER T Y_INT EGER enumeration.
prop_modifier
[in] Modifier of the specified property. For the first variant, the default modifier value is equal to
0. Most properties do not require a modifier. It denotes the number of the level in Fibonacci tools
and in the graphical object Andrew's pitchfork . The numeration of levels starts from zero.
long_var
[out] Variable of the long type that receives the value of the requested property.
Return Value
For the second variant the function returns true, if this property is maintained and the value has
been placed into the long _var variable, otherwise returns false. To read more about the error call
GetLastError().
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
ObjectGetString
The function returns the value of the corresponding object property. The object property must be of
the string type. There are 2 variants of the function.
2. Returns true or false, depending on the success of the function. If successful, the property value
is placed to a receiving variable passed by reference by the last parameter.
bool ObjectGetString(
long chart_id, // chart identifier
string name, // object name
ENUM_OBJECT_PROPERTY_STRING prop_id, // property identifier
int prop_modifier, // property modifier
string& string_var // here we accept the property value
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
name
[in] Name of the object.
prop_id
[in] I D of the object property. The value can be one of the values of the
ENUM _OBJECT _PR OPER T Y_ST R ING enumeration.
prop_modifier
[in] Modifier of the specified property. For the first variant, the default modifier value is equal to
0. Most properties do not require a modifier. It denotes the number of the level in Fibonacci tools
and in the graphical object Andrew's pitchfork . The numeration of levels starts from zero.
string_var
[out] Variable of the string type that receives the value of the requested properties.
Return Value
For the second version of the call returns true, if this property is maintained and the value has been
placed into the string _var variable, otherwise returns false. To read more about the error call
GetLastError().
Note
The function uses a synchronous call, which means that the function waits for the execution of all
commands that have been enqueued for this chart prior to its call, that is why this function can be
time consuming. This feature should be tak en into account when work ing with a large number of
objects on a chart.
W hen an object is renamed, two events are formed simultaneously. These events can be handled in
an Expert Advisor or indicator by the OnChartEvent() function:
· an event of deletion of an object with the old name;
· an event of creation of an object with a new name.
TextSetFont
The function sets the font for displaying the text using drawing methods and returns the result of that
operation. Arial font with the size -120 (12 pt) is used by default.
bool TextSetFont(
const string name, // font name or path to font file on the disk
int size, // font size
uint flags, // combination of flags
int orientation=0 // text slope angle
);
Parameters
name
[in] Font name in the system or the name of the resource containing the font or the path to font
file on the dis k .
size
[in] The font size that can be set using positive and negative values. In case of positive values,
the size of a displayed text does not depend on the operating system's font size settings. In case
of negative values, the value is set in tenths of a point and the text size depends on the operating
system settings (" standard scale" or " large scale" ). See the Note below for more information about
the differences between the modes.
flags
[in] Combination of flags describing font style.
orientation
[in] Text's horizontal inclination to X axis, the unit of measurement is 0.1 degrees. It means that
orientation=450 stands for inclination equal to 45 degrees.
Return Value
R eturns true if the current font is successfully installed, otherwise false. Possible code errors :
· ERR_I NVALI D_PARAM ET ER (4003) - name presents NULL or "" (empty string),
· ERR_I NT ERNAL _ERR OR (4001) - operating system error (for example, an attempt to create a non-
existent font).
Note
If "::" is used in font name, the font is downloaded from EX5 resource. If name font name is
specified with an extension, the font is downloaded from the file, if the path starts from "\" or "/" ,
the file is searched relative to MQL5 directory. Otherwise, it is searched relative to the path of EX5
file which called TextSetFont() function.
The font size is set using positive or negative values. This fact defines the dependence of the text
size from the operating system settings (size scale).
· If the size is specified using a positive number, this size is transformed into physical
measurement units of a device (pixels) when changing a logical font into a physical one, and this
size corresponds to the height of the symbol glyphs pick ed from the available fonts. This case is
not recommended when the texts displayed by TextOut() function and the ones displayed by
OBJ_L ABEL (" Label" ) graphical object are to be used together on the chart.
· If the size is specified using a negative number, this number is supposed to be set in tenths of a
logical point and is divided by 10 (for example, -350 is equal to 35 logical points). An obtained
value is then transformed into physical measurement units of a device (pixels) and corresponds to
the absolute value of the height of a symbol pick ed from the available fonts. Multiply the font size
specified in the object properties by -10 to mak e the size of a text on the screen similar to the
one in OBJ_L ABEL object.
The flags can be used as the combination of style flags with one of the flags specifying the font
width. Flag names are shown below.
Flag Description
Flag
FW_DONTCARE
FW_T H IN
FW_EXT RALIGH T
FW_ULT RALIGH T
FW_LIGH T
FW_NOR M AL
FW_REGUL AR
FW_M EDIUM
FW_S EMIBOL D
FW_DEMIBOL D
FW_BOL D
FW_EXT RABOL D
FW_ULT RABOL D
FW_HEAVY
FW_BL ACK
See also
R esources, R esourceCreate(), R esourceSave(), TextOut()
TextOut
The function displays a text in a custom array (buffer) and returns the result of that operation. The
array is designed to create the graphical resource.
bool TextOut(
const string text, // displayed text
int x, // X coordinate
int y, // Y coordinate
uint anchor, // anchor type
uint &data[], // output buffer
uint width, // buffer width in pixels
uint height, // buffer height in pixels
uint color, // text color
ENUM_COLOR_FORMAT color_format // color format for output
);
Parameters
text
[in] Displayed text that will be written to the buffer. Only one-lined text is displayed.
x
[in] X coordinate of the anchor point of the displayed text.
y
[in] Y coordinate of the anchor point of the displayed text.
anchor
[in] The value out of the 9 pre-defined methods of the displayed text's anchor point location. The
value is set by a combination of two flags – flags of horizontal and vertical text align. Flag names
are listed in the Note below.
data[]
[in] Buffer, in which text is displayed. The buffer is used to create the graphical resource.
width
[in] Buffer width in pixels.
height
[in] Buffer height in pixels.
color
[in] Text color.
color_format
[in] Color format is set by ENUM _COLOR_FOR M AT enumeration value.
Return Value
Note
Anchor point specified by anchor is a combination of two flags of horizontal and vertical text align.
H orizontal text align flags :
· T A_L EFT – anchor point on the left side of the bounding box
· T A_CENT ER – horizontal anchor point is located at the center of the bounding box
· T A_R I GH T – anchor point on the right side of the bounding box
Possible combinations of flags and specified anchor points are shown in the image.
Example:
int x,y; // variables for calculation of the current coordinates of text string anch
//--- rotate clock hands in an infinite loop, till the script is stopped
while(!IsStopped())
{
//--- clear the clock drawing buffer array
ArrayFill(ExtImg,0,IMG_WIDTH*IMG_HEIGHT,0);
//--- set the font for drawing digits for the clock-face
TextSetFont("Arial",-200,FW_EXTRABOLD,0);
//--- draw the clock-face
for(int i=1;i<=12;i++)
{
//--- receive the size of the current hour on the clock-face
TextGetSize(string(i),w,h);
//--- calculate the coordinates of the current hour on the clock-face
a=-((i*300)%3600*M_PI)/1800.0;
x=IMG_WIDTH/2-int(sin(a)*80+0.5+w/2);
y=IMG_HEIGHT/2-int(cos(a)*80+0.5+h/2);
//--- output the hour on the clock-face to ExtImg[] buffer
TextOut(string(i),x,y,TA_LEFT|TA_TOP,ExtImg,IMG_WIDTH,IMG_HEIGHT,0xFFFFFFFF,clr_format);
}
//--- now, specify the font for drawing the minute hand
TextSetFont("Arial",-200,FW_EXTRABOLD,-int(nm%3600));
//--- receive the size of the minute hand
TextGetSize("----->",w,h);
//--- calculate the coordinates of the minute hand on the clock-face
a=-(nm%3600*M_PI)/1800.0;
x=IMG_WIDTH/2-int(sin(a)*h/2+0.5);
y=IMG_HEIGHT/2-int(cos(a)*h/2+0.5);
//--- output of the minute hand to the clock-face in ExtImg[]buffer
TextOut("----->",x,y,TA_LEFT|TA_TOP,ExtImg,IMG_WIDTH,IMG_HEIGHT,0xFFFFFFFF,clr_format);
//--- now, set the font for drawing the minute hand
TextSetFont("Arial",-200,FW_EXTRABOLD,-int(nh/12%3600));
TextGetSize("==>",w,h);
//--- calculate the coordinates of the hour hand on the clock-face
a=-(nh/12%3600*M_PI)/1800.0;
x=IMG_WIDTH/2-int(sin(a)*h/2+0.5);
y=IMG_HEIGHT/2-int(cos(a)*h/2+0.5);
//--- output of the hour hand on the clock-face to ExtImg[] buffer
TextOut("==>",x,y,TA_LEFT|TA_TOP,ExtImg,IMG_WIDTH,IMG_HEIGHT,0xFFFFFFFF,clr_format);
See also
R esources, R esourceCreate(), R esourceSave(), TextGetSize(), TextSetFont()
TextGetSize
The function returns the line width and height at the current font settings.
bool TextGetSize(
const string text, // text string
uint& width, // buffer width in pixels
uint& height // buffer height in pixels
);
Parameters
text
[in] String, for which length and width should be obtained.
width
[out] Input parameter for receiving width.
height
[out] Input parameter for receiving height.
Return Value
See also
R esources, R esourceCreate(), R esourceSave(), TextSetFont(), TextOut()
These functions return the handle of the appropriate copy of the indicator. Further, using this handle,
you can receive data calculated by the corresponding indicator. The corresponding buffer data
(technical indicators contain calculated data in their internal buffers, which can vary from 1 to 5,
depending on the indicator) can be copied to a mql5-program using the CopyBuffer() function.
You can't refer to the indicator data right after it has been created, because calculation of indicator
values requires some time, so it's better to create indicator handles in OnInit(). Function iCustom()
creates the corresponding custom indicator, and returns its handle in case it is successfully create.
Custom indicators can contain up to 512 indicator buffers, the contents of which can also be obtained
by the CopyBuffer() function, using the obtained handle.
There is a universal method for creating any technical indicator using the IndicatorCreate() function.
This function accepts the following data as input parameters :
· symbol name;
· timeframe;
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note. R epeated call of the indicator function with the same parameters within one mql5-program does
not lead to a multiple increase of the reference counter; the counter will be increased only once by 1.
H owever, it's recommended to get the indicators handles in function OnInit() or in the class
constructor, and further use these handles in other functions. The reference counter decreases when a
mql5-program is deinitialized.
All indicator functions have at least 2 parameters - symbol and period. The NULL value of the symbol
means the current symbol, the 0 value of the period means the current timeframe.
iAD Accumulation/Distribution
iAlligator Alligator
iDeMark er DeMark er
iEnvelopes Envelopes
iFractals Fractals
iMomentum Momentum
iM A Moving Average
iVolumes Volumes
iAC
The function creates Accelerator Oscillator in a global cache of the client terminal and returns its
handle. It has only one buffer.
int iAC(
string symbol, // symbol name
ENUM_TIMEFRAMES period // period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES enumeration values, 0 means
the current timeframe.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iAC.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iAC technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//--- plotting of iAC
#property indicator_label1 "iAC"
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrGreen, clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iAC, // use iAC
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iAC; // type of the function
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffers
double iACBuffer[];
double iACColors[];
//--- variable for storing the handle of the iAC indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Accelerator Oscillator indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of arrays to indicator buffers
SetIndexBuffer(0,iACBuffer,INDICATOR_DATA);
SetIndexBuffer(1,iACColors,INDICATOR_COLOR_INDEX);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iAC)
handle=iAC(name,period);
else
handle=IndicatorCreate(name,period,IND_AC);
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iAC indicator for the symbol %s/%s, error code %d
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Accelerator Oscillator indicator is calculated for
short_name=StringFormat("iAC(%s/%s)",name,EnumToString(period));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iAC indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iA
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iACBuffer array is greater than the number of values in the iAC indicator for sy
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iACBuffer and iACColors arrays with values from the Accelerator Oscillator indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArraysFromBuffer(iACBuffer,iACColors,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Accelerator Oscillator indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iAC indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffer(double &values[], // indicator buffer of Accelerator Oscillator va
double &color_indexes[], // color buffer (for storing of color indexes)
int ind_handle, // handle of the iAC indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iACBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iAC indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- now copy the indexes of colors
if(CopyBuffer(ind_handle,1,0,amount,color_indexes)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy color values from the iAC indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iAD
The function returns the handle of the Accumulation/Distribution indicator. It has only one buffer.
int iAD(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
ENUM_APPLIED_VOLUME applied_volume // volume type for calculation
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES enumeration values, 0 means
the current timeframe.
applied_volume
[in] The volume used. Can be any of ENUM _APPLIED_VOL UM E values.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iAD.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iAD technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot iAD
#property indicator_label1 "iAD"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
MqlParam pars[1];
pars[0].type=TYPE_INT;
pars[0].integer_value=volumes;
handle=IndicatorCreate(name,period,IND_AD,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iAD indicator for the symbol %s/%s, error code %d
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Accumulation/Distribution indicator is calculated for
short_name=StringFormat("iAD(%s/%s)",name,EnumToString(period));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iAD indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iA
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iADBuffer array is greater than the number of values in the iAD indicator for sy
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iADBuffer array with values of the Accumulation/Distribution indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArrayFromBuffer(iADBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Accumulation/Distribution indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iAD indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer of the Accumulation/Distribution l
int ind_handle, // handle of the iAD indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iADBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iAD indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iADX
The function returns the handle of the Average Directional Movement Index indicator.
int iADX(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int adx_period // averaging period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
adx_period
[in] Period to calculate the index.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
The buffer numbers are the following : 0 - M AI N_LI NE, 1 - PL US DI _LI NE, 2 - MI NUS DI _LI NE.
Example:
//+------------------------------------------------------------------+
//| Demo_iADX.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iADX technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 3
SetIndexBuffer(0,ADXBuffer,INDICATOR_DATA);
SetIndexBuffer(1,DI_plusBuffer,INDICATOR_DATA);
SetIndexBuffer(2,DI_minusBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iADX)
handle=iADX(name,period,adx_period);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[1];
pars[0].type=TYPE_INT;
pars[0].integer_value=adx_period;
handle=IndicatorCreate(name,period,IND_ADX,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iADX indicator for the symbol %s/%s, error code %
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Average Directional Movement Index indicator is calculated for
short_name=StringFormat("iADX(%s/%s period=%d)",name,EnumToString(period),adx_period);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
//--- fill a part of the DI_plusBuffer array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,1,0,amount,DIplus_values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iADX indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the DI_minusBuffer array with values from the indicator buffer that has index
if(CopyBuffer(ind_handle,2,0,amount,DIminus_values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iADX indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iADXWilder
The function returns the handle of Average Directional Movement Index by W elles W ilder.
int iADXWilder(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int adx_period // averaging period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
adx_period
[in] Period to calculate the index.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
The buffer numbers are the following : 0 - M AI N_LI NE, 1 - PL US DI _LI NE, 2 - MI NUS DI _LI NE.
Example:
//+------------------------------------------------------------------+
//| iADXWilder.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iADXWilder technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 3
SetIndexBuffer(0,ADXBuffer,INDICATOR_DATA);
SetIndexBuffer(1,DI_plusBuffer,INDICATOR_DATA);
SetIndexBuffer(2,DI_minusBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iADXWilder)
handle=iADXWilder(name,period,adx_period);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[1];
pars[0].type=TYPE_INT;
pars[0].integer_value=adx_period;
handle=IndicatorCreate(name,period,IND_ADXW,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iADXWilder indicator for the symbol %s/%s, error
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Average Directional Movement Index by Welles Wilder indicator i
short_name=StringFormat("iADXWilder(%s/%s period=%d)",name,EnumToString(period),adx_period);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
//--- fill a part of the DI_plusBuffer array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,1,0,amount,DIplus_values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iADXWilder indicator, error code %d",GetLastError()
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the DI_plusBuffer array with values from the indicator buffer that has index 2
if(CopyBuffer(ind_handle,2,0,amount,DIminus_values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iADXWilder indicator, error code %d",GetLastError()
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iAlligator
The function returns the handle of the Alligator indicator.
int iAlligator(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int jaw_period, // period for the calculation of jaws
int jaw_shift, // horizontal shift of jaws
int teeth_period, // period for the calculation of teeth
int teeth_shift, // horizontal shift of teeth
int lips_period, // period for the calculation of lips
int lips_shift, // horizontal shift of lips
ENUM_MA_METHOD ma_method, // type of smoothing
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
jaw_period
[in] Averaging period for the blue line (Alligator's Jaw)
jaw_shift
[in] The shift of the blue line relative to the price chart.
teeth_period
[in] Averaging period for the red line (Alligator's Teeth).
teeth_shift
[in] The shift of the red line relative to the price chart.
lips_period
[in] Averaging period for the green line (Alligator's lips).
lips_shift
[in] The shift of the green line relative to the price chart.
ma_method
[in] The method of averaging. Can be any of the ENUM _M A_M ET H OD values.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
The buffer numbers are the following : 0 - GATORJAW_LI NE, 1 - GATOR T EET H_LI NE, 2 -
GATOR LIPS _LINE.
Example:
//+------------------------------------------------------------------+
//| Demo_iAlligator.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iAlligator technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All the other parameters are similar to the standard Alligator."
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
//--- plot Jaws
#property indicator_label1 "Jaws"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- plot Teeth
#property indicator_label2 "Teeth"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- plot Lips
#property indicator_label3 "Lips"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrLime
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//+------------------------------------------------------------------+
jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iAlligator indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iA
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the JawsBuffer array is greater than the number of values in the iAlligator indicato
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the Alligator indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArraysFromBuffers(JawsBuffer,jaw_shift,TeethBuffer,teeth_shift,LipsBuffer,lips_shift,han
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Alligator indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iAlligator indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &jaws_buffer[], // indicator buffer for the Jaw line
int j_shift, // shift of the Jaw line
double &teeth_buffer[], // indicator buffer for the Teeth line
int t_shift, // shift of the Teeth line
double &lips_buffer[], // indicator buffer for the Lips line
int l_shift, // shift of the Lips line
int ind_handle, // handle of the iAlligator indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the JawsBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,-j_shift,amount,jaws_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iAlligator indicator, error code %d",GetLastError()
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the TeethBuffer array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,1,-t_shift,amount,teeth_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iAlligator indicator, error code %d",GetLastError()
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the LipsBuffer array with values from the indicator buffer that has index 2
if(CopyBuffer(ind_handle,2,-l_shift,amount,lips_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iAlligator indicator, error code %d",GetLastError()
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iAMA
The function returns the handle of the Adaptive Moving Average indicator. It has only one buffer.
int iAMA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ama_period, // average period for AMA
int fast_ma_period, // fast MA period
int slow_ma_period, // slow MA period
int ama_shift, // horizontal shift of the indicator
ENUM_APPLIED_PRICE applied_price // type of the price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ama_period
[in] The calculation period, on which the efficiency coefficient is calculated.
fast_ma_period
[in] Fast period for the smoothing coefficient calculation for a rapid mark et.
slow_ma_period
[in] Slow period for the smoothing coefficient calculation in the absence of trend.
ama_shift
[in] Shift of the indicator relative to the price chart.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iAMA.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot iAMA
#property indicator_label1 "iAMA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iAMA, // use iAMA
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iAMA; // type of the function
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
input int ama_period=15; // period of calculation
input int fast_ma_period=2; // period of fast MA
input int slow_ma_period=30; // period of slow MA
input int ama_shift=0; // horizontal shift
input ENUM_APPLIED_PRICE applied_price; // type of price
//--- indicator buffer
double iAMABuffer[];
//--- variable for storing the handle of the iAMA indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Adaptive Moving Average indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,iAMABuffer,INDICATOR_DATA);
//--- set shift
PlotIndexSetInteger(0,PLOT_SHIFT,ama_shift);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iAMA)
handle=iAMA(name,period,ama_period,fast_ma_period,slow_ma_period,ama_shift,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[5];
pars[0].type=TYPE_INT;
pars[0].integer_value=ama_period;
pars[1].type=TYPE_INT;
pars[1].integer_value=fast_ma_period;
pars[2].type=TYPE_INT;
pars[2].integer_value=slow_ma_period;
pars[3].type=TYPE_INT;
pars[3].integer_value=ama_shift;
//--- type of price
pars[4].type=TYPE_INT;
pars[4].integer_value=applied_price;
handle=IndicatorCreate(name,period,IND_AMA,5,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iAMA indicator for the symbol %s/%s, error code %
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Adaptive Moving Average indicator is calculated for
short_name=StringFormat("iAMA(%s/%s,%d,%d,%d,d)",name,EnumToString(period),ama_period,fast_ma_pe
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iAMA indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iA
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iAMABuffer array is greater than the number of values in the iAMA indicator for
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the Adaptive Moving Average indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArrayFromBuffer(iAMABuffer,ama_shift,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Adaptive Moving Average indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffer from the iAMA indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &ama_buffer[], // indicator buffer of the AMA line
int a_shift, // shift of the AMA line
int ind_handle, // handle of the iAMA indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iAMABuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,-a_shift,amount,ama_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iAMA indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iAO
The function returns the handle of the Awesome Oscillator indicator. It has only one buffer.
int iAO(
string symbol, // symbol name
ENUM_TIMEFRAMES period // period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iAO.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iAO technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//--- the iAO plot
#property indicator_label1 "iAO"
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrGreen,clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iAO indicator for the symbol %s/%s, error code %d
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Awesome Oscillator indicator is calculated for
short_name=StringFormat("iAO(%s/%s)",name,EnumToString(period));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iAO indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iA
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iAOBuffer array is greater than the number of values in the iAO indicator for sy
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
iATR
The function returns the handle of the Average True R ange indicator. It has only one buffer.
int iATR(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period // averaging period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] The value of the averaging period for the indicator calculation.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iATR.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iATR technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot iATR
#property indicator_label1 "iATR"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
MqlParam pars[1];
pars[0].type=TYPE_INT;
pars[0].integer_value=atr_period;
handle=IndicatorCreate(name,period,IND_ATR,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iATR indicator for the symbol %s/%s, error code %
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Average True Range indicator is calculated for
short_name=StringFormat("iATR(%s/%s, period=%d)",name,EnumToString(period),atr_period);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iATR indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iA
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iATRBuffer array is greater than the number of values in the iATR indicator for
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iATRBuffer array with values of the Average True Range indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iATRBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Average True Range indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iATR indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer for ATR values
int ind_handle, // handle of the iATR indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iATRBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iATR indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iBearsPower
The function returns the handle of the Bears Power indicator. It has only one buffer.
int iBearsPower(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] The value of the averaging period for the indicator calculation.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iBearsPower.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iBearsPower technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iBearsPower plot
#property indicator_label1 "iBearsPower"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrSilver
MqlParam pars[1];
//--- period of ma
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
handle=IndicatorCreate(name,period,IND_BEARS,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iBearsPower indicator for the symbol %s/%s, error
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Bears Power indicator is calculated for
short_name=StringFormat("iBearsPower(%s/%s, period=%d)",name,EnumToString(period),ma_period);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iBearsPower indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iB
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iBearsPowerBuffer array is greater than the number of values in the iBearsPower
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iBearsPowerBuffer array with values of the Bears Power indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iBearsPowerBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Bears Power indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iBearsPower indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer for Bears Power values
int ind_handle, // handle of the iBearsPower indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iBearsPowerBuffer array with values from the indicator buffer that has 0 i
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iBearsPower indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
iBands
The function returns the handle of the Bollinger Bands ® indicator.
int iBands(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int bands_period, // period for average line calculation
int bands_shift, // horizontal shift of the indicator
double deviation, // number of standard deviations
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
bands_period
[in] The averaging period of the main line of the indicator.
bands_shift
[in] The shift the indicator relative to the price chart.
deviation
[in] Deviation from the main line.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
The buffer numbers are the following : 0 - BAS E_LI NE, 1 - UPPER_BAND, 2 - LOWER_BAND
Example:
//+------------------------------------------------------------------+
//| Demo_iBands.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 3
//--- the Upper plot
#property indicator_label1 "Upper"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrMediumSeaGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- the Lower plot
#property indicator_label2 "Lower"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrMediumSeaGreen
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- the Middle plot
#property indicator_label3 "Middle"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrMediumSeaGreen
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iBands, // use iBands
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iBands; // type of the function
input int bands_period=20; // period of moving average
input int bands_shift=0; // shift
input double deviation=2.0; // number of standard deviations
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffers
double UpperBuffer[];
double LowerBuffer[];
double MiddleBuffer[];
//--- variable for storing the handle of the iBands indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Bollinger Bands indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of arrays to indicator buffers
SetIndexBuffer(0,UpperBuffer,INDICATOR_DATA);
SetIndexBuffer(1,LowerBuffer,INDICATOR_DATA);
SetIndexBuffer(2,MiddleBuffer,INDICATOR_DATA);
//--- set shift of each line
PlotIndexSetInteger(0,PLOT_SHIFT,bands_shift);
PlotIndexSetInteger(1,PLOT_SHIFT,bands_shift);
PlotIndexSetInteger(2,PLOT_SHIFT,bands_shift);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iBands)
handle=iBands(name,period,bands_period,bands_shift,deviation,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[4];
//--- period of ma
pars[0].type=TYPE_INT;
pars[0].integer_value=bands_period;
//--- shift
pars[1].type=TYPE_INT;
pars[1].integer_value=bands_shift;
//--- number of standard deviation
pars[2].type=TYPE_DOUBLE;
pars[2].double_value=deviation;
{
//--- if the size of indicator buffers is greater than the number of values in the iBands ind
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the array with values of the Bollinger Bands indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArraysFromBuffers(MiddleBuffer,UpperBuffer,LowerBuffer,bands_shift,handle,values_to_copy
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Bollinger Bands indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iBands indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &base_values[], // indicator buffer of the middle line of Bol
double &upper_values[], // indicator buffer of the upper border
double &lower_values[], // indicator buffer of the lower border
int shift, // shift
int ind_handle, // handle of the iBands indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the MiddleBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,-shift,amount,base_values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iBands indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the UpperBuffer array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,1,-shift,amount,upper_values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iBands indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the LowerBuffer array with values from the indicator buffer that has index 2
if(CopyBuffer(ind_handle,2,-shift,amount,lower_values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iBands indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iBullsPower
The function returns the handle of the Bulls Power indicator. It has only one buffer.
int iBullsPower(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] The averaging period for the indicator calculation.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iBullsPower.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iBullsPower technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iBullsPower plot
#property indicator_label1 "iBullsPower"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrSilver
MqlParam pars[1];
//--- period of ma
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
handle=IndicatorCreate(name,period,IND_BULLS,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iBullsPower indicator for the symbol %s/%s, error
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Bulls Power indicator is calculated for
short_name=StringFormat("iBullsPower(%s/%s, period=%d)",name,EnumToString(period),ma_period);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iBullsPower indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iB
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iBullsPowerBuffer array is greater than the number of values in the iBullsPower
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iBullsPowerBuffer array with values of the Bulls Power indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iBullsPowerBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Bulls Power indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iBullsPower indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer of Bulls Power values
int ind_handle, // handle of the iBullsPower indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iBullsPowerBuffer array with values from the indicator buffer that has 0 i
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iBullsPower indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
iCCI
The function returns the handle of the Commodity Channel Index indicator. It has only one buffer.
int iCCI(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] The averaging period for the indicator calculation.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iCCI.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iCCI technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iCCI plot
#property indicator_label1 "iCCI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- horizontal levels in the indicator window
#property indicator_level1 -100.0
#property indicator_level2 100.0
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iCCI, // use iCCI
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iCCI; // type of the function
input int ma_period=14; // period of moving average
input ENUM_APPLIED_PRICE applied_price=PRICE_TYPICAL; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iCCIBuffer[];
//--- variable for storing the handle of the iCCI indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Commodity Channel Index indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iCCIBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
{
//--- number of values copied from the iCCI indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iC
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iCCIBuffer array is greater than the number of values in the iCCI indicator for
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iCCIBuffer array with values of the Commodity Channel Index indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iCCIBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Commodity Channel Index indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iCCI indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer of Commodity Channel Index values
int ind_handle, // handle of the iCCI indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iCCIBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iCCI indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iChaikin
The function returns the handle of the Chaik in Oscillator indicator. It has only one buffer.
int iChaikin(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int fast_ma_period, // fast period
int slow_ma_period, // slow period
ENUM_MA_METHOD ma_method, // smoothing type
ENUM_APPLIED_VOLUME applied_volume // type of volume
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
fast_ma_period
[in] Fast averaging period for calculations.
slow_ma_period
[in] Slow averaging period for calculations.
ma_method
[in] Smoothing type. Can be one of the averaging constants of ENUM _M A_M ET H OD.
applied_volume
[in] The volume used. Can be one of the constants of ENUM _APPLIED_VOL UM E.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iChaikin.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iChaikin technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iChaikin plot
#property indicator_label1 "iChaikin"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iChaikin, // use iChaikin
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iChaikin; // type of the function
input int fast_ma_period=3; // period of fast ma
input int slow_ma_period=10; // period of slow ma
input ENUM_MA_METHOD ma_method=MODE_EMA; // type of smoothing
input ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK; // type of volume
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iChaikinBuffer[];
//--- variable for storing the handle of the iChaikin indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Chaikin Oscillator indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iChaikinBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iChaikin indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iC
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iChaikinBuffer array is greater than the number of values in the iChaikin indica
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iChaikinBuffer array with values of the Chaikin Oscillator indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iChaikinBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Chaikin Oscillator indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iChaikin indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer of Chaikin Oscillator values
int ind_handle, // handle of the iChaikin indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iChaikinBuffer array with values from the indicator buffer that has 0 inde
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iChaikin indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iCustom
The function returns the handle of a specified custom indicator.
int iCustom(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
string name // folder/custom_indicator_name
... // list of indicator input parameters
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
name
[in] The name of the custom indicator, with path relative to the root directory of indicators
(MQL5/Indicators /). If an indicator is located in a subdirectory, for example, in
MQL5/Indicators /Examples , its name must be specified lik e: " Examples \\ indicator_name" (it is
necessary to use a double slash instead of the single slash as a separator).
...
[in] input-parameters of a custom indicator, separated by commas. Type and order of parameters
must match. If there is no parameters specified, then default values will be used.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
A custom indicator must be compiled (with extension EX5) and located in the directory
MQL5/Indicators of the client terminal or its subdirectory.
Indicators that require testing are defined automatically from the call of the iCustom() function, if
the corresponding parameter is set through a constant string. For all other cases (use of the
IndicatorCreate() function or use of a non-constant string in the parameter that sets the indicator
name) the property #property tester_indicator is required:
If the first call form is used in the indicator, then at the custom indicator start you can additionally
indicate data for calculation in its " Parameters " tab. If the "Apply to" parameter is not selected
explicitly, the default calculation is based on the values of " Close" prices.
W hen you call a custom indicator from mql5-program, the Applied_Price parameter or a handle of
another indicator should be passed last, after all input variables of the custom indicator.
See also
Program Properties, Timeseries and Indicators Access,IndicatorCreate(), IndicatorR elease()
Example:
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//---- plot Label1
#property indicator_label1 "Label1"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- input parameters
input int MA_Period=21;
input int MA_Shift=0;
input ENUM_MA_METHOD MA_Method=MODE_SMA;
//--- indicator buffers
double Label1Buffer[];
//--- Handle of the Custom Moving Average.mq5 custom indicator
int MA_handle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,Label1Buffer,INDICATOR_DATA);
ResetLastError();
iDEMA
The function returns the handle of the Double Exponential Moving Average indicator. It has only one
buffer.
int iDEMA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
int ma_shift, // horizontal shift
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period (bars count) for calculations.
ma_shift
[in] Shift of the indicator relative to the price chart.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iDEMA.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iDEMA technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iDEMA plot
#property indicator_label1 "iDEMA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iDEMA, // use iDEMA
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iDEMA; // type of te function
input int ma_period=14; // period of moving average
input int ma_shift=0; // shift
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iDEMABuffer[];
//--- variable for storing the handle of the iDEMA indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Double Exponential Moving Average indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iDEMABuffer,INDICATOR_DATA);
//--- set shift
PlotIndexSetInteger(0,PLOT_SHIFT,ma_shift);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iDEMA)
handle=iDEMA(name,period,ma_period,ma_shift,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[3];
//--- period of moving average
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
//--- shift
pars[1].type=TYPE_INT;
pars[1].integer_value=ma_shift;
//--- type of price
pars[2].type=TYPE_INT;
pars[2].integer_value=applied_price;
handle=IndicatorCreate(name,period,IND_DEMA,3,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iDEMA indicator for the symbol %s/%s, error code
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Double Exponential Moving Average indicator is calculated for
short_name=StringFormat("iDEMA(%s/%s, %d, %d, %s)",name,EnumToString(period),
ma_period,ma_shift,EnumToString(applied_price));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
iDeMarker
The function returns the handle of the DeMark er indicator. It has only one buffer.
int iDeMarker(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period // averaging period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period (bars count) for calculations.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iDeMarker.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iDeMarker technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iDeMarker plot
#property indicator_label1 "iDeMarker"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[1];
//--- period of moving average
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
handle=IndicatorCreate(name,period,IND_DEMARKER,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iDeMarker indicator for the symbol %s/%s, error c
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the DeMarker indicator is calculated for
short_name=StringFormat("iDeMarker(%s/%s, period=%d)",name,EnumToString(period),ma_period);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iDeMarker indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iD
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iDeMarkerBuffer array is greater than the number of values in the iDeMarker indi
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iDeMarkerBuffer array with values of the DeMarker indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iDeMarkerBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the DeMarker indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iDeMarker indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer for DeMarker values
int ind_handle, // handle of the iDeMarker indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iDeMarkerBuffer array with values from the indicator buffer that has 0 ind
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iDeMarker indicator, error code %d",GetLastError())
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iEnvelopes
The function returns the handle of the Envelopes indicator.
int iEnvelopes(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // period for the average line calculation
int ma_shift, // horizontal shift of the indicator
ENUM_MA_METHOD ma_method, // type of smoothing
ENUM_APPLIED_PRICE applied_price, // type of price or handle
double deviation // deviation of boundaries from the midline (in percents)
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period for the main line.
ma_shift
[in] The shift of the indicator relative to the price chart.
ma_method
[in] Smoothing type. Can be one of the values of ENUM _M A_M ET H OD.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
deviation
[in] The deviation from the main line (in percents).
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
Example:
//+------------------------------------------------------------------+
//| Demo_iEnvelopes.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iEnvelopes technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//--- the Upper plot
#property indicator_label1 "Upper"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- the Lower plot
#property indicator_label2 "Lower"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iEnvelopes, // use iEnvelopes
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iEnvelopes; // type of the function
input int ma_period=14; // period of moving average
input int ma_shift=0; // shift
input ENUM_MA_METHOD ma_method=MODE_SMA; // type of smoothing
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input double deviation=0.1; // deviation of borders from the moving avera
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double UpperBuffer[];
double LowerBuffer[];
//--- variable for storing the handle of the iEnvelopes indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Envelopes indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of arrays to indicator buffers
SetIndexBuffer(0,UpperBuffer,INDICATOR_DATA);
SetIndexBuffer(1,LowerBuffer,INDICATOR_DATA);
//--- set shift of each line
PlotIndexSetInteger(0,PLOT_SHIFT,ma_shift);
PlotIndexSetInteger(1,PLOT_SHIFT,ma_shift);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iEnvelopes)
handle=iEnvelopes(name,period,ma_period,ma_shift,ma_method,applied_price,deviation);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[5];
//--- period of moving average
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
//--- shift
pars[1].type=TYPE_INT;
pars[1].integer_value=ma_shift;
//--- type of smoothing
pars[2].type=TYPE_INT;
pars[2].integer_value=ma_method;
//--- type of price
pars[3].type=TYPE_INT;
pars[3].integer_value=applied_price;
//--- type of price
pars[4].type=TYPE_DOUBLE;
pars[4].double_value=deviation;
handle=IndicatorCreate(name,period,IND_ENVELOPES,5,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iEnvelopes indicator for the symbol %s/%s, error
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Envelopes indicator is calculated for
short_name=StringFormat("iEnvelopes(%s/%s, %d, %d, %s,%s, %G)",name,EnumToString(period),
ma_period,ma_shift,EnumToString(ma_method),EnumToString(applied_price),deviation);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iEnvelopes indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iE
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the UpperBuffer array is greater than the number of values in the iEnvelopes indicat
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the UpperBuffer and LowerBuffer arrays with values from the Envelopes indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArraysFromBuffers(UpperBuffer,LowerBuffer,ma_shift,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Envelopes indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iEnvelopes indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &upper_values[], // indicator buffer of the upper border
double &lower_values[], // indicator of the lower border
int shift, // shift
int ind_handle, // handle of the iEnvelopes indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the UpperBuffer array with values from the indicator buffer that has index 0
if(CopyBuffer(ind_handle,0,-shift,amount,upper_values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iEnvelopes indicator, error code %d",GetLastError()
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the LowerBuffer array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,1,-shift,amount,lower_values)<0)
{
iForce
The function returns the handle of the Force Index indicator. It has only one buffer.
int iForce(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
ENUM_MA_METHOD ma_method, // smoothing type
ENUM_APPLIED_VOLUME applied_volume // volume type for calculation
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period for the indicator calculations.
ma_method
[in] Smoothing type. Can be one of the values of ENUM _M A_M ET H OD.
applied_volume
[in] The volume used. Can be one of the values of ENUM _APPLIED_VOL UM E.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iForce.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iForce technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- drawing iForce
#property indicator_label1 "iForce"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iForce, // use iForce
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iForce; // type of the function
input int ma_period=13; // period of averaging
input ENUM_MA_METHOD ma_method=MODE_SMA; // type of smoothing
input ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK; // type of volume
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iForceBuffer[];
//--- variable for storing the handle of the iForce indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Force indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iForceBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iForce)
handle=iForce(name,period,ma_period,ma_method,applied_volume);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[3];
//--- period of moving average
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
//--- type of smoothing
pars[1].type=TYPE_INT;
pars[1].integer_value=ma_method;
//--- type of volume
pars[2].type=TYPE_INT;
pars[2].integer_value=applied_volume;
//--- type of price
handle=IndicatorCreate(name,period,IND_FORCE,3,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iForce indicator for the symbol %s/%s, error code
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Force indicator is calculated for
short_name=StringFormat("iForce(%s/%s, %d, %s, %s)",name,EnumToString(period),
ma_period,EnumToString(ma_method),EnumToString(applied_volume));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
iFractals
The function returns the handle of the Fractals indicator.
int iFractals(
string symbol, // symbol name
ENUM_TIMEFRAMES period // period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
The buffer numbers are the following : 0 - UPPER_LI NE, 1 - LOWER_LI NE.
Example:
//+------------------------------------------------------------------+
//| Demo_iFractals.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iFractals technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
//--- the FractalUp plot
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the FractalUpBuffer array is greater than the number of values in the iFractals indi
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the FractalUpBuffer and FractalDownBuffer arrays with values from the Fractals indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArraysFromBuffers(FractalUpBuffer,FractalDownBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Fractals indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iFractals indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &up_arrows[], // indicator buffer for up arrows
double &down_arrows[], // indicator buffer for down arrows
int ind_handle, // handle of the iFractals indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the FractalUpBuffer array with values from the indicator buffer that has 0 ind
if(CopyBuffer(ind_handle,0,0,amount,up_arrows)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iFractals indicator to the FractalUpBuffer array, e
GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the FractalDownBuffer array with values from the indicator buffer that has ind
if(CopyBuffer(ind_handle,1,0,amount,down_arrows)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iFractals indicator to the FractalDownBuffer array,
GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iFrAMA
The function returns the handle of the Fractal Adaptive Moving Average indicator. It has only one
buffer.
int iFrAMA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
int ma_shift, // horizontal shift on the chart
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Period (bars count) for the indicator calculations.
ma_shift
[in] Shift of the indicator in the price chart.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iFrAMA.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iFrAMA technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- drawing iFrAMA
#property indicator_label1 "iFrAMA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iFrAMA, // use iFrAMA
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iFrAMA; // type of the function
input int ma_period=14; // period of averaging
input int ma_shift=0; // shift
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iFrAMABuffer[];
//--- variable for storing the handle of the iFrAMA indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Fractal Adaptive Moving Average indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iFrAMABuffer,INDICATOR_DATA);
//--- set shift
PlotIndexSetInteger(0,PLOT_SHIFT,ma_shift);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iFrAMA)
handle=iFrAMA(name,period,ma_period,ma_shift,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[3];
//--- period of moving average
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
//--- shift
pars[1].type=TYPE_INT;
pars[1].integer_value=ma_shift;
//--- type of price
pars[2].type=TYPE_INT;
pars[2].integer_value=applied_price;
//--- type of price
handle=IndicatorCreate(name,period,IND_FRAMA,3,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iFrAMA indicator for the symbol %s/%s, error code
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the iFrAMA indicator is calculated for
short_name=StringFormat("iFrAMA(%s/%s, %d, %d, %s)",name,EnumToString(period),
ma_period,ma_shift,EnumToString(applied_price));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iFrAMA indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer of Fractal Adaptive Moving Average
int shift, // shift
int ind_handle, // handle of the iFrAMA indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iFrAMABuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,-shift,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iFrAMA indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iGator
The function returns the handle of the Gator indicator. The Oscillator shows the difference between
the blue and red lines of Alligator (upper histogram) and difference between red and green lines (lower
histogram).
int iGator(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int jaw_period, // period for the calculation of the jaws
int jaw_shift, // jaws horizontal shift
int teeth_period, // period for the calculation of the teeth
int teeth_shift, // teeth horizontal shift
int lips_period, // period for the calculation of the lips
int lips_shift, // lips horizontal shift
ENUM_MA_METHOD ma_method, // type of smoothing
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
jaw_period
[in] Averaging period for the blue line (Alligator's Jaw).
jaw_shift
[in] The shift of the blue line relative to the price chart. It isn't directly connected with the visual
shift of the indicator histogram.
teeth_period
[in] Averaging period for the red line (Alligator's Teeth).
teeth_shift
[in] The shift of the red line relative to the price chart. It isn't directly connected with the visual
shift of the indicator histogram.
lips_period
[in] Averaging period for the green line (Alligator's lips).
lips_shift
[in] The shift of the green line relative to the price charts. It isn't directly connected with the
visual shift of the indicator histogram.
ma_method
[in] Smoothing type. Can be one of the values of ENUM _M A_M ET H OD.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
Example:
//+------------------------------------------------------------------+
//| Demo_iGator.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iGator technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All other parameters are as in a standard Gator Oscillator."
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 2
//--- drawing GatorUp
#property indicator_label1 "GatorUp"
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrGreen, clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- drawing GatorDown
#property indicator_label2 "GatorDown"
#property indicator_type2 DRAW_COLOR_HISTOGRAM
#property indicator_color2 clrGreen, clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iGator, // use iGator
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iGator; // type of the function
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
input int jaw_period=13; // period of the Jaw line
input int jaw_shift=8; // shift of the Jaw line
input int teeth_period=8; // period of the Teeth line
input int teeth_shift=5; // shift of the Teeth line
input int lips_period=5; // period of the Lips line
input int lips_shift=3; // shift of the Lips line
input ENUM_MA_METHOD MA_method=MODE_SMMA; // method of averaging of the Alligator lines
input ENUM_APPLIED_PRICE applied_price=PRICE_MEDIAN;// type of price used for calculation of Alli
//--- indicator buffers
double GatorUpBuffer[];
double GatorUpColors[];
double GatorDownBuffer[];
double GatorDownColors[];
//--- variable for storing the handle of the iGator indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- shift values for the upper and lower histograms
int shift;
//--- we will keep the number of values in the Gator Oscillator indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of arrays to indicator buffers
SetIndexBuffer(0,GatorUpBuffer,INDICATOR_DATA);
SetIndexBuffer(1,GatorUpColors,INDICATOR_COLOR_INDEX);
SetIndexBuffer(2,GatorDownBuffer,INDICATOR_DATA);
SetIndexBuffer(3,GatorDownColors,INDICATOR_COLOR_INDEX);
/*
All the shifts specified in the parameters refer to the Alligator indicator on the basis which th
That's is why they don't move the Gator indicator itself, but they move the Alligator lines,
which values are used for calculation of the Gator Oscillator!
*/
//--- let's calculate the shift for the upper and lower histograms, that is equal to the difference
shift=MathMin(jaw_shift,teeth_shift);
PlotIndexSetInteger(0,PLOT_SHIFT,shift);
//--- despite the indicator contains two histograms, the same shift is used - this is the implement
PlotIndexSetInteger(1,PLOT_SHIFT,shift);
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Gator Oscillator indicator is calculated for
short_name=StringFormat("iGator(%s/%s, %d, %d ,%d, %d, %d, %d)",name,EnumToString(period),
jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iGator indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iG
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the GatorUpBuffer array is greater than the number of values in the iGator indicator
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the Gator Oscillator indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArraysFromBuffers(GatorUpBuffer,GatorUpColors,GatorDownBuffer,GatorDownColors,
shift,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Gator Oscillator indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iGator indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &ups_buffer[], // indicator buffer for the upper histogra
double &up_color_buffer[], // indicator buffer for price indexes of t
double &downs_buffer[], // indicator buffer for the lower histogra
double &downs_color_buffer[], // indicator buffer for price indexes of t
int u_shift, // shift for the upper and lower histogram
int ind_handle, // handle of the iGator indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the GatorUpBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,-u_shift,amount,ups_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iGator indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the GatorUpColors array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,1,-u_shift,amount,up_color_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iGator indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the GatorDownBuffer array with values from the indicator buffer that has index
if(CopyBuffer(ind_handle,2,-u_shift,amount,downs_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iGator indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the GatorDownColors array with values from the indicator buffer that has index
if(CopyBuffer(ind_handle,3,-u_shift,amount,downs_color_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iGator indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iIchimoku
The function returns the handle of the Ichimok u Kink o H yo indicator.
int iIchimoku(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int tenkan_sen, // period of Tenkan-sen
int kijun_sen, // period of Kijun-sen
int senkou_span_b // period of Senkou Span B
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
tenkan_sen
[in] Averaging period for Tenk an Sen.
kijun_sen
[in] Averaging period for Kijun Sen.
senkou_span_b
[in] Averaging period for Senk ou Span B.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
The buffer numbers : 0 - T ENKANS EN_LI NE, 1 - KI JUNS EN_LI NE, 2 - S ENKOUSPANA_LI NE, 3 -
S ENKOUSPANB_LI NE, 4 - CH I KOUSPAN_LI NE.
Example:
//+------------------------------------------------------------------+
//| Demo_iIchimoku.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iIchimoku technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All other parameters just like in the standard Ichimoku Kinko Hyo."
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 4
//--- the Tenkan_sen plot
#property indicator_label1 "Tenkan_sen"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- the Kijun_sen plot
#property indicator_label2 "Kijun_sen"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- the Senkou_Span plot
#property indicator_label3 "Senkou Span A;Senkou Span B" // two fields will be shown in Data Windo
#property indicator_type3 DRAW_FILLING
#property indicator_color3 clrSandyBrown, clrThistle
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
//--- the Chikou_Span plot
#property indicator_label4 "Chinkou_Span"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrLime
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iIchimoku, // use iIchimoku
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iIchimoku; // type of the function
input int tenkan_sen=9; // period of Tenkan-sen
input int kijun_sen=26; // period of Kijun-sen
input int senkou_span_b=52; // period of Senkou Span B
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double Tenkan_sen_Buffer[];
double Kijun_sen_Buffer[];
double Senkou_Span_A_Buffer[];
double Senkou_Span_B_Buffer[];
double Chinkou_Span_Buffer[];
//--- variable for storing the handle of the iIchimoku indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Ichimoku Kinko Hyo indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of arrays to indicator buffers
SetIndexBuffer(0,Tenkan_sen_Buffer,INDICATOR_DATA);
SetIndexBuffer(1,Kijun_sen_Buffer,INDICATOR_DATA);
SetIndexBuffer(2,Senkou_Span_A_Buffer,INDICATOR_DATA);
SetIndexBuffer(3,Senkou_Span_B_Buffer,INDICATOR_DATA);
SetIndexBuffer(4,Chinkou_Span_Buffer,INDICATOR_DATA);
//--- set the shift for the Senkou Span channel of kijun_sen bars in the future direction
PlotIndexSetInteger(2,PLOT_SHIFT,kijun_sen);
//--- setting a shift for the Chikou Span line is not required, since the Chinkou data Span
//--- is already stored with a shift in iIchimoku
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iIchimoku)
handle=iIchimoku(name,period,tenkan_sen,kijun_sen,senkou_span_b);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[3];
//--- periods and shifts of the Alligator lines
pars[0].type=TYPE_INT;
pars[0].integer_value=tenkan_sen;
pars[1].type=TYPE_INT;
pars[1].integer_value=kijun_sen;
pars[2].type=TYPE_INT;
pars[2].integer_value=senkou_span_b;
//--- create handle
handle=IndicatorCreate(name,period,IND_ICHIMOKU,3,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iIchimoku indicator for the symbol %s/%s, error c
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Ichimoku Kinko Hyo indicator is calculated for
short_name=StringFormat("iIchimoku(%s/%s, %d, %d ,%d)",name,EnumToString(period),
tenkan_sen,kijun_sen,senkou_span_b);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iIchimoku indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iI
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the Tenkan_sen_Buffer array is greater than the number of values in the iIchimoku in
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the Ichimoku Kinko Hyo indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArraysFromBuffers(Tenkan_sen_Buffer,Kijun_sen_Buffer,Senkou_Span_A_Buffer,Senkou_Span_B_
kijun_sen,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Ichimoku Kinko Hyo indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iIchimoku indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &tenkan_sen_buffer[], // indicator buffer of the Tenkan-sen l
double &kijun_sen_buffer[], // indicator buffer of the Kijun_sen li
double &senkou_span_A_buffer[], // indicator buffer of the Senkou Span
double &senkou_span_B_buffer[], // indicator buffer of the Senkou Span
double &chinkou_span_buffer[], // indicator buffer of the Chinkou Span
int senkou_span_shift, // shift of the Senkou Span lines in th
int ind_handle, // handle of the iIchimoku indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the Tenkan_sen_Buffer array with values from the indicator buffer that has 0 i
if(CopyBuffer(ind_handle,0,0,amount,tenkan_sen_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("1.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the Kijun_sen_Buffer array with values from the indicator buffer that has inde
if(CopyBuffer(ind_handle,1,0,amount,kijun_sen_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("2.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the Chinkou_Span_Buffer array with values from the indicator buffer that has i
//--- if senkou_span_shift>0, the line is shifted in the future direction by senkou_span_shift bars
if(CopyBuffer(ind_handle,2,-senkou_span_shift,amount,senkou_span_A_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("3.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the Senkou_Span_A_Buffer array with values from the indicator buffer that has
//--- if senkou_span_shift>0, the line is shifted in the future direction by senkou_span_shift bars
if(CopyBuffer(ind_handle,3,-senkou_span_shift,amount,senkou_span_B_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("4.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the Senkou_Span_B_Buffer array with values from the indicator buffer that has
//--- when copying Chinkou Span, we don't need to consider the shift, since the Chinkou Span data
//--- is already stored with a shift in iIchimoku
if(CopyBuffer(ind_handle,4,0,amount,chinkou_span_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("5.Failed to copy data from the iIchimoku indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iBWMFI
The function returns the handle of the Mark et Facilitation Index indicator. It has only one buffer.
int iBWMFI(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
ENUM_APPLIED_VOLUME applied_volume // volume type for calculation
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
applied_volume
[in] The volume used. Can be one of the constants of ENUM _APPLIED_VOL UM E.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iBWMFI.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iBWMFI technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//--- the iBWMFI plot
#property indicator_label1 "iBWMFI"
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrLime,clrSaddleBrown,clrBlue,clrPink
{
//--- fill the structure with parameters of the indicator
MqlParam pars[1];
//--- type of volume
pars[0].type=TYPE_INT;
pars[0].integer_value=applied_volume;
handle=IndicatorCreate(name,period,IND_BWMFI,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iBWMFI indicator for the symbol %s/%s, error code
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Market Facilitation Index by Bill Williams indicator is calcula
short_name=StringFormat("iBWMFI(%s/%s, %s)",name,EnumToString(period),
EnumToString(applied_volume));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iBWMFI indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iB
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iBWMFIBuffer array is greater than the number of values in the iBWMFI indicator
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the indicator Market Facilitation Index by Bill Williams
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArraysFromBuffers(iBWMFIBuffer,iBWMFIColors,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Market Facilitation Index by Bill Williams indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iBWMFI indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &values[], // indicator buffer for the histogram values
double &colors[], // indicator buffer of the histogram colors
int ind_handle, // handle of the iBWMFI indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iBWMFIBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iBWMFI indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the iBWMFIColors array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,1,0,amount,colors)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iBWMFI indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iMomentum
The function returns the handle of the Momentum indicator. It has only one buffer.
int iMomentum(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int mom_period, // averaging period
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
mom_period
[in] Averaging period (bars count) for the calculation of the price change.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iMomentum.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iMomentum technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All the other parameters are similar to the standard Momentum."
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot iMomentum
#property indicator_label1 "iMomentum"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iMomentum, // use iMomentum
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iMomentum; // type of the function
input int mom_period=14; // period of Momentum
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iMomentumBuffer[];
//--- variable for storing the handle of the iMomentum indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Momentum indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iMomentumBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iMomentum)
handle=iMomentum(name,period,mom_period,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[2];
//--- period
pars[0].type=TYPE_INT;
pars[0].integer_value=mom_period;
//--- type of price
pars[1].type=TYPE_INT;
pars[1].integer_value=applied_price;
handle=IndicatorCreate(name,period,IND_MOMENTUM,2,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iMomentum indicator for the symbol %s/%s, error c
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Momentum indicator is calculated for
short_name=StringFormat("iMomentum(%s/%s, %d, %s)",name,EnumToString(period),
mom_period, EnumToString(applied_price));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iMomentum indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iM
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iMomentumBuffer array is greater than the number of values in the iMomentum indi
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iMomentumBuffer array with values of the Momentum indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iMomentumBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Momentum indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iMomentum indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer of Momentum values
int ind_handle, // handle of the iMomentum indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iMomentumBuffer array with values from the indicator buffer that has 0 ind
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iMomentum indicator, error code %d",GetLastError())
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iMFI
The function returns the handle of the Money Flow Index indicator.
int iMFI(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
ENUM_APPLIED_VOLUME applied_volume // volume type for calculation
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period (bars count) for the calculation.
applied_volume
[in] The volume used. Can be any of the ENUM _APPLIED_VOL UM E values.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iMFI.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iMFI technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All the other parameters are similar to the standard Money Flow Index."
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iMFI plot
#property indicator_label1 "iMFI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- horizontal levels in the indicator window
#property indicator_level1 20
#property indicator_level2 80
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iMFI, // use iMFI
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iMFI; // type of the function
input int ma_period=14; // period
input ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK; // type of volume
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iMFIBuffer[];
//--- variable for storing the handle of the iMFI indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Money Flow Index indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iMFIBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
{
//--- number of values copied from the iMFI indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iM
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iMFIBuffer array is greater than the number of values in the iMFI indicator for
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the iMFIBuffer array with values of the Money Flow Index indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iMFIBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Money Flow Index indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iMFI indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer of Money Flow Index values
int ind_handle, // handle of the iMFI indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iMFIBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iMFI indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iMA
The function returns the handle of the Moving Average indicator. It has only one buffer.
int iMA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
int ma_shift, // horizontal shift
ENUM_MA_METHOD ma_method, // smoothing type
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period for the calculation of the moving average.
ma_shift
[in] Shift of the indicator relative to the price chart.
ma_method
[in] Smoothing type. Can be one of the ENUM _M A_M ET H OD values.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iMA.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iMA plot
#property indicator_label1 "iMA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iMA, // use iMA
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iMA; // type of the function
input int ma_period=10; // period of ma
input int ma_shift=0; // shift
input ENUM_MA_METHOD ma_method=MODE_SMA; // type of smoothing
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iMABuffer[];
//--- variable for storing the handle of the iMA indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Moving Average indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iMABuffer,INDICATOR_DATA);
iOsMA
The function returns the handle of the Moving Average of Oscillator indicator. The OsM A oscillator
shows the difference between values of M ACD and its signal line. It has only one buffer.
int iOsMA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int fast_ema_period, // period for Fast Moving Average
int slow_ema_period, // period for Slow Moving Average
int signal_period, // averaging period for their difference
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
fast_ema_period
[in] Period for Fast Moving Average calculation.
slow_ema_period
[in] Period for Slow Moving Average calculation.
signal_period
[in] Averaging period for signal line calculation.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
Example:
//+------------------------------------------------------------------+
//| Demo_iOsMA.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iOsMA technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All the other parameters are similar to the standard Moving Average of Oscil
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iOsMA plot
#property indicator_label1 "iOsMA"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrSilver
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iOsMA, // use iOsMA
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iOsMA; // type of the function
input int fast_ema_period=12; // period of fast ma
input int slow_ema_period=26; // period of slow ma
input int signal_period=9; // period of averaging of difference
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iOsMABuffer[];
//--- variable for storing the handle of the iAMA indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Moving Average indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iOsMABuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iOsMA)
handle=iOsMA(name,period,fast_ema_period,slow_ema_period,signal_period,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[4];
//--- period of fast ma
pars[0].type=TYPE_INT;
pars[0].integer_value=fast_ema_period;
//--- period of slow ma
pars[1].type=TYPE_INT;
pars[1].integer_value=slow_ema_period;
//--- period of averaging of difference between the fast and the slow moving average
pars[2].type=TYPE_INT;
pars[2].integer_value=signal_period;
//--- type of price
pars[3].type=TYPE_INT;
pars[3].integer_value=applied_price;
handle=IndicatorCreate(name,period,IND_OSMA,4,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create a handle of iOsMA for the pair %s/%s, error code is %d",
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Moving Average of Oscillator indicator is calculated for
short_name=StringFormat("iOsMA(%s/%s,%d,%d,%d,%s)",name,EnumToString(period),
fast_ema_period,slow_ema_period,signal_period,EnumToString(applied_price
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iOsMA indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iO
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iOsMABuffer array is greater than the number of values in the iOsMA indicator fo
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the iOsMA indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iOsMABuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Moving Average of Oscillator indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iOsMA indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &ama_buffer[], // indicator buffer of OsMA values
int ind_handle, // handle of the iOsMA indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iOsMABuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,ama_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iOsMA indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iMACD
The function returns the handle of the Moving Averages Convergence/Divergence indicator. In systems
where OsM A is called M ACD H istogram, this indicator is shown as two lines. In the client terminal the
Moving Averages Convergence/Divergence look s lik e a histogram.
int iMACD(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int fast_ema_period, // period for Fast average calculation
int slow_ema_period, // period for Slow average calculation
int signal_period, // period for their difference averaging
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
fast_ema_period
[in] Period for Fast Moving Average calculation.
slow_ema_period
[in] Period for Slow Moving Average calculation.
signal_period
[in] Period for Signal line calculation.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
The buffer numbers are the following : 0 - M AI N_LI NE, 1 - SI GNAL _LI NE.
Example:
//+------------------------------------------------------------------+
//| Demo_iMACD.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iMACD technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All other parameters like in the standard MACD."
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 2
//--- the MACD plot
#property indicator_label1 "MACD"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrSilver
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- the Signal plot
#property indicator_label2 "Signal"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_DOT
#property indicator_width2 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iMACD, // use iMACD
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iMACD; // type of the function
input int fast_ema_period=12; // period of fast ma
input int slow_ema_period=26; // period of slow ma
input int signal_period=9; // period of averaging of difference
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffers
double MACDBuffer[];
double SignalBuffer[];
//--- variable for storing the handle of the iMACD indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Moving Averages Convergence/Divergence indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of arrays to indicator buffers
SetIndexBuffer(0,MACDBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iMACD)
handle=iMACD(name,period,fast_ema_period,slow_ema_period,signal_period,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[4];
//--- period of fast ma
pars[0].type=TYPE_INT;
pars[0].integer_value=fast_ema_period;
//--- period of slow ma
pars[1].type=TYPE_INT;
pars[1].integer_value=slow_ema_period;
//--- period of averaging of difference between the fast and the slow moving average
pars[2].type=TYPE_INT;
pars[2].integer_value=signal_period;
//--- type of price
pars[3].type=TYPE_INT;
pars[3].integer_value=applied_price;
handle=IndicatorCreate(name,period,IND_MACD,4,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iMACD indicator for the symbol %s/%s, error code
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Moving Average Convergence/Divergence indicator is calculated f
short_name=StringFormat("iMACD(%s/%s,%d,%d,%d,%s)",name,EnumToString(period),
fast_ema_period,slow_ema_period,signal_period,EnumToString(applied_price
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iMACD indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iM
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the MACDBuffer array is greater than the number of values in the iMACD indicator for
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- fill a part of the SignalBuffer array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,1,0,amount,signal_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iMACD indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iOBV
The function returns the handle of the On Balance Volume indicator. It has only one buffer.
int iOBV(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
ENUM_APPLIED_VOLUME applied_volume // volume type for calculation
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
applied_volume
[in] The volume used. Can be any of the ENUM _APPLIED_VOL UM E values.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iOBV.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iOBV technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- iOBV
#property indicator_label1 "iOBV"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
MqlParam pars[1];
//--- type of volume
pars[0].type=TYPE_INT;
pars[0].integer_value=applied_volume;
handle=IndicatorCreate(name,period,IND_OBV,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iOBV indicator for the symbol %s/%s, error code %
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the On Balance Volume indicator is calculated for
short_name=StringFormat("iOBV(%s/%s, %s)",name,EnumToString(period),
EnumToString(applied_volume));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iOBV indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iO
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iSAR
The function returns the handle of the Parabolic Stop and R everse system indicator. It has only one
buffer.
int iSAR(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
double step, // price increment step - acceleration factor
double maximum // maximum value of step
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
step
[in] The step of price increment, usually 0.02.
maximum
[in] The maximum step, usually 0.2.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iSAR.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iSAR technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All the other parameters are similar to the standard Parabolic Stop and Reve
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- drawing iSAR
#property indicator_label1 "iSAR"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iSAR, // use iSAR
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iSAR; // type of the function
input double step=0.02; // step - the acceleration factor for trai
input double maximum=0.2; // maximum value of step
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffers
double iSARBuffer[];
//--- variable for storing the handle of the iSAR indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Parabolic SAR indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iSARBuffer,INDICATOR_DATA);
//--- set a symbol code from the Wingdings charset for the PLOT_ARROW property for displaying on a
PlotIndexSetInteger(0,PLOT_ARROW,159);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
{
//--- number of values copied from the iSAR indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iS
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iSARBuffer array is greater than the number of values in the iSAR indicator for
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the iSAR indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iSARBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Parabolic SAR indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iSAR indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &sar_buffer[], // indicator buffer of Parabolic SAR values
int ind_handle, // handle of the iSAR indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iSARBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,sar_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iSAR indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iRSI
The function returns the handle of the R elative Strength Index indicator. It has only one buffer.
int iRSI(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period for the R SI calculation.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iRSI.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iRSI technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All the other parameters are similar to the standard Relative Strength Index
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- drawing iRSI
#property indicator_label1 "iRSI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- limits for displaying of values in the indicator window
#property indicator_maximum 100
#property indicator_minimum 0
//--- horizontal levels in the indicator window
#property indicator_level1 70.0
#property indicator_level2 30.0
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iRSI, // use iRSI
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iRSI; // type of the function
input int ma_period=14; // period of averaging
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iRSIBuffer[];
//--- variable for storing the handle of the iRSI indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Relative Strength Index indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iRSIBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iRSI)
handle=iRSI(name,period,ma_period,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[2];
//--- period of moving average
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
//--- limit of the step value that can be used for calculations
pars[1].type=TYPE_INT;
pars[1].integer_value=applied_price;
handle=IndicatorCreate(name,period,IND_RSI,2,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Relative Strength Index indicator is calculated for
short_name=StringFormat("iRSI(%s/%s, %d, %d)",name,EnumToString(period),
ma_period,applied_price);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
iRVI
The function returns the handle of the R elative Vigor Index indicator.
int iRVI(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period // averaging period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period for the RVI calculation.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
The buffer numbers are the following : 0 - M AI N_LI NE, 1 - SI GNAL _LI NE.
Example:
//+------------------------------------------------------------------+
//| Demo_iRVI.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iRVI technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property description "All the other parameters are similar to the standard Relative Vigor Index."
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 2
//--- the RVI plot
#property indicator_label1 "RVI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- the Signal plot
#property indicator_label2 "Signal"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iRVI, // use iRVI
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iRVI; // type of the function
input int ma_period=10; // period for calculations
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffers
double RVIBuffer[];
double SignalBuffer[];
//--- variable for storing the handle of the iRVI indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Relative Vigor Index indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of arrays to indicator buffers
SetIndexBuffer(0,RVIBuffer,INDICATOR_DATA);
SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iRVI)
handle=iRVI(name,period,ma_period);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[1];
//--- period for calculations
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
handle=IndicatorCreate(name,period,IND_RVI,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iRVI indicator for the symbol %s/%s, error code %
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Relative Vigor Index indicator is calculated for
short_name=StringFormat("iRVI(%s/%s, %d, %d)",name,EnumToString(period),ma_period);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iRVI indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iR
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the RVIBuffer array is greater than the number of values in the iRVI indicator for s
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the iRVI indicator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(RVIBuffer,SignalBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Relative Vigor Index indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iRVI indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &rvi_buffer[], // indicator buffer of Relative Vigor Index valu
double &signal_buffer[], // indicator buffer of the signal line
int ind_handle, // handle of the iRVI indicator
int amount // number of copied values
)
{
iStdDev
The function returns the handle of the Standard Deviation indicator. It has only one buffer.
int iStdDev(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
int ma_shift, // horizontal shift
ENUM_MA_METHOD ma_method, // smoothing type
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period for the indicator calculations.
ma_shift
[in] Shift of the indicator relative to the price chart.
ma_method
[in] Type of averaging. Can be any of the ENUM _M A_M ET H OD values.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iStdDev.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iStdDev plot
#property indicator_label1 "iStdDev"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrMediumSeaGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iStdDev, // use iStdDev
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iStdDev; // type of the function
input int ma_period=20; // period of averaging
input int ma_shift=0; // shift
input ENUM_MA_METHOD ma_method=MODE_SMA; // type of smoothing
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iStdDevBuffer[];
//--- variable for storing the handle of the iStdDev indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Standard Deviation indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iStdDevBuffer,INDICATOR_DATA);
iStochastic
The function returns the handle of the Stochastic Oscillator indicator.
int iStochastic(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int Kperiod, // K-period (number of bars for calculations)
int Dperiod, // D-period (period of first smoothing)
int slowing, // final smoothing
ENUM_MA_METHOD ma_method, // type of smoothing
ENUM_STO_PRICE price_field // stochastic calculation method
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
Kperiod
[in] Averaging period (bars count) for the %K line calculation.
Dperiod
[in] Averaging period (bars count) for the %D line calculation.
slowing
[in] Slowing value.
ma_method
[in] Type of averaging. Can be any of the ENUM _M A_M ET H OD values.
price_field
[in] Parameter of price selection for calculations. Can be one of the ENUM _STO_PR ICE values.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Note
Example:
//+------------------------------------------------------------------+
//| Demo_iStochastic.mq5 |
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 2
//--- the Stochastic plot
#property indicator_label1 "Stochastic"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLightSeaGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- the Signal plot
#property indicator_label2 "Signal"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
//--- set limit of the indicator values
#property indicator_minimum 0
#property indicator_maximum 100
//--- horizontal levels in the indicator window
#property indicator_level1 -100.0
#property indicator_level2 100.0
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iStochastic, // use iStochastic
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iStochastic; // type of the function
input int Kperiod=5; // the K period (the number of bars for calcu
input int Dperiod=3; // the D period (the period of primary smooth
input int slowing=3; // period of final smoothing
input ENUM_MA_METHOD ma_method=MODE_SMA; // type of smoothing
input ENUM_STO_PRICE price_field=STO_LOWHIGH; // method of calculation of the Stochastic
pars[3].type=TYPE_INT;
pars[3].integer_value=ma_method;
//--- method of calculation of the Stochastic
pars[4].type=TYPE_INT;
pars[4].integer_value=price_field;
handle=IndicatorCreate(name,period,IND_STOCHASTIC,5,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iStochastic indicator for the symbol %s/%s, error
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Stochastic Oscillator indicator is calculated for
short_name=StringFormat("iStochastic(%s/%s, %d, %d, %d, %s, %s)",name,EnumToString(period),
Kperiod,Dperiod,slowing,EnumToString(ma_method),EnumToString(price_field
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iStochastic indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iS
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the StochasticBuffer array is greater than the number of values in the iStochastic i
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the iStochastic indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArraysFromBuffers(StochasticBuffer,SignalBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Stochastic Oscillator indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iStochastic indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &main_buffer[], // indicator buffer of Stochastic Oscillator v
double &signal_buffer[], // indicator buffer of the signal line
int ind_handle, // handle of the iStochastic indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the StochasticBuffer array with values from the indicator buffer that has 0 in
if(CopyBuffer(ind_handle,MAIN_LINE,0,amount,main_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iStochastic indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the SignalBuffer array with values from the indicator buffer that has index 1
if(CopyBuffer(ind_handle,SIGNAL_LINE,0,amount,signal_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iStochastic indicator, error code %d",GetLastError(
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iTEMA
The function returns the handle of the Triple Exponential Moving Average indicator. It has only one
buffer.
int iTEMA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
int ma_shift, // horizontal shift of indicator
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period (bars count) for calculation.
ma_shift
[in] Shift of indicator relative to the price chart.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iTEMA.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iTEMA technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iTEMA plot
#property indicator_label1 "iTEMA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iTEMA, // use iTEMA
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iTEMA; // type of the function
input int ma_period=14; // period of averaging
input int ma_shift=0; // shift
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iTEMABuffer[];
//--- variable for storing the handle of the iTEMA indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Triple Exponential Moving Average indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iTEMABuffer,INDICATOR_DATA);
//--- set shift
PlotIndexSetInteger(0,PLOT_SHIFT,ma_shift);
//--- determine the symbol the indicator is drawn for
name=symbol;
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iTEMA indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &tema_buffer[], // indicator buffer of Triple Exponential Moving Av
int t_shift, // shift of the line
int ind_handle, // handle of the iTEMA indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iTEMABuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,-t_shift,amount,tema_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iTEMA indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iTriX
The function returns the handle of the Triple Exponential Moving Averages Oscillator indicator. It has
only one buffer.
int iTriX(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int ma_period, // averaging period
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
ma_period
[in] Averaging period (bars count) for calculations.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iTriX.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iTriX technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iTriX plot
#property indicator_label1 "iTriX"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iTriX, // use iTriX
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iTriX; // type of the function
input int ma_period=14; // period
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iTriXBuffer[];
//--- variable for storing the handle of the iTriX indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Triple Exponential Moving Averages Oscillator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iTriXBuffer,INDICATOR_DATA);
//--- determine the symbol the indicator is drawn for
name=symbol;
//--- delete spaces to the right and to the left
StringTrimRight(name);
StringTrimLeft(name);
//--- if it results in zero length of the 'name' string
if(StringLen(name)==0)
{
//--- take the symbol of the chart the indicator is attached to
name=_Symbol;
}
//--- create handle of the indicator
if(type==Call_iTriX)
handle=iTriX(name,period,ma_period,applied_price);
else
{
//--- fill the structure with parameters of the indicator
MqlParam pars[2];
//--- period
pars[0].type=TYPE_INT;
pars[0].integer_value=ma_period;
//--- type of price
pars[1].type=TYPE_INT;
pars[1].integer_value=applied_price;
handle=IndicatorCreate(name,period,IND_TRIX,2,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iTriX indicator for the symbol %s/%s, error code
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Triple Exponential Moving Averages Oscillator is calculated for
short_name=StringFormat("iTriX(%s/%s, %d, %s)",name,EnumToString(period),
ma_period,EnumToString(applied_price));
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iTriX indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iT
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iTriXBuffer array is greater than the number of values in the iTriX indicator fo
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the array with values from the Triple Exponential Moving Averages Oscillator
//--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operati
if(!FillArrayFromBuffer(iTriXBuffer,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Triple Exponential Moving Averages Oscillator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iTriX indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &trix_buffer[], // indicator buffer of values of Triple Exponential
int ind_handle, // handle of the iTriX indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iTriXBuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,0,amount,trix_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iTriX indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iWPR
The function returns the handle of the Larry W illiams ' Percent R ange indicator. It has only one buffer.
int iWPR(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int calc_period // averaging period
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
calc_period
[in] Period (bars count) for the indicator calculation.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iWPR.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iWPR technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iWPR plot
#property indicator_label1 "iWPR"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrCyan
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
iVIDyA
The function returns the handle of the Variable Index Dynamic Average indicator. It has only one
buffer.
int iVIDyA(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
int cmo_period, // period for Chande Momentum
int ema_period, // EMA smoothing period
int ma_shift, // horizontal shift on the price chart
ENUM_APPLIED_PRICE applied_price // type of price or handle
);
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
cmo_period
[in] Period (bars count) for the Chande Momentum Oscillator calculation.
ema_period
[in] EM A period (bars count) for smoothing factor calculation.
ma_shift
[in] Shift of the indicator relative to the price chart.
applied_price
[in] The price used. Can be any of the price constants ENUM _APPLIED_PR ICE or a handle of
another indicator.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iVIDyA.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- the iVIDyA plot
#property indicator_label1 "iVIDyA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//+------------------------------------------------------------------+
//| Enumeration of the methods of handle creation |
//+------------------------------------------------------------------+
enum Creation
{
Call_iVIDyA, // use iVIDyA
Call_IndicatorCreate // use IndicatorCreate
};
//--- input parameters
input Creation type=Call_iVIDyA; // type of the function
input int cmo_period=15; // the Chande Momentum period
input int ema_period=12; // period of the factor of smoothing
input int ma_shift=0; // shift
input ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE; // type of price
input string symbol=" "; // symbol
input ENUM_TIMEFRAMES period=PERIOD_CURRENT; // timeframe
//--- indicator buffer
double iVIDyABuffer[];
//--- variable for storing the handle of the iVIDyA indicator
int handle;
//--- variable for storing
string name=symbol;
//--- name of the indicator on a chart
string short_name;
//--- we will keep the number of values in the Variable Index Dynamic Average indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- assignment of array to indicator buffer
SetIndexBuffer(0,iVIDyABuffer,INDICATOR_DATA);
iVolumes
The function returns the handle of the Volumes indicator. It has an only one buffer.
int iVolumes(
string symbol, // symbol name
ENUM_TIMEFRAMES period, // period
ENUM_APPLIED_VOLUME applied_volume // volume type for calculation
)
Parameters
symbol
[in] The symbol name of the security, the data of which should be used to calculate the indicator.
The NULL value means the current symbol.
period
[in] The value of the period can be one of the ENUM _TIM EFRAM ES values, 0 means the current
timeframe.
applied_volume
[in] The volume used. Can be any of the ENUM _APPLIED_VOL UM E values.
Return Value
R eturns the handle of a specified technical indicator, in case of failure returns INVALID_HANDL E.
The computer memory can be freed from an indicator that is no more utilized, using the
IndicatorR elease() function, to which the indicator handle is passed.
Example:
//+------------------------------------------------------------------+
//| Demo_iVolumes.mq5 |
//| Copyright 2011, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property description "The indicator demonstrates how to obtain data"
#property description "of indicator buffers for the iVolumes technical indicator."
#property description "A symbol and timeframe used for calculation of the indicator,"
#property description "are set by the symbol and period parameters."
#property description "The method of creation of the handle is set through the 'type' parameter (fu
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots 1
//--- the iVolumes plot
#property indicator_label1 "iVolumes"
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrGreen, clrRed
{
//--- fill the structure with parameters of the indicator
MqlParam pars[1];
//--- type of price
pars[0].type=TYPE_INT;
pars[0].integer_value=applied_volume;
handle=IndicatorCreate(name,period,IND_VOLUMES,1,pars);
}
//--- if the handle is not created
if(handle==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iVolumes indicator for the symbol %s/%s, error co
name,
EnumToString(period),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//--- show the symbol/timeframe the Volumes indicator is calculated for
short_name=StringFormat("iVolumes(%s/%s, %s)",name,EnumToString(period),EnumToString(applied_vol
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- normal initialization of the indicator
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//--- number of values copied from the iVolumes indicator
int values_to_copy;
//--- determine the number of values calculated in the indicator
int calculated=BarsCalculated(handle);
if(calculated<=0)
{
PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
return(0);
}
//--- if it is the first start of calculation of the indicator or if the number of values in the iV
//---or if it is necessary to calculated the indicator for two or more bars (it means something has
if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
{
//--- if the iVolumesBuffer array is greater than the number of values in the iVolumes indica
//--- otherwise, we copy less than the size of indicator buffers
if(calculated>rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
//--- it means that it's not the first time of the indicator calculation, and since the last
//--- for calculation not more than one bar is added
values_to_copy=(rates_total-prev_calculated)+1;
}
//--- fill the arrays with values of the iVolumes indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operat
if(!FillArraysFromBuffers(iVolumesBuffer,iVolumesColors,handle,values_to_copy)) return(0);
//--- form the message
string comm=StringFormat("%s ==> Updated value in the indicator %s: %d",
TimeToString(TimeCurrent(),TIME_DATE|TIME_SECONDS),
short_name,
values_to_copy);
//--- display the service message on the chart
Comment(comm);
//--- memorize the number of values in the Volumes indicator
bars_calculated=calculated;
//--- return the prev_calculated value for the next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iVolumes indicator |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &volume_buffer[], // indicator buffer of Volumes values
double &color_buffer[], // indicator buffer of colors
int ind_handle, // handle of the iVolumes indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iVolumesBuffer array with values from the indicator buffer that has 0 inde
if(CopyBuffer(ind_handle,0,0,amount,volume_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iVolumes indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- fill a part of the iVolumesColors array with values from the indicator buffer that has index
if(CopyBuffer(ind_handle,1,0,amount,color_buffer)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iVolumes indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+
//| Indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- clear the chart after deleting the indicator
Comment("");
}
W hen you run an Expert Advisor in the strategy tester, you can create your own data array based on
the simple types or simple structures (they do not contain strings, class objects or objects of dynamic
arrays). This data set can be saved using the FrameAdd() function in a special structure called a
frame. During the optimization of an Expert Advisor, each agent can send a series of frames to the
terminal. All the received frames are written in the *.MQD file named as the Expert Advisor in the
terminal_directory\ MQL5\Files \ Tester folder. They are written in the order they are received from the
agents. R eceipt of a frame in the client terminal from a testing agent generates the TesterPass event.
Frames can be stored in the computer memory and in a file with the specified name. The MQL5
language sets no limitations on the number of frames.
Function Action
See also
Testing Statistics, Properties of a R unning MQL5 Program
FrameFirst
Moves a pointer of frame reading to the beginning and resets a set filter.
bool FrameFirst();
Return Value
R eturns true if successful, otherwise false. To get information about the error, call the
GetLastError() function.
FrameFilter
Sets the frame reading filter and moves the pointer to the beginning.
bool FrameFilter(
const string name, // Public name/label
long id // Public ID
);
Return Value
R eturns true if successful, otherwise false. To get information about the error, call the
GetLastError() function.
Note
If an empty string is passed as the first parameter, the filter will work only with a numeric
parameter, i.e. only frames with the specified id will be viewed. If the value of the second
parameter is ULONG_M AX, only a text filter work s.
Call of FrameFilter("" , ULONG_M AX) is equivalent to calling FrameFirst(), i.e. equal to not using any
filter.
FrameNext
R eads a frame and moves the pointer to the next one. There are two variants of the function.
bool FrameNext(
ulong& pass, // The number of a pass in the optimization, during which the frame has been
string& name, // Public name/label
long& id, // Public ID
double& value // Value
);
Parameters
pass
[out] The number of a pass during optimization in the strategy tester.
name
[out] The name of the identifier.
id
[out] The value of the identifier.
value
[out] A single numeric value.
data
[out] An array of any type.
Return Value
R eturns true if successful, otherwise false. To get information about the error, call the
GetLastError() function.
Note
In the second version of the call, you must correctly handle the received data in the data[] array.
FrameInputs
R eceives input parameters, on which the frame with the specified pass number is formed.
bool FrameInputs(
ulong pass, // The number of a pass in the optimization
string& parameters[], // An array of strings of form "parameterN=valueN"
uint& parameters_count // The total number of parameters
);
Parameters
pass
[in] The number of a pass during optimization in the strategy tester.
parameters
[out] A string array with the description of names and parameter values
parameters_count
[out] The number of elements in the array parameters[].
Return Value
R eturns true if successful, otherwise false. To get information about the error, call the
GetLastError() function.
Note
H aving obtained the number of strings parameters_count in the parameters[] array, you can
organize a loop to go through all records. This will help you find the values of input parameters of an
Expert Advisor for the specified pass number.
FrameAdd
Adds a frame with data. There are two variants of the function.
bool FrameAdd(
const string name, // Public name/label
long id, // Public ID
double value, // Value
const string filename // Name of a data file
);
Parameters
name
[in] Public frame label. It can be used for a filter in the FrameFilter() function.
id
[in] A public identifier of the frame. It can be used for a filter in the FrameFilter() function.
value
[in] A numeric value to write into the frame. It is used to transmit a single pass result lik e in the
OnTester() function.
filename
[in] The name of the file that contains data to add to the frame. The file must be locate in the
folder MQL5/Files.
data
[in] An array of any type to write into the frame. Passed by reference.
Return Value
R eturns true if successful, otherwise false. To get information about the error, call the
GetLastError() function.
ParameterGetRange
R eceives data on the values range and the change step for an input variable when optimizing an
Expert Advisor in the Strategy Tester. There are 2 variants of the function.
bool ParameterGetRange(
const string name, // parameter (input variable) name
bool& enable, // parameter optimization enabled
long& value, // parameter value
long& start, // initial value
long& step, // change step
long& stop // final value
);
bool ParameterGetRange(
const string name, // parameter (input variable) name
bool& enable, // parameter optimization enabled
double& value, // parameter value
double& start, // initial value
double& step, // change step
double& stop // final value
);
Parameters
name
[in] input variable ID. These variables are external parameters of an application. Their values can
be specified when launching on a chart or during a single test.
enable
[out] Flag that this parameter can be used to enumerate the values during the optimization in the
Strategy Tester.
value
[out] Parameter value.
start
[out] Initial parameter value during the optimization.
step
[out] Parameter change step when enumerating its values.
stop
[out] Final parameter value during the optimization.
Return Value
R eturns true if successful, otherwise false. For information about the error, use the GetLastError()
function.
Note
The function can be called only from OnTesterInit(), OnTesterPass() and OnTesterDeinit() handlers.
It has been introduced to receive Expert Advisor input parameters ' values and variation ranges
during the optimization in the Strategy Tester.
W hen called in OnTesterInit(), the obtained data can be used to redefine the rules for enumeration
of any input variable using ParameterSetR ange() function. Therefore, new Start, Stop and Step
values can be set and the input parameter can even be completely excluded from optimization
regardless of the Strategy Tester settings. This allows you to manage the area of the input
parameters during the optimization by excluding some parameters from the optimization depending
on the Expert Advisor's k ey parameters ' values.
Example:
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Expert Advisor is designed for operation only in the Strategy Tester
if(!MQL5InfoInteger(MQL5_OPTIMIZATION))
{
MessageBox("Should be launched in the optimization mode of the Strategy Tester!");
//--- finish the Expert Advisor operation in advance and remove from the chart
return(INIT_FAILED);
}
//--- successful completion of initialization
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| TesterInit function |
//+------------------------------------------------------------------+
void OnTesterInit()
{
//--- example for long type input parameter
string name="Input1";
bool enable;
long par1,par1_start,par1_step,par1_stop;
ParameterGetRange(name,enable,par1,par1_start,par1_step,par1_stop);
Print("First parameter");
PrintFormat("%s=%d enable=%s from %d to %d with step=%d",
name,par1,(string)enable,par1_start,par1_stop,par1_step);
//--- example for double type input parameter
name="Input2";
double par2,par2_start,par2_step,par2_stop;
ParameterGetRange(name,enable,par2,par2_start,par2_step,par2_stop);
Print("Second parameter");
PrintFormat("%s=%G enable=%s from %G to %G with step=%G",
name,par2,(string)enable,par2_start,par2_stop,par2_step);
ParameterSetRange
Specifies the use of input variable when optimizing an Expert Advisor in the Strategy Tester: value,
change step, initial and final values. There are 2 variants of the function.
bool ParameterSetRange(
const string name, // parameter (input variable) name
bool enable, // parameter optimization enabled
long value, // parameter value
long start, // initial value
long step, // change step
long stop // final value
);
bool ParameterSetRange(
const string name, // parameter (input variable) name
bool enable, // parameter optimization enabled
double value, // parameter value
double start, // initial value
double step, // change step
double stop // final value
);
Parameters
name
[in] input or sinput variable ID. These variables are external parameters of an application. Their
values can be specified when launching the program.
enable
[in] Enable this parameter to enumerate the values during the optimization in the Strategy
Tester.
value
[in] Parameter value.
start
[in] Initial parameter value during the optimization.
step
[in] Parameter change step when enumerating its values.
stop
[in] Final parameter value during the optimization.
Return Value
R eturns true if successful, otherwise false. For information about the error, use the GetLastError()
function.
Note
The function can be called only from OnTesterInit() handler when launching optimization from the
Strategy Tester. It is designed for specifying the parameter's range and change step. The parameter
can be completely excluded from optimization regardless of the Strategy Tester settings. It also
allows using the variables declared with sinput modifier in the optimization process.
ParameterSetR ange() function allows you to manage an Expert Advisor optimization in the Strategy
Tester depending on its k ey parameters ' values by including or excluding required input parameters
from the optimization and setting the required range and the change step.
Event Functions
This group contains functions for work ing with custom events and timer events. Besides this group,
there are special functions for handling predefined events.
Function Action
See also
Types of Chart Events
EventSetMillisecondTimer
The function indicates to the client terminal that timer events should be generated at intervals less
than one second for this Expert Advisor or indicator.
bool EventSetMillisecondTimer(
int milliseconds // number of milliseconds
);
Parameters
milliseconds
[in] Number of milliseconds defining the frequency of timer events.
Return Value
In case of successful execution, returns true, otherwise - false. To receive an error code,
GetLastError() function should be called.
Note
This feature is designed for the cases when high-resolution timer is required. In other words, timer
events should be received more frequently than once per second. If a conventional timer with the
period of more than one second is enough for you, use EventSetTimer().
The minimum interval of 1000 milliseconds is used in the strategy tester. In general, when the timer
period is reduced, the testing time is increased, as the handler of timer events is called more often.
W hen work ing in real-time mode, timer events are generated no more than 1 time in 10-16
milliseconds due to hardware limitations.
Usually, this function should be called from OnInit() function or in class constructor. To handle
events coming from the timer, an Expert Advisor or an indicator should have OnTimer() function.
Each Expert Advisor and each indicator work with its own timer receiving events solely from this
timer. During mql5 application shutdown, the timer is forcibly destroyed in case it has been created
but has not been disabled by EventKillTimer() function.
Only one timer can be launched for each program. Each mql5 application and chart have their own
queue of events where all newly arrived events are placed. If the queue already contains Timer
event or this event is in the processing stage, then the new Timer event is not added to mql5
application queue.
EventSetTimer
The function indicates to the client terminal, that for this indicator or Expert Advisor, events from the
timer must be generated with the specified periodicity.
bool EventSetTimer(
int seconds // number of seconds
);
Parameters
seconds
[in] Number of seconds that determine the frequency of the timer event occurrence.
Return Value
In case of success returns true, otherwise false. In order to get an error code, the GetLastError()
function should be called.
Note
Normally, this function must be called from the OnInit() function or from a class constructor. In
order to handle events coming from the timer, the Expert Advisor must have the OnTimer()
function.
Every Expert Advisor, as well as every indicator work s with its own timer and receives events only
from it. As soon as a mql5 program stops operating, the timer is destroyed forcibly if it was created
but hasn't been disabled by the EventKillTimer() function.
For each program no more than one timer can be run. Each mql5 program and each chart has its own
queue of events, in which all the newly received events are placed. If the Timer event is present in
the queue or is being processed, the new Timer event will not be placed in the queue of the mql5
program.
EventKillTimer
Specifies the client terminal that is necessary to stop the generation of events from Timer.
void EventKillTimer();
Return Value
No return value.
Note
Typically, this function must be called from a function OnDeinit(), if the EventSetTimer() function
has been called from OnInit(). This function can also be called form the class destructor, if the
EventSetTimer() function has been called in the constructor of this class.
Every Expert Advisor, as well as every indicator work s with its own timer and receives events only
from it. As soon as a mql5 program stops operating, the timer is destroyed forcibly if it was created
but hasn't been disabled by the EventKillTimer() function
EventChartCustom
The function generates a custom event for the specified chart.
bool EventChartCustom(
long chart_id, // identifier of the event receiving chart
ushort custom_event_id, // event identifier
long lparam, // parameter of type long
double dparam, // parameter of type double
string sparam // string parameter of the event
);
Parameters
chart_id
[in] Chart identifier. 0 means the current chart.
custom_event_id
[in] ID of the user events. This identifier is automatically added to the value
CHAR T EVENT _CUSTOM and converted to the integer type.
lparam
[in] Event parameter of the long type passed to the OnChartEvent function.
dparam
[in] Event parameter of the double type passed to the OnChartEvent function.
sparam
[in] Event parameter of the string type passed to the OnChartEvent function. If the string is longer
than 63 characters, it is truncated.
Return Value
R eturns true if a custom event has been successfully placed in the events queue of the chart that
receives the events. In case of failure, it returns false. Use GetLastError() to get an error code.
Note
An Expert Advisor or indicator attached to the specified chart handles the event using the function
OnChartEvent(int event_id, long & lparam, double& dparam, string & sparam).
For each type of event, the input parameters of the OnChartEvent() function have definite values that
are required for the processing of this event. The events and values passed through this parameters
are listed in the below table.
Event of a CHAR T EVENT _KE code of a R epeat count The string value
k eystrok e YDOWN pressed k ey (the number of of a bit mas k
times the describing the
k eystrok e is
repeated as a status of
result of the user k eyboard buttons
holding down the
k ey)
Mouse event (if CHAR T EVENT _MO the X coordinate the Y coordinate The string value
property US E_MOVE of a bit mas k
CHAR T _EVENT _ describing the
MOUS E_MOVE=tr status of mouse
ue is set for the buttons
chart)
Event of a CHAR T EVENT _OB the X coordinate the Y coordinate Name of the
mouse click in a JECT _CLICK graphical object,
graphical object on which the
belonging to the event occurred
chart
I D of the user CHAR T EVENT _CU Value set by the Value set by the Value set by the
event under the STOM+N EventChartCusto EventChartCusto EventChartCusto
N number m() function m() function m() function
Example:
//+------------------------------------------------------------------+
//| ButtonClickExpert.mq5 |
//| Copyright 2009, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
string buttonID="Button";
string labelID="Info";
int broadcastEventID=5000;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- Create a button to send custom events
ObjectCreate(0,buttonID,OBJ_BUTTON,0,100,100);
ObjectSetInteger(0,buttonID,OBJPROP_COLOR,clrWhite);
ObjectSetInteger(0,buttonID,OBJPROP_BGCOLOR,clrGray);
ObjectSetInteger(0,buttonID,OBJPROP_XDISTANCE,100);
ObjectSetInteger(0,buttonID,OBJPROP_YDISTANCE,100);
ObjectSetInteger(0,buttonID,OBJPROP_XSIZE,200);
ObjectSetInteger(0,buttonID,OBJPROP_YSIZE,50);
ObjectSetString(0,buttonID,OBJPROP_FONT,"Arial");
ObjectSetString(0,buttonID,OBJPROP_TEXT,"Button");
ObjectSetInteger(0,buttonID,OBJPROP_FONTSIZE,10);
ObjectSetInteger(0,buttonID,OBJPROP_SELECTABLE,0);
ObjectSetInteger(0,labelID,OBJPROP_FONTSIZE,20);
ObjectSetInteger(0,labelID,OBJPROP_SELECTABLE,0);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
ObjectDelete(0,buttonID);
ObjectDelete(0,labelID);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- Check the event by pressing a mouse button
if(id==CHARTEVENT_OBJECT_CLICK)
{
string clickedChartObject=sparam;
//--- If you click on the object with the name buttonID
if(clickedChartObject==buttonID)
{
//--- State of the button - pressed or not
bool selected=ObjectGetInteger(0,buttonID,OBJPROP_STATE);
//--- log a debug message
Print("Button pressed = ",selected);
int customEventID; // Number of the custom event to send
string message; // Message to be sent in the event
//--- If the button is pressed
if(selected)
{
message="Button pressed";
customEventID=CHARTEVENT_CUSTOM+1;
}
else // Button is not pressed
{
message="Button in not pressed";
customEventID=CHARTEVENT_CUSTOM+999;
}
//--- Send a custom event "our" chart
EventChartCustom(0,customEventID-CHARTEVENT_CUSTOM,0,0,message);
///--- Send a message to all open charts
BroadcastEvent(ChartID(),0,"Broadcast Message");
//--- Debug message
Print("Sent an event with ID = ",customEventID);
}
ChartRedraw();// Forced redraw all chart objects
}
See also
Events of the client terminal, Event handler functions
In some graphic cards work ing with the double type numbers is disabled by default. This can lead to
compilation error 5105. To enable support for the double type numbers, please add the following
directive to your OpenCL program: #pragma OPENCL EXT ENSION cl_k hr_fp64 : enable. H owever if a
graphic card doesn't support double, enabling this directive won't be of help.
It is recommended to write the source code for OpenCL in separate CL files, which can later be
included in the MQL5 program using the resource variables.
Function Action
See also
OpenCL, R esources
CLHandleType
R eturns the type of an OpenCL handle as a value of the ENUM _OPENCL _HANDL E_T YPE enumeration.
ENUM_OPENCL_HANDLE_TYPE CLHandleType(
int handle // Handle of an OpenCL object
);
Parameters
handle
[in] A handle to an OpenCL object: a context, a k ernel or an OpenCL program.
Return Value
The type of the OpenCL handle as a value of the ENUM _OPENCL _HANDL E_T YPE enumeration.
ENUM_OPENCL_HANDLE_TY PE
Identifier Description
CLGetInfoInteger
R eturns the value of an integer property for an OpenCL object or device.
long CLGetInfoInteger(
int handle, // The handle of the OpenCL object or the number of the O
ENUM_OPENCL_PROPERTY_INTEGER prop // Requested property
);
Parameters
handle
[in] A handle to the OpenCL object or number of the OpenCL device. Numbering of OpenCL
devices starts with zero.
prop
[in] The type of a requested property from the ENUM _OPENCL _PR OPER T Y_INT EGER enumeration,
the value of which you want to obtain.
Return Value
The value of the property if successful or -1 in case of an error. For information about the error, use
the GetLastError() function.
ENUM_OPENCL_PROPERTY _INTEGER
CL _KERNEL _PR I VAT E_M EM _SI Z The minimum size of the ulong
E private memory (in bytes)
used by each tas k in the
OpenCL program k ernel.
The ENUM _CL _DEVICE_T YPE enumeration contains possible types of devices supporting OpenCL. You
can receive the type of device by its number or the handle of the OpenCL object by calling
CL GetInfoInteger(handle_or_deviceN, CL _DEVICE_T YPE).
ENUM_CL_DEVICE_TY PE
Identifier Description
Example:
void OnStart()
{
int cl_ctx;
//--- initialize OpenCL context
if((cl_ctx=CLContextCreate(CL_USE_GPU_ONLY))==INVALID_HANDLE)
{
Print("OpenCL not found");
return;
}
//--- Display general information about OpenCL device
Print("OpenCL type: ",EnumToString((ENUM_CL_DEVICE_TYPE)CLGetInfoInteger(cl_ctx,CL_DEVICE_TYPE))
Print("OpenCL vendor ID: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_VENDOR_ID));
Print("OpenCL units: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_MAX_COMPUTE_UNITS));
Print("OpenCL freq: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_MAX_CLOCK_FREQUENCY)," MHz");
Print("OpenCL global mem: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_GLOBAL_MEM_SIZE)," bytes");
Print("OpenCL local mem: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_LOCAL_MEM_SIZE)," bytes");
//---
}
CLGetInfoString
R eturns string value of a property for OpenCL object or device.
bool CLGetInfoString(
int handle, // OpenCL object handle or OpenCL device number
ENUM_OPENCL_PROPERTY_STRING prop, // requested property
string& value // referenced string
);
Parameters
handle
[in] OpenCL object handle or OpenCL device number. The numbering of OpenCL devices starts
with zero.
prop
[in] Type of requested property from ENUM _OPENCL _PR OPER T Y_ST R ING enumeration, the value
of which should be obtained.
value
[out] String for receiving the property value.
Return Value
true if successful, otherwise false. For information about the error, use the GetLastError() function.
ENUM_OPENCL_PROPERTY _STRING
Identifier Description
CL _PL AT FOR M _PR OFIL E CL _PL AT FOR M _PR OFIL E - OpenCL Profile. Profile
name may be one of the following values :
· FULL _PR OFIL E - implementation supports
OpenCL (functionality is defined as the part
of the k ernel specification without requiring
additional extensions for OpenCL support);
· EM BEDDED_PR OFIL E - implementation
supports OpenCL as a supplement.
Amended profile is defined as a subset for
each OpenCL version.
Example:
void OnStart()
{
int cl_ctx;
string str;
//--- initialize OpenCL context
if((cl_ctx=CLContextCreate(CL_USE_GPU_ONLY))==INVALID_HANDLE)
{
Print("OpenCL not found");
return;
}
//--- Display information about the platform
if(CLGetInfoString(cl_ctx,CL_PLATFORM_NAME,str))
Print("OpenCL platform name: ",str);
if(CLGetInfoString(cl_ctx,CL_PLATFORM_VENDOR,str))
Print("OpenCL platform vendor: ",str);
if(CLGetInfoString(cl_ctx,CL_PLATFORM_VERSION,str))
Print("OpenCL platform ver: ",str);
if(CLGetInfoString(cl_ctx,CL_PLATFORM_PROFILE,str))
Print("OpenCL platform profile: ",str);
if(CLGetInfoString(cl_ctx,CL_PLATFORM_EXTENSIONS,str))
Print("OpenCL platform ext: ",str);
//--- Display information about the device
if(CLGetInfoString(cl_ctx,CL_DEVICE_NAME,str))
Print("OpenCL device name: ",str);
if(CLGetInfoString(cl_ctx,CL_DEVICE_PROFILE,str))
Print("OpenCL device profile: ",str);
if(CLGetInfoString(cl_ctx,CL_DEVICE_BUILT_IN_KERNELS,str))
Print("OpenCL device kernels: ",str);
if(CLGetInfoString(cl_ctx,CL_DEVICE_EXTENSIONS,str))
Print("OpenCL device ext: ",str);
if(CLGetInfoString(cl_ctx,CL_DEVICE_VENDOR,str))
Print("OpenCL device vendor: ",str);
if(CLGetInfoString(cl_ctx,CL_DEVICE_VERSION,str))
Print("OpenCL device ver: ",str);
if(CLGetInfoString(cl_ctx,CL_DEVICE_OPENCL_C_VERSION,str))
Print("OpenCL open c ver: ",str);
//--- Display general information about the OpenCL device
Print("OpenCL type: ",EnumToString((ENUM_CL_DEVICE_TYPE)CLGetInfoInteger(cl_ctx,CL_DEVICE_TYPE))
Print("OpenCL vendor ID: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_VENDOR_ID));
Print("OpenCL units: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_MAX_COMPUTE_UNITS));
Print("OpenCL freq: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_MAX_CLOCK_FREQUENCY));
Print("OpenCL global mem: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_GLOBAL_MEM_SIZE));
Print("OpenCL local mem: ",CLGetInfoInteger(cl_ctx,CL_DEVICE_LOCAL_MEM_SIZE));
//---
}
CLContextCreate
Creates an OpenCL context and returns its handle.
int CLContextCreate(
int device // Serial number of the OpenCL device or macro
);
Parameter
device
[in] The ordinal number of the OpenCL-device in the system. Instead of a specific number, you
can specify one of the following values :
· CL _US E_GPU_ONL Y – OpenCL emulation is prohibited and only specialized devices with OpenCL
support (video cards) can be used.
Return Value
A handle to the OpenCL context if successful, otherwise -1. For information about the error, use the
GetLastError() function.
CLContextFree
R emoves an OpenCL context.
void CLContextFree(
int context // Handle to an OpenCL context
);
Parameters
context
[in] H andle of the OpenCL context.
Return Value
None. In the case of an internal error the value of _LastError changes. For information about the
error, use the GetLastError() function.
CLGetDeviceInfo
The function receives device property from OpenCL driver.
bool CLGetDeviceInfo(
int handle, // OpenCL device handle
int property_id, // requested property ID
uchar& data[], // array for receiving data
uint& size // shift in the array elements, default value is 0
);
Parameters
handle
[in] OpenCL device index or OpenCL handle created by CLContextCreate() function.
property_id
[in] ID of the OpenCL device property that should be received. The values can be of one of the
predetermined ones listed in the table below.
data[]
[out] The array for receiving data on the requested property.
size
[out] Size of the received data in the array data[].
Return Value
true if successful, otherwise false. For information about the error, use the GetLastError() function.
Note
For one-dimensional arrays, the number of the element, from which data reading for OpenCL buffer
starts, is calculated considering AS _S ER I ES flag.
Exact description of the property and its functions can be found at the official OpenCL web site.
Identifier Value
CL _DEVICE_VENDOR_I D 0x 1001
CL _DEVICE_EXECUTION_CAPABILITI ES 0x 1029
CL _DEVICE_NAM E 0x 102B
CL _DEVICE_VENDOR 0x 102C
CL _DEVICE_REFERENCE_COUNT 0x 1047
Example:
void OnStart()
{
//---
int dCount= CLGetInfoInteger(0,CL_DEVICE_COUNT);
for(int i = 0; i<dCount; i++)
{
int clCtx=CLContextCreate(i);
if(clCtx == -1)
Print("ERROR in CLContextCreate");
string device;
CLGetInfoString(clCtx,CL_DEVICE_NAME,device);
Print(i,": ",device);
uchar data[1024];
uint size;
CLGetDeviceInfo(clCtx,CL_DEVICE_VENDOR,data,size);
Print("size = ",size);
string str=CharArrayToString(data);
Print(str);
}
}
//--- example of entries in Experts journal
// 2013.07.24 10:50:48 opencl (EURUSD,H1) 2: Advanced Micro Devices, Inc.
// 2013.07.24 10:50:48 opencl (EURUSD,H1) size = 32
// 2013.07.24 10:50:48 opencl (EURUSD,H1) Tahiti
// 2013.07.24 10:50:48 opencl (EURUSD,H1) Intel(R) Corporation
// 2013.07.24 10:50:48 opencl (EURUSD,H1) size = 21
// 2013.07.24 10:50:48 opencl (EURUSD,H1) 1: Intel(R) Core(TM) i7-3770 CPU @ 3.40G
// 2013.07.24 10:50:48 opencl (EURUSD,H1) NVIDIA Corporation
// 2013.07.24 10:50:48 opencl (EURUSD,H1) size = 19
// 2013.07.24 10:50:48 opencl (EURUSD,H1) 0: GeForce GTX 580
CLProgramCreate
Creates an OpenCL program from a source code.
int CLProgramCreate(
int context, // Handle to an OpenCL context
const string source // Source code
);
An overloaded function version creates an OpenCL program and writes compiler messages into the
passed string.
int CLProgramCreate(
int context, // Handle to an OpenCL context
const string source, // Source code
string &build_log // A string for receiving the compilation log
);
Parameters
context
[in] H andle of the OpenCL context.
source
[in] String with the source code of the OpenCL program.
&build_log
[in] A string for receiving the OpenCL compiler messages.
Return Value
A handle to an OpenCL object if successful. In case of error -1 is returned. For information about
the error, use the GetLastError() function.
Note
In some graphic cards work ing with the double type numbers is disabled by default. This can lead to
compilation error 5105. To enable support for the double type numbers, please add the following
directive to your OpenCL program: #pragma OPENCL EXT ENSION cl_k hr_fp64 : enable. H owever if a
graphic card doesn't support double, enabling this directive won't be of help.
Example:
//+------------------------------------------------------------------+
//| OpenCL kernel |
//+------------------------------------------------------------------+
const string
cl_src=
//--- by default some GPU doesn't support doubles
//--- cl_khr_fp64 directive is used to enable work with doubles
"#pragma OPENCL EXTENSION cl_khr_fp64 : enable \r\n"
//--- OpenCL kernel function
"__kernel void Test_GPU(__global double *data, \r\n"
" const int N, \r\n"
" const int total_arrays) \r\n"
" { \r\n"
" uint kernel_index=get_global_id(0); \r\n"
" if (kernel_index>total_arrays) return; \r\n"
" uint local_start_offset=kernel_index*N; \r\n"
" for(int i=0; i<N; i++) \r\n"
" { \r\n"
" data[i+local_start_offset] *= 2.0; \r\n"
" } \r\n"
" } \r\n";
//+------------------------------------------------------------------+
//| Test_CPU |
//+------------------------------------------------------------------+
bool Test_CPU(double &data[],const int N,const int id,const int total_arrays)
{
//--- check array size
if(ArraySize(data)==0) return(false);
//--- check array index
if(id>total_arrays) return(false);
//--- calculate local offset for array with index id
int local_start_offset=id*N;
//--- multiply elements by 2
for(int i=0; i<N; i++)
{
data[i+local_start_offset]*=2.0;
}
return true;
}
//---
#define ARRAY_SIZE 100 // size of the array
#define TOTAL_ARRAYS 5 // total arrays
//--- OpenCL handles
int cl_ctx; // OpenCL context handle
int cl_prg; // OpenCL program handle
int cl_krn; // OpenCL kernel handle
int cl_mem; // OpenCL buffer handle
//---
double DataArray1[]; // data array for CPU calculation
double DataArray2[]; // data array for GPU calculation
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
int OnStart()
{
//--- initialize OpenCL objects
//--- create OpenCL context
if((cl_ctx=CLContextCreate())==INVALID_HANDLE)
{
Print("OpenCL not found. Error=",GetLastError());
return(1);
}
//--- create OpenCL program
if((cl_prg=CLProgramCreate(cl_ctx,cl_src))==INVALID_HANDLE)
{
CLContextFree(cl_ctx);
Print("OpenCL program create failed. Error=",GetLastError());
return(1);
}
//--- create OpenCL kernel
if((cl_krn=CLKernelCreate(cl_prg,"Test_GPU"))==INVALID_HANDLE)
{
CLProgramFree(cl_prg);
CLContextFree(cl_ctx);
Print("OpenCL kernel create failed. Error=",GetLastError());
return(1);
}
//--- create OpenCL buffer
if((cl_mem=CLBufferCreate(cl_ctx,ARRAY_SIZE*TOTAL_ARRAYS*sizeof(double),CL_MEM_READ_WRITE))==INV
{
CLKernelFree(cl_krn);
CLProgramFree(cl_prg);
CLContextFree(cl_ctx);
Print("OpenCL buffer create failed. Error=",GetLastError());
return(1);
}
//--- set OpenCL kernel constant parameters
CLSetKernelArgMem(cl_krn,0,cl_mem);
CLSetKernelArg(cl_krn,1,ARRAY_SIZE);
CLSetKernelArg(cl_krn,2,TOTAL_ARRAYS);
//--- prepare data arrays
ArrayResize(DataArray1,ARRAY_SIZE*TOTAL_ARRAYS);
ArrayResize(DataArray2,ARRAY_SIZE*TOTAL_ARRAYS);
//--- fill arrays with data
for(int j=0; j<TOTAL_ARRAYS; j++)
{
//--- calculate local start offset for jth array
uint local_offset=j*ARRAY_SIZE;
//--- prepare array with index j
for(int i=0; i<ARRAY_SIZE; i++)
{
//--- fill arrays with function MathCos(i+j);
DataArray1[i+local_offset]=MathCos(i+j);
DataArray2[i+local_offset]=MathCos(i+j);
}
};
//--- test CPU calculation
for(int j=0; j<TOTAL_ARRAYS; j++)
{
//--- calculation of the array with index j
Test_CPU(DataArray1,ARRAY_SIZE,j,TOTAL_ARRAYS);
}
//--- prepare CLExecute params
uint offset[]={0};
//--- global work size
uint work[]={TOTAL_ARRAYS};
//--- write data to OpenCL buffer
CLBufferWrite(cl_mem,DataArray2);
//--- execute OpenCL kernel
CLExecute(cl_krn,1,offset,work);
//--- read data from OpenCL buffer
CLBufferRead(cl_mem,DataArray2);
//--- total error
double total_error=0;
//--- compare results and calculate error
for(int j=0; j<TOTAL_ARRAYS; j++)
{
//--- calculate local offset for jth array
uint local_offset=j*ARRAY_SIZE;
//--- compare the results
for(int i=0; i<ARRAY_SIZE; i++)
{
double v1=DataArray1[i+local_offset];
double v2=DataArray2[i+local_offset];
double delta=MathAbs(v2-v1);
total_error+=delta;
//--- show first and last arrays
if((j==0) || (j==TOTAL_ARRAYS-1))
PrintFormat("array %d of %d, element [%d]: %f, %f, [error]=%f",j+1,TOTAL_ARRAYS,i,v1,v
}
}
PrintFormat("Total error: %f",total_error);
//--- delete OpenCL objects
//--- free OpenCL buffer
CLBufferFree(cl_mem);
//--- free OpenCL kernel
CLKernelFree(cl_krn);
//--- free OpenCL program
CLProgramFree(cl_prg);
//--- free OpenCL context
CLContextFree(cl_ctx);
//---
return(0);
}
CLProgramFree
R emoves an OpenCL program.
void CLProgramFree(
int program // Handle to an OpenCL object
);
Parameters
program
[in] H andle of the OpenCL object.
Return Value
None. In the case of an internal error the value of _LastError changes. For information about the
error, use the GetLastError() function.
CLKernelCreate
Creates the OpenCL program k ernel and returns its handle.
int CLKernelCreate(
int program, // Handle to an OpenCL object
const string kernel_name // Kernel name
);
Parameters
program
[in] H andle to an object of the OpenCL program.
kernel_name
[in] The name of the k ernel function in the appropriate OpenCL program, in which execution
begins.
Return Value
A handle to an OpenCL object if successful. In case of error -1 is returned. For information about
the error, use the GetLastError() function.
Note
CLKernelFree
R emoves an OpenCL start function.
void CLKernelFree(
int kernel // Handle to the kernel of an OpenCL program
);
Parameters
kernel_name
[in] H andle of the k ernel object.
Return Value
None. In the case of an internal error the value of _LastError changes. For information about the
error, use the GetLastError() function.
CLSetKernelArg
Sets a parameter for the OpenCL function.
bool CLSetKernelArg(
int kernel, // Handle to the kernel of an OpenCL program
uint arg_index, // The number of the argument of the OpenCL function
void arg_value // Source code
);
Parameters
kernel
[in] H andle to a k ernel of the OpenCL program.
arg_index
[in] The number of the function argument, numbering starts with zero.
arg_value
[in] The value of the function argument.
Return Value
R eturns true if successful, otherwise returns false. For information about the error, use the
GetLastError() function.
Note
CLSetKernelArgMem
Sets an OpenCL buffer as a parameter of the OpenCL function.
bool CLSetKernelArgMem(
int kernel, // Handle to the kernel of an OpenCL program
uint arg_index, // The number of the argument of the OpenCL function
int cl_mem_handle // Handle to OpenCL buffer
);
Parameters
kernel
[in] H andle to a k ernel of the OpenCL program.
arg_index
[in] The number of the function argument, numbering starts with zero.
cl_mem_handle
[in] A handle to an OpenCL buffer.
Return Value
R eturns true if successful, otherwise returns false. For information about the error, use the
GetLastError() function.
CLSetKernelArgMemLocal
Sets the local buffer as an argument of the k ernel function.
bool CLSetKernelArgMemLocal(
int kernel, // handle to a kernel of an OpenCL program
uint arg_index, // number of the OpenCL function argument
ulong local_mem_size // buffer size
);
Parameters
kernel
[in] H andle to a k ernel of the OpenCL program.
arg_index
[in] The number of the function argument, numbering starts with zero.
local_mem_size
[in] Buffer size in bytes.
Return Value
R eturns true if successful, otherwise returns false. For information about the error, use the
GetLastError() function.
CLBufferCreate
Creates an OpenCL buffer and returns its handle.
int CLBufferCreate(
int context, // Handle to an OpenCL context
uint size, // Buffer size
uint flags // Flags combination which specify properties of OpenCL buffer
);
Parameters
context
[in] A handle to context OpenCL.
size
[in] Buffer size in bytes.
flags
[in] Buffer properties that are set using a combination of flags : CL _M EM _READ_WR IT E,
CL _M EM _WR IT E_ONL Y, CL _M EM _READ_ONL Y, CL _M EM _ALLOC_H OST _PT R .
Return Value
A handle to an OpenCL buffer if successful. In case of error -1 is returned. For information about the
error, use the GetLastError() function.
Note
CLBufferFree
Deletes an OpenCL buffer.
void CLBufferFree(
int buffer // Handle to an OpenCL buffer
);
Parameters
buffer
[in] A handle to an OpenCL buffer.
Return Value
None. In the case of an internal error the value of _LastError changes. For information about the
error, use the GetLastError() function.
CLBufferWrite
W rites into the OpenCL buffer and returns the number of written elements.
uint CLBufferWrite(
int buffer, // A handle to the OpenCL buffer
const void& data[], // An array of values
uint buffer_offset=0, // An offset in the OpenCL buffer in bytes, 0 by default
uint data_offset=0, // An offset in the array in elements, 0 by default
uint data_count=WHOLE_ARRAY // The number of values from the array for writing, the
);
Parameters
buffer
[in] A handle of the OpenCL buffer.
data[]
[in] An array of values that should be written in the OpenCL buffer. Passed by reference.
buffer_offset
[in] An offset in the OpenCL buffer in bytes, from which writing begins. By default, writing start
with the very beginning of the buffer.
data_offset
[in] The index of the first array element, starting from which values from the array are written in
the OpenCL buffer. By default, values from the very beginning of the array are tak en.
data_count
[in] The number of values that should be written. All the values of the array, by default.
Return Value
The number of written elements. 0 is returned in case of an error. For information about the error,
use the GetLastError() function.
Note
For one-dimensional arrays, the number of the element, with which reading of data for writing into
an OpenCL buffer begins, is calculated tak ing into account the AS _S ER I ES flags.
An array of two or more dimensions is presented as one-dimensional. In this case, data_offset is the
number of elements that should be s k ipped in the presentation, not the number of elements in the
first dimension.
CLBufferRead
R eads an OpenCL buffer into an array and returns the number of read elements.
uint CLBufferRead(
int buffer, // A handle to the OpenCL buffer
const void& data[], // An array of values
uint buffer_offset=0, // An offset in the OpenCL buffer in bytes, 0 by default
uint data_offset=0, // An offset in the array in elements, 0 by default
uint data_count=WHOLE_ARRAY // The number of values from the buffer for reading, the
);
Parameters
buffer
[in] A handle of the OpenCL buffer.
data[]
[in] An array for receiving values from the OpenCL buffer. Passed by reference.
buffer_offset
[in] An offset in the OpenCL buffer in bytes, from which reading begins. By default, reading start
with the very beginning of the buffer.
data_offset
[in] The index of the first array element for writing the values of the OpenCL buffer. By default,
writing of the read values into an array starts from the zero index.
data_count
[in] The number of values that should be read. The whole OpenCL buffer is read by default.
Return Value
The number of read elements. 0 is returned in case of an error. For information about the error, use
the GetLastError() function.
Note
For one-dimensional arrays, the number of the element, into which writing of data into an OpenCL
buffer begins, is calculated tak ing into account the AS _S ER I ES flags.
An array of two or more dimensions is presented as one-dimensional. In this case, data_offset is the
number of elements that should be s k ipped in the presentation, not the number of elements in the
first dimension.
CLExecute
The function runs an OpenCL program. There are 3 versions of the function:
bool CLExecute(
int kernel // Handle to the kernel of an OpenCL program
);
2. Launching several k ernel copies (OpenCL function) with tas k space description
bool CLExecute(
int kernel, // Handle to the kernel of an OpenCL program
uint work_dim, // Dimension of the tasks space
const uint& global_work_offset[], // Initial offset in the tasks space
const uint& global_work_size[] // Total number of tasks
);
3. Launching several k ernel copies (OpenCL function) with tas k space description and specification of
the size of the group's local tas k subset
bool CLExecute(
int kernel, // Handle to the kernel of an OpenCL program
uint work_dim, // Dimension of the tasks space
const uint& global_work_offset[], // Initial offset in the tasks space
const uint& global_work_size[], // Total number of tasks
const uint& local_work_size[] // Number of tasks in the local group
);
Parameters
kernel
[in] H andle to the OpenCL k ernel.
work_dim
[in] Dimension of the tas k s space.
global_work_offset[]
[in] Initial offset in the tas k s space.
global_work_size[]
[in] The size of a subset of tas k s.
local_work_size[]
[in] The size of the group's local tas k subset.
Return Value
R eturns true if successful, otherwise returns false. For information about the error, use the
GetLastError() function.
Note
CLExecutionStatus
R eturns the OpenCL program execution status.
int CLExecutionStatus(
int kernel // handle to a kernel of an OpenCL program
);
Parameters
kernel
[in] H andle to a k ernel of the OpenCL program.
Return Value
R eturns the OpenCL program status. The value can be one of the following :
· CL _COMPL ET E=0 – program complete,
· CL _RUNNI NG=1 – running,
· CL _S UBMITT ED=2 – submitted for execution,
· CL _QUEUED=3 – queued,
· -1 (minus one) – error occurred when executing CL ExecutionStatus().
In addition to all the above advantages, the MetaTrader 5 platform provides MQL5 developers with the
ability to integrate with other popular solutions for processing financial data. This allows specialists in
statistics and machine learning to receive data directly from MetaTrader 5 without developing
additional programs and adapters.
· MetaTrader for Python – module for work ing with Python programs.
The presented functions allow connecting directly to the MetaTrader 5 terminal and requesting a price
history in the required amount and form for any financial instruments available in the platform.
MetaTrader pack age for Python is designed for convenient and fast obtaining of exchange data via
interprocessor communication directly from the MetaTrader 5 terminal. The data received this way can
be further used for statistical calculations and machine learning.
Function Action
MT5CopyR ates R ange Get bars in the specified date range from the
MetaTrader 5 terminal
MT5CopyTick s R ange Get tick s for the specified date range from the
MetaTrader 5 terminal
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 establishes connection to the trade server and synchronizes the environ
MT5WaitForTerminal()
#DATA
print('euraud_ticks(', len(euraud_ticks), ')')
for val in euraud_ticks[:10]: print(val)
print('audusd_ticks(', len(audusd_ticks), ')')
for val in audusd_ticks[:10]: print(val)
print('eurusd_rates(', len(eurusd_rates), ')')
for val in eurusd_rates[:10]: print(val)
print('eurrub_rates(', len(eurrub_rates), ')')
for val in eurrub_rates[:10]: print(val)
print('eurjpy_rates(', len(eurjpy_rates), ')')
for val in eurjpy_rates[:10]: print(val)
#PLOTTING
x_time = [x.time.astimezone(utc_tz) for x in euraud_ticks]
# prepare Bid and Ask arrays
bid = [y.bid for y in euraud_ticks]
ask = [y.ask for y in euraud_ticks]
euraud_ticks( 1000 )
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 3, 512000), bid=1.5764200000000002, ask=1.57837, l
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 8, 70000), bid=1.57643, ask=1.57837, last=0.0, vol
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 26, 142000), bid=1.57649, ask=1.57837, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 26, 260000), bid=1.5765500000000001, ask=1.57837,
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 26, 365000), bid=1.5765500000000001, ask=1.5785900
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 26, 410000), bid=1.5765500000000001, ask=1.57837,
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 26, 636000), bid=1.57663, ask=1.57837, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 30, 72000), bid=1.57659, ask=1.57837, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 34, 320000), bid=1.57656, ask=1.57837, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 35, 61000), bid=1.57653, ask=1.57837, last=0.0, vo
audusd_ticks( 61336 )
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 1, 410000), bid=0.71262, ask=0.7128, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 2, 380000), bid=0.71263, ask=0.71282, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 2, 753000), bid=0.71262, ask=0.71282, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 2, 842000), bid=0.71262, ask=0.71281, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 3, 428000), bid=0.71261, ask=0.71279, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 3, 771000), bid=0.71261, ask=0.7128, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 3, 936000), bid=0.71261, ask=0.71279, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 4, 2000), bid=0.7126, ask=0.71279, last=0.0, volu
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 4, 108000), bid=0.71258, ask=0.71276, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 13, 0, 4, 186000), bid=0.71257, ask=0.71275, last=0.0, v
eurusd_rates( 1000 )
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 20), open=1.12162, low=1.12171, high=1.12152, close=
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 21), open=1.12153, low=1.1217, high=1.12153, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 22), open=1.1217, low=1.12179, high=1.1217, close=1.
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 23), open=1.12178, low=1.12189, high=1.12178, close=
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 24), open=1.12188, low=1.12188, high=1.12181, close=
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 25), open=1.12183, low=1.12187, high=1.12173, close=
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 26), open=1.12174, low=1.12179, high=1.12173, close=
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 27), open=1.12178, low=1.12179, high=1.12171, close=
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 28), open=1.12171, low=1.12171, high=1.12166, close=
MT5Rate(time=datetime.datetime(2019, 4, 4, 22, 29), open=1.12169, low=1.12169, high=1.1215600000000
eurrub_rates( 1000 )
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 49), open=73.369, low=73.371, high=73.346, close=73.
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 50), open=73.353, low=73.367, high=73.352, close=73.
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 51), open=73.367, low=73.367, high=73.347, close=73.
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 52), open=73.356, low=73.358, high=73.341, close=73.
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 53), open=73.347, low=73.35, high=73.334, close=73.3
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 54), open=73.333, low=73.337, high=73.316, close=73.
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 55), open=73.32, low=73.33, high=73.32, close=73.328
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 56), open=73.328, low=73.334, high=73.322, close=73.
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 57), open=73.326, low=73.327, high=73.319, close=73.
MT5Rate(time=datetime.datetime(2019, 4, 3, 18, 58), open=73.32, low=73.331, high=73.319, close=73.3
eurjpy_rates( 1441 )
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 0), open=124.763, low=124.785, high=124.737, close=1
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 1), open=124.748, low=124.754, high=124.735, close=1
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 2), open=124.752, low=124.768, high=124.735, close=1
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 3), open=124.752, low=124.756, high=124.736, close=1
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 4), open=124.738, low=124.76, high=124.734, close=12
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 5), open=124.756, low=124.773, high=124.752, close=1
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 6), open=124.773, low=124.802, high=124.771, close=1
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 7), open=124.777, low=124.781, high=124.758, close=1
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 8), open=124.776, low=124.79, high=124.768, close=12
MT5Rate(time=datetime.datetime(2019, 4, 1, 13, 9), open=124.777, low=124.803, high=124.774, close=1
MT5Initialize
Establish a connection with the MetaTrader 5 terminal.
MT5Initialize(
path=None // path to the MetaTrader 5 terminal EXE file
)
Parameters
path=None
[in] Path to the metatrader.exe or metatrader64.exe file. If the path is not specified, the module
attempts to find the executable file on its own.
Return Value
R eturns True in case of successful connection to the MetaTrader 5 terminal, otherwise - False.
Note
If required, the MetaTrader 5 terminal is launched to establish connection when executing the
MT5Initialize() call.
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to the trade server
MT5WaitForTerminal()
# display data on connection status, server name and trading account
print(MT5TerminalInfo())
# display data on MetaTrader 5 version
print(MT5Version())
# shut down connection to the MetaTrader 5 terminal
MT5Shutdown()
See also
MT5Shutdown, MT5W aitForTerminal, MT5TerminalInfo, MT5Version
MT5Shutdown
Close the previously established connection to the MetaTrader 5 terminal.
MT5Shutdown()
Return Value
None.
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to the trade server
MT5WaitForTerminal()
# display data on connection status, server name and trading account
print(MT5TerminalInfo())
# display data on MetaTrader 5 version
print(MT5Version())
# shut down connection to the MetaTrader 5 terminal
MT5Shutdown()
See also
MT5Initialize, MT5W aitForTerminal, MT5TerminalInfo, MT5Version
MT5TerminalInfo
Get status and parameters of the connected MetaTrader 5 terminal.
MT5TerminalInfo()
Return Value
R eturns connection status, trade server name and trading account number.
Note
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to the trade server
MT5WaitForTerminal()
# display data on connection status, server name and trading account
print(MT5TerminalInfo())
# display data on MetaTrader 5 version
print(MT5Version())
# shut down connection to the MetaTrader 5 terminal
MT5Shutdown()
Result:
>>> from datetime import datetime
>>> from MetaTrader5 import *
>>> MT5Initialize()
True
>>> MT5WaitForTerminal()
True
>>> print(MT5TerminalInfo())
[2, 'MetaQuotes-Demo', '16167573']
>>> print(MT5Version())
[500, 2009, '15 Mar 2019']
>>> MT5Shutdown()
True
See also
MT5Initialize, MT5W aitForTerminal, MT5Shutdown, MT5Version
MT5Version
R eturn the MetaTrader 5 terminal version.
MT5Version()
Return Value
Note
The MT5Version() function returns connection status, trade server address and trading account
number as a tuple.
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to the trade server
MT5WaitForTerminal()
# display data on connection status, server name and trading account
print(MT5TerminalInfo())
# display data on MetaTrader 5 version
print(MT5Version())
# shut down connection to the MetaTrader 5 terminal
MT5Shutdown()
Result:
>>> from datetime import datetime
>>> from MetaTrader5 import *
>>> MT5Initialize()
True
>>> MT5WaitForTerminal()
True
>>> print(MT5TerminalInfo())
[2, 'MetaQuotes-Demo', '16167573']
>>> print(MT5Version())
[500, 2009, '15 Mar 2019']
>>> MT5Shutdown()
True
See also
MT5WaitForTerminal
W ait till the MetaTrader 5 terminal connects to the trade server.
MT5WaitForTerminal()
Return Value
R eturns True if the MetaTrader 5 terminal successfully connects to the trading server, otherwise -
False.
Note
The MT5Version() function returns connection status, trade server address and trading account
number as a tuple.
The waiting time is 1 minute. MT5TerminalInfo() should be called to check the connection status
after MT5W aitForTerminal().
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to the trade server
MT5WaitForTerminal()
# display data on connection status, server name and trading account
print(MT5TerminalInfo())
# display data on MetaTrader 5 version
print(MT5Version())
# shut down connection to the MetaTrader 5 terminal
MT5Shutdown()
See also
MT5Initialize, MT5TerminalInfo, MT5Version, MT5Shutdown
MT5CopyRatesFrom
Get bars from the MetaTrader 5 terminal starting from the specified date.
MT5CopyRatesFrom(
symbol, // symbol name
timeframe, // timeframe
from, // initial bar open date
count // number of bars
)
Parameters
symbol
[in] Financial instrument name, for example, "EURUS D" .
timeframe
[in] Timeframe the bars are requested for. Set by a value from the MT5_TIM EFRAM E
enumeration.
from
[in] Date of opening of the first bar from the requested sample. Set by the 'datetime' object or as
a number of seconds elapsed since 1970.01.01.
count
[in] Number of bars to receive.
Return Value
R eturns bars as tuples (time, open, high, low, close, tick_volume, spread, real_volume).
Note
W hen creating the 'datetime' object, Python uses the local time zone, while MetaTrader 5 stores tick
and bar open time in UTC time zone (without the shift). Therefore, 'datetime' should be created in
UTC time for executing functions that use time. The data obtained from MetaTrader 5 have UTC
time, but Python applies the local time shift again when trying to print them. Thus, the obtained
data should also be corrected for visual presentation.
ID Description
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to the trade server
MT5WaitForTerminal()
# apply the offset for the 'time' column in the rates_frame dataframe
rates_frame['time'] = rates_frame.apply(lambda rate: local_to_utc(rate['time']), axis=1)
# display the data once again and make sure the H4 candles open time is now multiple of 4
print("\nDisplay the dataframe after adjusting the time")
print(rates_frame)
Result:
Display obtained data 'as is'
MT5Rate(time=datetime.datetime(2019, 4, 3, 15, 0), open=1.12431, low=1.12543, high=1.12335, close=1
MT5Rate(time=datetime.datetime(2019, 4, 3, 19, 0), open=1.12339, low=1.12487, high=1.12247, close=1
MT5Rate(time=datetime.datetime(2019, 4, 3, 23, 0), open=1.12439, low=1.12478, high=1.12311, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 3, 0), open=1.12324, low=1.12472, high=1.12318, close=1.
MT5Rate(time=datetime.datetime(2019, 4, 4, 7, 0), open=1.1244, low=1.12451, high=1.12364, close=1.1
MT5Rate(time=datetime.datetime(2019, 4, 4, 11, 0), open=1.12406, low=1.12472, high=1.12302, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 15, 0), open=1.12313, low=1.12359, high=1.12122, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 19, 0), open=1.12171, low=1.12246, high=1.12056, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 23, 0), open=1.12187, low=1.12265, high=1.1213, close=1.
MT5Rate(time=datetime.datetime(2019, 4, 5, 3, 0), open=1.12199, low=1.12286, high=1.1217, close=1.1
See also
CopyR ates, MT5CopyR ates FromPos, MT5CopyR ates R ange, MT5CopyTick s From, MT5CopyTick s R ange
MT5CopyRatesFromPos
Get bars from the MetaTrader 5 terminal starting from the specified index.
MT5CopyRatesFromPos(
symbol, // symbol name
timeframe, // timeframe
start_pos, // initial bar index
count // number of bars
)
Parameters
symbol
[in] Financial instrument name, for example, "EURUS D" .
timeframe
[in] Timeframe the bars are requested for. Set by a value from the MT5_TIM EFRAM E
enumeration.
start_pos
[in] Initial index of the bar the data are requested from. The numbering of bars goes from
present to past. Thus, the zero bar means the current one.
count
[in] Number of bars to receive.
Return Value
R eturns bars as tuples (time, open, high, low, close, tick_volume, spread, real_volume).
Note
Example:
# import the pandas module for displaying data obtained in the tabular form
import pandas as pd
pd.set_option('display.max_columns', 500) # number of columns to be displayed
pd.set_option('display.width', 1500) # max table width to display
# apply the offset for the 'time' column in the rates_frame dataframe
rates_frame['time'] = rates_frame.apply(lambda rate: local_to_utc(rate['time']), axis=1)
# display the data once again and make sure the D1 candles open time is 00:00
print("\nDisplay the dataframe after adjusting the candle open time ")
print(rates_frame)
Result:
Display obtained data 'as is'
MT5Rate(time=datetime.datetime(2019, 4, 3, 15, 0), open=1.12431, low=1.12543, high=1.12335, close=1
MT5Rate(time=datetime.datetime(2019, 4, 3, 19, 0), open=1.12339, low=1.12487, high=1.12247, close=1
MT5Rate(time=datetime.datetime(2019, 4, 3, 23, 0), open=1.12439, low=1.12478, high=1.12311, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 3, 0), open=1.12324, low=1.12472, high=1.12318, close=1.
MT5Rate(time=datetime.datetime(2019, 4, 4, 7, 0), open=1.1244, low=1.12451, high=1.12364, close=1.1
MT5Rate(time=datetime.datetime(2019, 4, 4, 11, 0), open=1.12406, low=1.12472, high=1.12302, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 15, 0), open=1.12313, low=1.12359, high=1.12122, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 19, 0), open=1.12171, low=1.12246, high=1.12056, close=1
MT5Rate(time=datetime.datetime(2019, 4, 4, 23, 0), open=1.12187, low=1.12265, high=1.1213, close=1.
MT5Rate(time=datetime.datetime(2019, 4, 5, 3, 0), open=1.12199, low=1.12286, high=1.1217, close=1.1
See also
CopyR ates, MT5CopyR ates From, MT5CopyR ates R ange, MT5CopyTick s From, MT5CopyTick s R ange
MT5CopyRatesRange
Get bars in the specified date range from the MetaTrader 5 terminal.
MT5CopyRatesRange(
symbol, // symbol name
timeframe, // timeframe
date_from, // date the bars are requested from
date_to // date, up to which the bars are requested
)
Parameters
symbol
[in] Financial instrument name, for example, "EURUS D" .
timeframe
[in] Timeframe the bars are requested for. Set by a value from the MT5_TIM EFRAM E
enumeration.
date_from
[in] Date the bars are requested from. Set by the 'datetime' object or as a number of seconds
elapsed since 1970.01.01. Bars with the open time >= date_from are returned.
date_to
[in] Date, up to which the bars are requested. Set by the 'datetime' object or as a number of
seconds elapsed since 1970.01.01. Bars with the open time <= date_to are returned.
Return Value
R eturns bars as tuples (time, open, high, low, close, tick_volume, spread, real_volume).
Note
W hen creating the 'datetime' object, Python uses the local time zone, while MetaTrader 5 stores tick
and bar open time in UTC time zone (without the shift). Therefore, 'datetime' should be created in
UTC time for executing functions that use time. The data obtained from MetaTrader 5 have UTC
time, but Python applies the local time shift again when trying to print them. Thus, the obtained
data should also be corrected for visual presentation.
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to trade server
MT5WaitForTerminal()
# apply the offset for the 'time' column in the rates_frame dataframe
rates_frame['time'] = rates_frame.apply(lambda rate: local_to_utc(rate['time']), axis=1)
# display the data once again and make sure the open time has changed
print("\nDisplay dataframe after correcting time")
print(rates_frame)
Result:
Display obtained data 'as is'
MT5Rate(time=datetime.datetime(2019, 4, 1, 3, 30), open=4.2988, low=4.2993, high=4.2986, close=4.29
MT5Rate(time=datetime.datetime(2019, 4, 1, 3, 35), open=4.2989, low=4.2989, high=4.2989, close=4.29
MT5Rate(time=datetime.datetime(2019, 4, 1, 3, 40), open=4.2989, low=4.2991, high=4.2987, close=4.29
MT5Rate(time=datetime.datetime(2019, 4, 1, 3, 45), open=4.2989, low=4.2989, high=4.2989, close=4.29
MT5Rate(time=datetime.datetime(2019, 4, 1, 3, 50), open=4.2989, low=4.2989, high=4.2989, close=4.29
MT5Rate(time=datetime.datetime(2019, 4, 1, 3, 55), open=4.2989, low=4.2989, high=4.2989, close=4.29
MT5Rate(time=datetime.datetime(2019, 4, 1, 4, 0), open=4.2989, low=4.2995, high=4.29872, close=4.29
MT5Rate(time=datetime.datetime(2019, 4, 1, 4, 5), open=4.2995, low=4.2998, high=4.299, close=4.2998
MT5Rate(time=datetime.datetime(2019, 4, 1, 4, 10), open=4.2998, low=4.2998, high=4.2991, close=4.29
MT5Rate(time=datetime.datetime(2019, 4, 1, 4, 15), open=4.2992, low=4.2995, high=4.2989, close=4.29
Display the first 10 values from the dataframe after adjusting the time
time open low high close tick_volume spread real_volume
0 2019-04-01 00:30:00 4.2988 4.2993 4.29860 4.2989 853 540 0
1 2019-04-01 00:35:00 4.2989 4.2989 4.29890 4.2989 1 630 0
2 2019-04-01 00:40:00 4.2989 4.2991 4.29870 4.2989 10 560 0
3 2019-04-01 00:45:00 4.2989 4.2989 4.29890 4.2989 2 600 0
4 2019-04-01 00:50:00 4.2989 4.2989 4.29890 4.2989 4 640 0
5 2019-04-01 00:55:00 4.2989 4.2989 4.29890 4.2989 4 640 0
6 2019-04-01 01:00:00 4.2989 4.2995 4.29872 4.2994 40 500 0
7 2019-04-01 01:05:00 4.2995 4.2998 4.29900 4.2998 38 440 0
8 2019-04-01 01:10:00 4.2998 4.2998 4.29910 4.2992 35 440 0
9 2019-04-01 01:15:00 4.2992 4.2995 4.29890 4.2993 379 500 0
See also
CopyR ates, MT5CopyR ates From, MT5CopyR ates R ange, MT5CopyTick s From, MT5CopyTick s R ange
MT5CopyTicksFrom
Get tick s from the MetaTrader 5 terminal starting from the specified date.
MT5CopyTicksFrom(
symbol, // symbol name
from, // date the ticks are requested from
count, // number of requested ticks
flags // combination of flags defining the type of requested ticks
)
Parameters
symbol
[in] Financial instrument name, for example, "EURUS D" .
from
[in] Date the tick s are requested from. Set by the 'datetime' object or as a number of seconds
elapsed since 1970.01.01.
count
[in] Number of tick s to receive.
flags
[in] A flag to define the type of the requested tick s. MT5_COPY_TICKS _INFO – tick s with Bid
and/or As k changes, MT5_COPY_TICKS _T RADE – tick s with changes in Last and Volume,
MT5_COPY_TICKS _ALL – all tick s. Flag values are described in the MT5_COPY_TICKS enumeration.
Return Value
R eturns tick s in the form of tuples (time, bid, as k , last, flags). In the tuple, the flags variable can
be a combination of flags from the MT5_TICK_FL AG enumeration.
Note
W hen creating the 'datetime' object, Python uses the local time zone, while MetaTrader 5 stores tick
and bar open time in UTC time zone (without the shift). Therefore, 'datetime' should be created in
UTC time for executing functions that use time. The data obtained from MetaTrader 5 have UTC
time, but Python applies the local time shift again when trying to print them. Thus, the obtained
data should also be corrected for visual presentation.
MT5_COPY _TICKS defines the types of tick s that can be requested using the MT5CopyTick s From()
and MT5CopyTick s R ange() functions.
ID Description
MT5_TICK_FLAG defines possible flags for tick s. These flags are used to describe tick s obtained by
the MT5CopyTick s From() and MT5CopyTick s R ange() functions.
ID Description
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to the trade server
MT5WaitForTerminal()
# apply the offset for the 'time' column in the ticks_frame dataframe
ticks_frame['time'] = ticks_frame.apply(lambda tick: local_to_utc(tick['time']), axis=1)
# display the data once again and make sure the tick time changed
print("\nDisplay the dataframe with ticks after adjusting the time")
print(ticks_frame.head(10))
Result:
Ticks received: 100 000
Display obtained ticks 'as is'
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 5, 745000), bid=1.12258, ask=1.12339, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 26, 155000), bid=1.12260, ask=1.12339, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 26, 497000), bid=1.12272, ask=1.12339, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 34, 327000), bid=1.12268, ask=1.12336, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 35, 61000), bid=1.12268, ask=1.12339, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 35, 369000), bid=1.12258, ask=1.12339, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 40, 577000), bid=1.12258, ask=1.12336, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 46, 494000), bid=1.1225, ask=1.12336, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 47, 288000), bid=1.12248, ask=1.12336, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 56, 114000), bid=1.1225, ask=1.12336, last=0.0, vo
See also
CopyR ates, MT5CopyR ates FromPos, MT5CopyR ates R ange, MT5CopyTick s From, MT5CopyTick s R ange
MT5CopyTicksRange
Get tick s for the specified date range from the MetaTrader 5 terminal.
MT5CopyTicksRange(
symbol, // symbol name
from, // date the ticks are requested from
to, // date, up to which the ticks are requested
flags // combination of flags defining the type of requested ticks
)
Parameters
symbol
[in] Financial instrument name, for example, "EURUS D" .
from
[in] Date the tick s are requested from. Set by the 'datetime' object or as a number of seconds
elapsed since 1970.01.01.
to
[in] Date, up to which the tick s are requested. Set by the 'datetime' object or as a number of
seconds elapsed since 1970.01.01.
flags
[in] A flag to define the type of the requested tick s. MT5_COPY_TICKS _INFO – tick s with Bid
and/or As k changes, MT5_COPY_TICKS _T RADE – tick s with changes in Last and Volume,
MT5_COPY_TICKS _ALL – all tick s. Flag values are described in the MT5_COPY_TICKS enumeration.
Return Value
R eturns tick s in the form of tuples (time, bid, as k , last, flags). In the tuple, the flags variable can
be a combination of flags from the MT5_TICK_FL AG enumeration.
Note
W hen creating the 'datetime' object, Python uses the local time zone, while MetaTrader 5 stores tick
and bar open time in UTC time zone (without the shift). Therefore, 'datetime' should be created in
UTC time for executing functions that use time. The data obtained from MetaTrader 5 have UTC
time, but Python applies the local time shift again when trying to print them. Thus, the obtained
data should also be corrected for visual presentation.
Example:
# connect to MetaTrader 5
MT5Initialize()
# wait till MetaTrader 5 connects to the trade server
MT5WaitForTerminal()
# apply the offset for the 'time' column in the ticks_frame dataframe
ticks_frame['time'] = ticks_frame.apply(lambda tick: local_to_utc(tick['time']), axis=1)
# display the data once again and make sure the tick time changed
print("\nDisplay the dataframe with ticks after adjusting the time")
print(ticks_frame.head(10))
Result:
Ticks received: 243374
Display obtained ticks 'as is'
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 2, 759000), bid=0.71155, ask=0.71223, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 7, 824000), bid=0.71154, ask=0.71222, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 27, 818000), bid=0.71155, ask=0.71223, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 43, 794000), bid=0.71159, ask=0.71204, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 44, 67000), bid=0.71145, ask=0.71209, last=0.0, vo
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 44, 140000), bid=0.71157, ask=0.71223, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 44, 432000), bid=0.71157, ask=0.71225, last=0.0, v
MT5Tick(time=datetime.datetime(2019, 4, 1, 3, 2, 44, 872000), bid=0.71159, ask=0.71204, last=0.0, v
See also
CopyR ates, MT5CopyR ates FromPos, MT5CopyR ates R ange, MT5CopyTick s From, MT5CopyTick s R ange
Standard Library
This group of chapters contains the technical details of the MQL5 Standard Library and descriptions of
all its k ey components.
MQL5 Standard Library is written in MQL5 and is designed to facilitate writing programs (indicators,
scripts, experts) for end users. Library provides convenient access to the most of the internal MQL5
functions.
MQL5 Standard Library is placed in the work ing directory of the terminal in the 'Include' folder.
Section Location
Files Include\Files \
· Statistics – functions for work ing with various distributions of the Probability theory
· Fuzzy logic – library that implements Mamdani and Sugeno fuzzy inference systems
· AL GLI B – data analysis (clustering, decision trees, linear regression, neural network s), solving
differential equations, Fourier transform, numerical integration, optimization problems, statistical
analysis, and more.
Statistics
The Statistical Library provides a convenient way of work ing with the basic statistical distributions.
In addition to calculation of values for the individual random variables, the library also provides
overloads for the functions, which perform the same calculations for arrays.
· Statistical Characteristics
· Normal Distribution
· Log-normal distribution
· Beta distribution
· Gamma distribution
· Exponential distribution
· F-distribution
· Noncentral F-distribution
· t-distribution
· Noncentral t-distribution
· Logistic distribution
· Cauchy distribution
· Uniform distribution
· W eibull distribution
· Binomial distribution
· Geometric distribution
· H ypergeometric distribution
· Poisson distribution
· Subfunctions
Example:
//+------------------------------------------------------------------+
//| NormalDistributionExample.mq5 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//--- include the functions for calculating the normal distribution
#include <Math\Stat\Normal.mqh>
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- set the parameters of the normal distribution
double mu=5.0;
double sigma=1.0;
PrintFormat("Normal distribution with parameters mu=%G and sigma=%G, calculation examples:",mu,s
//--- set the interval
double x1=mu-sigma;
double x2=mu+sigma;
//--- variables for probability calculation
double cdf1,cdf2,probability;
//--- variables for error codes
int error_code1,error_code2;
//--- calculate the values of distribution functions
cdf1=MathCumulativeDistributionNormal(x1,mu,sigma,error_code1);
cdf2=MathCumulativeDistributionNormal(x2,mu,sigma,error_code2);
//--- check the error codes
if(error_code1==ERR_OK && error_code2==ERR_OK)
{
//--- calculate probability of a random variable in the range
probability=cdf2-cdf1;
//--- output the result
PrintFormat("1. Calculate probability of a random variable within the range of %.5f<x<%.5f",x
PrintFormat(" Answer: Probability = %5.8f",probability);
}
//--- Find the value range of random variable x, corresponding to the 95% confidence level
probability=0.95; // set the confidence probability
//--- set the probabilities at the interval bounds
double p1=(1.0-probability)*0.5;
double p2=probability+(1.0-probability)*0.5;
//--- calculate the interval bounds
x1=MathQuantileNormal(p1,mu,sigma,error_code1);
x2=MathQuantileNormal(p2,mu,sigma,error_code2);
//--- check the error codes
if(error_code1==ERR_OK && error_code2==ERR_OK)
{
//--- output the result
PrintFormat("2. For confidence interval = %.2f, find the range of random variable",probabilit
PrintFormat(" Answer: range is %5.8f <= x <=%5.8f",x1,x2);
}
PrintFormat("3. Compute the first 4 calculated and theoretical moments of the distribution");
//--- Generate an array of random numbers, calculate the first 4 moments and compare with the theor
int data_count=1000000; // set the number of values and prepare an array
double data[];
ArrayResize(data,data_count);
//--- generate random values and store them into the array
Statistical Characteristics
This group of functions calculates the Statistical Characteristics of the array elements :
· mean,
· variance,
· s k ewness,
· k urtosis,
· median,
· root-mean-s quare and
· standard deviation.
Function Description
MathMean
Calculates the mean (first moment) of array elements. Analog of the mean() in R .
double MathMean(
const double& array[] // array with data
);
Parameters
array
[in] Array with data for calculation of the mean.
start=0
[in] Initial index for calculation.
count=WHOLE_ARRAY
[in] The number of elements for calculation.
Return Value
The mean of array elements. In case of error it returns NaN (not a number).
MathVariance
Calculates the variance (second moment) of array elements. Analog of the var() in R .
double MathVariance(
const double& array[] // array with data
);
Parameters
array
[in] Array with data for calculation.
start=0
[in] Initial index for calculation.
count=WHOLE_ARRAY
[in] The number of elements for calculation.
Return Value
MathSkewness
Calculates the s k ewness (third moment) of array elements. Analog of the s k ewness() in R (e1071
library).
double MathSkewness(
const double& array[] // array with data
);
Parameters
array
[in] Array with data for calculation.
start=0
[in] Initial index for calculation.
count=WHOLE_ARRAY
[in] The number of elements for calculation.
Return Value
MathKurtosis
Calculates the k urtosis (fourth moment) of array elements. Analog of the k urtosis() in R (e1071
library).
double MathKurtosis(
const double& array[] // array with data
);
Parameters
array
[in] Array with data for calculation.
start=0
[in] Initial index for calculation.
count=WHOLE_ARRAY
[in] The number of elements for calculation.
Return Value
Disclaimer
Calculation of the k urtosis is performed using the excess k urtosis around the normal distribution
(excess k urtosis =k urtosis-3), i.e. the excess k urtosis of a normal distribution is zero.
It is positive if the peak of the distribution around the expected value is sharp, and negative if the
peak is flat.
MathMoments
Calculates the first 4 moments (mean, variance, s k ewness, k urtosis) of array elements.
double MathMoments(
const double& array[], // array with data
double& mean, // mean (1st moment)
double& variance, // variance (2nd moment)
double& skewness, // skewness (3rd moment)
double& kurtosis, // kurtosis (4th moment)
const int start=0, // initial index
const int count=WHOLE_ARRAY // the number of elements
);
Parameters
array
[in] Array with data for calculation.
mean
[out] Variable for the mean (1st moment)
variance
[out] Variable for the variance (2nd moment)
skewness
[out] Variable for the s k ewness (3rd moment)
kurtosis
[out] Variable for the k urtosis (4th moment)
start=0
[in] Initial index for calculation.
count=WHOLE_ARRAY
[in] The number of elements for calculation.
Return Value
R eturns true if the moments have been calculated successfully, otherwise false.
Disclaimer
Calculation of the k urtosis is performed using the excess k urtosis around the normal distribution
(excess k urtosis =k urtosis-3), i.e. the excess k urtosis of a normal distribution is zero.
It is positive if the peak of the distribution around the expected value is sharp, and negative if the
peak is flat.
MathMedian
Calculates the median value of array elements. Analog of the median() in R .
double MathMedian(
const double& array[] // array with data
);
Parameters
array
[in] Array with data for calculation.
start=0
[in] Initial index for calculation.
count=WHOLE_ARRAY
[in] The number of elements for calculation.
Return Value
The median value of array elements. In case of error it returns NaN (not a number).
MathStandardDeviation
Calculates the standard deviation of array elements. Analog of the sd() in R .
double MathStandardDeviation(
const double& array[] // array with data
);
Parameters
array
[in] Array with data for calculation.
start=0
[in] Initial index for calculation.
count=WHOLE_ARRAY
[in] The number of elements for calculation.
Return Value
The standard deviation of array elements. In case of error it returns NaN (not a number).
MathAverageDeviation
Calculates the average absolute deviation of array elements. Analog of the aad() in R .
double MathAverageDeviation(
const double& array[] // array with data
);
Parameters
array
[in] Array with data for calculation.
start=0
[in] Initial index for calculation.
count=WHOLE_ARRAY
[in] The number of elements for calculation.
Return Value
The average absolute deviation of array elements. In case of error it returns NaN (not a number).
Normal Distribution
This section contains functions for work ing with normal distribution. They allow to calculate density,
probability, quantiles and to generate pseudo-random numbers distributed according to the normal
law. The distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Normal.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double mean_value=0; // expected value (mean)
input double std_dev=1; // root-mean-square deviation (standard deviation)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the normal distribution
MathRandomNormal(mean_value,std_dev,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityNormal(x2,mean_value,std_dev,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Normal distribution mu=%G sigma=%G",mean_value,std_dev));
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
//--- plot all curves
graphic.CurvePlotAll();
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
MathProbabilityDensityNormal
Calculates the value of the probability density function of normal distribution with the mu and sigma
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNormal(
const double x, // value of random variable
const double mu, // mean parameter of the distribution (expected value)
const double sigma, // sigma parameter of the distribution (root-mean-square deviation
const bool log_mode, // calculate the logarithm of the value
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of normal distribution with the mu and sigma
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNormal(
const double x, // value of random variable
const double mu, // mean parameter of the distribution (expected value)
const double sigma, // sigma parameter of the distribution (root-mean-square deviation
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of normal distribution with the mu and sigma
parameters for an array of random variables x []. In case of error it returns false. Analog of the
dnorm() in R .
bool MathProbabilityDensityNormal(
const double& x[], // array with the values of random variable
const double mu, // mean parameter of the distribution (expected value)
const double sigma, // sigma parameter of the distribution (root-mean-square deviatio
const bool log_mode, // calculate the logarithm of the value
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of normal distribution with the mu and sigma
parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityNormal(
const double& x[], // array with the values of random variable
const double mu, // mean parameter of the distribution (expected value)
const double sigma, // sigma parameter of the distribution (root-mean-square deviatio
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
mu
[in] mean parameter of the distribution (expected value).
sigma
[in] sigma parameter of the distribution (root-mean-s quare deviation).
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to get the error code.
result[]
[out] Array to obtain the values of the probability density function.
MathCumulativeDistributionNormal
Calculates the value of the normal distribution function with the mu and sigma parameters for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNormal(
const double x, // value of random variable
const double mu, // expected value
const double sigma, // root-mean-square deviation
const bool tail, // flag for calculation of tail
const bool log_mode, // calculate the logarithm of the value
int& error_code // variable to store the error code
);
Calculates the value of the normal distribution function with the mu and sigma parameters for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNormal(
const double x, // value of random variable
const double mu, // expected value
const double sigma, // root-mean-square deviation
int& error_code // variable to store the error code
);
Calculates the value of the normal distribution function with the mu and sigma parameters for an array
of random variables x []. In case of error it returns false. Analog of the dnorm() in R .
bool MathCumulativeDistributionNormal(
const double& x[], // array with the values of random variable
const double mu, // expected value
const double sigma, // root-mean-square deviation
const bool tail, // flag for calculation of tail
const bool log_mode, // calculate the logarithm of the value
double& result[] // array for values of the probability function
);
Calculates the value of the normal distribution function with the mu and sigma parameters for an array
of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionNormal(
const double& x[], // array with the values of random variable
const double mu, // expected value
const double sigma, // root-mean-square deviation
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
mu
[in] mean parameter of the distribution (expected value).
sigma
[in] sigma parameter of the distribution (root-mean-s quare deviation).
tail
[in] Flag of calculation. If tail=true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to get the error code.
result[]
[out] Array to obtain the values of the probability function.
MathQuantileNormal
For the specifiedprobability, the function calculates the value of inverse normal distribution function
double MathQuantileNormal(
const double probability, // probability value of random variable
const double mu, // expected value
const double sigma, // root-mean-square deviation
const bool tail, // flag for calculation of tail
const bool log_mode, // calculate the logarithm of the value
int& error_code // variable to store the error code
);
For the specifiedprobability, the function calculates the value of inverse normal distribution function
double MathQuantileNormal(
const double probability, // probability value of random variable
const double mu, // expected value
const double sigma, // root-mean-square deviation
int& error_code // variable to store the error code
);
For the specified array of probability values, the function calculates the values of inverse
probability[]
normal distribution function with the mu and sigma parameters. In case of error it returns false.
Analog of the qnorm() in R .
bool MathQuantileNormal(
const double& probability[], // array with probability values of random variable
const double mu, // expected value
const double sigma, // root-mean-square deviation
const bool tail, // flag for calculation of tail
const bool log_mode, // calculate the logarithm of the value
double& result[] // array with values of quantiles
);
For the specified array of probability values, the function calculates the values of inverse
probability[]
normal distribution function with the mu and sigma parameters. In case of error it returns false.
bool MathQuantileNormal(
const double& probability[], // array with probability values of random variable
const double mu, // expected value
const double sigma, // root-mean-square deviation
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
mu
[in] mean parameter of the distribution (expected value).
sigma
[in] sigma parameter of the distribution (root-mean-s quare deviation).
tail
[in] Flag of calculation. If false, then calculation is performed for 1.0 - probability.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to get the error code.
result[]
[out] Array to obtain the quantiles.
MathRandomNormal
Generates a pseudorandom variable distributed according to the normal law with the mu and sigma
parameters. In case of error it returns NaN.
double MathRandomNormal(
const double mu, // expected value
const double sigma, // root-mean-square deviation
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the normal law with the mu and sigma
parameters. In case of error it returns false. Analog of the rnorm() in R .
bool MathRandomNormal(
const double mu, // expected value
const double sigma, // root-mean-square deviation
const int data_count, // amount of required data
double& result[] // array to obtain the pseudorandom variables
);
Parameters
mu
[in] mean parameter of the distribution (expected value).
sigma
[in] sigma parameter of the distribution (root-mean-s quare deviation).
data_count
[in] The number of pseudorandom variables to be obtained.
error_code
[out] Variable to get the error code.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsNormal
Calculates the theoretical numerical values of the first 4 moments of the normal distribution.
double MathMomentsNormal(
const double mu, // expected value
const double sigma, // root-mean-square deviation
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable to store the error code
);
Parameters
mu
[in] mean parameter of the distribution (expected value).
sigma
[in] sigma parameter of the distribution (root-mean-s quare deviation).
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if the moments have been calculated successfully, otherwise false.
Log-normal distribution
This section contains functions for work ing with log-normal distribution. They allow to calculate
density, probability, quantiles and to generate pseudo-random numbers distributed according to the
log-normal law. The log-normal distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Lognormal.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double mean_value=1.0; // logarithm of the expected value (log mean)
input double std_dev=0.25; // logarithm of the root-mean-square deviation (log standard deviatio
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the log-normal distribution
MathRandomLognormal(mean_value,std_dev,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityLognormal(x2,mean_value,std_dev,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityLognormal
Calculates the value of the probability density function of log-normal distribution with the mu and
sigma parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityLognormal(
const double x, // value of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then th
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of log-normal distribution with the mu and
sigma parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityLognormal(
const double x, // value of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of log-normal distribution with the mu and
sigma parameters for an array of random variables x []. In case of error it returns NaN. Analog of
the dlnorm() in R .
bool MathProbabilityDensityLognormal(
const double& x[], // array with the values of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devi
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then t
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of log-normal distribution with the mu and
sigma parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityLognormal(
const double& x[], // array with the values of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devi
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
mu
[in] Logarithm of the expected value (log _mean).
sigma
[in] Logarithm of the root-mean-s quare deviation (log standard deviation).
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array to obtain the values of the probability density function.
MathCumulativeDistributionLognormal
Calculates the log-normal distribution function of probabilities with the mu and sigma parameters for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionLognormal(
const double x, // value of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then th
int& error_code // variable to store the error code
);
Calculates the log-normal distribution function of probabilities with the mu and sigma parameters for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionLognormal(
const double x, // value of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
int& error_code // variable to store the error code
);
Calculates the log-normal distribution function of probabilities with the mu and sigma parameters for
an array of random variables x []. In case of error it returns false. Analog of the plnorm() in R .
bool MathCumulativeDistributionLognormal(
const double& x[], // array with the values of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devi
const bool tail, // flag of calculation, if true, then the probability of random v
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true
double& result[] // array for values of the probability function
);
Calculates the log-normal distribution function of probabilities with the mu and sigma parameters for
an array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionLognormal(
const double& x[], // array with the values of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devi
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
mu
[in] Logarithm of the expected value (log _mean).
sigma
[in] Logarithm of the root-mean-s quare deviation (log standard deviation).
tail
[in] Flag of calculation, if true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array to obtain the values of the probability function.
MathQuantileLognormal
For the specified probability, the function calculates the value of inverse log-normal distribution
function with the mu and sigma parameters. In case of error it returns NaN.
double MathQuantileLognormal(
const double probability, // probability value of random variable occurrence
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse log-normal distribution
function with the mu and sigma parameters. In case of error it returns NaN.
double MathQuantileLognormal(
const double probability, // probability value of random variable occurrence
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
int& error_code // variable to store the error code
);
For the specified probability[] array of probability values, the function calculates the value of inverse
log-normal distribution function with the mu and sigma parameters. In case of error it returns false.
Analog of the qlnorm() in R .
bool MathQuantileLognormal(
const double& probability[], // array with probability values of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devi
const bool tail, // flag of calculation, if false, then calculation is performed f
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performe
double& result[] // array with values of quantiles
);
For the specified probability[] array of probability values, the function calculates the value of inverse
log-normal distribution function with the mu and sigma parameters. In case of error it returns false.
bool MathQuantileLognormal(
const double& probability[], // array with probability values of random variable
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devi
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable occurrence.
probability[]
[in] Array with probability values of random variable.
mu
[in] Logarithm of the expected value (log _mean).
sigma
[in] Logarithm of the root-mean-s quare deviation (log standard deviation).
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to store the error code.
result[]
[out] Array with values of quantiles.
MathRandomLognormal
Generates a pseudorandom variable distributed according to the log-normal law with the mu sigma
parameters. In case of error it returns NaN.
double MathRandomLognormal(
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the log-normal law with the mu sigma
parameters. In case of error it returns false. Analog of the rlnorm() in R .
double MathRandomLognormal(
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
mu
[in] Logarithm of the expected value (log _mean).
sigma
[in] Logarithm of the root-mean-s quare deviation (log standard deviation).
data_count
[in] Amount of required data.
error_code
[out] Variable to store the error code.
result[]
[out] Array with values of pseudorandom variables.
MathMomentsLognormal
Calculates the theoretical numerical values of the first 4 moments of the log-normal distribution.
R eturns true if calculation of the moments has been successful, otherwise false.
double MathMomentsLognormal(
const double mu, // logarithm of the expected value (log mean)
const double sigma, // logarithm of the root-mean-square deviation (log standard devia
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable to store the error code
);
Parameters
mu
[in] Logarithm of the expected value (log _mean).
sigma
[in] Logarithm of the root-mean-s quare deviation (log standard deviation).
mean
[in] Variable for the mean.
variance
[out] Variable for the variance.
skewness
[out] Variable for the s k ewness.
kurtosis
[out] Variable for the k urtosis.
error code
[out] Variable to store the error code.
Return Value
R eturns true if the moments have been calculated successfully, otherwise false.
Beta distribution
This section contains functions for work ing with beta distribution. They allow to calculate density,
probability, quantiles and to generate pseudo-random numbers distributed according to the
corresponding law. The beta distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Beta.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double alpha=2; // the first parameter of beta distribution (shape1)
input double beta=5; // the second parameter of beta distribution (shape2)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the beta distribution
MathRandomBeta(alpha,beta,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityBeta(x2,alpha,beta,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Beta distribution alpha=%G beta=%G",alpha,beta));
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
MathProbabilityDensityBeta
Calculates the value of the probability density function of beta distribution with the a and b
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityBeta(
const double x, // value of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of beta distribution with the a and b
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityBeta(
const double x, // value of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of beta distribution with the a and b
parameters for an array of random variables x []. In case of error it returns false. Analog of the dbeta()
in R .
bool MathProbabilityDensityBeta(
const double& x[], // array with the values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of beta distribution with the a and b
parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityBeta(
const double& x[], // array with the values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
a
[in] The first parameter of beta distribution (shape 1).
b
[in] The second parameter of beta distribution (shape 2)
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionBeta
Calculates the probability distribution function of beta distribution with the a and b parameters for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionBeta(
const double x, // value of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the probability distribution function of beta distribution with the a and b parameters for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionBeta(
const double x, // value of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
int& error_code // variable to store the error code
);
Calculates the probability distribution function of beta distribution with the a and b parameters for an
array of random variables x []. In case of error it returns false. Analog of the pbeta() in R .
bool MathCumulativeDistributionBeta(
const double& x[], // array with the values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
<t0>Calculates the probability distribution function of beta distribution with the a and b parameters
for an array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionBeta(
const double& x[], // array with the values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
a
[in] The first parameter of beta distribution (shape 1).
b
[in] The second parameter of beta distribution (shape 2)
tail
[in] Flag of calculation, if true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileBeta
For the specified probability, the function calculates the value of inverse beta distribution function
double MathQuantileBeta(
const double probability, // probability value of random variable occurrence
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse beta distribution function
double MathQuantileBeta(
const double probability, // probability value of random variable occurrence
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
int& error_code // variable to store the error code
);
For the specified array of probability values, the function calculates the values of inverse
probability[]
beta distribution function with the a and b parameters. In case of error it returns false. Analog of
the qbeta() in R .
double MathQuantileBeta(
const double& probability[], // array with probability values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified array of probability values, the function calculates the values of inverse
probability[]
beta distribution function with the a and b parameters. In case of error it returns false.
bool MathQuantileBeta(
const double& probability[], // array with probability values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
a
[in] The first parameter of beta distribution (shape1).
b
[in] The second parameter of beta distribution (shape2).
tail
[in] Flag of calculation, if lower_tail=false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomBeta
Generates a pseudorandom variable distributed according to the law of beta distribution with the a
and b parameters. In case of error it returns NaN.
double MathRandomBeta(
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of beta distribution with the a and
b parameters. In case of error it returns false. Analog of the rbeta() in R .
bool MathRandomBeta(
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const int data_count, // amount of required data
double& result[] // array to obtain the pseudorandom variables
);
Parameters
a
[in] The first parameter of beta distribution (shape1)
b
[in] The second parameter of beta distribution (shape2).
data_count
[in] The number of pseudorandom variables to be obtained.
error_code
[out] Variable to store the error code.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsBeta
Calculates the theoretical numerical values of the first 4 moments of the beta distribution.
double MathMomentsBeta(
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
a
[in] The first parameter of beta distribution (shape1).
b
[in] The second parameter of beta distribution (shape2).
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if the moments have been calculated successfully, otherwise false.
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\NoncentralBeta.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double a_par=2; // the first parameter of beta distribution (shape1)
input double b_par=5; // the second parameter of beta distribution (shape2)
input double l_par=1; // noncentrality parameter (lambda)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=53; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the noncentral beta distribution
MathRandomNoncentralBeta(a_par,b_par,l_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityNoncentralBeta(x2,a_par,b_par,l_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Noncentral Beta distribution alpha=%G beta=%G lambda=%G",
a_par,b_par,l_par));
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityNoncentralBeta
Calculates the value of the probability density function of noncentral beta distribution with the a, b
and lambda parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNoncentralBeta(
const double x, // value of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of noncentral beta distribution with the a, b
and lambda parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNoncentralBeta(
const double x, // value of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of noncentral beta distribution with the a, b
and lambda parameters for an array of random variables x []. In case of error it returns false. Analog
of the dbeta() in R .
bool MathProbabilityDensityNoncentralBeta(
const double& x[], // array with the values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of noncentral beta distribution with the a, b
and lambda parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityNoncentralBeta(
const double& x[], // array with the values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
a
[in] The first parameter of beta distribution (shape 1).
b
[in] The second parameter of beta distribution (shape 2)
lambda
[in] Noncentrality parameter
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionNoncentralBeta
Calculates the probability distribution function of noncentral beta distribution with the a, b and lambda
parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNoncentralBeta(
const double x, // value of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the probability distribution function of noncentral beta distribution with the a, b and lambda
parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNoncentralBeta(
const double x, // value of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
int& error_code // variable to store the error code
);
Calculates the probability distribution function of noncentral beta distribution with the a, b and lambda
parameters for an array of random variables x []. In case of error it returns false. Analog of the pbeta()
in R .
bool MathCumulativeDistributionNoncentralBeta(
const double& x[], // array with the values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the probability distribution function of noncentral beta distribution with the a, b and lambda
parameters for an array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionNoncentralBeta(
const double& x[], // array with the values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
a
[in] The first parameter of beta distribution (shape 1).
b
[in] The second parameter of beta distribution (shape 2)
lambda
[in] Noncentrality parameter
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileNoncentralBeta
Calculates the value of the inverse probability distribution function of noncentral beta distribution with
the a, b and lambda parameters for the occurrence probability of a random variable probability. In
case of error it returns NaN.
double MathQuantileNoncentralBeta(
const double probability, // probability value of random variable occurrence
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
Calculates the value of the inverse probability distribution function of noncentral beta distribution with
the a, b and lambda parameters for the occurrence probability of a random variable probability. In
case of error it returns NaN.
double MathQuantileNoncentralBeta(
const double probability, // probability value of random variable occurrence
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
int& error_code // variable to store the error code
);
For the specified probability[] array of probability values, the function calculates the value of the
inverse probability distribution function of noncentral beta distribution with the a, b and lambda
parameters. In case of error it returns false. Analog of the qbeta() in R .
double MathQuantileNoncentralBeta(
const double& probability[], // array with probability values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified probability[] array of probability values, the function calculates the value of the
inverse probability distribution function of noncentral beta distribution with the a, b and lambda
parameters. In case of error it returns false.
bool MathQuantileNoncentralBeta(
const double& probability[], // array with probability values of random variable
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
a
[in] The first parameter of beta distribution (shape1).
b
[in] The second parameter of beta distribution (shape2).
lambda
[in] Noncentrality parameter.
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomNoncentralBeta
Generates a pseudorandom variable distributed according to the law of noncentral beta distribution
the a, b and lambda parameters. In case of error it returns NaN.
double MathRandomNoncentralBeta(
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of noncentral beta distribution the
a, b and lambda parameters. In case of error it returns false. Analog of the rbeta() in R .
bool MathRandomNoncentralBeta(
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
const int data_count, // amount of required data
double& result[] // array to obtain the pseudorandom variables
);
Parameters
a
[in] The first parameter of beta distribution (shape1)
b
[in] The second parameter of beta distribution (shape2).
lambda
[in] Noncentrality parameter
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsNoncentralBeta
Calculates the theoretical numerical values of the first 4 moments of the noncentral beta distribution
with the a, b and lambda parameters.
double MathMomentsNoncentralBeta(
const double a, // the first parameter of beta distribution (shape1)
const double b, // the second parameter of beta distribution (shape2)
const double lambda, // noncentrality parameter
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
a
[in] The first parameter of beta distribution (shape1).
b
[in] The second parameter of beta distribution (shape2).
lambda
[in] Noncentrality parameter
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
Gamma distribution
This section contains functions for work ing with gamma distribution. They allow to calculate density,
probability, quantiles and to generate pseudo-random numbers distributed according to the
corresponding law. The gamma distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Gamma.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double alpha=9; // the first parameter of distribution (shape)
input double beta=0.5; // the second parameter of distribution (scale)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the gamma distribution
MathRandomGamma(alpha,beta,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityGamma(x2,alpha,beta,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Gamma distribution alpha=%G beta=%G",alpha,beta));
graphic.BackgroundMainSize(16);
//--- disable automatic scaling of the Y axis
graphic.YAxis().AutoScale(false);
graphic.YAxis().Max(NormalizeDouble(theor_max,1));
graphic.YAxis().Min(0);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityGamma
Calculates the value of the probability density function of gamma distribution with the a and b
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityGamma(
const double x, // value of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of gamma distribution with the a and b
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityGamma(
const double x, // value of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of gamma distribution with the a and b
parameters for an array of random variables x []. In case of error it returns false. Analog of the
dgamma() in R .
bool MathProbabilityDensityGamma(
const double& x[], // array with the values of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of gamma distribution with the a and b
parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityGamma(
const double& x[], // array with the values of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
a
[in] The first parameter of the distribution (shape).
b
[in] The second parameter of the distribution (scale).
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionGamma
Calculates the probability distribution function of gamma distribution with the a and b parameters for
a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionGamma(
const double x, // value of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the probability distribution function of gamma distribution with the a and b parameters for
a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionGamma(
const double x, // value of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
int& error_code // variable to store the error code
);
Calculates the probability distribution function of gamma distribution with the a and b parameters for
an array of random variables x []. In case of error it returns false. Analog of the pgamma() in R .
bool MathCumulativeDistributionGamma(
const double& x[], // array with the values of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the probability distribution function of gamma distribution with the a and b parameters for
an array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionGamma(
const double& x[], // array with the values of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
a
[in] The first parameter of the distribution (shape).
b
[in] The second parameter of the distribution (scale)
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileGamma
For the specified probability, the function calculates the value of inverse gamma distribution function
double MathQuantileGamma(
const double probability, // probability value of random variable occurrence
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse gamma distribution function
double MathQuantileGamma(
const double probability, // probability value of random variable occurrence
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
int& error_code // variable to store the error code
);
For the specified array of probability values, the function calculates the value of inverse
probability[]
gamma distribution function with the a and b parameters. In case of error it returns false. Analog of
the qgamma() in R .
double MathQuantileGamma(
const double& probability[], // array with probability values of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified array of probability values, the function calculates the value of inverse
probability[]
gamma distribution function with the a and b parameters. In case of error it returns false.
bool MathQuantileGamma(
const double& probability[], // array with probability values of random variable
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
a
[in] The first parameter of the distribution (shape).
b
[in] The second parameter of the distribution (scale).
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomGamma
Generates a pseudorandom variable distributed according to the law of gamma distribution with the a
and b parameters. In case of error it returns NaN.
double MathRandomGamma(
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of gamma distribution with the a
and b parameters. In case of error it returns false. Analog of the rgamma() in R .
bool MathRandomGamma(
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
a
[in] The first parameter of the distribution (shape).
b
[in] The second parameter of the distribution (scale).
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsGamma
Calculates the theoretical numerical values of the first 4 moments of the gamma distribution with the
a and b parameters.
double MathMomentsGamma(
const double a, // the first parameter of the distribution (shape)
const double b, // the second parameter of the distribution (scale)
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
a
[in] The first parameter of the distribution (shape).
b
[in] The second parameter of the distribution (scale).
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
Chi-squared distribution
This section contains functions for work ing with chi-s quared distribution. They allow to calculate
density, probability, quantiles and to generate pseudo-random numbers distributed according to the
corresponding law. The chi-s quared distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\ChiSquare.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double nu_par=5; // the number of degrees of freedom
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the chi-squared distribution
MathRandomChiSquare(nu_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityChiSquare(x2,nu_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("ChiSquare distribution nu=%G ",nu_par));
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
MathProbabilityDensityChiSquare
Calculates the value of the probability density function of chi-s quared distribution with the nu
parameter for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityChiSquare(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of chi-s quared distribution with the nu
parameter for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityChiSquare(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of chi-s quared distribution with the nu
parameter for an array of random variables x []. In case of error it returns false. Analog of the dchis q()
in R .
bool MathProbabilityDensityChiSquare(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of chi-s quared distribution with the nu
parameter for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityChiSquare(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom)
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionChiSquare
Calculates the probability distribution function of chi-s quared distribution with the nu parameter for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionChiSquare(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the probability distribution function of chi-s quared distribution with the nu parameter for a
random variable x. In case of error it returns NaN
double MathCumulativeDistributionChiSquare(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
int& error_code // variable to store the error code
);
Calculates the probability distribution function of chi-s quared distribution with the nu parameter for an
array of random variables x []. In case of error it returns false. Analog of the pchis q() in R .
bool MathCumulativeDistributionChiSquare(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the probability distribution function of chi-s quared distribution with the nu parameter for an
array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionChiSquare(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom).
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileChiSquare
For the specified probability, the function calculates the value of inverse chi-s quared distribution
double MathQuantileChiSquare(
const double probability, // probability value of random variable occurrence
const double nu, // parameter of distribution (number of degrees of freedom)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse chi-s quared distribution
double MathQuantileChiSquare(
const double probability, // probability value of random variable occurrence
const double nu, // parameter of distribution (number of degrees of freedom)
int& error_code // variable to store the error code
);
For the specified probability[] array of probability values, the function calculates the value of inverse
chi-s quared distribution function. In case of error it returns false. Analog of the qchis q() in R .
double MathQuantileChiSquare(
const double& probability[], // array with probability values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified probability[] array of probability values, the function calculates the value of inverse
chi-s quared distribution function. In case of error it returns false.
bool MathQuantileChiSquare(
const double& probability[], // array with probability values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom).
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomChiSquare
Generates a pseudorandom variable distributed according to the law of chi-s quared distribution with
the nu parameter. In case of error it returns NaN.
double MathRandomChiSquare(
const double nu, // parameter of distribution (number of degrees of freedom)
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of chi-s quared distribution with
the nu parameter. In case of error it returns false. Analog of the rchis q() in R .
bool MathRandomChiSquare(
const double nu, // parameter of distribution (number of degrees of freedom)
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
nu
[in] Parameter of distribution (number of degrees of freedom).
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsChiSquare
Calculates the theoretical numerical values of the first 4 moments of the chi-s quared distribution with
the nu parameter.
double MathMomentsChiSquare(
const double nu, // parameter of distribution (number of degrees of freedom)
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
nu
[in] Parameter of distribution (number of degrees of freedom).
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\NoncentralChiSquare.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double nu_par=8; // the number of degrees of freedom
input double si_par=1; // noncentrality parameter
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the noncentral chi-squared distribution
MathRandomNoncentralChiSquare(nu_par,si_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityNoncentralChiSquare(x2,nu_par,si_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Noncentral ChiSquare distribution nu=%G sigma=%G",nu_par,si
graphic.BackgroundMainSize(16);
//--- disable automatic scaling of the X axis
graphic.XAxis().AutoScale(false);
graphic.XAxis().Max(NormalizeDouble(max,0));
graphic.XAxis().Min(min);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityNoncentralChiSquare
Calculates the value of the probability density function of noncentral chi-s quared distribution with the
nu and sigma parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNoncentralChiSquare(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of noncentral chi-s quared distribution with the
nu and sigma parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNoncentralChiSquare(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of noncentral chi-s quared distribution with the
nu and sigma parameters for an array of random variables x []. In case of error it returns false. Analog
of the dchis q() in R .
bool MathProbabilityDensityNoncentralChiSquare(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of noncentral chi-s quared distribution with the
nu parameter for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityNoncentralChiSquare(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
nu
[in] Parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionNoncentralChiSquare
Calculates the probability distribution function of noncentral chi-s quared distribution with the nu and
sigma parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNoncentralChiSquare(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
const bool tail, // flag of calculation, if lower_tail=true, then the probability of
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the probability distribution function of noncentral chi-s quared distribution with the nu and
sigma parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNoncentralChiSquare(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
int& error_code // variable to store the error code
);
Calculates the probability distribution function of noncentral chi-s quared distribution with the nu and
sigma parameters for an array of random variables x []. In case of error it returns false. Analog of the
pchis q() in R .
bool MathCumulativeDistributionNoncentralChiSquare(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
const bool tail, // flag of calculation, if lower_tail=true, then the probability o
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the probability distribution function of noncentral chi-s quared distribution with the nu and
sigma parameters for an array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionNoncentralChiSquare(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileNoncentralChiSquare
For the specified probability, the function calculates the value of inverse noncentral chi-s quared
distribution function with the nu and sigma parameters. In case of error it returns NaN.
double MathQuantileNoncentralChiSquare(
const double probability, // probability value of random variable occurrence
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse noncentral chi-s quared
distribution function with the nu and sigma parameters. In case of error it returns NaN.
double MathQuantileNoncentralChiSquare(
const double probability, // probability value of random variable occurrence
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
int& error_code // variable to store the error code
);
For the specified probability[] array of probability values, the function calculates the value of inverse
noncentral chi-s quared distribution function with the nu and sigma parameters. In case of error it
returns false. Analog of the qchis q() in R .
double MathQuantileNoncentralChiSquare(
const double& probability[], // array with probability values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
const bool tail, // flag of calculation, if false, then calculation is performed f
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performe
double& result[] // array with values of quantiles
);
For the specified probability[] array of probability values, the function calculates the value of inverse
noncentral chi-s quared distribution function. In case of error it returns false.
bool MathQuantileNoncentralChiSquare(
const double& probability[], // array with probability values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomNoncentralChiSquare
Generates a pseudorandom variable distributed according to the law of noncentral chi-s quared
distribution with the nu and sigma parameters. In case of error it returns NaN.
double MathRandomNoncentralChiSquare(
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of noncentral chi-s quared
distribution with the nu and sigma parameters. In case of error it returns false. Analog of the rchis q()
in R .
bool MathRandomNoncentralChiSquare(
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
nu
[in] Parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsNoncentralChiSquare
Calculates the theoretical numerical values of the first 4 moments of the noncentral chi-s quared
distribution with the nu and sigma parameters.
double MathMomentsNoncentralChiSquare(
const double nu, // parameter of distribution (number of degrees of freedom)
const double sigma, // noncentrality parameter
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
nu
[in] Parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
Exponential
This section contains functions for work ing with exponential distribution. They allow to calculate
density, probability, quantiles and to generate pseudo-random numbers distributed according to the
law of exponential distribution. The exponential distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
distribution
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Exponential.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double mu_par=1.5; // the number of degrees of freedom
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the exponential distribution
MathRandomExponential(mu_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityExponential(x2,mu_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Exponential distribution mu=%G ",mu_par));
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+i*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
MathProbabilityDensityExponential
Calculates the value of the probability density function of exponential distribution with the mu
parameter for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityExponential(
const double x, // value of random variable
const double mu, // parameter of the distribution (expected value)
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of exponential distribution with the mu
parameter for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityExponential(
const double x, // value of random variable
const double mu, // parameter of the distribution (expected value)
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of exponential distribution with the mu
parameter for an array of random variables x []. In case of error it returns false. Analog of the dexp()
in R .
bool MathProbabilityDensityExponential(
const double& x[], // array with the values of random variable
const double mu, // parameter of the distribution (expected value)
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of exponential distribution with the mu
parameter for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityExponential(
const double& x[], // array with the values of random variable
const double mu, // parameter of the distribution (expected value)
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
mu
[in] Parameter of the distribution (expected value)
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionExponential
Calculates the exponential distribution function of probabilities with the mu parameter for a random
variable x. In case of error it returns NaN.
double MathCumulativeDistributionExponential(
const double x, // value of random variable
const double mu, // parameter of the distribution (expected value)
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the exponential distribution function of probabilities with the mu parameter for a random
variable x. In case of error it returns NaN.
double MathCumulativeDistributionExponential(
const double x, // value of random variable
const double mu, // parameter of the distribution (expected value)
int& error_code // variable to store the error code
);
Calculates the exponential distribution function of probabilities with the mu parameter for an array of
random variables x []. In case of error it returns false. Analog of the pexp() in R .
bool MathCumulativeDistributionExponential(
const double& x[], // array with the values of random variable
const double mu, // parameter of the distribution (expected value)
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the exponential distribution function of probabilities with the mu parameter for an array of
random variables x []. In case of error it returns false.
bool MathCumulativeDistributionExponential(
const double& x[], // array with the values of random variable
const double mu, // parameter of the distribution (expected value)
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
mu
[in] Parameter of the distribution (expected value).
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileExponential
For the specified probability, the function calculates the value of inverse exponential distribution
double MathQuantileExponential(
const double probability, // probability value of random variable occurrence
const double mu, // parameter of the distribution (expected value)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse exponential distribution
double MathQuantileExponential(
const double probability, // probability value of random variable occurrence
const double mu, // parameter of the distribution (expected value)
int& error_code // variable to store the error code
);
For the specified probability[] array of probability values, the function calculates the value of inverse
exponential distribution function with the mu parameter. In case of error it returns false. Analog of
the qexp() in R .
double MathQuantileExponential(
const double& probability[], // array with probability values of random variable
const double mu, // parameter of the distribution (expected value)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified array of probability values, the function calculates the value of inverse
probability[]
exponential distribution function with the mu parameter. In case of error it returns false.
bool MathQuantileExponential(
const double& probability[], // array with probability values of random variable
const double mu, // parameter of the distribution (expected value)
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
mu
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomExponential
Generates a pseudorandom variable distributed according to the law of exponential distribution with
the mu parameter. In case of error it returns NaN.
double MathRandomExponential(
const double mu, // parameter of the distribution (expected value)
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of exponential distribution with
the mu parameter. In case of error it returns false. Analog of the rexp() in R .
bool MathRandomExponential(
const double mu, // parameter of the distribution (expected value)
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
mu
[in] Parameter of the distribution (expected value).
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsExponential
Calculates the theoretical numerical values of the first 4 moments of the exponential distribution with
the mu parameter.
double MathMomentsExponential(
const double mu, // parameter of the distribution (expected value)
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
mu
[in] Parameter of the distribution (expected value).
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
F-distribution
This section contains functions for work ing with F-distribution. They allow to calculate density,
probability, quantiles and to generate pseudo-random numbers distributed according to the law of
Fisher's F-distribution. The F-distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\F.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double nu_1=100; // the first number of degrees of freedom
input double nu_2=100; // the second number of degrees of freedom
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the Fisher's F-distribution
MathRandomF(nu_1,nu_2,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityF(x2,nu_1,nu_2,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("F-distribution nu1=%G nu2=%G",nu_1,nu_2));
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(4);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityF
Calculates the value of the probability density function of Fisher's F-distribution with the nu1 and nu2
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityF(
const double x, // value of random variable
const double nu1, // the first parameter of distribution (number of degrees of freedo
const double nu2, // the second parameter of distribution (number of degrees of freed
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of Fisher's F-distribution with the nu1 and nu2
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityF(
const double x, // value of random variable
const double nu1, // the first parameter of distribution (number of degrees of freedo
const double nu2, // the second parameter of distribution (number of degrees of freed
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of Fisher's F-distribution with the nu1 and nu2
parameters for an array of random variables x []. In case of error it returns false. Analog of the df() in
R.
bool MathProbabilityDensityF(
const double& x[], // array with the values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of Fisher's F-distribution with the nu1 and nu2
parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityF(
const double& x[], // array with the values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionF
Calculates the value of the probability distribution function of Fisher's F-distribution with the nu1 and
nu2 parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionF(
const double x, // value of random variable
const double nu1, // the first parameter of distribution (number of degrees of freedo
const double nu2, // the second parameter of distribution (number of degrees of freed
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability distribution function of Fisher's F-distribution with the nu1 and
nu2 parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionF(
const double x, // value of random variable
const double nu1, // the first parameter of distribution (number of degrees of freedo
const double nu2, // the second parameter of distribution (number of degrees of freed
int& error_code // variable to store the error code
);
Calculates the value of the probability distribution function of Fisher's F-distribution with the nu1 and
nu2 parameters for an array of random variables x []. In case of error it returns false. Analog of the
pf() in R .
bool MathCumulativeDistributionF(
const double& x[], // array with the values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then th
double& result[] // array for values of the probability function
);
Calculates the value of the probability distribution function of Fisher's F-distribution with the nu1 and
nu2 parameters for an array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionF(
const double& x[], // array with the values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileF
For the specified probability, the function calculates the value of inverse Fisher's F-distribution
function with the nu1 and nu2 parameters. In case of error it returns NaN.
double MathQuantileF(
const double probability, // probability value of random variable occurrence
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse Fisher's F-distribution
function with the nu1 and nu2 parameters. In case of error it returns NaN.
double MathQuantileF(
const double probability, // probability value of random variable occurrence
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
int& error_code // variable to store the error code
);
For the specified probability[] array of probability values, the function calculates the value of inverse
Fisher's F-distribution function with the nu1 and nu2 parameters. In case of error it returns false.
Analog of the qf() in R .
double MathQuantileF(
const double& probability[], // array with probability values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified probability[] array of probability values, the function calculates the value of inverse
Fisher's F-distribution function with the nu1 and nu2 parameters. In case of error it returns false.
bool MathQuantileF(
const double& probability[], // array with probability values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
tail
[in] Flag of calculation, if lower_tail=false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomF
Generates a pseudorandom variable distributed according to the law of Fisher's F-distribution with the
nu1 and nu2 parameters. In case of error it returns NaN.
double MathRandomF(
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of Fisher's F-distribution with the
nu1 and nu2 parameters. In case of error it returns false. Analog of the rf() in R .
bool MathRandomF(
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsF
Calculates the theoretical numerical values of the first 4 moments of the Fisher's F-distribution with
the nu1 and nu2 parameters.
double MathMomentsF(
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
Noncentral F-distribution
This section contains functions for work ing with noncentral F-distribution. They allow to calculate
density, probability, quantiles and to generate pseudo-random numbers distributed according to the
law of noncentral Fisher's F-distribution. The noncentral F-distribution is defined by the following
formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\NoncentralF.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double nu_1=20; // the first number of degrees of freedom
input double nu_2=20; // the second number of degrees of freedom
input double sig=10; // noncentrality parameter
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the noncentral Fisher's F-distribution
MathRandomNoncentralF(nu_1,nu_2,sig,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityNoncentralF(x2,nu_1,nu_2,sig,false,y2);
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityNoncentralF
Calculates the value of the probability density function of noncentral Fisher's F-distribution with the
nu1, nu2 and sigma parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNoncentralF(
const double x, // value of random variable
const double nu1, // the first parameter of distribution (number of degrees of freedo
const double nu2, // the second parameter of distribution (number of degrees of freed
const double sigma, // noncentrality parameter
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of noncentral Fisher's F-distribution with the
nu1, nu2 and sigma parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNoncentralF(
const double x, // value of random variable
const double nu1, // the first parameter of distribution (number of degrees of freedo
const double nu2, // the second parameter of distribution (number of degrees of freed
const double sigma, // noncentrality parameter
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of noncentral Fisher's F-distribution with the
nu1, nu2 and sigma parameters for an array of random variables x []. In case of error it returns false.
Analog of the df() in R .
bool MathProbabilityDensityNoncentralF(
const double& x[], // array with the values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of noncentral Fisher's F-distribution with the
nu1, nu2 and sigma parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityNoncentralF(
const double& x[], // array with the values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionNoncentralF
Calculates the value of the probability distribution function of noncentral Fisher's F-distribution with
the nu1, nu2 and sigma parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNoncentralF(
const double x, // value of random variable
const double nu1, // the first parameter of distribution (number of degrees of freedo
const double nu2, // the second parameter of distribution (number of degrees of freed
const double sigma, // noncentrality parameter
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
int& error_code // variable to store the error code
);
Calculates the value of the probability distribution function of noncentral Fisher's F-distribution with
the nu1, nu2 and sigma parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNoncentralF(
const double x, // value of random variable
const double nu1, // the first parameter of distribution (number of degrees of freedo
const double nu2, // the second parameter of distribution (number of degrees of freed
const double sigma, // noncentrality parameter
int& error_code // variable to store the error code
);
Calculates the value of the probability distribution function of noncentral Fisher's F-distribution with
the nu1, nu2 and sigma parameters for an array of random variables x []. In case of error it returns
false. Analog of the pf() in R .
bool MathCumulativeDistributionNoncentralF(
const double& x[], // array with the values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the value of the probability distribution function of noncentral Fisher's F-distribution with
the nu1, nu2 and sigma parameters for an array of random variables x []. In case of error it returns
false.
bool MathCumulativeDistributionNoncentralF(
const double& x[], // array with the values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileF
For the specified probability, the function calculates the value of inverse noncentral Fisher's F-
distribution function with the nu1, nu2 and sigma parameters. In case of error it returns NaN.
double MathQuantileF(
const double probability, // probability value of random variable occurrence
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse noncentral Fisher's F-
distribution function with the nu1, nu2 and sigma parameters. In case of error it returns NaN.
double MathQuantileF(
const double probability, // probability value of random variable occurrence
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
int& error_code // variable to store the error code
);
For the specified probability[] array of probability values, the function calculates the value of inverse
noncentral Fisher's F-distribution function with the nu1, nu2 and sigma parameters. In case of error it
returns false. Analog of the qf() in R .
double MathQuantileF(
const double& probability[], // array with probability values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified probability[] array of probability values, the function calculates the value of inverse
noncentral Fisher's F-distribution function with the nu1, nu2 and sigma parameters. In case of error it
returns false.
bool MathQuantileF(
const double& probability[], // array with probability values of random variable
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomNoncentralF
Generates a pseudorandom variable distributed according to the law of noncentral Fisher's F-
distribution with the nu1, nu2 and sigma parameters. In case of error it returns NaN.
double MathRandomNoncentralF(
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
int& error_code // variable to store the error code
);
bool MathRandomNoncentralF(
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsNoncentralF
Calculates the theoretical numerical values of the first 4 moments of the noncentral Fisher's F-
distribution with the nu1, nu2 and sigma parameters.
double MathMomentsNoncentralF(
const double nu1, // the first parameter of distribution (number of degrees of freed
const double nu2, // the second parameter of distribution (number of degrees of free
const double sigma, // noncentrality parameter
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
nu1
[in] The first parameter of distribution (number of degrees of freedom).
nu2
[in] The second parameter of distribution (number of degrees of freedom).
sigma
[in] Noncentrality parameter.
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
t-distribution
This section contains functions for work ing with Student's t-distribution. They allow to calculate
density, probability, quantiles and to generate pseudo-random numbers distributed according to the
Student's law. The t-distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\T.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double nu_par=10; // the number of degrees of freedom
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the Student's t-distribution
MathRandomT(nu_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityT(x2,nu_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityT
Calculates the value of the probability density function of Student's t-distribution with the nu
parameter for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityT(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of Student's t-distribution with the nu
parameter for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityT(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of Student's t-distribution with the nu
parameter for an array of random variables x []. In case of error it returns false. Analog of the dt() in
R.
bool MathProbabilityDensityT(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of Student's t-distribution with the nu
parameter for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityT(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom).
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionT
Calculates the value of the Student's t-distribution function with the nu parameter for a random
variable x. In case of error it returns NaN.
double MathCumulativeDistributionT(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
int& error_code // variable to store the error code
);
Calculates the value of the Student's t-distribution function with the nu parameter for a random
variable x. In case of error it returns NaN.
double MathCumulativeDistributionT(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
int& error_code // variable to store the error code
);
Calculates the value of the Student's t-distribution function with the nu parameter for an array of
random variables x []. In case of error it returns false. Analog of the pt() in R .
bool MathCumulativeDistributionT(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the value of the Student's t-distribution function with the nu parameter for an array of
random variables x []. In case of error it returns false.
bool MathCumulativeDistributionT(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom).
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileT
For the specified probability, the function calculates the value of inverse Student's t-distribution
double MathQuantileT(
const double probability, // probability value of random variable occurrence
const double nu, // parameter of distribution (number of degrees of freedom)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse Student's t-distribution
double MathQuantileT(
const double probability, // probability value of random variable occurrence
const double nu, // parameter of distribution (number of degrees of freedom)
int& error_code // variable to store the error code
);
For the specified probability[] array of probability values, the function calculates the value of inverse
Student's t-distribution function with the nu parameter. In case of error it returns false. Analog of
the qt() in R .
double MathQuantileT(
const double& probability[], // array with probability values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified probability[] array of probability values, the function calculates the value of inverse
Student's t-distribution function with the nu parameter. In case of error it returns false.
bool MathQuantileT(
const double& probability[], // array with probability values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
nu
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomT
Generates a pseudorandom variable distributed according to the law of Student's t-distribution with
the nu parameter. In case of error it returns NaN.
double MathRandomT(
const double nu, // parameter of distribution (number of degrees of freedom)
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of Student's t-distribution with the
nu parameter. In case of error it returns false. Analog of the rt() in R .
bool MathRandomT(
const double nu, // parameter of distribution (number of degrees of freedom)
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
nu
[in] Parameter of distribution (number of degrees of freedom).
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsT
Calculates the theoretical numerical values of the first 4 moments of the Student's t-distribution with
the nu parameter.
double MathMomentsT(
const double nu, // parameter of distribution (number of degrees of freedom)
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
nu
[in] Parameter of distribution (number of degrees of freedom).
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
t-distribution
This section contains functions for work ing with noncentral Student's t-distribution. They allow to
calculate density, probability, quantiles and to generate pseudo-random numbers distributed according
to the law of noncentral t-distribution. The noncentral t-distribution is defined by the following
formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\NoncentralT.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double nu_par=30; // the number of degrees of freedom
input double delta_par=5; // noncentrality parameter
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the noncentral Student's t-distribution
MathRandomNoncentralT(nu_par,delta_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityNoncentralT(x2,nu_par,delta_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Noncentral t-distribution nu=%G delta=%G",nu_par,delta_par)
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityNoncentralT
Calculates the value of the probability density function of noncentral Student's t-distribution with the
nu and delta parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNoncentralT(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable for the error code
);
Calculates the value of the probability density function of noncentral Student's t-distribution with the
nu and delta parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityNoncentralT(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
int& error_code // variable for the error code
);
Calculates the value of the probability density function of noncentral Student's t-distribution with the
nu and delta parameters for an array of random variables x []. In case of error it returns false. Analog
of the dt() in R .
bool MathProbabilityDensityNoncentralT(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of noncentral Student's t-distribution with the
nu and delta parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityNoncentralT(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
nu
[in] Parameter of distribution (number of degrees of freedom).
delta
[in] Noncentrality parameter.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionNoncentralT
Calculates the probability distribution function of noncentral Student's t-distribution with the nu and
delta parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNoncentralT(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
int& error_code // variable to store the error code
);
Calculates the probability distribution function of noncentral Student's t-distribution with the nu and
delta parameters for a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionNoncentralT(
const double x, // value of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
int& error_code // variable to store the error code
);
Calculates the probability distribution function of noncentral Student's t-distribution with the nu and
delta parameters for an array of random variables x []. In case of error it returns false. Analog of the
pt() in R .
bool MathCumulativeDistributionNoncentralT(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the probability distribution function of noncentral Student's t-distribution with the nu and
delta parameters for an array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionNoncentralT(
const double& x[], // array with the values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
[in] Array with the values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom).
delta
[in] Noncentrality parameter.
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileNoncentralT
For the specified probability, the function calculates the value of inverse noncentral Student's t-
distribution function with the nu and delta parameters. In case of error it returns NaN.
double MathQuantileNoncentralT(
const double probability, // probability value of random variable occurrence
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
const bool tail, // flag of calculation, if lower_tail=false, then calculation is p
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse noncentral Student's t-
distribution function with the nu and delta parameters. In case of error it returns NaN.
double MathQuantileNoncentralT(
const double probability, // probability value of random variable occurrence
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
int& error_code // variable to store the error code
);
For the specified array of probability values, the function calculates the value of inverse
probability[]
noncentral Student's t-distribution function with the nu and delta parameters. In case of error it
returns false. Analog of the qt() in R .
double MathQuantileNoncentralT(
const double& probability[], // array with probability values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
const bool tail, // flag of calculation, if lower_tail=false, then calculation is p
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified array of probability values, the function calculates the value of inverse
probability[]
noncentral Student's t-distribution function with the nu and delta parameters. In case of error it
returns false.
bool MathQuantileNoncentralT(
const double& probability[], // array with probability values of random variable
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
double& result[] // array with values of quantiles
);
Parameters
probability
probability[]
[in] Array with probability values of random variable.
nu
[in] Parameter of distribution (number of degrees of freedom).
delta
[in] Noncentrality parameter.
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomNoncentralT
Generates a pseudorandom variable distributed according to the law of noncentral Student's t-
distribution with the nu and delta parameters. In case of error it returns NaN.
double MathRandomNoncentralT(
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
int& error_code // variable to store the error code
);
bool MathRandomNoncentralT(
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
nu
[in] Parameter of distribution (number of degrees of freedom).
delta
[in] Noncentrality parameter.
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsNoncentralT
Calculates the theoretical numerical values of the first 4 moments of the noncentral Student's t-
distribution with the nu and delta parameters.
double MathMomentsNoncentralT(
const double nu, // parameter of distribution (number of degrees of freedom)
const double delta, // noncentrality parameter
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
nu
[in] Parameter of distribution (number of degrees of freedom).
delta
[in] Noncentrality parameter.
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
Logistic distribution
This section contains functions for work ing with logistic distribution. They allow to calculate density,
probability, quantiles and to generate pseudo-random numbers distributed according to the logistic
law. The logistic distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Logistic.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double mu_par=6; // mean parameter of the distribution
input double sigma_par=2; // scale parameter of the distribution
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the logistic distribution
MathRandomLogistic(mu_par,sigma_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityLogistic(x2,mu_par,sigma_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
//| Calculates values for sequence generation |
//+------------------------------------------------------------------+
void GetMaxMinStepValues(double &maxv,double &minv,double &stepv)
{
//--- calculate the absolute range of the sequence to obtain the precision of normalization
double range=MathAbs(maxv-minv);
int degree=(int)MathRound(MathLog10(range));
//--- normalize the maximum and minimum values to the specified precision
maxv=NormalizeDouble(maxv,degree);
minv=NormalizeDouble(minv,degree);
//--- sequence generation step is also set based on the specified precision
stepv=NormalizeDouble(MathPow(10,-degree),degree);
if((maxv-minv)/stepv<10)
stepv/=10.;
}
MathProbabilityDensityLogistic
Calculates the value of the probability density function of logistic distribution with the mu and sigma
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityLogistic(
const double x, // value of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of logistic distribution with the mu and sigma
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityLogistic(
const double x, // value of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of logistic distribution with the mu and sigma
parameters for an array of random variables x []. In case of error it returns false. Analog of the
dlogis() in R .
bool MathProbabilityDensityLogistic(
const double& x[], // array with the values of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of logistic distribution with the mu and sigma
parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityLogistic(
const double& x[], // array with the values of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
mu
[in] mean parameter of the distribution.
sigma
[in] scale parameter of the distribution.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionLogistic
Calculates the logistic distribution function of probabilities with the mu and sigma parameters for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionLogistic(
const double x, // value of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
int& error_code // variable to store the error code
);
Calculates the logistic distribution function of probabilities with the mu and sigma parameters for a
random variable x. In case of error it returns NaN.
double MathCumulativeDistributionLogistic(
const double x, // value of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
int& error_code // variable to store the error code
);
Calculates the logistic distribution function of probabilities with the mu and sigma parameters for an
array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionLogistic(
const double& x[], // array with the values of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the logistic distribution function of probabilities with the mu and sigma parameters for an
array of random variables x []. In case of error it returns false. Analog of the plogis() in R .
bool MathCumulativeDistributionLogistic(
const double& x[], // array with the values of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
mu
[in] mean parameter of the distribution.
sigma
[in] scale parameter of the distribution.
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileLogistic
For the specifiedprobability, the function calculates the value of inverse logistic distribution function
double MathQuantileLogistic(
const double probability, // probability value of random variable occurrence
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specifiedprobability, the function calculates the value of inverse logistic distribution function
double MathQuantileLogistic(
const double probability, // probability value of random variable occurrence
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
int& error_code // variable to store the error code
);
For the specified array of probability values, the function calculates the value of inverse
probability[]
logistic distribution function with the mu and sigma parameters. In case of error it returns false.
Analog of the qlogis() in R .
double MathQuantileLogistic(
const double& probability[], // array with probability values of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified probability[]array of probability values, the function calculates the value of inverse
logistic distribution function with the mu and sigma parameters. In case of error it returns false.
bool MathQuantileLogistic(
const double& probability[], // array with probability values of random variable
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
mu
[in] mean parameter of the distribution.
sigma
[in] scale parameter of the distribution.
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomLogistic
Generates a pseudorandom variable distributed according to the law of logistic distribution with the
mu and sigma parameters. In case of error it returns NaN.
double MathRandomLogistic(
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of logistic distribution with the mu
and sigma parameters. In case of error it returns false. Analog of the rlogis() in R .
bool MathRandomLogistic(
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
mu
[in] mean parameter of the distribution.
sigma
[in] scale parameter of the distribution.
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsLogistic
Calculates the theoretical numerical values of the first 4 moments of the logistic distribution with the
mu and sigma parameters.
double MathMomentsLogistic(
const double mu, // mean parameter of the distribution
const double sigma, // scale parameter of the distribution
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
mu
[in] mean parameter of the distribution.
sigma
[in] scale parameter of the distribution.
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
Cauchy distribution
This section contains functions for work ing with Cauchy distribution. They allow to calculate density,
probability, quantiles and to generate pseudo-random numbers distributed according to the Cauchy
law. The Cauchy distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Cauchy.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double a_par=-2; // mean parameter of the distribution
input double b_par=1; // scale parameter of the distribution
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the Cauchy distribution
MathRandomCauchy(a_par,b_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityCauchy(x2,a_par,b_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Cauchy distribution a=%G b=%G",a_par,b_par));
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1)
return(false);
int size=ArraySize(data);
if(size<cells*10)
return(false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
Print("min=",minv," max=",maxv);
minv=-20;
maxv=20;
double range=maxv-minv;
double width=range/cells;
if(width==0)
return(false);
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+i*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=(int)MathRound((data[i]-minv)/width);
MathProbabilityDensityCauchy
Calculates the value of the probability density function of Cauchy distribution with the a and b
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityCauchy(
const double x, // value of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of Cauchy distribution with the a and b
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityCauchy(
const double x, // value of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of Cauchy distribution with the a and b
parameters for an array of random variables x []. In case of error it returns false. Analog of the
dcauchy() in R .
bool MathProbabilityDensityCauchy(
const double& x[], // array with the values of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of Cauchy distribution with the a and b
parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityCauchy(
const double& x[], // array with the values of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
double& result[] // array for values of the probability density function
);
Parameters
x
[in] Value of random variable.
x[]
a
[in] mean parameter of the distribution.
b
[in] scale parameter of the distribution.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability density is returned.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability density function.
MathCumulativeDistributionCauchy
Calculates the probability distribution function of Cauchy distribution with the a and b parameters for
a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionCauchy(
const double x, // value of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
const bool tail, // flag of calculation, if true, then the probability of random var
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
int& error_code // variable to store the error code
);
Calculates the probability distribution function of Cauchy distribution with the a and b parameters for
a random variable x. In case of error it returns NaN.
double MathCumulativeDistributionCauchy(
const double x, // value of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
int& error_code // variable to store the error code
);
Calculates the probability distribution function of Cauchy distribution with the a and b parameters for
an array of random variables x []. In case of error it returns false.
bool MathCumulativeDistributionCauchy(
const double& x[], // array with the values of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
const bool tail, // flag of calculation, if true, then the probability of random va
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability function
);
Calculates the probability distribution function of Cauchy distribution with the a and b parameters for
an array of random variables x []. In case of error it returns false. Analog of the plogis() in R .
bool MathCumulativeDistributionCauchy(
const double& x[], // array with the values of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
double& result[] // array for values of the probability function
);
Parameters
x
[in] Value of random variable.
x[]
a
[in] mean parameter of the distribution.
b
[in] scale parameter of the distribution.
tail
[in] Flag of calculation. If true, then the probability of random variable not exceeding x is
calculated.
log_mode
[in] Flag to calculate the logarithm of the value. If log _mode=true, then the natural logarithm of
the probability is calculated.
error_code
[out] Variable to store the error code.
result[]
[out] Array for values of the probability function.
MathQuantileCauchy
For the specified probability, the function calculates the value of inverse Cauchy distribution function
double MathQuantileCauchy(
const double probability, // probability value of random variable occurrence
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
int& error_code // variable to store the error code
);
For the specified probability, the function calculates the value of inverse Cauchy distribution function
double MathQuantileCauchy(
const double probability, // probability value of random variable occurrence
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
int& error_code // variable to store the error code
);
For the specified array of probability values, the function calculates the value of inverse
probability[]
Cauchy distribution function with the a and b parameters. In case of error it returns false. Analog of
the qcauschy() in R .
double MathQuantileCauchy(
const double& probability[], // array with probability values of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
const bool tail, // flag of calculation, if false, then calculation is performed fo
const bool log_mode, // flag of calculation, if log_mode=true, calculation is performed
double& result[] // array with values of quantiles
);
For the specified array of probability values, the function calculates the value of inverse
probability[]
Cauchy distribution function with the a and b parameters. In case of error it returns false.
bool MathQuantileCauchy(
const double& probability[], // array with probability values of random variable
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
double& result[] // array with values of quantiles
);
Parameters
probability
[in] Probability value of random variable.
probability[]
[in] Array with probability values of random variable.
a
[in] mean parameter of the distribution.
b
[in] scale parameter of the distribution.
tail
[in] Flag of calculation, if false, then calculation is performed for 1.0-probability.
log_mode
[in] Flag of calculation, if log _mode=true, calculation is performed for Exp(probability).
error_code
[out] Variable to get the error code.
result[]
[out] Array with values of quantiles.
MathRandomCauchy
Generates a pseudorandom variable distributed according to the law of Cauchy distribution with the a
and b parameters. In case of error it returns NaN.
double MathRandomCauchy(
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
int& error_code // variable to store the error code
);
Generates pseudorandom variables distributed according to the law of Cauchy distribution with the a
and b parameters. In case of error it returns false. Analog of the rcauchy() in R .
bool MathRandomCauchy(
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
const int data_count, // amount of required data
double& result[] // array with values of pseudorandom variables
);
Parameters
a
[in] mean parameter of the distribution.
b
[in] scale parameter of the distribution.
error_code
[out] Variable to store the error code.
data_count
[out] Amount of required data.
result[]
[out] Array to obtain the values of pseudorandom variables.
MathMomentsCauchy
Calculates the theoretical numerical values of the first 4 moments of the Cauchy distribution with the
a and b parameters.
double MathMomentsCauchy(
const double a, // mean parameter of the distribution
const double b, // scale parameter of the distribution
double& mean, // variable for the mean
double& variance, // variable for the variance
double& skewness, // variable for the skewness
double& kurtosis, // variable for the kurtosis
int& error_code // variable for the error code
);
Parameters
a
[in] mean parameter of the distribution.
b
[in] scale parameter of the distribution.
mean
[out] Variable to get the mean value.
variance
[out] Variable to get the variance.
skewness
[out] Variable to get the s k ewness.
kurtosis
[out] Variable to get the k urtosis.
error_code
[out] Variable to get the error code.
Return Value
R eturns true if calculation of the moments has been successful, otherwise false.
Uniform distribution
This section contains functions for work ing with uniform distribution. They allow to calculate density,
probability, quantiles and to generate pseudo-random numbers distributed according to the uniform
law. The uniform distribution is defined by the following formula:
where:
In addition to the calculation of the individual random variables, the library also implements the ability
to work with arrays of random variables.
Function Description
Example:
#include <Graphics\Graphic.mqh>
#include <Math\Stat\Uniform.mqh>
#include <Math\Stat\Math.mqh>
#property script_show_inputs
//--- input parameters
input double a_par=0; // distribution parameter a (lower bound)
input double b_par=10; // distribution parameter b (upper bound)
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//--- hide the price chart
ChartSetInteger(0,CHART_SHOW,false);
//--- initialize the random number generator
MathSrand(GetTickCount());
//--- generate a sample of the random variable
long chart=0;
string name="GraphicNormal";
int n=1000000; // the number of values in the sample
int ncells=51; // the number of intervals in the histogram
double x[]; // centers of the histogram intervals
double y[]; // the number of values from the sample falling within the interval
double data[]; // sample of random values
double max,min; // the maximum and minimum values in the sample
//--- obtain a sample from the uniform distribution
MathRandomUniform(a_par,b_par,n,data);
//--- calculate the data to plot the histogram
CalculateHistogramArray(data,x,y,max,min,ncells);
//--- obtain the sequence boundaries and the step for plotting the theoretical curve
double step;
GetMaxMinStepValues(max,min,step);
step=MathMin(step,(max-min)/ncells);
//--- obtain the theoretically calculated data at the interval of [min,max]
double x2[];
double y2[];
MathSequence(min,max,step,x2);
MathProbabilityDensityUniform(x2,a_par,b_par,false,y2);
//--- set the scale
double theor_max=y2[ArrayMaximum(y2)];
double sample_max=y[ArrayMaximum(y)];
double k=sample_max/theor_max;
for(int i=0; i<ncells; i++)
y[i]/=k;
//--- output charts
CGraphic graphic;
if(ObjectFind(chart,name)<0)
graphic.Create(chart,name,0,0,0,780,380);
else
graphic.Attach(chart,name);
graphic.BackgroundMain(StringFormat("Uniform distribution a=%G b=%G",a_par,b_par));
graphic.BackgroundMainSize(16);
//--- plot all curves
graphic.CurveAdd(x,y,CURVE_HISTOGRAM,"Sample").HistogramWidth(6);
//--- and now plot the theoretical curve of the distribution density
graphic.CurveAdd(x2,y2,CURVE_LINES,"Theory");
graphic.CurvePlotAll();
//--- plot all curves
graphic.Update();
}
//+------------------------------------------------------------------+
//| Calculate frequencies for data set |
//+------------------------------------------------------------------+
bool CalculateHistogramArray(const double &data[],double &intervals[],double &frequency[],
double &maxv,double &minv,const int cells=10)
{
if(cells<=1) return (false);
int size=ArraySize(data);
if(size<cells*10) return (false);
minv=data[ArrayMinimum(data)];
maxv=data[ArrayMaximum(data)];
double range=maxv-minv;
double width=range/cells;
if(width==0) return false;
ArrayResize(intervals,cells);
ArrayResize(frequency,cells);
//--- define the interval centers
for(int i=0; i<cells; i++)
{
intervals[i]=minv+(i+0.5)*width;
frequency[i]=0;
}
//--- fill the frequencies of falling within the interval
for(int i=0; i<size; i++)
{
int ind=int((data[i]-minv)/width);
if(ind>=cells) ind=cells-1;
frequency[ind]++;
}
return (true);
}
//+------------------------------------------------------------------+
MathProbabilityDensityUniform
Calculates the value of the probability density function of uniform distribution with the a and b
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityUniform(
const double x, // value of random variable
const double a, // distribution parameter a (lower bound)
const double b, // distribution parameter b (upper bound)
const bool log_mode, // calculate the logarithm of the value, if log_mode=true, then the
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of uniform distribution with the a and b
parameters for a random variable x. In case of error it returns NaN.
double MathProbabilityDensityUniform(
const double x, // value of random variable
const double a, // distribution parameter a (lower bound)
const double b, // distribution parameter b (upper bound)
int& error_code // variable to store the error code
);
Calculates the value of the probability density function of uniform distribution with the a and b
parameters for an array of random variables x []. In case of error it returns false. Analog of the dunif()
in R .
bool MathProbabilityDensityUniform(
const double& x[], // array with the values of random variable
const double a, // distribution parameter a (lower bound)
const double b, // distribution parameter b (upper bound)
const bool log_mode, // flag to calculate the logarithm of the value, if log_mode=true,
double& result[] // array for values of the probability density function
);
Calculates the value of the probability density function of uniform distribution with the a and b
parameters for an array of random variables x []. In case of error it returns false.
bool MathProbabilityDensityUniform(
const double& x[], // array with the values of random variable
const double a, // distribution parameter a (lower bound)
const double b, // distribution parameter b (uppe