Orders Execution
Miscellaneous
0
Views
0
Downloads
0
Favorites
OrderExample
//+------------------------------------------------------------------+
//| OrderExample.mq5 |
//| Copyright 2016, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2016, MetaQuotes Software Corp. ~ edited By 3rjfx : 2016/01/29"
#property link "http://www.mql5.com"
#property version "1.00"
//--
#property description "Expert Advisor for sending trade requests using OrderSendAsync() function.\r\n"
#property description "Handling trading events using OnTrade() handler functions is displayed\r\n"
#property description "Expert Advisor parameters allow setting Magic Number (unique Expert ID)"
//---
#include <Trade\Trade.mqh>
//---
//--- input parameters
input int MagicNumber = 1234567; // Expert Advisor ID
input double RiskPercentage = 1.0; // Risk Percentage
input double TPvsSLRatio = 1.5; // multiplication SL to TP Ratio
input bool CalculatedTradeSize = true; // Automatic calculate Lots size
input string ManualyLotsSize = "If Set CalculatedTradeSize = False, Input TradeLotSize Below";
input double TradeLotSize = 0.1; // Input Lots Size manualy
//--
//--- variable for using in HistorySelect() call
datetime history_start;
//--
//----//
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- check if autotrading is allowed
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
{
Alert("Autotrading in the terminal is disabled, Expert Advisor will be removed.");
ExpertRemove();
return(-1);
}
//--- unable to trade on a real account // If the EA is used in the Real Account, the code at line 54 to 59 must be removed like this
/*
if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
{
Alert("Expert Advisor cannot trade on a real account!");
ExpertRemove();
return(-2);
}
*/
//--- check if it is possible to trade on this account (for example, trading is impossible when using an investor password)
if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED))
{
Alert("Trading on this account is disabled");
ExpertRemove();
return(-3);
}
//--- save the time of launching the Expert Advisor for receiving trading history
history_start=TimeCurrent();
//---
CreateBuySellButtons();
return(INIT_SUCCEEDED);
}
//----//
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- delete all graphical objects
ObjectDelete(0,"Buy");
ObjectDelete(0,"Sell");
//---
}
//----//
//+------------------------------------------------------------------+
//| Trade function |
//+------------------------------------------------------------------+
void OnTrade()
{
//--- static members for storing trading account status
static int prev_positions=0,prev_orders=0,prev_deals=0,prev_history_orders=0;
//--- request trading history
bool update=HistorySelect(history_start,TimeCurrent());
PrintFormat("HistorySelect(%s , %s) = %s",
TimeToString(history_start),TimeToString(TimeCurrent()),(string)update);
//--- heading named after trading event's handler function
Print("=> ",__FUNCTION__," at ",TimeToString(TimeCurrent(),TIME_SECONDS));
//--- display handler's name and the number of orders at the moment of handling
int curr_positions=PositionsTotal();
int curr_orders=OrdersTotal();
int curr_deals=HistoryOrdersTotal();
int curr_history_orders=HistoryDealsTotal();
//--- display the number of orders, positions, deals, as well as changes in parentheses
PrintFormat("PositionsTotal() = %d (%+d)",
curr_positions,(curr_positions-prev_positions));
PrintFormat("OrdersTotal() = %d (%+d)",
curr_orders,curr_orders-prev_orders);
PrintFormat("HistoryOrdersTotal() = %d (%+d)",
curr_deals,curr_deals-prev_deals);
PrintFormat("HistoryDealsTotal() = %d (%+d)",
curr_history_orders,curr_history_orders-prev_history_orders);
//--- insert a string break to view the log more conveniently
Print("");
//--- save the account status
prev_positions=curr_positions;
prev_orders=curr_orders;
prev_deals=curr_deals;
prev_history_orders=curr_history_orders;
//---
}
//----//
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- handling CHARTEVENT_CLICK event ("Clicking the chart")
if(id==CHARTEVENT_OBJECT_CLICK)
{
Print("=> ",__FUNCTION__,": sparam = ",sparam);
//--- deal BUY at price
double size=TradeSize();
//--- if "Buy" button is pressed, then buy
if(sparam=="Buy")
{
PrintFormat("Buy %s %G lot",_Symbol,size);
BuyAsync(size);
//--- unpress the button
ObjectSetInteger(0,"Buy",OBJPROP_STATE,false);
}
//---
//--- if "Sell" button is pressed, then sell
if(sparam=="Sell")
{
PrintFormat("Sell %s %G lot",_Symbol,size);
SellAsync(size);
//--- unpress the button
ObjectSetInteger(0,"Sell",OBJPROP_STATE,false);
}
ChartRedraw();
}
//---
}
//----//
//+------------------------------------------------------------------+
//| Create two buttons for buying and selling |
//+------------------------------------------------------------------+
void CreateBuySellButtons()
{
//--- check the object named "Buy"
if(ObjectFind(0,"Buy")>=0)
{
//--- if the found object is not a button, delete it
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
int stbar=0;
int xhilo=26;
int minstop=28;
double prcHi=0.0;
double prcLo=0.0;
double high[];
double low[];
ArrayResize(high,100);
ArrayResize(low,100);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
int copyHigh=CopyHigh(_Symbol,PERIOD_CURRENT,0,99,high);
int copyLow=CopyLow(_Symbol,PERIOD_CURRENT,0,99,low);
int barHi=iHighest(high,PERIOD_CURRENT,xhilo,stbar);
int barLo=iLowest(low,PERIOD_CURRENT,xhilo,stbar);
if(barHi!=-1) prcHi=high[barHi];
if(barLo!=-1) prcLo=low[barLo];
//--
double lots=volume;
if(!CalculatedTradeSize) lots = NormalizeDouble(TradeLotSize,2);
//--
double tp=NormalizeDouble(prcHi-(2*SymbolInfoInteger(_Symbol,SYMBOL_SPREAD)*_Point),_Digits);
double sl=NormalizeDouble(prcLo-(2*SymbolInfoInteger(_Symbol,SYMBOL_SPREAD)*_Point),_Digits);
if((tp-SymbolInfoDouble(_Symbol,SYMBOL_ASK)<20*_Point)||(SymbolInfoDouble(_Symbol,SYMBOL_BID)-sl<20*_Point))
{
sl=NormalizeDouble(sl-(minstop*_Point),_Digits);
tp=NormalizeDouble(tp+(minstop*TPvsSLRatio*_Point),_Digits);
}
//--
MqlTradeRequest req={0};
req.action = TRADE_ACTION_DEAL;
req.symbol = _Symbol;
req.magic = MagicNumber;
req.volume = lots;
req.type = ORDER_TYPE_BUY;
req.price = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
req.sl = sl;
req.tp = tp;
req.deviation = 10;
req.comment = "Buy using OrderSendAsync()";
MqlTradeResult res={0};
if(!OrderSendAsync(req,res))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
}
else PlaySound("ok.wav.");
//----
}
//----//
//+------------------------------------------------------------------+
//| Sell using OrderSendAsync() asynchronous function |
//+------------------------------------------------------------------+
void SellAsync(double volume)
{
//--- prepare the request
int stbar=0;
int xhilo=26;
int minstop=28;
double prcHi=0.0;
double prcLo=0.0;
double high[];
double low[];
ArrayResize(high,100);
ArrayResize(low,100);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
int copyHigh=CopyHigh(_Symbol,PERIOD_CURRENT,0,99,high);
int copyLow=CopyLow(_Symbol,PERIOD_CURRENT,0,99,low);
int barHi=iHighest(high,PERIOD_CURRENT,xhilo,stbar);
int barLo=iLowest(low,PERIOD_CURRENT,xhilo,stbar);
if(barHi!=-1) prcHi=high[barHi];
if(barLo!=-1) prcLo=low[barLo];
//--
double lots=volume;
if(!CalculatedTradeSize) lots = NormalizeDouble(TradeLotSize,2);
//--
double tp=NormalizeDouble(prcLo+(2*SymbolInfoInteger(_Symbol,SYMBOL_SPREAD)*_Point),_Digits);
double sl=NormalizeDouble(prcHi+(2*SymbolInfoInteger(_Symbol,SYMBOL_SPREAD)*_Point),_Digits);
if((SymbolInfoDouble(_Symbol,SYMBOL_BID)-tp<20*_Point)||(sl-SymbolInfoDouble(_Symbol,SYMBOL_ASK)<20*_Point))
{
sl=NormalizeDouble(sl+(minstop*_Point),_Digits);
tp=NormalizeDouble(tp-(minstop*TPvsSLRatio*_Point),_Digits);
}
//--
MqlTradeRequest req={0};
req.action = TRADE_ACTION_DEAL;
req.symbol = _Symbol;
req.magic = MagicNumber;
req.volume = lots;
req.type = ORDER_TYPE_SELL;
req.price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
req.sl = sl;
req.tp = tp;
req.deviation = 10;
req.comment = "Sell using OrderSendAsync()";
MqlTradeResult res={0};
if(!OrderSendAsync(req,res))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
}
else PlaySound("ok.wav.");
//----
}
//----//
//+-------------------------------------------------------------------------+
//| Money Managment |
//+-------------------------------------------------------------------------+
double TradeSize()
{
//---
double lots_min = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
double lots_max = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
long leverage = AccountInfoInteger(ACCOUNT_LEVERAGE);
double lots_size = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE);
double lots_step = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
//--
double final_account_balance = MathMin(AccountInfoDouble(ACCOUNT_BALANCE),AccountInfoDouble(ACCOUNT_EQUITY));
int normalization_factor = 0;
double lots = 0.0;
//--
if(lots_step == 0.01) {normalization_factor = 2;}
if(lots_step == 0.1) {normalization_factor = 1;}
//--
lots = (final_account_balance*RiskPercentage/100.0)/(lots_size/leverage);
lots = NormalizeDouble(lots,normalization_factor);
//--
if (lots < lots_min) {lots = lots_min;}
if (lots > lots_max) {lots = lots_max;}
//---
return(lots);
//----
}
//----//
//+------------------------------------------------------------------+
//| searching index of the highest bar |
//+------------------------------------------------------------------+
int iHighest(const double &array[],
int timeframe,
int depth,
int startPos)
{
int index=startPos;
//--- start index validation
if(startPos<0)
{
Print("Invalid parameter in the function iHighest, startPos =",startPos);
return 0;
}
int size=ArraySize(array);
//---
double max=array[startPos];
//--- start searching
for(int i=depth; i>startPos; i--)
{
if(array[i]>max)
{
index=i;
max=array[i];
}
}
//--- return index of the highest bar
return(index);
}
//----//
//+------------------------------------------------------------------+
//| searching index of the lowest bar |
//+------------------------------------------------------------------+
int iLowest(const double &array[],
int timeframe,
int depth,
int startPos)
{
int index=startPos;
//--- start index validation
if(startPos<0)
{
Print("Invalid parameter in the function iLowest, startPos =",startPos);
return 0;
}
int size=ArraySize(array);
//---
double min=array[startPos];
//--- start searching
for(int i=depth; i>startPos; i--)
{
if(array[i]<min)
{
index=i;
min=array[i];
}
}
//--- return index of the lowest bar
return(index);
}
//----//
//+----------------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---