mql4


We do remember that: multi-line comments start with the /* pair of symbols and end with the */ one. Such kind 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:
//--- Single-line comment

/* Multi-
line // Nested single-line comment comment
*/

I need write some function on mql4 code to open trading position on forex chart. In this case I write mql4 code for open BUY and SELL order by OrderSend () function - open market order. There are incliding parameters whitch I want to use. This parameters are specified in "()". I can use all parameters including function "OrderSend".


int OrderSend ( string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment=NULL, int magic=0, datetime expiration=0, color arrow_color=CLR_NONE);

ticket ::: Order index or order ticket depending on the second parameter.
select ::: Selecting flags. It can be any of the following values:
SELECT_BY_POS - index in the order pool,
SELECT_BY_TICKET - index is order ticket.
pool=MODE_TRADES ::: Optional order pool index. Used when the selected parameter is SELECT_BY_POS. It can be any of the following values:
MODE_TRADES (default)- order selected from trading pool(opened and pending orders),
MODE_HISTORY - order selected from history pool (closed and canceled order).

For example: type of order, lot amount, StopLoss, TakeProfit, magic number of order. However I can use all paremeters.
I write:


int OpenPendingOrder( int pType,double pLots,double pLevel,int sp,double pr,int sl,int tp,string comm,int pMagic,color pColor ){
int ticket = 0;
if ( pType == 0) /*0 - BUY order according mql4 including function*/
{
ticket = OrderSend( Symbol(), OP_BUY, pLots, Ask, sp, Bid, sl, comm, pMagic, 0, pColor );
}
else /* 1 - SELL order according mql4 including function */
{
ticket = OrderSend( Symbol(), OP_SELL, pLots, Bid, sp, Ask, sl, comm, pMagic, 0, pColor);
}
return ( ticket );
}


We have many open orders and is need to know how much it is. So, I need calculate amount of open orders. I do this by OrderSelect () function.
I write:



bool OrderSelect( int index, int select, int pool=MODE_TRADES );

ticket ::: Order index or order ticket depending on the second parameter.
select ::: Selecting flags. It can be any of the following values:
SELECT_BY_POS - index in the order pool,
SELECT_BY_TICKET - index is order ticket.
pool=MODE_TRADES ::: Optional order pool index. Used when the selected parameter is SELECT_BY_POS.
It can be any of the following values:
MODE_TRADES (default) - order selected from trading pool(opened and pending orders),
MODE_HISTORY - order selected from history pool (closed and canceled order).


int CountTrades() // the name of my function
{
int count = 0; // the value
for (int trade = OrdersTotal() - 1; trade >= 0; trade--) // I do recalculation of all open positions
{
if (OrderSelect(trade, SELECT_BY_POS, MODE_TRADES) == TRUE)
if (OrderMagicNumber() != MagicNumber) continue; // if order magic number is not equal Magic Number - go to next
if (OrderMagicNumber() == MagicNumber) // yea! order magic number is select
if (OrderType() == OP_SELL || OrderType() == OP_BUY) count++; // do count +1;
}
return ( count ); // after the function is entering amount of all orders
}

In other time I need to calculate not only the number of orders, but also the amount of profit by each open order (it means OrderProfit() + OrderCommision() + OrderSwap()). I do the calculation by one of magic numbers. For example, only one magic number using one expert advisor (One expert advisor can control many orders, many magic numbers). So, I write next:


double CalculateProfit()
{
double Profit = 0;
for (cnt = OrdersTotal() - 1; cnt >= 0; cnt--)
{
if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES) == TRUE)
if (OrderMagicNumber() != MagicNumber) continue;
if (OrderMagicNumber() == MagicNumber)
if (OrderType() == OP_BUY || OrderType() == OP_SELL) Profit += OrderProfit() + OrderCommision() + OrderSwap();
}
return ( Profit );
}


I have one function on H4 graph, which open the orders by iMA signals ( iMA - Calculates the Moving Average indicator and returns its value ). Today I wrote a function to close this orders by iMA too. This function is located inside the mane code. So, what I have?
The simple function to close orders by iMA by market price.


double iMA( string symbol, int timeframe, int ma_period, int ma_shift, int ma_method, int applied_price, int shift );

symbol ::: Symbol name on the data of which the indicator will be calculated. NULL means the current symbol.
timeframe ::: Timeframe. It can be any of ENUM_TIMEFRAMES enumeration values. 0 means the current chart timeframe.
ma_period ::: Averaging period for calculation.
ma_shift ::: MA shift. Indicators line offset relate to the chart by timeframe.
ma_method ::: Moving Average method. It can be any of ENUM_MA_METHOD enumeration values.
applied_price ::: Applied price. It can be any of ENUM_APPLIED_PRICE enumeration values.
shift ::: Index of the value taken from the indicator buffer (shift relative to the current bar the given amount of periods ago).


bool order_close_position = TRUE;
...

if ( order_close_position )
{
for (int trade = OrdersTotal()-1; trade >= 0; trade--)
{
if (OrderSelect( trade, SELECT_BY_POS, MODE_TRADES) )
{
if (OrderSymbol() == MY_SYMBOL )
{

if ( OrderMagicNumber() == mg_b && OrderType() == OP_BUY)
{
if ( OrderProfit() > 0 && Ask > OrderOpenPrice() )
{
if (
iMA (MY_SYMBOL, 240, 13, 0, 0, 0, 1) < iOpen(MY_SYMBOL, 240, 1) && iMA (MY_SYMBOL, 240, 13, 0, 0, 0, 1) > iClose(MY_SYMBOL, 240, 1)
)
if ( Open[1] > Close[1] )
{
//if ( (Minute() == 0 || Minute() == 30 /*|| Minute() == 15 || Minute() == 45*/) )
{
if (OrderClose( OrderTicket() , OrderLots(), MarketInfo( MY_SYMBOL,MODE_BID ), slip, Blue) == true) break;
}
}
}
}

if ( OrderType() == OP_SELL && OrderMagicNumber() == mg_s )
{
if ( OrderProfit() > 0 && Bid < OrderOpenPrice() )
{
if (
iMA (MY_SYMBOL, 240, 9, 0, 0, 0, 1) < iClose(MY_SYMBOL, 240, 1) && iMA (MY_SYMBOL, 240, 9, 0, 0, 0, 1) > iClose(MY_SYMBOL, 240, 1)
)
if ( Close[1] > Open[1] )
{
//if ( (Minute() == 0 || Minute() == 30 /*|| Minute() == 15 || Minute() == 45*/) )
{
if (OrderClose( OrderTicket() , OrderLots(), MarketInfo( MY_SYMBOL,MODE_ASK ), slip, Blue) == true) break;
}
}
}
}
}
}
}
}

...


Using the function I have been wrote before in this page I can create a new function to calculate profit of all closed orders in the trade history. For example, I need to know how many profit I received up over the last 2 weeks. So, I need 2 time: the time begining and the time end.
In this case I used "OrderSelect ()" function with a pool parameter: "MODE_HISTORY".


double Result_2 ( datetime dt1, datetime dt2 )
{
double profit = 0;
for ( int i = 0; i < OrdersHistoryTotal(); i++ )
{
if ( OrderSelect( i, SELECT_BY_POS, MODE_HISTORY ))
{
if ( OrderClosePrice() == 0 ) continue;
if ( OrderCloseTime() < dt1 || OrderCloseTime() > dt2 ) continue;
profit += OrderProfit() + OrderCommission() + OrderSwap() ;
}
}
return ( profit );
}

If I need amount of profit only one symbol current - I'll add one parameter to select what I need: "string symbol" and use it inside this function.


double Result_2 ( datetime dt1, datetime dt2, string symbol )
{
profit = 0;
for ( int i = 0; i < OrdersHistoryTotal(); i++ )
{
if ( OrderSelect( i, SELECT_BY_POS, MODE_HISTORY ))
{
if ( OrderClosePrice() == 0 ) continue;
if ( OrderCloseTime() < dt1 || OrderCloseTime() > dt2 ) continue;



if ( OrderSymbol() == symbol ) // here use "EURUSD", "GBPUSD", "USDJPY", ..



profit += OrderProfit() + OrderCommission() + OrderSwap() ;
}
}
return ( profit );
}

In this case are calculated orders by OrderCloseTime() parameter in history. All orders have many parameters: ticket, orderopentime, price, lot, stoploss and other.

How can I use this function? very simple:

Result_2 ( iTime( Symbol(), PERIOD_W1, 1 ), iTime( Symbol(), PERIOD_W1, 0 ), Symbol() );
If I write " Symbol() " - it will be current symbol on chart, but I can use "USDCHF" or another symbol.

Why iTime? - because this function returns Time value for the bar of specified symbol with timeframe and shift.

So, iTime( Symbol(), PERIOD_W1, 1 ) - return a value the beginning of last week from first seconds. iTime( Symbol(), PERIOD_W1, 0 ) - return a value current time.


datetime iTime( string symbol, int timeframe, int shift );

Parameters:
symbol ::: Symbol name. NULL means the current symbol.
timeframe ::: Timeframe. It can be any of ENUM_TIMEFRAMES enumeration values. 0 means the current chart timeframe.
shift ::: Index of the value taken from the indicator buffer (shift relative to the current bar the given amount of periods ago).

However timeframe:

ENUM_TIMEFRAMES
PERIOD_M1 - Value 1 - 1 minute
PERIOD_M5 - Value 5 - 5 minutes
PERIOD_M15 - Value 15 - 15 minutes
PERIOD_M30 - Value 30 - 30 minutes
PERIOD_H1 - Value 60 - 1 hour
PERIOD_H4 - Value 240 - 4 hours
PERIOD_D1 - Value 1440 - 1 day
PERIOD_W1 - Value 10080 - 1 week
PERIOD_MN1 - Value 43200 - month

And, Result_2 ( iTime( Symbol(), PERIOD_W1, 1 ), iTime( Symbol(), PERIOD_W1, 0 ), Symbol() ) can be Result_2 ( iTime( Symbol(), 10080, 1 ), iTime( Symbol(), 10080, 0 ), Symbol() ). That's simple, right?


An expert advisor trade on my forex trading account and sometime I open orders by myself. How I can discern these orders? I can write comment (in special field "Comment") for each market order OR I can use MagicNumber for each orders.

Comment ::: This function outputs a comment defined by a user in the top left corner of a chart. Comments are displayed in MT4 in the "Terminal" window ( MT4 menu Viev - Termonal ), the "Trade" section, press on right mouse button on free space and select "Comment".
MQL4 code be able to set the special parameter for each market order ( except was opened by hand, by myself ), like MagicNumber. In another case the Forex Broker can to see all of orders which have been open by expert or client ( which have been open from client's MT4 terminal ). They have special notes "expert" or "client" in MetaTrader 4 Manager.

In short. If order have been open by myself = MagicNumber is "0".

I write:

if ( OrderMagicNumber() == 0 ) OR I can set this parameter in name of this function: double Result_2 ( datetime dt1, datetime dt2, string symbol, int MagicNumber )


double Result_2 ( datetime dt1, datetime dt2, string symbol, int MagicNumber )
{
profit = 0;
for ( int i = 0; i < OrdersHistoryTotal(); i++ )
{
if ( OrderSelect(i, SELECT_BY_POS, MODE_HISTORY ))
{
if ( OrderClosePrice() == 0 ) continue;
if ( OrderCloseTime() < dt1 || OrderCloseTime() > dt2 ) continue;



if ( MagicNumber == 0 )



profit += OrderProfit() + OrderCommission() + OrderSwap() ;
}
}
return ( profit );
}

Good. But I want to calculate all my withdrawals of profit in History. I know that OrderType() == OP_BUY - that "0", OrderType() == OP_SELL - that "1".


OrderType - Returns order operation type of the currently selected order.
int OrderType();
Returned value

Order operation type of the currently selected order. It can be any of the following values:

OP_BUY - buy order - value 0,
OP_SELL - sell order - value 1,
OP_BUYLIMIT - buy limit pending order - value 2,
OP_BUYSTOP - buy stop pending order - value 3,
OP_SELLLIMIT - sell limit pending order - value 4,
OP_SELLSTOP - sell stop pending order - value 5.

BUT value 6 - is balance operation.

So, what I have now? if ( OrderType () == 6 && OrderProfit () < 0 ) - good.

In this case a function return the amount calculation of balance operations in History which less then 0 - that is withdrawals orders.


double Result_2 ( datetime dt1, datetime dt2, string symbol, int MagicNumber )
{
profit = 0;
for ( int i = 0; i < OrdersHistoryTotal(); i++ )
{
if ( OrderSelect(i, SELECT_BY_POS, MODE_HISTORY ))
{
if ( OrderClosePrice() == 0 ) continue;
if ( OrderCloseTime() < dt1 || OrderCloseTime() > dt2 ) continue;



if ( MagicNumber == 0 )



if ( OrderType () == 6 && OrderProfit () < 0 )



profit += OrderProfit();



}
}
return ( profit );
}

Many time ago I looking for ideas to create new code for expert advisor. In this time a forex robot work. One time in the week I chech closed orders in the history and to calculate on paper amount of profits. A wile I create a simple mql4 function to calculate automatically.
It's so simple for mql4 code.

This function return a double type value ( 78.454534, 12.475435435, 78.6267567 ).

I write:


double Result_of_closed_positions ( datetime dt1, datetime dt2 )
{
double r = 0;
for ( int i = 0; i < OrdersHistoryTotal(); i++ )
{
if ( OrderSelect ( i, SELECT_BY_POS, MODE_HISTORY ) )
{
if ( OrderClosePrice() == 0 ) continue;
if ( ( OrderCloseTime() < dt1 ) || ( OrderCloseTime() > dt2 ) ) continue;
r = NormalizeDouble ( r + OrderProfit() + OrderCommission() + OrderSwap(), 2 );
}
}
return(r);
}

I use NormalizeDouble () function to rounding floating point number to a specified accuracy. I can set a parrameter digits what I want.


NormalizeDouble - Rounding floating point number to a specified accuracy.

double NormalizeDouble ( double value, int digits );

Parameters
Value ::: with a floating point.
digits ::: Accuracy format, number of digits after point (0-8).

Return Value
Value of double type with preset accuracy.

Note
Calculated values of StopLoss, TakeProfit, 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.

So, how can I use this function in my robot code? look on



double Result_of_closed_positions ( iTime ( Symbol (), PERIOD_W1, 1 ), iTime ( Symbol (), PERIOD_W1, 0 ) )

iTime ( Symbol (), PERIOD_W1, 1 ) - the start time of the last week

iTime ( Symbol (), PERIOD_W1, 0 ) - the start time of current week

or

iTime ( Symbol (), PERIOD_D1, 1 ) - the start time of the last day

iTime ( Symbol (), PERIOD_D1, 0 ) - the start time of the tooday

or

TimeCurrent () - time is now, this is mql4 built-in function



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 marks 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.

With literal date specification, it is desirable that you specify year, month and day. Otherwise the compiler returns a warning about an incomplete entry.

And when I write:

double Result_of_closed_positions ( iTime ( Symbol (), PERIOD_W1, 1 ), iTime ( Symbol (), PERIOD_W1, 0 ) ) / AccountBalance () * 100 % - I found a percent of profit money in this time.

For example, my profit $784, Account Depo is $5671, so = 784 / 5671 * 100 % = 13.82 %



featured post

the expert advisor "XAU_GOLD_v3.056"