Skip to content

Commit

Permalink
Seasonality cpp (#69)
Browse files Browse the repository at this point in the history
* Downloading TXTS & TSDIFF

* Seasonality and moving average data
  • Loading branch information
mj-xmr authored May 23, 2022
1 parent f020baa commit 07072c5
Show file tree
Hide file tree
Showing 24 changed files with 553 additions and 32 deletions.
2 changes: 1 addition & 1 deletion externals/EnjoLib
15 changes: 13 additions & 2 deletions src/lib-base/src/CLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ EnjoLib::Result<CLIResult> CLI::GetConfigs(int argc, char ** argv) const
const char * OPT_MIN_YEAR = "min-year";
const char * OPT_MAX_MONTH = "max-month";
const char * OPT_MAX_YEAR = "max-year";
//const char * OPT_LATEST_DATE = "latest-date";
const char * OPT_LATEST_DATE = "latest-date";
const char * OPT_SYMBOL = "sym";
const char * OPT_PERIOD = "per";
const char * OPT_DATA_FILE = "data";
const char * OPT_OUT_DIR = "out";
const char * OPT_LAGS = "lags";
const char * OPT_PER_SEASONAL = "per-seasonal";

Expand All @@ -33,9 +35,12 @@ EnjoLib::Result<CLIResult> CLI::GetConfigs(int argc, char ** argv) const
popState.AddInt(OPT_MIN_YEAR, "Start year");
popState.AddInt(OPT_MAX_MONTH, "End month");
popState.AddInt(OPT_MAX_YEAR, "End year");
popState.AddBool(OPT_LATEST_DATE, "Select latest date");
popState.AddStr(OPT_SYMBOL, "Symbol name");
popState.AddStr(OPT_PERIOD, "Period name");

popState.AddStr(OPT_DATA_FILE, "Data file");
popState.AddStr(OPT_OUT_DIR, "Output directory");

popState.AddInt(OPT_LAGS, ConfigTS::DESCR_PLOT_LAGS_NUM);
popState.AddInt(OPT_PER_SEASONAL, ConfigTS::DESCR_PLOT_PERIOD_NUM);

Expand Down Expand Up @@ -75,11 +80,17 @@ EnjoLib::Result<CLIResult> CLI::GetConfigs(int argc, char ** argv) const
confSym.dates.yearStart = pops.GetIntFromMap(OPT_MIN_YEAR);
confSym.dates.monthEnd = pops.GetIntFromMap(OPT_MAX_MONTH);
confSym.dates.yearEnd = pops.GetIntFromMap(OPT_MAX_YEAR);
if (pops.GetBoolFromMap(OPT_LATEST_DATE))
{
confSym.dates.SetNoEnd();
}
confSym.symbol = pops.GetStrFromMap(OPT_SYMBOL);
confSym.period = pops.GetStrFromMap(OPT_PERIOD);
confSym.dataFile = pops.GetStrFromMap(OPT_DATA_FILE);

confTS.PLOT_LAGS_NUM = pops.GetIntFromMap(OPT_LAGS);
confTS.PLOT_PERIOD_NUM = pops.GetIntFromMap(OPT_PER_SEASONAL);
confTS.m_outDir = pops.GetStrFromMap(OPT_OUT_DIR);

//auto pluginName = pops.GetStrFromMap (OPT_PLUGIN);

Expand Down
1 change: 1 addition & 0 deletions src/lib-base/src/ConfigSym.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void ConfigSym::UpdateFromOther(const ConfigSym & cfgSymCmdLine)
dates.UpdateIfNot0(cfgSymCmdLine.dates);
if (cfgSymCmdLine.symbol.size()) symbol = cfgSymCmdLine.symbol;
if (cfgSymCmdLine.period.size()) period = cfgSymCmdLine.period;
if (cfgSymCmdLine.dataFile.size()) dataFile = cfgSymCmdLine.dataFile;
}

/*
Expand Down
2 changes: 1 addition & 1 deletion src/lib-base/src/ConfigSym.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ConfigSym : public ConfigBase
DataDates dates;
long int percentBars = 100;
long int barNum = 0;
EnjoLib::Str symbol, period;
EnjoLib::Str symbol, period, dataFile;

protected:
EnjoLib::Str GetFileNameProt() const override;
Expand Down
3 changes: 3 additions & 0 deletions src/lib-base/src/ConfigTS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ void ConfigTS::RegisterAndReadStrs(EnjoLib::Istream & f)
RegisterAndReadStr(f, m_scriptPathTxt, dirs.DIR_SCRIPTS2 + DEFAULT_SCRIPT_FILE_NAME);
RegisterAndReadStr(f, m_scriptPathTxtR, dirs.DIR_SCRIPTS2 + DEFAULT_SCRIPT_FILE_NAME_R);
RegisterAndReadStr(f, m_scriptPathTxtGen, dirs.DIR_SCRIPTS2 + DEFAULT_SCRIPT_FILE_NAME_GEN);
//RegisterAndReadStr(f, m_outDir, "");
}

PredictorType ConfigTS::GetPredType() const
Expand All @@ -81,6 +82,8 @@ void ConfigTS::SetPriceType(const PriceType & type)

void ConfigTS::UpdateFromOther(const ConfigTS & cfgTSCmdLine)
{
if (cfgTSCmdLine.m_outDir.size()) m_outDir = cfgTSCmdLine.m_outDir;

if (cfgTSCmdLine.PLOT_LAGS_NUM > 0)
{
PLOT_LAGS_NUM = cfgTSCmdLine.PLOT_LAGS_NUM;
Expand Down
2 changes: 2 additions & 0 deletions src/lib-base/src/ConfigTS.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class ConfigTS : public ConfigBase
EnjoLib::Str m_scriptPathTxt;
EnjoLib::Str m_scriptPathTxtR;
EnjoLib::Str m_scriptPathTxtGen;
EnjoLib::Str m_outDir;

bool crashOnRecoverableErrors = false;
bool PLOT_SERIES = true;
bool PLOT_BASELINE = true;
Expand Down
8 changes: 8 additions & 0 deletions src/lib-base/src/DataDates.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "DataDates.h"
#include "TimeUtil.h"

#include <Ios/Osstream.hpp>

Expand All @@ -15,6 +16,13 @@ void DataDates::Set0()
yearStart = yearEnd = monthStart = monthEnd = 0;
}

void DataDates::SetNoEnd()
{
const TimeUtil tut;
monthEnd = tut.GetCurrentMonth();
yearEnd = tut.GetCurrentYear();
}

EnjoLib::Str DataDates::ToStr() const
{
EnjoLib::Osstream oss;
Expand Down
1 change: 1 addition & 0 deletions src/lib-base/src/DataDates.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class DataDates
virtual ~DataDates() {}

void Set0();
void SetNoEnd();
void SetStart(int year, int month);
void SetEnd(int year, int month);
void UpdateIfNot0(const DataDates & other);
Expand Down
29 changes: 18 additions & 11 deletions src/lib-base/src/MainTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,25 @@ MainTester::MainTester(const SymbolFactoryAbstract & symFact, const ConfigTF2 *
{
if (confSym)
{
const DataSrcType type = confSym->GetDataSrc();
switch (type)
if (not confSym->dataFile.empty())
{
case DataSrcType::FOREX_TESTER:
m_tickProvType = TickProviderType::ARCHIVER;
break;
case DataSrcType::MONERO:
m_tickProvType = TickProviderType::XMR;
break;
case DataSrcType::GENERATED:
m_tickProvType = TickProviderType::GENERATED;
break;
m_tickProvType = TickProviderType::DATA_FILE;
}
else
{
const DataSrcType type = confSym->GetDataSrc();
switch (type)
{
case DataSrcType::FOREX_TESTER:
m_tickProvType = TickProviderType::ARCHIVER;
break;
case DataSrcType::MONERO:
m_tickProvType = TickProviderType::XMR;
break;
case DataSrcType::GENERATED:
m_tickProvType = TickProviderType::GENERATED;
break;
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/lib-base/src/PredictorOutputType.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ enum class PredictorOutputType
SERIES,
PREDICTION,
BASELINE,
SEASONAL,
MA,
MA2DIFF,
MA2DIFF_NO_SEASONAL,
RECONSTRUCTION,
RECONSTRUCTION_PRED,
RECONSTRUCTION_PRED_BASELINE
Expand Down
4 changes: 2 additions & 2 deletions src/lib-base/src/PredictorSMAMA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ using namespace EnjoLib;

PredictorSMAMA::PredictorSMAMA(const IDataProvider & dat)
: PredictorBase(dat, "SMAMA_MA")
, m_lagMine(dat, "LAG_SMAMA", true, 10, 1, 50, 1)
, m_lagMine(dat, "LAG_SMAMA", true, 10, 1, 150, 1)
{
AddOptiVar(m_lagMine);
}
Expand All @@ -24,7 +24,7 @@ EnjoLib::VecD PredictorSMAMA::PredictVec(const EnjoLib::VecD & data) const
const EnjoLib::VecD & predSma = util.SimpleMA(numSamplesSma, data);
const EnjoLib::VecD & errors = util.GetErrorsCorrected(predSma, data);
const EnjoLib::VecD & predMA = util.Regression(numSamplesMA, errors);
const EnjoLib::VecD & SMAMA = predSma + predMA;
const EnjoLib::VecD & SMAMA = predSma;// + predMA;

return SMAMA;
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib-base/src/PredictorStats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ PredictorStatsRes PredictorStats::GenPoints(const EnjoLib::VecD & orig, const En
res.rmsBase2Truth = stat.RMSTwo(predBaseline, orig); /// TODO: different readouts with diffs and without
res.rmsPred2Base = stat.RMSTwo(predCorrected, predBaseline);
res.rmsPred2Truth = stat.RMSTwo(predCorrected, orig);
//res.rmsBase2Truth = (predBaseline - orig).Mean(); /// TODO: different readouts with diffs and without
//res.rmsPred2Base = (predCorrected - predBaseline).Mean();
//res.rmsPred2Truth = (predCorrected - orig).Mean();

if (res.rmsBase2Truth != 0)
{
Expand Down
165 changes: 165 additions & 0 deletions src/lib-base/src/Seasonal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#include "Seasonal.h"
#include "IDataProvider.h"
#include "IBufferCandles.h"
#include "Candle.h"
#include "typesVec.h"

#include <Util/CoutBuf.hpp>
#include <Statistical/Matrix.hpp>
#include <Statistical/Statistical.hpp>

#include <STD/VectorCpp.hpp>


using namespace EnjoLib;

const int Seasonal::PERIOD_SEASONAL = 24; /// TODO: Exclude Weekend! Iterate by date?

/*
Seasonal::Seasonal()
{
//ctor
}
Seasonal::~Seasonal()
{
//dtor
}
*/


VecF Seasonal::Run(const VecD & sig, int pred) const
{
const int period = PERIOD_SEASONAL;
//const int maxNumObs = 1; /// TODO: This is the original signal
//const int maxNumObs = 50; /// TODO: This is already a model
const int maxNumObs = m_averages;
const Statistical stat;
const VecCan & canVec = m_dat.GetCandles().GetDataVec();
//Matrix obs(period);

VecF ret;
for (int i = 0; i < sig.size(); ++i)
{
if (i < period)
{
ret.Add(0);
}
else
{
const Candle & canThis = canVec.at(i);

VecD obsV(period);
for (int j = i - 1; j >= pred; j -= 1)
//for (int j = i; j >= period; j -= period)
{
const Candle & canTest = canVec.at(j);
if (not IsSeasonalCandle(canThis, canTest))
{
continue;
}
//LOGL << "Found can = " << canTest.GetDateStr() << " for this " << canThis.GetDateStr() << Nl;
const double diff = sig.at(j) - sig.at(j-pred);
//const double diff = sig.at(j) - sig.at(j-period);
const int idx = j % period;
obsV.Add(diff);
if (int(obsV.size()) >= maxNumObs)
{
break;
}
}
const double val = obsV.Mean();
//const double val = stat.Median(obsV);
ret.Add(val);
}


}
//ret = sig;
//LOGL << "Len ret = " << ret.Len() << ", sig = " << sig.Len() << Nl;
return ret;
}

int Seasonal::FindOffsetToSeasonalCandle(int idxStart0, const VecCan & vecCan)
{
const Candle & canThis = vecCan.at(idxStart0);
for (int j = idxStart0 - 1; j >= 0; j -= 1)
{
const Candle & canTest = vecCan.at(j);
if (not IsSeasonalCandle(canThis, canTest))
{
continue;
}
return j;
}
return -1;
}

bool Seasonal::IsSeasonalCandle(const Candle & canThis, const Candle & canTest)
{
return canThis.GetHour() == canTest.GetHour();
}

VecF SeasonalModel::Run(const VecD & sig, int pred) const
{
const VecF & base = Seasonal::Run(sig, pred);
return base * m_averages * 0.7;
}

double SeasonalModel::PredictNext(const BufferDouble & datExpanding) const
{
return Run(datExpanding.GetData()).Last();
}
unsigned SeasonalModel::GetLags() const
{
return PERIOD_SEASONAL;
}


VecF SeasonalModel2::Run(const VecD & sig, int pred) const
{
const int pers = Seasonal::PERIOD_SEASONAL;
const VecF & base = m_model.Run(sig, pred);
VecF ret(base.size(), 0);
for (int i = pred; i < 2 ; ++i)
{
const float val = base[i];
//ret.push_back(val);
}
for (int i = pers; i < base.size() - pred; ++i)
{
//const float val = base.at(i + pred);
//ret.push_back(val);
}

for (int i = pers; i < base.size(); ++i)
{
if (i < base.size() - 1)
{
const float val = base.at(i - pers + 1);
ret.at(i) = val;
}
else
{
const float val = base.at(i);
//ret.push_back(val);
ret.at(i) = val;
}

}
//ret.pop_front();
//ret.pop_back();
//LOGL << "Seasonal2 = " << ret.Print();
//ret = base;
return ret;
}

double SeasonalModel2::PredictNext(const BufferDouble & datExpanding) const
{
return Run(datExpanding.GetData()).Last();
}
unsigned SeasonalModel2::GetLags() const
{
return Seasonal::PERIOD_SEASONAL - 1;
}

Loading

0 comments on commit 07072c5

Please sign in to comment.