//+------------------------------------------------------------------+
//| SimpleHistoryReceiver.mq5 |
//| Copyright 2021, Yuriy Bykov |
//| https://www.mql5.com/ru/code/37331 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Yuriy Bykov"
#property description ""
#property link "https://www.mql5.com/ru/code/37331"
#property version "1.4"
#include <Object.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\Trade.mqh>
#define DATE 0
#define TICKET 1
#define TYPE 2
#define SYMBOL 3
#define VOLUME 4
#define ENTRY 5
#define PRICE 6
#define STOPLOSS 7
#define TAKEPROFIT 8
#define PROFIT 9
#define COMMISSION 10
#define FEE 11
#define SWAP 12
#define MAGIC 13
input string fileName = "SomeExpert.history.csv"; // Trade history file name in Common folder
// TODO:
// Add available magics
int f;
int c = 0;
int totalDeals = 0;
bool isNetting;
string L[][14];
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
//---
if(!MQLInfoInteger(MQL_TESTER)) {
Print("ERROR: This expert can run only in tester");
return INIT_SUCCEEDED;
}
isNetting = AccountInfoInteger(ACCOUNT_MARGIN_MODE) != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING;
f = FileOpen(fileName, FILE_READ | FILE_CSV, ',');
if(f <= 0) {
f = FileOpen(fileName, FILE_COMMON | FILE_READ | FILE_CSV, ',');
}
if(f <= 0) {
Print("ERROR: Can't open file ", fileName, " from common folder ", TerminalInfoString(TERMINAL_COMMONDATA_PATH), ", error code: ", GetLastError());
return INIT_PARAMETERS_INCORRECT;
}
ArrayResize(L, 1000000);
while(!FileIsEnding(f)) {
string s = FileReadString(f);
if(s == "[DealsHistory]") {
for(int i = 0; i < 14; i++) {
FileReadString(f);
}
break;
} else if(s == "DATE") {
for(int i = 0; i < 13; i++) {
FileReadString(f);
}
break;
}
}
while(!FileIsEnding(f)) {
L[totalDeals][DATE] = FileReadString(f);
L[totalDeals][TICKET] = FileReadString(f);
L[totalDeals][TYPE] = FileReadString(f);
L[totalDeals][SYMBOL] = FileReadString(f);
L[totalDeals][VOLUME] = FileReadString(f);
L[totalDeals][ENTRY] = FileReadString(f);
L[totalDeals][PRICE] = FileReadString(f);
L[totalDeals][STOPLOSS] = FileReadString(f);
L[totalDeals][TAKEPROFIT] = FileReadString(f);
L[totalDeals][PROFIT] = FileReadString(f);
L[totalDeals][COMMISSION] = FileReadString(f);
L[totalDeals][FEE] = FileReadString(f);
L[totalDeals][SWAP] = FileReadString(f);
L[totalDeals][MAGIC] = FileReadString(f);
Print(L[totalDeals][DATE]);
totalDeals++;
}
Print("Found ", totalDeals, " strings in ", fileName);
if(totalDeals > 1) {
ArrayResize(L, totalDeals);
if(StringToTime(L[0][DATE]) < TimeCurrent()) {
Print("ERROR: For this history file [", fileName, "] set start date less than ", L[0][DATE]);
return INIT_PARAMETERS_INCORRECT;
}
}
FileClose(f);
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
//---
while(c < totalDeals && StringToTime(L[c][DATE]) <= TimeCurrent()) {
ENUM_DEAL_TYPE type = (ENUM_DEAL_TYPE) StringToInteger(L[c][TYPE]);
ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY) StringToInteger(L[c][ENTRY]);
string symbol = L[c][SYMBOL];
double volume = NormalizeDouble(StringToDouble(L[c][VOLUME]), 2);
Print("Process command ", c, ": ", (type == DEAL_TYPE_BUY ? "BUY" : (type == DEAL_TYPE_SELL ? "SELL" : EnumToString(type))), " ", volume, " ", symbol);
if (volume == 0) {
c++;
continue;
}
CTrade trade;
CSymbolInfo symbolInfo;
CPositionInfo position;
COrderInfo order;
double freeMarginLevel = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
double price = 0;
bool res = false;
trade.SetExpertMagicNumber(310);
symbolInfo.Name(symbol);
symbolInfo.RefreshRates();
if(isNetting) {
if(AccountInfoInteger(ACCOUNT_TRADE_ALLOWED)) {
if(type == DEAL_TYPE_BUY) {
res = trade.Buy(volume, symbol, 0, 0, 0, "");
ulong retcode = trade.ResultRetcode();
if(res && trade.ResultDeal() && retcode == TRADE_RETCODE_DONE) {
c++;
} else {
break;
}
} else if(type == DEAL_TYPE_SELL) {
res = trade.Sell(volume, symbol, 0, 0, 0, "");
ulong retcode = trade.ResultRetcode();
if(res && trade.ResultDeal() && retcode == TRADE_RETCODE_DONE) {
c++;
} else {
break;
}
}
}
} else {
if(AccountInfoInteger(ACCOUNT_TRADE_ALLOWED)) {
if(type == DEAL_TYPE_BUY && entry == DEAL_ENTRY_IN) {
res = trade.Buy(volume, symbol, 0, 0, 0, "");
ulong retcode = trade.ResultRetcode();
Print("RetCode=", retcode, " | ResDeal=", trade.ResultDeal());
if(res && trade.ResultDeal() && retcode == TRADE_RETCODE_DONE) {
c++;
} else {
break;
}
}
if(type == DEAL_TYPE_SELL && entry == DEAL_ENTRY_IN) {
res = trade.Sell(volume, symbol, 0, 0, 0, "");
ulong retcode = trade.ResultRetcode();
Print("RetCode=", retcode, " | ResDeal=", trade.ResultDeal());
if(res && trade.ResultDeal() && retcode == TRADE_RETCODE_DONE) {
c++;
} else {
break;
}
}
if(entry == DEAL_ENTRY_OUT) {
position.Select(symbol);
ulong ticket = position.Ticket();
// TODO: Close only needed volume
if(position.Volume() == volume) {
res = trade.PositionClose(ticket);
ulong retcode = trade.ResultRetcode();
Print("Close RetCode=", retcode, " | ResDeal=", trade.ResultDeal());
if(res) {
c++;
} else {
break;
}
} else {
res = trade.PositionClosePartial(ticket, volume);
ulong retcode = trade.ResultRetcode();
Print("Close RetCode=", retcode, " | ResDeal=", trade.ResultDeal());
if(res) {
c++;
} else {
break;
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
Comments