#include <QDateTime>
#include <fstream>
#include <sstream>
#include <iostream>

constexpr char filesEURUSD[12][67] = {
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-01_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-02_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-03_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-04_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-05_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-06_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-07_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-08_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-09_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-10_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-11_EURUSD.csv",
    "C:/Users/petr/Desktop/HistData/EURUSD/2014_tick/2014-12_EURUSD.csv"
};

constexpr char filesGBPUSD[12][67] = {
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-01_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-02_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-03_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-04_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-05_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-06_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-07_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-08_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-09_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-10_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-11_GBPUSD.csv",
    "C:/Users/petr/Desktop/HistData/GBPUSD/2014_tick/2014-12_GBPUSD.csv"
};

constexpr char dateFormat[] = "yyyyMMdd";
constexpr char timeFormat[] = "hhmmsszzz";

constexpr char outputFile[] =
    "C:/Users/petr/Desktop/SpreadAnalysis/spreadAnalysis.csv";

constexpr char outputLogFile[] =
    "C:/Users/petr/Desktop/SpreadAnalysis/spreadAnalysis.txt";

bool isTradingTime(const QDateTime& dateTime)
{
    int dayOfWeek = dateTime.date().dayOfWeek();
    QTime time = dateTime.time();

    // Tuesdays, wednesdays and thursdays
    if (dayOfWeek != 2 && dayOfWeek != 3 && dayOfWeek != 4)
        return false;

    // London market trading hours with start delayed by 4 hours in Eastern
    // Standard Time (EST) WITHOUT Day Light Savings adjustments
    if (!(time >= QTime(6, 0, 0) && time < QTime(11, 0, 0)))
        return false;

    return true;
}

double averageSpread(const std::string& file, std::ofstream& logStream)
{
    std::ifstream stream(file);
    std::string line;

    double spreadSum = 0;
    int valueCount = 0;

    while (std::getline(stream, line)) {
        std::replace(line.begin(), line.end(), ',', ' ');
        std::istringstream lineStream(line);

        std::string date;
        std::string time;

        lineStream >> date;
        lineStream >> time;

        QDateTime dateTime;

        dateTime.setDate(QDate::fromString(
            QString::fromStdString(date), dateFormat));

        dateTime.setTime(QTime::fromString(
            QString::fromStdString(time), timeFormat));

        if (!isTradingTime(dateTime))
            continue;

        double bid = 0;
        double ask = 0;

        lineStream >> bid;
        lineStream >> ask;

        spreadSum += ask - bid;
        valueCount++;
    }

    std::cout << spreadSum << " " << valueCount << std::endl;
    logStream << spreadSum << " " << valueCount << std::endl;

    return spreadSum / valueCount;
}

int main()
{   
    std::ofstream outputStream(outputFile);
    std::ofstream logStream(outputLogFile);

    outputStream << "EURUSD" << std::endl;

    for (int i = 0; i < 12; i++) {
        std::cout << filesEURUSD[i] << std::endl;
        logStream << filesEURUSD[i] << std::endl;

        double spread = averageSpread(filesEURUSD[i], logStream);

        std::cout << spread << std::endl << std::endl;
        logStream << spread << std::endl << std::endl;

        outputStream << i << ", " << spread << std::endl;
    }

    outputStream << std::endl << "GBPUSD" << std::endl;

    for (int i = 0; i < 12; i++) {
        std::cout << filesGBPUSD[i] << std::endl;
        logStream << filesGBPUSD[i] << std::endl;

        double spread = averageSpread(filesGBPUSD[i], logStream);

        std::cout << spread << std::endl << std::endl;
        logStream << spread << std::endl << std::endl;

        outputStream << i << ", " << spread << std::endl;
    }

    return 0;
}
