MT4の取引レポートをCSV出力するツール

2014/8/23更新

特定のブローカーで、通貨レートの桁数が取得できない場合に対応。

正常に取得できれば、ブローカーからの情報を利用するが、取得エラーの場合は、標準的な5桁レート対応のブローカーに準ずる情報で稼働するように改良。

2014/7/11更新

Lot数と、損益pipsの出力結果で、ときどき小数点以下の数値がおかしくなる問題に対処。

2014/6/8更新

主に自分の使用用途に合わせ、CSVファイルにヘッダーを出力しないようにするオプションと、期間選択機能を無効化するオプションを追加しました。

version1.2として、ソースコードを公開します。また、以前のバージョンのソースコードも残しています。

ご自由にご利用下さい。

 

MT4の出力するトレード記録がHTML形式オンリーであり、直近のEA性能の計算や損益集計する際にデータ加工が面倒したので、MT4からトレード結果をCSV出力するツールを作成しました。

 

前々からこんなツールが欲しくて、ネットをかけずり回りましたが、有料であったり、古くて動かなかったり、個人情報の登録が必要だったりでイマイチでしたので、自作しました。

 

:::このツールは、MT4のScriptプログラムとして動作し、下記イメージのようなCSVファイルを出力します。(解り易いように、CSVファイルをExcelで開いています)

csv09

 

 

 

 

 

 

 

 

 

 

 

 

 

それでは、例によってmq4のソースコードです。

※ソースのベースはこちらのサイト様のものを参考にしております。(http://eacreater.blog48.fc2.com)

MT4 Build600ではコンパイル不能で、挙動もちょっと、、、でしたので、構造的に再構成しています。

 

更新情報

  • 2014/8/23 – version1.40][ 一部ブローカーで、通貨レートの桁数情報が取得できない場合に、エラーではなく代替情報にて稼働するよう調整
  • 2014/7/11 – version1.30 ][  Lot数と、トレードpipsの小数点以下の数値がおかしくなる問題に対処
  • 2014/6/8 – version1.20 ][  ヘッダー付与有無の選択オプションと、期間フィルター使用有無の選択オプションを追加
  • 2014/4/18 – version1.10 ][  項目追加(トレードのpipsを追加しました)
StatementToCSV.mq4 version1.40: MT4のレポートをCSV出力するスクリプト。
//+------------------------------------------------------------------+
//|                                               StatementToCSV.mq4 |
//|                                     Copyright 2014, Life with FX |
//|                                             http://lifewithfx.jp |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Life with FX"
#property link      "http://lifewithfx.jp"
#property version   "1.40"
#property strict
#property show_inputs

extern string CSVOutputFolder = "-- MT4 MQL4/Files folder --";
extern bool OutputRecordDescendingOrder = false;
extern bool OutputHeaderRecord = true;
extern string ReportPeriod = "-- PeriodFilter: Order close time base --";
extern bool UsePeriodFilter = false;
extern int  ReportFromDate = 20140331;
extern int  ReportToDate   = 20159999;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
int OnStart()
{

  int hFile = -1;
  int historyTotal = OrdersHistoryTotal();

  if(historyTotal <= 0)
    {
      Print("No History Data. Skip process...");
      return(0);
    }

  int ticket[];

  ArrayResize(ticket, historyTotal);
  ArrayInitialize(ticket, -1);

  for(int i=0; i<historyTotal; i++)
    {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
        {
          switch(OrderType())
            {
            case OP_BUY:
            case OP_SELL:
              ticket[i] = OrderTicket();
              break;
            default:
              ticket[i] = -1;
            }
        }
    }

  // output filename  StatementCSV_YYYYMMDD_HHMM.csv
  string fileName = "StatementCSV_" + Year();
  if(Month() < 10)  { fileName = fileName + "0" + Month(); }
  else              { fileName = fileName + Month(); }
  if(Day() < 10)    { fileName = fileName + "0" + Day() + "_"; }
  else              { fileName = fileName + Day() + "_"; }
  if(Hour() < 10)   { fileName = fileName + "0" + Hour(); }
  else              { fileName = fileName + Hour(); }
  if(Minute() < 10) { fileName = fileName + "0" + Minute(); }
  else              { fileName = fileName + Minute(); }
  fileName = fileName + ".csv";
  Print("output filename: " + fileName);

  //get handle
  hFile = FileOpen(fileName, FILE_BIN|FILE_WRITE, ",");
  if(hFile < 0) {
    Print("error abort: output file creation error!!");
    return(-1);
  }

  // CSV Record Header
  string header = "Ticket,OrderType,OrderSymbol,OrderLots,OrderOpenTime,OrderOpenPrice,OrderCloseTime,OrderClosePrice,OrderProfitInPips,OrderCommission,OrderSwap,OrderProfit,TradeProfit,OrderMagicNumber,OrderComment,OrderCommentShort" + "\n";
  if (OutputHeaderRecord) {
    FileWriteString(hFile, header, StringLen(header));
  }

  const string ITEM_SEPARATOR = ",";
  int startIdx;  
  int idxStep;
  int ordersLastIdx = historyTotal - 1;
  double pipScale;
  double pipScaleDigits;  
  double takeprice;
  double takepips;  
   
  if (!OutputRecordDescendingOrder) {
    startIdx = 0;
    idxStep = 1;
  } else {
    startIdx = ordersLastIdx;
    idxStep = -1;
  }

  for (int i = startIdx; !(i < 0 || ordersLastIdx < i) ; i += idxStep) {

    if(ticket[i] != -1) {
      if(OrderSelect(ticket[i], SELECT_BY_TICKET, MODE_HISTORY)) {

        // PeriodRangeFilter
        string closeDateStr = TimeToStr(OrderCloseTime(), TIME_DATE);
        int closeDateInt = StrToInteger(StringSubstr(closeDateStr, 0, 4) + StringSubstr(closeDateStr, 5, 2) + StringSubstr(closeDateStr, 8, 2));

        if (!UsePeriodFilter) {
          // OK
        } else if (ReportFromDate <= closeDateInt &&
                   closeDateInt   <= ReportToDate) {
          // OK
        } else {
          continue;
        }

        // scale setting
        if (MarketInfo(OrderSymbol(), MODE_DIGITS) != 0) {
          pipScale = MarketInfo(OrderSymbol(), MODE_POINT) * 10;
          pipScaleDigits = MarketInfo(OrderSymbol(), MODE_DIGITS);
        } else {
          pipScale = getPipScale(OrderSymbol());
          pipScaleDigits =getPipScaleDigits(OrderSymbol());
        }
            
        string output = ticket[i]                                                                    + ITEM_SEPARATOR;
        switch(OrderType()) {
        case OP_BUY:
          output = output + "BUY"                                                                    + ITEM_SEPARATOR;
          break;
        case OP_SELL:
          output = output + "SELL"                                                                   + ITEM_SEPARATOR;
          break;
        default:
          output = output + ""                                                                       + ITEM_SEPARATOR;
        }
            
        output = output + OrderSymbol()                                                              + ITEM_SEPARATOR;
        output = output + DoubleToStr(OrderLots(),2)                                                 + ITEM_SEPARATOR;
        output = output + TimeToStr(OrderOpenTime())                                                 + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderOpenPrice(), pipScaleDigits)  + ITEM_SEPARATOR;
        output = output + TimeToStr(OrderCloseTime())                                                + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderClosePrice(), pipScaleDigits) + ITEM_SEPARATOR;
        switch(OrderType()) {
        case OP_BUY:
          takeprice = (OrderClosePrice() / pipScale) - (OrderOpenPrice() / pipScale);
          takepips = NormalizeDouble(takeprice, pipScaleDigits);          

          output = output + takepips + ITEM_SEPARATOR;
          break;
        case OP_SELL:
          takeprice = (OrderOpenPrice() / pipScale) - (OrderClosePrice() / pipScale);
          takepips = NormalizeDouble(takeprice, pipScaleDigits);          

          output = output + takepips + ITEM_SEPARATOR;
          break;
        }               
        output = output + NormalizeDouble(OrderCommission(), 2)                                      + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderSwap(), 2)                                            + ITEM_SEPARATOR;
        output = output + OrderProfit()                                                              + ITEM_SEPARATOR;
        output = output + (NormalizeDouble(OrderSwap(), 2) + NormalizeDouble(OrderCommission(), 2) + OrderProfit()) + ITEM_SEPARATOR;
        output = output + OrderMagicNumber()                                                         + ITEM_SEPARATOR;
        output = output + OrderComment()                                                             + ITEM_SEPARATOR;
        output = output + StringSubstr(OrderComment(), 0, 2);
        output = output + "\n";

        FileSeek(hFile, 0, SEEK_END);
        FileWriteString(hFile, output, StringLen(output));
      }
    }
  }

  if(0 < hFile) {
    FileClose(hFile);
  }

  Print ("works fine: finished!!");
  return(0);
}

double getPipScale(string symbol) {
  if (symbol == "EURUSD") { return 0.0001;}
  else if (symbol == "AUDCAD") { return 0.0001;}
  else if (symbol == "AUDCHF") { return 0.0001;}
  else if (symbol == "AUDJPY") { return 0.01;}
  else if (symbol == "AUDNZD") { return 0.0001;}
  else if (symbol == "AUDSGD") { return 0.0001;}
  else if (symbol == "AUDUSD") { return 0.0001;}
  else if (symbol == "CADCHF") { return 0.0001;}
  else if (symbol == "CADJPY") { return 0.01;}
  else if (symbol == "CHFJPY") { return 0.01;}
  else if (symbol == "EURAUD") { return 0.0001;}
  else if (symbol == "EURCAD") { return 0.0001;}
  else if (symbol == "EURCHF") { return 0.0001;}
  else if (symbol == "EURGBP") { return 0.0001;}
  else if (symbol == "EURJPY") { return 0.01;}
  else if (symbol == "EURNZD") { return 0.0001;}
  else if (symbol == "GBPAUD") { return 0.0001;}
  else if (symbol == "GBPCAD") { return 0.0001;}
  else if (symbol == "GBPCHF") { return 0.0001;}
  else if (symbol == "GBPJPY") { return 0.01;}
  else if (symbol == "GBPNZD") { return 0.0001;}
  else if (symbol == "GBPUSD") { return 0.0001;}
  else if (symbol == "NZDJPY") { return 0.01;}
  else if (symbol == "NZDUSD") { return 0.0001;}
  else if (symbol == "USDCAD") { return 0.0001;}
  else if (symbol == "USDCHF") { return 0.0001;}
  else if (symbol == "USDHKD") { return 0.0001;}
  else if (symbol == "USDJPY") { return 0.01;}
  else if (symbol == "USDMXN") { return 0.0001;}
  else if (symbol == "USDPLN") { return 0.0001;}
  else if (symbol == "USDSEK") { return 0.0001;}
  else if (symbol == "USDSGD") { return 0.0001;}
  else if (symbol == "USDZAR") { return 0.0001;}
  else if (symbol == "XAGEUR") { return 0.01;}
  else if (symbol == "XAGUSD") { return 0.01;}
  else if (symbol == "XAUEUR") { return 0.1;}
  else if (symbol == "XAUUSD") { return 0.1;}
  else if (symbol == "ZARJPY") { return 0.01;}
  else { return 0.0001; }  
}

double getPipScaleDigits(string symbol) {
  if (symbol == "EURUSD") { return 5;}
  else if (symbol == "AUDCAD") { return 5;}
  else if (symbol == "AUDCHF") { return 5;}
  else if (symbol == "AUDJPY") { return 3;}
  else if (symbol == "AUDNZD") { return 5;}
  else if (symbol == "AUDSGD") { return 5;}
  else if (symbol == "AUDUSD") { return 5;}
  else if (symbol == "CADCHF") { return 5;}
  else if (symbol == "CADJPY") { return 3;}
  else if (symbol == "CHFJPY") { return 3;}
  else if (symbol == "EURAUD") { return 5;}
  else if (symbol == "EURCAD") { return 5;}
  else if (symbol == "EURCHF") { return 5;}
  else if (symbol == "EURGBP") { return 5;}
  else if (symbol == "EURJPY") { return 3;}
  else if (symbol == "EURNZD") { return 5;}
  else if (symbol == "GBPAUD") { return 5;}
  else if (symbol == "GBPCAD") { return 5;}
  else if (symbol == "GBPCHF") { return 5;}
  else if (symbol == "GBPJPY") { return 3;}
  else if (symbol == "GBPNZD") { return 5;}
  else if (symbol == "GBPUSD") { return 5;}
  else if (symbol == "NZDJPY") { return 3;}
  else if (symbol == "NZDUSD") { return 5;}
  else if (symbol == "USDCAD") { return 5;}
  else if (symbol == "USDCHF") { return 5;}
  else if (symbol == "USDHKD") { return 5;}
  else if (symbol == "USDJPY") { return 3;}
  else if (symbol == "USDMXN") { return 5;}
  else if (symbol == "USDPLN") { return 5;}
  else if (symbol == "USDSEK") { return 5;}
  else if (symbol == "USDSGD") { return 5;}
  else if (symbol == "USDZAR") { return 5;}
  else if (symbol == "XAGEUR") { return 3;}
  else if (symbol == "XAGUSD") { return 3;}
  else if (symbol == "XAUEUR") { return 2;}
  else if (symbol == "XAUUSD") { return 2;}
  else if (symbol == "ZARJPY") { return 3;}
  else { return 5; }  
}

StatementToCSV.mq4 version1.30: MT4のレポートをCSV出力するスクリプト。MT4 Build600以上で稼働します。
//+------------------------------------------------------------------+
//|                                               StatementToCSV.mq4 |
//|                                     Copyright 2014, Life with FX |
//|                                             http://lifewithfx.jp |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Life with FX"
#property link      "http://lifewithfx.jp"
#property version   "1.30"
#property strict
#property show_inputs

extern string CSVOutputFolder = "-- MT4 MQL4/Files folder --";
extern bool OutputRecordDescendingOrder = false;
extern bool OutputHeaderRecord = true;
extern string ReportPeriod = "-- PeriodFilter: Order close time base --";
extern bool UsePeriodFilter = false;
extern int  ReportFromDate = 20140331;
extern int  ReportToDate   = 20150830;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
int OnStart()
{

  int hFile = -1;
  int historyTotal = OrdersHistoryTotal();

  if(historyTotal <= 0)
    {
      Print("No History Data. Skip process...");
      return(0);
    }

  int ticket[];

  ArrayResize(ticket, historyTotal);
  ArrayInitialize(ticket, -1);

  for(int i=0; i<historyTotal; i++)
    {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
        {
          switch(OrderType())
            {
            case OP_BUY:
            case OP_SELL:
              ticket[i] = OrderTicket();
              break;
            default:
              ticket[i] = -1;
            }
        }
    }

  // output filename  StatementCSV_YYYYMMDD_HHMM.csv
  string fileName = "StatementCSV_" + Year();
  if(Month() < 10)  { fileName = fileName + "0" + Month(); }
  else              { fileName = fileName + Month(); }
  if(Day() < 10)    { fileName = fileName + "0" + Day() + "_"; }
  else              { fileName = fileName + Day() + "_"; }
  if(Hour() < 10)   { fileName = fileName + "0" + Hour(); }
  else              { fileName = fileName + Hour(); }
  if(Minute() < 10) { fileName = fileName + "0" + Minute(); }
  else              { fileName = fileName + Minute(); }
  fileName = fileName + ".csv";
  Print("output filename: " + fileName);

  //get handle
  hFile = FileOpen(fileName, FILE_BIN|FILE_WRITE, ",");
  if(hFile < 0) {
    Print("error abort: output file creation error!!");
    return(-1);
  }

  // CSV Record Header
  string header = "Ticket,OrderType,OrderSymbol,OrderLots,OrderOpenTime,OrderOpenPrice,OrderCloseTime,OrderClosePrice,OrderProfitInPips,OrderCommission,OrderSwap,OrderProfit,TradeProfit,OrderMagicNumber,OrderComment,OrderCommentShort" + "\n";
  if (OutputHeaderRecord) {
    FileWriteString(hFile, header, StringLen(header));
  }

  const string ITEM_SEPARATOR = ",";
  int startIdx;  
  int idxStep;
  int ordersLastIdx = historyTotal - 1;
  double takeprice;
  double takepips;  
   
  if (!OutputRecordDescendingOrder) {
    startIdx = 0;
    idxStep = 1;
  } else {
    startIdx = ordersLastIdx;
    idxStep = -1;
  }

  for (int i = startIdx; !(i < 0 || ordersLastIdx < i) ; i += idxStep) {

    if(ticket[i] != -1) {
      if(OrderSelect(ticket[i], SELECT_BY_TICKET, MODE_HISTORY)) {

        // PeriodRangeFilter
        string closeDateStr = TimeToStr(OrderCloseTime(), TIME_DATE);
        int closeDateInt = StrToInteger(StringSubstr(closeDateStr, 0, 4) + StringSubstr(closeDateStr, 5, 2) + StringSubstr(closeDateStr, 8, 2));

        if (!UsePeriodFilter) {
	  // OK
        } else if (ReportFromDate <= closeDateInt &&
                   closeDateInt   <= ReportToDate) {
	  // OK
        } else {
          continue;
        }
            
        string output = ticket[i]                                                                    + ITEM_SEPARATOR;
        switch(OrderType()) {
        case OP_BUY:
          output = output + "BUY"                                                                    + ITEM_SEPARATOR;
          break;
        case OP_SELL:
          output = output + "SELL"                                                                   + ITEM_SEPARATOR;
          break;
        default:
          output = output + ""                                                                       + ITEM_SEPARATOR;
        }
            
        output = output + OrderSymbol()                                                              + ITEM_SEPARATOR;
        output = output + DoubleToStr(OrderLots(),2)                                                 + ITEM_SEPARATOR;
        output = output + TimeToStr(OrderOpenTime())                                                 + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderOpenPrice(), MarketInfo(OrderSymbol(), MODE_DIGITS))  + ITEM_SEPARATOR;
        output = output + TimeToStr(OrderCloseTime())                                                + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderClosePrice(), MarketInfo(OrderSymbol(), MODE_DIGITS)) + ITEM_SEPARATOR;
        switch(OrderType()) {
        case OP_BUY:
          takeprice = (OrderClosePrice() / (MarketInfo(OrderSymbol(), MODE_POINT) * 10))
            - (OrderOpenPrice() / (MarketInfo(OrderSymbol(), MODE_POINT) * 10));

          takepips = NormalizeDouble(takeprice, MarketInfo(OrderSymbol(), MODE_DIGITS));          

          output = output + takepips + ITEM_SEPARATOR;
          break;
        case OP_SELL:
          takeprice = (OrderOpenPrice() / (MarketInfo(OrderSymbol(), MODE_POINT) * 10))
            - (OrderClosePrice() / (MarketInfo(OrderSymbol(), MODE_POINT) * 10));
          takepips = NormalizeDouble(takeprice, MarketInfo(OrderSymbol(), MODE_DIGITS));          

          output = output + takepips + ITEM_SEPARATOR;
          break;
        }               
        output = output + NormalizeDouble(OrderCommission(), 2)                                      + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderSwap(), 2)                                            + ITEM_SEPARATOR;
        output = output + OrderProfit()                                                              + ITEM_SEPARATOR;
        output = output + (NormalizeDouble(OrderSwap(), 2) + NormalizeDouble(OrderCommission(), 2) + OrderProfit()) + ITEM_SEPARATOR;
        output = output + OrderMagicNumber()                                                         + ITEM_SEPARATOR;
        output = output + OrderComment()                                                             + ITEM_SEPARATOR;
        output = output + StringSubstr(OrderComment(), 0, 2);
        output = output + "\n";

        FileSeek(hFile, 0, SEEK_END);
        FileWriteString(hFile, output, StringLen(output));
      }
    }
  }

  if(0 < hFile) {
    FileClose(hFile);
  }

  Print ("works fine: finished!!");
  return(0);
}
StatementToCSV.mq4 version1.20: MT4のレポートをCSV出力するスクリプト。MT4 Build600以上で稼働します。

 

//+------------------------------------------------------------------+
//|                                               StatementToCSV.mq4 |
//|                                     Copyright 2014, Life with FX |
//|                                             http://lifewithfx.jp |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Life with FX"
#property link      "http://lifewithfx.jp"
#property version   "1.20"
#property strict
#property show_inputs

extern string CSVOutputFolder = "-- MT4 MQL4/Files folder --";
extern bool OutputRecordDescendingOrder = false;
extern bool OutputHeaderRecord = true;
extern string ReportPeriod = "-- PeriodFilter: Order close time base --";
extern bool UsePeriodFilter = false;
extern int  ReportFromDate = 20140331;
extern int  ReportToDate   = 20150331;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
int OnStart()
{

  int hFile = -1;
  int historyTotal = OrdersHistoryTotal();

  if(historyTotal <= 0)
    {
      Print("No History Data. Skip process...");
      return(0);
    }

  int ticket[];

  ArrayResize(ticket, historyTotal);
  ArrayInitialize(ticket, -1);

  for(int i=0; i<historyTotal; i++)
    {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
        {
          switch(OrderType())
            {
            case OP_BUY:
            case OP_SELL:
              ticket[i] = OrderTicket();
              break;
            default:
              ticket[i] = -1;
            }
        }
    }

  // output filename  StatementCSV_YYYYMMDD_HHMM.csv
  string fileName = "StatementCSV_" + Year();
  if(Month() < 10)  { fileName = fileName + "0" + Month(); }
  else              { fileName = fileName + Month(); }
  if(Day() < 10)    { fileName = fileName + "0" + Day() + "_"; }
  else              { fileName = fileName + Day() + "_"; }
  if(Hour() < 10)   { fileName = fileName + "0" + Hour(); }
  else              { fileName = fileName + Hour(); }
  if(Minute() < 10) { fileName = fileName + "0" + Minute(); }
  else              { fileName = fileName + Minute(); }
  fileName = fileName + ".csv";
  Print("output filename: " + fileName);

  //get handle
  hFile = FileOpen(fileName, FILE_BIN|FILE_WRITE, ",");
  if(hFile < 0) {
    Print("error abort: output file creation error!!");
    return(-1);
  }

  // CSV Record Header
  string header = "Ticket,OrderType,OrderSymbol,OrderLots,OrderOpenTime,OrderOpenPrice,OrderCloseTime,OrderClosePrice,OrderProfitInPips,OrderCommission,OrderSwap,OrderProfit,TradeProfit,OrderMagicNumber,OrderComment,OrderCommentShort" + "\n";
  if (OutputHeaderRecord) {
      FileWriteString(hFile, header, StringLen(header));
  }

  const string ITEM_SEPARATOR = ",";
  int startIdx;  
  int idxStep;
  int ordersLastIdx = historyTotal - 1;
  double takeprice;
  double takepips;  
   
  if (!OutputRecordDescendingOrder) {
    startIdx = 0;
    idxStep = 1;
  } else {
    startIdx = ordersLastIdx;
    idxStep = -1;
  }

  for (int i = startIdx; !(i < 0 || ordersLastIdx < i) ; i += idxStep) {

    if(ticket[i] != -1) {
      if(OrderSelect(ticket[i], SELECT_BY_TICKET, MODE_HISTORY)) {

        // PeriodRangeFilter
        string closeDateStr = TimeToStr(OrderCloseTime(), TIME_DATE);
        int closeDateInt = StrToInteger(StringSubstr(closeDateStr, 0, 4) + StringSubstr(closeDateStr, 5, 2) + StringSubstr(closeDateStr, 8, 2));

        if (!UsePeriodFilter) {
            // OK
        } else if (ReportFromDate <= closeDateInt &&
                   closeDateInt   <= ReportToDate) {
            // OK
        } else {
          continue;
        }
            
        string output = ticket[i]                                                                    + ITEM_SEPARATOR;
        switch(OrderType()) {
        case OP_BUY:
          output = output + "BUY"                                                                    + ITEM_SEPARATOR;
          break;
        case OP_SELL:
          output = output + "SELL"                                                                   + ITEM_SEPARATOR;
          break;
        default:
          output = output + ""                                                                       + ITEM_SEPARATOR;
        }
            
        output = output + OrderSymbol()                                                              + ITEM_SEPARATOR;
        output = output + OrderLots()                                                                + ITEM_SEPARATOR;
        output = output + TimeToStr(OrderOpenTime())                                                 + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderOpenPrice(), MarketInfo(OrderSymbol(), MODE_DIGITS))  + ITEM_SEPARATOR;
        output = output + TimeToStr(OrderCloseTime())                                                + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderClosePrice(), MarketInfo(OrderSymbol(), MODE_DIGITS)) + ITEM_SEPARATOR;
        switch(OrderType()) {
        case OP_BUY:
          takeprice = NormalizeDouble(OrderClosePrice(), MarketInfo(OrderSymbol(), MODE_DIGITS)) -
            NormalizeDouble(OrderOpenPrice(), MarketInfo(OrderSymbol(), MODE_DIGITS));
          takepips = takeprice / (MarketInfo(OrderSymbol(), MODE_POINT) * 10.0);
          
          output = output + takepips + ITEM_SEPARATOR;
          break;
        case OP_SELL:
          takeprice = NormalizeDouble(OrderOpenPrice(), MarketInfo(OrderSymbol(), MODE_DIGITS)) -
            NormalizeDouble(OrderClosePrice(), MarketInfo(OrderSymbol(), MODE_DIGITS));
          takepips = takeprice / (MarketInfo(OrderSymbol(), MODE_POINT) * 10.0);          
          
          output = output + takepips + ITEM_SEPARATOR;
          break;
        }               
        output = output + NormalizeDouble(OrderCommission(), 2)                                      + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderSwap(), 2)                                            + ITEM_SEPARATOR;
        output = output + OrderProfit()                                                              + ITEM_SEPARATOR;
        output = output + (NormalizeDouble(OrderSwap(), 2) + NormalizeDouble(OrderCommission(), 2) + OrderProfit()) + ITEM_SEPARATOR;
        output = output + OrderMagicNumber()                                                         + ITEM_SEPARATOR;
        output = output + OrderComment()                                                             + ITEM_SEPARATOR;
        output = output + StringSubstr(OrderComment(), 0, 2);
        output = output + "\n";

        FileSeek(hFile, 0, SEEK_END);
        FileWriteString(hFile, output, StringLen(output));
      }
    }
  }

  if(0 < hFile) {
    FileClose(hFile);
  }

  Print ("works fine: finished!!");
  return(0);
}

 

StatementToCSV.mq4 version1.10: 古いバージョンです。期間選択機能がデフォルトで機能します
//+------------------------------------------------------------------+
//|                                               StatementToCSV.mq4 |
//|                                     Copyright 2014, Life with FX |
//|                                             http://lifewithfx.jp |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Life with FX"
#property link      "http://lifewithfx.jp"
#property version   "1.10"
#property strict
#property show_inputs

extern string CSVOutputFolder = "-- MT4 MQL4/Files folder --";
extern bool OutputRecordDescendingOrder = false;
extern string ReportPeriod = "-- PeriodFilter: Order close time base --";
extern int  ReportFromDate = 20140101;
extern int  ReportToDate   = 20140331;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
int OnStart()
{

  int hFile = -1;
  int historyTotal = OrdersHistoryTotal();

  if(historyTotal <= 0)
    {
      Print("No History Data. Skip process...");
      return(0);
    }

  int ticket[];

  ArrayResize(ticket, historyTotal);
  ArrayInitialize(ticket, -1);

  for(int i=0; i<historyTotal; i++)
    {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
        {
          switch(OrderType())
            {
            case OP_BUY:
            case OP_SELL:
              ticket[i] = OrderTicket();
              break;
            default:
              ticket[i] = -1;
            }
        }
    }

  // output filename  StatementCSV_YYYYMMDD_HHMM.csv
  string fileName = "StatementCSV_" + Year();
  if(Month() < 10)  { fileName = fileName + "0" + Month(); }
  else              { fileName = fileName + Month(); }
  if(Day() < 10)    { fileName = fileName + "0" + Day() + "_"; }
  else              { fileName = fileName + Day() + "_"; }
  if(Hour() < 10)   { fileName = fileName + "0" + Hour(); }
  else              { fileName = fileName + Hour(); }
  if(Minute() < 10) { fileName = fileName + "0" + Minute(); }
  else              { fileName = fileName + Minute(); }
  fileName = fileName + ".csv";
  Print("output filename: " + fileName);

  //get handle
  hFile = FileOpen(fileName, FILE_BIN|FILE_WRITE, ",");
  if(hFile < 0) {
    Print("error abort: output file creation error!!");
    return(-1);
  }

  // CSV Record Header
  string header = "Ticket,OrderType,OrderSymbol,OrderLots,OrderOpenTime,OrderOpenPrice,OrderCloseTime,OrderClosePrice,OrderProfitInPips,OrderCommission,OrderSwap,OrderProfit,TradeProfit,OrderMagicNumber,OrderComment,OrderCommentShort" + "\n";
  FileWriteString(hFile, header, StringLen(header));

  const string ITEM_SEPARATOR = ",";
  int startIdx;  
  int idxStep;
  int ordersLastIdx = historyTotal - 1;
  double takeprice;
  double takepips;  
   
  if (!OutputRecordDescendingOrder) {
    startIdx = 0;
    idxStep = 1;
  } else {
    startIdx = ordersLastIdx;
    idxStep = -1;
  }

  for (int i = startIdx; !(i < 0 || ordersLastIdx < i) ; i += idxStep) {

    if(ticket[i] != -1) {
      if(OrderSelect(ticket[i], SELECT_BY_TICKET, MODE_HISTORY)) {

        // PeriodRangeFilter
        string closeDateStr = TimeToStr(OrderCloseTime(), TIME_DATE);
        int closeDateInt = StrToInteger(StringSubstr(closeDateStr, 0, 4) + StringSubstr(closeDateStr, 5, 2) + StringSubstr(closeDateStr, 8, 2));

        if (ReportFromDate <= closeDateInt &&
            closeDateInt   <= ReportToDate) {
          // OK
        } else {
          continue;
        }
            
        string output = ticket[i]                                                                    + ITEM_SEPARATOR;
        switch(OrderType()) {
        case OP_BUY:
          output = output + "BUY"                                                                    + ITEM_SEPARATOR;
          break;
        case OP_SELL:
          output = output + "SELL"                                                                   + ITEM_SEPARATOR;
          break;
        default:
          output = output + ""                                                                       + ITEM_SEPARATOR;
        }
            
        output = output + OrderSymbol()                                                              + ITEM_SEPARATOR;
        output = output + OrderLots()                                                                + ITEM_SEPARATOR;
        output = output + TimeToStr(OrderOpenTime())                                                 + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderOpenPrice(), MarketInfo(OrderSymbol(), MODE_DIGITS))  + ITEM_SEPARATOR;
        output = output + TimeToStr(OrderCloseTime())                                                + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderClosePrice(), MarketInfo(OrderSymbol(), MODE_DIGITS)) + ITEM_SEPARATOR;
        switch(OrderType()) {
        case OP_BUY:
          takeprice = NormalizeDouble(OrderClosePrice(), MarketInfo(OrderSymbol(), MODE_DIGITS)) -
            NormalizeDouble(OrderOpenPrice(), MarketInfo(OrderSymbol(), MODE_DIGITS));
          takepips = takeprice / (MarketInfo(OrderSymbol(), MODE_POINT) * 10.0);
          
          output = output + takepips + ITEM_SEPARATOR;
          break;
        case OP_SELL:
          takeprice = NormalizeDouble(OrderOpenPrice(), MarketInfo(OrderSymbol(), MODE_DIGITS)) -
            NormalizeDouble(OrderClosePrice(), MarketInfo(OrderSymbol(), MODE_DIGITS));
          takepips = takeprice / (MarketInfo(OrderSymbol(), MODE_POINT) * 10.0);          
          
          output = output + takepips + ITEM_SEPARATOR;
          break;
        }               
        output = output + NormalizeDouble(OrderCommission(), 2)                                      + ITEM_SEPARATOR;
        output = output + NormalizeDouble(OrderSwap(), 2)                                            + ITEM_SEPARATOR;
        output = output + OrderProfit()                                                              + ITEM_SEPARATOR;
        output = output + (NormalizeDouble(OrderSwap(), 2) + NormalizeDouble(OrderCommission(), 2) + OrderProfit()) + ITEM_SEPARATOR;
        output = output + OrderMagicNumber()                                                         + ITEM_SEPARATOR;
        output = output + OrderComment()                                                             + ITEM_SEPARATOR;
        output = output + StringSubstr(OrderComment(), 0, 2);
        output = output + "\n";

        FileSeek(hFile, 0, SEEK_END);
        FileWriteString(hFile, output, StringLen(output));
      }
    }
  }

  if(0 < hFile) {
    FileClose(hFile);
  }

  Print ("works fine: finished!!");
  return(0);
}

 

 

次に使い方の説明です。

 

csv01

MT4を起動して、ソースファイルをコンパイルしましょう。

 

 

 

 

 

csv02

 

メタエディタで、ソースファイルをコンパイルします。

Newをクリック後、スクリプトを選択して適当に進めます。

エディタが立ち上がったら、当サイトのStatementToCSV.mq4の内容を全て上書きして、ボタンを3つクリックします。

 

 

 

 

csv03

 

上記オペレーションを行えば、起動しているMT4のスクリプトに、StatementToCSVが現れます。

実際に、スクリプトを動かす前に、1つ準備が必要です。

MT4の”口座履歴タブ”から、データピックアップ期間分が表示されるように、調整します。(カスタム期間か、全履歴を選択して下さい)

 

 

 

 

csv04

 

表示期間の設定がおわりましたら、いよいよ稼働です。

 

 

 

 

 

csv05

 

 

 

 

 

 

 

csv06

 

こんな感じで良いです。

 

 

 

 

 

csv07

 

レコード出力順(チケットベース)が、昇順・降順の選択可能

また、オーダークローズ日ベースで、CSV出力期間の選択抽出が可能

 

3ヶ月程度でしたら、スクリプトの稼働は数秒で完了します。

 

 

csv08

 

CSVファイルの出力先は、MT4の更新データが存在するフォルダの、MQL4->Filesに出力されます。

CSVファイル名は、自動設定となりまして、実行前に任意設定できません。

 

 

出来上がり。

csv09

 

 

 

 

 

 

“MT4の取引レポートをCSV出力するツール” への1件の返信

  1. とても、素晴らしいスクリプトですね。
    確定申告に必要な、取引履歴作成に利用しています。

    あつかましい要望ですが、取引履歴以外のデータも出力出来れば、尚、有用と思います。

    具体的には、入金と出金の履歴も出力出来れば、取引の全てのデータを取得する事ができます。

    ”直近のEA性能の計算や損益集計する際にデータ加工が面倒なので” と言う、当該スクリプトの
    作成コンセプトからは外れますが、入金、出金のデータも、重要な情報です。

    このスクリプトを利用するレベルの人であれば、excelで、必要なデータ選択は出来ると思いますので、是非とも、MT4のターミナルで取得出来るデータ全てを、出力出来るように、機能を追加して戴けないでしょうか。

    お忙しい中で、時間が取れましたら、御一考戴ければ幸いです。
    大変有用なスクリプトを、無償で提供いただきまして、誠に有難う御座います。

コメントを残す