string str; ... if(str) // will result in "Cannot convert type 'string' to 'bool'" compilation error (no error would appear in the previous versions) Print("str is true");One should use an explicit condition:
string str; ... //--- check if the string is initialized if(str!=NULL) Print("str is true"); or //--- check if the string value is "true" if(StringCompare(str,"true",false)) Print("str is true"); or //--- check if the string is integer and is not equal to zero if((int)str!=0) Print("str is true");
Fixed errors reported in crash logs.
void ArrayPrint( const void& array[], // Printed array uint digits=_Digits, // The number of decimal places const string separator=NULL, // A separator between the values of the structure fields ulong start=0, // The index of the first displayed element ulong count=WHOLE_ARRAY, // The number of displayed elements ulong flags=ARRAYPRINT_HEADER|ARRAYPRINT_INDEX|ARRAYPRINT_LIMIT|ARRAYPRINT_ALIGN );ArrayPrint does not print all fields of a structure array to logs – array fields and pointer fields of objects are skipped. If you want to print all fields of a structure, you should use a custom function for the mass printing with a desired formatting.
//--- Prints the values of the last 10 bars MqlRates rates[]; if(CopyRates(_Symbol,_Period,1,10,rates)) { ArrayPrint(rates); Print("Проверка\n[time]\t[open]\t[high]\t[low]\t[close]\t[tick_volume]\t[spread]\t[real_volume]"); for(int i=0;i<10;i++) { PrintFormat("[%d]\t%s\t%G\t%G\t%G\t%G\t%G\t%G\t%I64d\t",i, TimeToString(rates[i].time,TIME_DATE|TIME_MINUTES|TIME_SECONDS), rates[i].open,rates[i].high,rates[i].low,rates[i].close, rates[i].tick_volume,rates[i].spread,rates[i].real_volume); } } else PrintFormat("CopyRates failed, error code=%d",GetLastError()); //--- A log example /* [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2016.11.09 04:00:00 1.11242 1.12314 1.11187 1.12295 18110 10 17300175000 [1] 2016.11.09 05:00:00 1.12296 1.12825 1.11930 1.12747 17829 9 15632176000 [2] 2016.11.09 06:00:00 1.12747 1.12991 1.12586 1.12744 13458 10 9593492000 [3] 2016.11.09 07:00:00 1.12743 1.12763 1.11988 1.12194 15362 9 12352245000 [4] 2016.11.09 08:00:00 1.12194 1.12262 1.11058 1.11172 16833 9 12961333000 [5] 2016.11.09 09:00:00 1.11173 1.11348 1.10803 1.11052 15933 8 10720384000 [6] 2016.11.09 10:00:00 1.11052 1.11065 1.10289 1.10528 11888 9 8084811000 [7] 2016.11.09 11:00:00 1.10512 1.11041 1.10472 1.10915 7284 10 5087113000 [8] 2016.11.09 12:00:00 1.10915 1.11079 1.10892 1.10904 8710 9 6769629000 [9] 2016.11.09 13:00:00 1.10904 1.10913 1.10223 1.10263 8956 7 7192138000 Check [time] [open] [high] [low] [close] [tick_volume] [spread] [real_volume] [0] 2016.11.09 04:00:00 1.11242 1.12314 1.11187 1.12295 18110 10 17300175000 [1] 2016.11.09 05:00:00 1.12296 1.12825 1.1193 1.12747 17829 9 15632176000 [2] 2016.11.09 06:00:00 1.12747 1.12991 1.12586 1.12744 13458 10 9593492000 [3] 2016.11.09 07:00:00 1.12743 1.12763 1.11988 1.12194 15362 9 12352245000 [4] 2016.11.09 08:00:00 1.12194 1.12262 1.11058 1.11172 16833 9 12961333000 [5] 2016.11.09 09:00:00 1.11173 1.11348 1.10803 1.11052 15933 8 10720384000 [6] 2016.11.09 10:00:00 1.11052 1.11065 1.10289 1.10528 11888 9 8084811000 [7] 2016.11.09 11:00:00 1.10512 1.11041 1.10472 1.10915 7284 10 5087113000 [8] 2016.11.09 12:00:00 1.10915 1.11079 1.10892 1.10904 8710 9 6769629000 [9] 2016.11.09 13:00:00 1.10904 1.10913 1.10223 1.10263 8956 7 7192138000 */
void OnStart() { int arr[]; //--- Amount of memory initially used Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- Amount of memory used for the array of size 1, with a reserve ArrayResize(arr,1,1024*1024); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- After the increase of the array, the amount of memory used will not change due to the reserve ArrayResize(arr,1024*512,1024*1024); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- After reducing the array, the memory size will not change either ArrayResize(arr,1); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); //--- Unused memory will be released after the removal of the reserve ArrayResize(arr,1,-1); Print("Array size:",ArraySize(arr)," Memory used:",MQLInfoInteger(MQL_MEMORY_USED)," MB"); }
#include <Graphics/Graphic.mqh> double Func1(double x) { return MathPow(x,2); } double Func2(double x) { return MathPow(x,3); } double Func3(double x) { return MathPow(x,4); } void OnStart() { GraphPlot(Func1,Func2,Func3,-2,2,0.05,CURVE_LINES); }The result:
#include <Math/Stat/Binomial.mqh> #include <Graphics/Graphic.mqh> void OnStart(void) { double vars[101]; double results[101]; const int N=2000; //--- MathSequence(0,N,20,vars); MathProbabilityDensityBinomial(vars,N,M_PI/10,true,results); ArrayPrint(results,4); GraphPlot(results); //--- }The result:
Updated documentation.
Added tooltips for the Buy, Sell and Close buttons in trade dialogs. The tooltips contain information about the security to be bought or sold during the operation, to help beginners understand the trading process.
An MQL5 version of the ALGLIB numerical analysis library has been included into the Standard Library.
Library Features
How to Use
ALGLIB files are located in \MQL5\Include\Math\Alglib. To use the functions, add the main library file into your program:
Mathematical statistics functions have been included into the Standard Library. MQL5 now provides the functionality of the R language, which is one of the best tools for statistical data processing and analysis.
Library Features
The statistical library contains functions for calculating the statistical characteristics of data, as well as functions for operations with statistical distributions:
How to Use
The statistical library files are located in \MQL5\Include\Math\Stat. To use the library, add the file with required functions into your program, for example:
#include <Math\Stat\Binomal.mqh> #include <Math\Stat\Cauchy.mqh>
The detailed description of the library functions is available in the article Statistical Distributions in MQL5 - Taking the Best of R.
The MQL5 version of the Fuzzy library has been included into the Standard Library. The Fuzzy library implements Mamdani and Sugeno fuzzy inference systems.
Library Features
How to Use
Fuzzy Library files are located in \MQL5\Include\Math\Fuzzy. To use the library, add the file with required functions into your program, for example:
#include <Math\Fuzzy\mamdanifuzzysystem.mqh> #include <Math\Fuzzy\sugenofuzzysystem.mqh>
A detailed description of the library is available in the Code Base: Fuzzy - library for developing fuzzy models
long FileLoad( const string filename, // [in] File name void &buffer[], // [out] An array to which the file is read uint common_flag=0 // [in] 0 - search for the file in the Files folder of the terminal, FILE_COMMON - search in the common directory of terminals ); bool FileSave( const string filename, // [in] File name const void &buffer[], // [in] An array to which the file is saved uint common_flag=0 // [in] 0 - create a file in the Files folder of the terminal, FILE_COMMON - create in the common directory of terminals );An example of how to write ticks to a file and then read them:
//--- input parameters input int ticks_to_save=1000; // Number of ticks //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { string filename=_Symbol+"_ticks.bin"; MqlTick ticks[]; //--- int copied=CopyTicks(_Symbol,ticks,COPY_TICKS_ALL,0,ticks_to_save); if(copied!=-1) { PrintFormat(" CopyTicks(%s) copied %d ticks",_Symbol,copied); //--- If the tick history is synchronized, the error code is equal to zero if(!GetLastError()==0) PrintFormat("%s: Ticks are not synchronized. Error=",_Symbol,copied,_LastError); //--- Writing ticks to a file if(!FileSave(filename,ticks,FILE_COMMON)) PrintFormat("FileSave() failed, error=%d",GetLastError()); } else PrintFormat("Failed CopyTicks(%s), Error=",_Symbol,GetLastError()); //--- Now reading the ticks back to the file ArrayFree(ticks); long count=FileLoad(filename,ticks,FILE_COMMON); if(count!=-1) { Print("Time\tBid\tAsk\tLast\tVolume\tms\tflags"); for(int i=0;i<count;i++) { PrintFormat("%s.%03I64u:\t%G\t%G\t%G\t%I64u\t0x%04x", TimeToString(ticks[i].time,TIME_DATE|TIME_SECONDS),ticks[i].time_msc%1000, ticks[i].bid,ticks[i].ask,ticks[i].last,ticks[i].volume,ticks[i].flags); } } }
//--- Candlesticks painted in the same color #property indicator_label1 "One color candles" #property indicator_type1 DRAW_CANDLES //--- Only one color is specified, so all candlesticks are the same color #property indicator_color1 clrGreenIf two colors are specified, one color is used for candlestick edges, the other one is used for the body.
//--- The color of the candlesticks differs from the color of shadows #property indicator_label1 "Two color candles" #property indicator_type1 DRAW_CANDLES //--- Candlestick edges and shadows are green, body is white #property indicator_color1 clrGreen,clrWhiteIf three colors are specified, one color is used for candlestick edges, two other colors are used for the bodies of bullish and bearish candlesticks.
//--- The color of the candlesticks differs from the color of shadows #property indicator_label1 "One color candles" #property indicator_type1 DRAW_CANDLES //--- Candlestick edges and shadows are green, the body of a bullish candle is white, the body of a bearish candle is red #property indicator_color1 clrGreen,clrWhite,clrRedThe DRAW_CANDLES style allows setting custom colors of candlesticks. All colors can also be changed dynamically while the indicator is running, using the function PlotIndexSetInteger(drawing_index_DRAW_CANDLES, PLOT_LINE_COLOR, modifier_number, color) where modifier_number can have the following values:
//--- Setting the color of edges and shadows PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,clrBlue); //--- Setting the color of the bullish candlestick body PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,clrGreen); //--- Setting the color of the bearish candlestick body PlotIndexSetInteger(0,PLOT_LINE_COLOR,2,clrRed);
Updated documentation.
class CFoo final { //--- class body }; class CBar : public CFoo { //--- class body };When attempting to inherit from a class with the 'final' modifier as shown above, the compiler displays an error:
class CFoo { void virtual func(int x) const { } };The method is overridden in the inherited class:
class CBar : public CFoo { void func(short x) { } };But the argument type is mistakenly changed from 'int' to 'short'. In fact, the method overload instead of overriding is performed in that case. While acting according to the overloaded function definition algorithm, the compiler may in some cases select a method defined in the base class instead of an overridden one.
class CBar : public CFoo { void func(short x) override { } };If the method signature is changed during the overriding process, the compiler cannot find the method with the same signature in the parent class issuing the compilation error:
class CFoo { void virtual func(int x) final { } }; class CBar : public CFoo { void func(int) { } };When attempting to override a method with the 'final' modifier as shown above, the compiler displays an error:
Updated documentation.
class CFoo { }; class CBar { }; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { void *vptr[2]; vptr[0]=new CFoo(); vptr[1]=new CBar(); //--- for(int i=0;i<ArraySize(vptr);i++) { if(dynamic_cast<CFoo *>(vptr[i])!=NULL) Print("CFoo * object at index ",i); if(dynamic_cast<CBar *>(vptr[i])!=NULL) Print("CBar * object at index ",i); } CFoo *fptr=vptr[1]; // Will return an error while casting pointers, vptr[1] is not an object of CFoo } //+------------------------------------------------------------------+
string text="Hello"; ushort symb=text[0]; // Will return the code of symbol 'H'
Updated documentation.
Fixed calculation of commission as a percentage per annum during testing.
Fixed calculation and display of balance on the chart generated in the process of testing.
After two months of public testing, the web version of the multi-asset MetaTrader 5 platform has been officially released. It allows trading Forex and exchanges from any browser and operating system. Only Internet connection is necessary, no software installation is required.
The application combines the key advantages of the desktop platform (high speed, support for multiple markets and expanded trading functions) with the convenience of the cross-platform nature of the web terminal. The key feature of the release version is the depth of market, which was not present in the beta version.
The web platform allows traders to perform technical analysis and
trading operations just like in the desktop version. The web platform
provides the following features:
It is now much easier to transfer SSL certificates from the desktop platform to the mobile one. You no longer need iTunes to do that.
MetaTrader 5 allows you to add an extra protection to your account by using a certificate. Without the certificate, connection is impossible. If the certificate was created in the desktop version, you should transfer it to be able to enter your account via a mobile device.
To do this, open a desktop platform, right-click the necessary account in the Navigator window, and select Transfer. Set the certificate password which is known only to you, open the mobile platform, and connect to your account. You will be immediately offered to import the certificate.
Besides, the latest version features the migration dialog for accounts transferred from MetaTrader 4. If your account has been transferred to the 5th generation platform, you are warmly greeted, provided with information on the new features, and offered to change your password.
Before |
After |
|
---|---|---|
Triggering | Bid/Ask for all types of Pending Orders and SL/TP |
Bid/Ask for Limit Orders Last for Stop, Stop-Limit and SL/TP orders |
Execution | The price specified in the order for all types of Pending Orders and SL/TP |
Bid/Ask at the time of order triggering for all types of Pending Orders and SL/TP |
Let us consider an example of the Si-6.16 symbol. A new Buy Stop
order with the trigger price = 72580 is set while the current prices
are: Bid=72570, Ask=72572, Last=72552. New current prices are received
in a price stream:
A trigger for Stop-Orders of exchange instruments is the Last
price. So the Last price=72580 received in the stream activates the Buy
Stop order. In the earlier versions, the same price would be used to
execute this order. This behavior is incorrect, because there is no
Ask=72580 in the market to execute the Buy transaction.
Fixed errors reported in crash logs.
The beta version of the MetaTrader 5 Web Platform has been released. The new product combines convenience and cross-platform nature of the web terminal with the advantages of the desktop version of MetaTrader 5 – speed, support for multiple markets, and expanded trading functions.
The MetaTrader 5 web platform is available on the MQL5.community, and it allows traders to perform trading operation on financial markets from any browser and any operating system, including Windows, Mac, and Linux. You only need to have an Internet connection. No additional software is required.
The following features are available in the beta version:
Netting system
With this system, you can have only one common position for a symbol at the same time:
It does not matter, what has caused the opposite deal — an executed market order or a triggered pending order.
The below example shows execution of two EURUSD Buy deals 0.5 lots each:
Execution of both deals resulted in one common position of 1 lot.
Hedging system
With this system, you can have multiple open positions of one and the same symbol, including opposite position.
If you have an open position for a symbol, and execute a new deal
(or a pending order triggers), a new position is additionally opened.
Your current position does not change.
The below example shows execution of two EURUSD Buy deals 0.5 lots each:
Execution of these deals resulted in opening two separate positions.
New trade operation type - Close By
The new trade operation type has been added for hedging accounts —
closing a position by an opposite one. This operation allows closing
two oppositely directed positions at a single symbol. If the opposite
positions have different numbers of lots, only one order of the two
remains open. Its volume will be equal to the difference of lots of the
closed positions, while the position direction and open price will match
(by volume) the greater of the closed positions.
Compared with a single closure of the two positions, the closing
by an opposite position allows traders to save one spread:
In the latter case, a "close by" order is placed. Tickets of closed positions are specified in its comment. A pair of opposite positions is closed by two "out by" deals. Total profit/loss resulting from closing the both positions is specified only in one deal.
The tickets of orders and positions
(including history orders) are not preserved during import, because one
history record from MetaTrader 4 can be imported as up to 4 history
operations in MetaTrader 5. New tickets are assigned to all trading
records.
The account numbers can be preserved or replaced depending on how the broker imports them.
class CAnimal { public: CAnimal(); // Constructor virtual void Sound() = 0; // A pure virtual function private: double m_legs_count; // How many feet the animal has };Here Sound() is a pure virtual function, because it is declared with the specifier of the pure virtual function PURE (=0).
class CAnimal { public: virtual void Sound()=NULL; // PURE method, should be overridden in the derived class, CAnimal is now abstract and cannot be created }; //--- Derived from an abstract class class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // PURE is overridden, CCat is not abstract and can be created }; //--- examples of wrong use new CAnimal; // Error of 'CAnimal' - the compiler returns the "cannot instantiate abstract class" error CAnimal some_animal; // Error of 'CAnimal' - the compiler returns the "cannot instantiate abstract class" error //--- examples of correct use new CCat; // no error - the CCat class is not abstract CCat cat; // no error - the CCat class is not abstractRestrictions on abstract classes
//+------------------------------------------------------------------+ //| 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 purely virtual //--- the call causes the "pure virtual function call" critical execution error } };However, constructors and destructors for abstract classes can call other member functions.
typedef int (*TFunc)(int,int);Now, TFunc is a type, and it is possible to declare the variable pointer to the function:
TFunc func_ptr;The func_ptr variable may store the function address to declare it later:
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // error: neg is not of int (int,int) type Print(func_ptr(10)); // error: there should be two parametersPointers to functions can be stored and passed as parameters. You cannot get a pointer to a non-static class method.
ulong PositionGetTicket( int index // index in the list of positions );
bool PositionSelectByTicket(
ulong ticket // position ticket
);
Netting system
With this system, you can have only one common position for a symbol at
the same time:
It does not matter, what has caused the opposite deal — an executed market
order or a triggered pending order.
The below example shows execution of two EURUSD Buy deal 0.5 lots each:
Execution of both deals resulted in one common position of 1 lot.
Hedging system
With this system, you can have multiple open positions of one and the same
symbol, including opposite position.
If you have an open position for a symbol, and execute a new deal (or a
pending order triggers), a new position is additionally opened. Your current
position does not change.
The below example shows execution of two EURUSD Buy deal 0.5 lots each:
Execution of these deals resulted in opening two separate positions.
New trade operation type - Close By
The new trade operation type has been added for hedging accounts — closing
a position by an opposite one. This operation allows closing two oppositely
directed positions at a single symbol. If the opposite positions have different
numbers of lots, only one order of the two remains open. Its volume will
be equal to the difference of lots of the closed positions, while the position
direction and open price will match (by volume) the greater of the closed
positions.
Compared with a single closure of the two positions, the closing by an
opposite position allows traders to save one spread:
In the latter case, a "close by" order is placed. Tickets of closed positions are specified in its comment. A pair of opposite positions is closed by two "out by" deals. Total profit/loss resulting from closing the both positions is specified only in one deal.
class CAnimal { public: CAnimal(); // constructor virtual void Sound() = 0; // pure virtual function private: double m_legs_count; // number of animal legs };Here Sound() is a pure virtual function, because it is declared with the specifier of the pure virtual function PURE (=0).
class CAnimal { public: virtual void Sound()=NULL; // PURE method, should be overridden in the derived class, CAnimal is now abstract and cannot be created }; //--- descendant from the abstract class class CCat : public CAnimal { public: virtual void Sound() { Print("Myau"); } // PURE is overridden, CCat is not abstract and can be created }; //--- examples of wrong use new CAnimal; // Error of 'CAnimal' - the compiler returns the "cannot instantiate abstract class" error CAnimal some_animal; // Error of 'CAnimal' - the compiler returns the "cannot instantiate abstract class" error //--- examples of correct use new CCat; // no error - the CCat class is not abstract CCat cat; // no error - the CCat class is not abstractRestrictions on abstract classes
//+------------------------------------------------------------------+ //| 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 purely virtual //--- the call causes the "pure virtual function call" critical execution error } };However, constructors and destructors for abstract classes can call other member functions.
typedef int (*TFunc)(int,int);Now, TFunc is a type, and it is possible to declare the variable pointer to the function:
TFunc func_ptr;The func_ptr variable may store the function address to declare it later:
int sub(int x,int y) { return(x-y); } int add(int x,int y) { return(x+y); } int neg(int x) { return(~x); } func_ptr=sub; Print(func_ptr(10,5)); func_ptr=add; Print(func_ptr(10,5)); func_ptr=neg; // error: neg is not of int (int,int) type Print(func_ptr(10)); // error: there should be two parametersPointers to functions can be stored and passed as parameters. You cannot get a pointer to a non-static class method.
ulong PositionGetTicket( int index // index in the list of positions );
bool PositionSelectByTicket(
ulong ticket // position ticket
);
The new position accounting system is similar to that of MetaTrader 4, combined with all the advantages of the fifth-generation platform — execution of orders using multiple deals (including partial filling), stop-limit orders, and more.
Update the platform right now to see how the hedging option works. When opening a new demo account, enable the \"Use hedge\" option. The option will be available if your broker's server has already been updated and configured.