SimpleHistoryReceiver

Author: Copyright 2021, Yuriy Bykov
Price Data Components
Series array that contains tick volumes of each bar
Miscellaneous
Uses files from the file systemIt reads information from a file
0 Views
0 Downloads
0 Favorites
SimpleHistoryReceiver
//+------------------------------------------------------------------+
//|                                        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