add MQL5Test Workspace Content as BKP Solution ...
This commit is contained in:
@@ -0,0 +1,505 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| TradeControl_en.mq5 |
|
||||
//| Copyright KlimMalgin |
|
||||
//| |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "KlimMalgin"
|
||||
#property link ""
|
||||
#property version "1.00"
|
||||
|
||||
|
||||
datetime start_date = 0; // Date, from which we begin to read history
|
||||
|
||||
int OrdersPrev = 0; // Number of orders at the time of previous OnTrade() call
|
||||
int PositionsPrev = 0; // Number of positions at the time of previous OnTrade() call
|
||||
ulong LastOrderTicket = 0; // Ticket of the last processed order
|
||||
|
||||
int _GetLastError=0; // Error code
|
||||
long state=0; // Order state
|
||||
|
||||
/*
|
||||
*
|
||||
* Structure that stores information about positions
|
||||
*
|
||||
*/
|
||||
struct _position
|
||||
{
|
||||
|
||||
long type, // Position type
|
||||
magic; // Magic number for position
|
||||
datetime time; // Time of position opening
|
||||
|
||||
double volume, // Position volume
|
||||
priceopen, // Position price
|
||||
sl, // Stop Loss level for opened position
|
||||
tp, // Take Profit level for opened position
|
||||
pricecurrent, // Symbol current price
|
||||
comission, // Commission
|
||||
swap, // Accumulated swap
|
||||
profit; // Current profit
|
||||
|
||||
string symbol, // Symbol, by which the position has been opened
|
||||
comment; // Comment to position
|
||||
};
|
||||
|
||||
int _ExpertPositionsTotal = 0;
|
||||
|
||||
_position PositionList[], // Array that stores info about position
|
||||
PrevPositionList[];
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Structure that stores information about orders
|
||||
*
|
||||
*/
|
||||
struct _orders
|
||||
{
|
||||
|
||||
datetime time_setup, // Time of order placement
|
||||
time_expiration, // Time of order expiration
|
||||
time_done; // Time of order execution or cancellation
|
||||
|
||||
long type, // Order type
|
||||
state, // Order state
|
||||
type_filling, // Type of execution by remainder
|
||||
type_time, // Order lifetime
|
||||
ticket; // Order ticket
|
||||
|
||||
long magic, // Id of Expert Advisor, that placed an order
|
||||
// (intended to ensure that each Expert
|
||||
// must place it's own unique number)
|
||||
|
||||
position_id; // Position id, that is placed on order,
|
||||
// when it is executed. Each executed order invokes a
|
||||
// deal, that opens new or changes existing
|
||||
// position. Id of that position is placed on
|
||||
// executed order in this moment.
|
||||
|
||||
double volume_initial, // Initial volume on order placement
|
||||
volume_current, // Unfilled volume
|
||||
price_open, // Price, specified in the order
|
||||
sl, // Stop Loss level
|
||||
tp, // Take Profit level
|
||||
price_current, // Current price by order symbol
|
||||
price_stoplimit; // Price of placing Limit order when StopLimit order is triggered
|
||||
|
||||
string symbol, // Symbol, by which the order has been placed
|
||||
comment; // Comment
|
||||
|
||||
};
|
||||
|
||||
int _ExpertOrdersTotal = 0;
|
||||
|
||||
_orders OrderList[], // Arrays that store info about orders
|
||||
PrevOrderList[];
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//---
|
||||
start_date = 0;
|
||||
|
||||
OrdersPrev = OrdersTotal();
|
||||
PositionsPrev = PositionsTotal();
|
||||
|
||||
GetPosition(PrevPositionList);
|
||||
GetOrders(PrevOrderList);
|
||||
//---
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//---
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| OnTrade function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTrade()
|
||||
{
|
||||
//---
|
||||
GetPosition(PositionList);
|
||||
GetOrders(OrderList);
|
||||
datetime dc = TimeCurrent();
|
||||
HistorySelect(start_date,dc);
|
||||
|
||||
|
||||
Alert("The Trade event occurred");
|
||||
|
||||
if (OrdersPrev < OrdersTotal())
|
||||
{
|
||||
OrderGetTicket(OrdersTotal()-1);// Select the last order to work with
|
||||
_GetLastError=GetLastError();
|
||||
Print("Error #",_GetLastError);ResetLastError();
|
||||
//--
|
||||
if (OrderGetInteger(ORDER_STATE) == ORDER_STATE_STARTED)
|
||||
{
|
||||
Alert(OrderGetTicket(OrdersTotal()-1),"Order has arrived for processing");
|
||||
LastOrderTicket = OrderGetTicket(OrdersTotal()-1); // Saving the order ticket for further work
|
||||
}
|
||||
|
||||
|
||||
state = OrderGetInteger(ORDER_STATE);
|
||||
if (state == ORDER_STATE_PLACED)
|
||||
{
|
||||
switch(OrderGetInteger(ORDER_TYPE))
|
||||
{
|
||||
case 2:
|
||||
Alert("Pending order Buy Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
Alert("Pending order Sell Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
Alert("Pending order Buy Stop #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
Alert("Pending order Sell Stop #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
Alert("Pending order Buy Stop Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
|
||||
case 7:
|
||||
Alert("Pending order Sell Stop Limit #", OrderGetTicket(OrdersTotal()-1)," accepted!");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if(OrdersPrev > OrdersTotal())
|
||||
{
|
||||
state = HistoryOrderGetInteger(LastOrderTicket,ORDER_STATE);
|
||||
|
||||
// If order is not found, generate an error
|
||||
_GetLastError=GetLastError();
|
||||
if (_GetLastError != 0){Alert("Error #",_GetLastError," Order ",LastOrderTicket," is not found!");LastOrderTicket = 0;}
|
||||
Print("Error #",_GetLastError," state: ",state);ResetLastError();
|
||||
|
||||
|
||||
// If order is fully executed
|
||||
if (state == ORDER_STATE_FILLED)
|
||||
{
|
||||
// Then analyze the last deal
|
||||
// --
|
||||
Alert(LastOrderTicket, "Order executed, going to deal");
|
||||
switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ENTRY))
|
||||
{
|
||||
|
||||
// Entering the market
|
||||
case DEAL_ENTRY_IN:
|
||||
Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER),
|
||||
" order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1));
|
||||
|
||||
switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE))
|
||||
{
|
||||
case 0:
|
||||
// If volumes of position and deal are equal, then position has just been opened
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL))
|
||||
&& (PositionGetDouble(POSITION_VOLUME) == HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME)))
|
||||
{
|
||||
Alert("Buy position has been opened on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL));
|
||||
}
|
||||
else
|
||||
// If volumes of position and deal are not equal, then position has been incremented
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL))
|
||||
&& (PositionGetDouble(POSITION_VOLUME) > HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME)))
|
||||
{
|
||||
Alert("Buy position has incremented on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// If volumes of position and deal are equal, then position has just been opened
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL))
|
||||
&& (PositionGetDouble(POSITION_VOLUME) == HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME)))
|
||||
{
|
||||
Alert("Sell position has been opened on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL));
|
||||
}
|
||||
else
|
||||
// If volumes of position and deal are not equal, then position has been incremented
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL))
|
||||
&& (PositionGetDouble(POSITION_VOLUME) > HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_VOLUME)))
|
||||
{
|
||||
Alert("Sell position has incremented on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Alert("Unprocessed code of type: ",
|
||||
HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Âûõîä èç ðûíêà
|
||||
case DEAL_ENTRY_OUT:
|
||||
Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER),
|
||||
" order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1));
|
||||
|
||||
switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE))
|
||||
{
|
||||
case 0:
|
||||
// If position, we tried to close, is still present, then we have closed only part of it
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == true)
|
||||
{
|
||||
Alert("Part of Sell position has been closed on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" with profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
}
|
||||
else
|
||||
// If position is not found, then it is fully closed
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == false)
|
||||
{
|
||||
Alert("Sell position has been closed on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" with profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// If position, we tried to close, is still present, then we have closed only part of it
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == true)
|
||||
{
|
||||
Alert("Part of Buy position has been closed on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" with profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
}
|
||||
else
|
||||
// If position is not found, then it is fully closed
|
||||
if (PositionSelect(HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL)) == false)
|
||||
{
|
||||
Alert("Buy position has been closed on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" with profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Alert("Unprocessed code of type: ",
|
||||
HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Reverse
|
||||
case DEAL_ENTRY_INOUT:
|
||||
Alert(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_ORDER),
|
||||
" order invoked deal #",HistoryDealGetTicket(HistoryDealsTotal()-1));
|
||||
|
||||
switch(HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE))
|
||||
{
|
||||
case 0:
|
||||
Alert("Sell is reversed to Buy on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" resulting profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
Alert("Buy is reversed to Sell on pair ",
|
||||
HistoryDealGetString(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_SYMBOL),
|
||||
" resulting profit = ",
|
||||
HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PROFIT));
|
||||
break;
|
||||
|
||||
default:
|
||||
Alert("Unprocessed code of type: ",
|
||||
HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Indicates the state record
|
||||
case DEAL_ENTRY_STATE:
|
||||
Alert("Indicates the state record. Unprocessed code of direction: ",
|
||||
HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE));
|
||||
break;
|
||||
}
|
||||
// --
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ((PositionsPrev == PositionsTotal()) && (OrdersPrev == OrdersTotal()))
|
||||
{
|
||||
string _alerts = "";
|
||||
bool modify = false;
|
||||
|
||||
for (int i=0;i<_ExpertPositionsTotal;i++)
|
||||
{
|
||||
if (PrevPositionList[i].sl != PositionList[i].sl)
|
||||
{
|
||||
_alerts += "On pair "+PositionList[i].symbol+" Stop Loss changed from "+ PrevPositionList[i].sl +" to "+ PositionList[i].sl +"\n";
|
||||
modify = true;
|
||||
}
|
||||
if (PrevPositionList[i].tp != PositionList[i].tp)
|
||||
{
|
||||
_alerts += "On pair "+PositionList[i].symbol+" Take Profit changed from "+ PrevPositionList[i].tp +" to "+ PositionList[i].tp +"\n";
|
||||
modify = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0;i<_ExpertOrdersTotal;i++)
|
||||
{
|
||||
if (PrevOrderList[i].sl != OrderList[i].sl)
|
||||
{
|
||||
_alerts += "Order "+OrderList[i].ticket+" has changed Stop Loss from "+ PrevOrderList[i].sl +" to "+ OrderList[i].sl +"\n";
|
||||
modify = true;
|
||||
}
|
||||
if (PrevOrderList[i].tp != OrderList[i].tp)
|
||||
{
|
||||
_alerts += "Order "+OrderList[i].ticket+" has changed Take Profit from "+ PrevOrderList[i].tp +" to "+ OrderList[i].tp +"\n";
|
||||
modify = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (modify == true)
|
||||
{
|
||||
Alert(_alerts);
|
||||
modify = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GetPosition(PrevPositionList);
|
||||
GetOrders(PrevOrderList);
|
||||
OrdersPrev = OrdersTotal();
|
||||
PositionsPrev = PositionsTotal();
|
||||
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Expert tick function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnTick()
|
||||
{
|
||||
//---
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
void GetPosition(_position &Array[])
|
||||
{
|
||||
int _GetLastError=0,_PositionsTotal=PositionsTotal();
|
||||
|
||||
int temp_value=(int)MathMax(_PositionsTotal,1);
|
||||
ArrayResize(Array, temp_value);
|
||||
|
||||
_ExpertPositionsTotal=0;
|
||||
for(int z=_PositionsTotal-1; z>=0; z--)
|
||||
{
|
||||
if(!PositionSelect(PositionGetSymbol(z)))
|
||||
{
|
||||
_GetLastError=GetLastError();
|
||||
Print("OrderSelect() - Error #",_GetLastError);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the position is found, then put its info to the array
|
||||
Array[z].type = PositionGetInteger(POSITION_TYPE);
|
||||
Array[z].time = PositionGetInteger(POSITION_TIME);
|
||||
Array[z].magic = PositionGetInteger(POSITION_MAGIC);
|
||||
Array[z].volume = PositionGetDouble(POSITION_VOLUME);
|
||||
Array[z].priceopen = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||
Array[z].sl = PositionGetDouble(POSITION_SL);
|
||||
Array[z].tp = PositionGetDouble(POSITION_TP);
|
||||
Array[z].pricecurrent = PositionGetDouble(POSITION_PRICE_CURRENT);
|
||||
Array[z].comission = PositionGetDouble(POSITION_COMMISSION);
|
||||
Array[z].swap = PositionGetDouble(POSITION_SWAP);
|
||||
Array[z].profit = PositionGetDouble(POSITION_PROFIT);
|
||||
Array[z].symbol = PositionGetString(POSITION_SYMBOL);
|
||||
Array[z].comment = PositionGetString(POSITION_COMMENT);
|
||||
_ExpertPositionsTotal++;
|
||||
}
|
||||
}
|
||||
|
||||
temp_value=(int)MathMax(_ExpertPositionsTotal,1);
|
||||
ArrayResize(Array,temp_value);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Function GetOrders() |
|
||||
//+------------------------------------------------------------------+
|
||||
void GetOrders(_orders &OrdersList[])
|
||||
{
|
||||
|
||||
int _GetLastError=0,_OrdersTotal=OrdersTotal();
|
||||
|
||||
int temp_value=(int)MathMax(_OrdersTotal,1);
|
||||
ArrayResize(OrdersList,temp_value);
|
||||
|
||||
_ExpertOrdersTotal=0;
|
||||
for(int z=_OrdersTotal-1; z>=0; z--)
|
||||
{
|
||||
if(!OrderGetTicket(z))
|
||||
{
|
||||
_GetLastError=GetLastError();
|
||||
Print("GetOrders() - Error #",_GetLastError);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
OrdersList[z].ticket = OrderGetTicket(z);
|
||||
OrdersList[z].time_setup = OrderGetInteger(ORDER_TIME_SETUP);
|
||||
OrdersList[z].time_expiration = OrderGetInteger(ORDER_TIME_EXPIRATION);
|
||||
OrdersList[z].time_done = OrderGetInteger(ORDER_TIME_DONE);
|
||||
OrdersList[z].type = OrderGetInteger(ORDER_TYPE);
|
||||
|
||||
OrdersList[z].state = OrderGetInteger(ORDER_STATE);
|
||||
OrdersList[z].type_filling = OrderGetInteger(ORDER_TYPE_FILLING);
|
||||
OrdersList[z].type_time = OrderGetInteger(ORDER_TYPE_TIME);
|
||||
OrdersList[z].magic = OrderGetInteger(ORDER_MAGIC);
|
||||
OrdersList[z].position_id = OrderGetInteger(ORDER_POSITION_ID);
|
||||
|
||||
OrdersList[z].volume_initial = OrderGetDouble(ORDER_VOLUME_INITIAL);
|
||||
OrdersList[z].volume_current = OrderGetDouble(ORDER_VOLUME_CURRENT);
|
||||
OrdersList[z].price_open = OrderGetDouble(ORDER_PRICE_OPEN);
|
||||
OrdersList[z].sl = OrderGetDouble(ORDER_SL);
|
||||
OrdersList[z].tp = OrderGetDouble(ORDER_TP);
|
||||
OrdersList[z].price_current = OrderGetDouble(ORDER_PRICE_CURRENT);
|
||||
OrdersList[z].price_stoplimit = OrderGetDouble(ORDER_PRICE_STOPLIMIT);
|
||||
|
||||
OrdersList[z].symbol = OrderGetString(ORDER_SYMBOL);
|
||||
OrdersList[z].comment = OrderGetString(ORDER_COMMENT);
|
||||
|
||||
_ExpertOrdersTotal++;
|
||||
}
|
||||
}
|
||||
|
||||
temp_value=(int)MathMax(_ExpertOrdersTotal,1);
|
||||
ArrayResize(OrdersList,temp_value);
|
||||
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user