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 Trade Master 9 – speed, support for multiple markets, and expanded trading functions.
The Trade Master 9 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 Trade Master 9. 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.
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.
MetaEditor: Added a link to the tutorial video "How to Create a Trading Robot in the MQL5 Wizard" to the MQL5 Wizard. Watch this three-minute video and develop a trading robot without writing a single line of code.
2015.10.14 14:48:18.486 Data Folder: C:\Program Files\Trade Master 9 2015.10.14 14:48:18.486 Windows 7 Professional (x64 based PC), IE 11.00, UAC, 8 x Intel Core i7 920 @ 2.67GHz, RAM: 8116 / 12277 Mb, HDD: 534262 / 753865 Mb, GMT+03:00 2015.10.14 14:48:18.486 Trade Master 9 build 1190 started (MetaQuotes Software Corp.)
struct MqlTick { datetime time; // Time of a price last update double bid; // Current Bid price double ask; // Current Ask price double last; // Current Last price ulong volume; // Volume for the current Last price long time_msc; // Time of a price last update in milliseconds uint flags; // Tick flags };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 Ask price, volume, etc. You can analyze the tick flags to find out what data have been changed exactly:
//+------------------------------------------------------------------+ //| TemplTest.mq5 | //| Copyright 2015, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2015, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| Declare a template class | //+------------------------------------------------------------------+ template<typename T> class TArray { protected: T m_data[]; public: bool Append(T item) { int new_size=ArraySize(m_data)+1; int reserve =(new_size/2+15)&~15; //--- if(ArrayResize(m_data,new_size,reserve)!=new_size) return(false); //--- m_data[new_size-1]=item; return(true); } T operator[](int index) { static T invalid_index; //--- if(index<0 || index>=ArraySize(m_data)) return(invalid_index); //--- return(m_data[index]); } }; //+------------------------------------------------------------------+ //| Template class of a pointer array. In the destructor, it deletes | //| the objects, the pointers to which were stored in the array. | //| | //| Please note the inheritance from the TArray template class | //+------------------------------------------------------------------+ template<typename T> class TArrayPtr : public TArray<T *> { public: void ~TArrayPtr() { for(int n=0,count=ArraySize(m_data);n<count;n++) if(CheckPointer(m_data[n])==POINTER_DYNAMIC) delete m_data[n]; } }; //+--------------------------------------------------------------------------+ //| Declare the class. Pointers to its objects will be stored in the array | //+--------------------------------------------------------------------------+ class CFoo { int m_x; public: CFoo(int x):m_x(x) { } int X(void) const { return(m_x); } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ TArray<int> ExtIntArray; // instantiate TArray (specialize TArray by the int type) TArray<double> ExtDblArray; // instantiate TArray (specialize TArray by the double type) TArrayPtr<CFoo> ExtPtrArray; // instantiate TArrayPtr (specialize TArrayPtr by the CFoo type) //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- fill arrays with data for(int i=0;i<10;i++) { int integer=i+10; ExtIntArray.Append(integer); double dbl=i+20.0; ExtDblArray.Append(dbl); CFoo *ptr=new CFoo(i+30); ExtPtrArray.Append(ptr); } //--- output the array contents string str="Int:"; for(int i=0;i<10;i++) str+=" "+(string)ExtIntArray[i]; Print(str); str="Dbl:"; for(int i=0;i<10;i++) str+=" "+DoubleToString(ExtDblArray[i],1); Print(str); str="Ptr:"; for(int i=0;i<10;i++) str+=" "+(string)ExtPtrArray[i].X(); Print(str); //--- CFoo objects created via new should not be deleted, since they are deleted in the TArrayPtr<CFoo> object destructor }Execution result:
int ObjectsDeleteAll( long chart_id, // chart ID const string prefix, // object name prefix int sub_window=-1, // window index int object_type=-1 // object type for deletion );
Updated documentation.