diff --git a/.github/workflows/auto-close-external-prs.yml b/.github/workflows/auto-close-external-prs.yml new file mode 100644 index 0000000..42a3926 --- /dev/null +++ b/.github/workflows/auto-close-external-prs.yml @@ -0,0 +1,58 @@ +name: "Auto-Close External PRs" + +on: + pull_request_target: + types: [opened] + workflow_dispatch: + +jobs: + close-on-open: + if: github.event_name == 'pull_request_target' && github.event.pull_request.user.login != github.repository_owner + runs-on: ubuntu-latest + permissions: + pull-requests: write + issues: write + steps: + - uses: actions/github-script@v7 + with: + script: | + const pr = context.issue.number; + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr, + body: "Thanks for the interest! This repository isn't currently accepting external contributions as I am actively experimenting with different approaches and want to avoid merge conflicts. Therefore, this PR is being closed automatically by Github Bot." + }); + await github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: pr, + state: "closed" + }); + + sweep-existing: + if: github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + permissions: + pull-requests: write + issues: write + steps: + - uses: actions/github-script@v7 + with: + script: | + const owner = context.repo.owner; + const repo = context.repo.repo; + const prs = await github.paginate(github.rest.pulls.list, { + owner, repo, state: 'open', per_page: 100 + }); + for (const pr of prs) { + if (pr.user.login === owner) continue; + core.info(`Closing PR #${pr.number} by ${pr.user.login}`); + await github.rest.issues.createComment({ + owner, repo, issue_number: pr.number, + body: "Thanks for the interest! This repository isn't currently accepting external contributions as I am actively experimenting with different approaches and want to avoid merge conflicts. Therefore, this PR is being closed automatically by Github Bot." + }); + await github.rest.pulls.update({ + owner, repo, pull_number: pr.number, state: "closed" + }); + } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 04bd431..77be3d6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,15 +41,12 @@ jobs: CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO xcodebuild -scheme tests - -destination 'platform=macOS' + -destination 'platform=macOS,arch=arm64' -resultBundlePath TestResult/ -enableCodeCoverage YES -derivedDataPath "${RUNNER_TEMP}/Build/DerivedData" -parallelizeTargets -jobs "$(sysctl -n hw.logicalcpu)" - HEADER_SEARCH_PATHS="./external/libpqxx/include/pqxx/internal ./external/libpqxx/include/ ./external/libpqxx/build/include/ ./external/boost-decimal/include/ ./external/boost-decimal/include/decimal/ ./external/" - LIBRARY_SEARCH_PATHS="./external/libpqxx/src/ ./external/libpqxx/build/src/" - OTHER_LDFLAGS="-L./external/libpqxx/build/src -lpqxx -lpq -L$(brew --prefix pkgconf)/lib -L$(brew --prefix pkgconf)/lib/pkgconfig -L$(brew --prefix postgresql@18)/lib/postgresql -L$(brew --prefix postgresql@18)/lib/postgresql/pgxs -L$(brew --prefix postgresql@18)/lib/postgresql/pkgconfig" clean build test | xcpretty -r junit && exit ${PIPESTATUS[0]} diff --git a/.github/workflows/scripts/brew.sh b/.github/workflows/scripts/brew.sh index 2c7376f..6e60614 100644 --- a/.github/workflows/scripts/brew.sh +++ b/.github/workflows/scripts/brew.sh @@ -11,5 +11,5 @@ check_and_install() { } # Install packages if they don't exist -check_and_install postgresql # Check and install PostgreSQL (which includes libpq) +check_and_install postgresql@18 # Check and install PostgreSQL (which includes libpq) check_and_install pkg-config # Check and install pkg-config \ No newline at end of file diff --git a/backtesting-engine-cpp.xcodeproj/project.pbxproj b/backtesting-engine-cpp.xcodeproj/project.pbxproj index 84dc9c9..fbdaccb 100644 --- a/backtesting-engine-cpp.xcodeproj/project.pbxproj +++ b/backtesting-engine-cpp.xcodeproj/project.pbxproj @@ -21,7 +21,6 @@ 943398252D57E53400287A2D /* jsonParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 943398232D57E53400287A2D /* jsonParser.cpp */; }; 943398272D57E54000287A2D /* jsonParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 943398262D57E54000287A2D /* jsonParser.mm */; }; 94364CB62D416D8D00F35B55 /* db.mm in Sources */ = {isa = PBXBuildFile; fileRef = 94364CB52D416D8000F35B55 /* db.mm */; }; - 944698852D3A545B0070E30F /* libpq.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 94CD8A972D2D34A100041BBA /* libpq.a */; }; 9464E5F12FA7467200D82BAD /* symbolScale.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9464E5F02FA7467200D82BAD /* symbolScale.mm */; }; 94674B872D533B4000973137 /* tradeManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94674B852D533B4000973137 /* tradeManager.cpp */; }; 94674B882D533B4000973137 /* tradeManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94674B852D533B4000973137 /* tradeManager.cpp */; }; @@ -32,11 +31,8 @@ 9470B5B62C8C5BFD007D9CC6 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9470B5A32C8C5AD0007D9CC6 /* main.cpp */; }; 94724A832F8B92C10029B940 /* operations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94724A822F8B92C10029B940 /* operations.cpp */; }; 94724A842F8B92C10029B940 /* operations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94724A822F8B92C10029B940 /* operations.cpp */; }; - 94CD8B992D2DCDD800041BBA /* libpqxx-7.10.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 94CD8B982D2DCDD800041BBA /* libpqxx-7.10.a */; }; - 94CD8B9C2D2DD02A00041BBA /* libpqxx-7.10.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 94CD8B9A2D2DCF6E00041BBA /* libpqxx-7.10.a */; }; 94CD8BA02D2E8CE500041BBA /* databaseConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD8B9F2D2E8CE500041BBA /* databaseConnection.cpp */; }; 94CD8BA12D2E8CE500041BBA /* databaseConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD8B9F2D2E8CE500041BBA /* databaseConnection.cpp */; }; - 94CD8BA22D2E8FC600041BBA /* libpq.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 94CD8A972D2D34A100041BBA /* libpq.a */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -95,8 +91,8 @@ 94724A822F8B92C10029B940 /* operations.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = operations.cpp; sourceTree = ""; }; 94724A852F8B92E30029B940 /* operations.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = operations.hpp; sourceTree = ""; }; 948A9CCD2C906A5600E23669 /* CONVENTIONS.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONVENTIONS.md; sourceTree = ""; }; - 948A9CED2C906AFE00E23669 /* 2020.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = 2020.csv; sourceTree = ""; }; 94BBA4512D2EA2640010E04D /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = ""; }; + 94C331A02FA899A8006BD690 /* decimal_json.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = decimal_json.hpp; sourceTree = ""; }; 94CD832A2D2D22C900041BBA /* config.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = config.yml; sourceTree = ""; }; 94CD832C2D2D22C900041BBA /* codeql.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = codeql.yml; sourceTree = ""; }; 94CD832D2D2D22C900041BBA /* stale.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = stale.yml; sourceTree = ""; }; @@ -1265,8 +1261,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 94CD8BA22D2E8FC600041BBA /* libpq.a in Frameworks */, - 94CD8B992D2DCDD800041BBA /* libpqxx-7.10.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1274,8 +1268,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 944698852D3A545B0070E30F /* libpq.a in Frameworks */, - 94CD8B9C2D2DD02A00041BBA /* libpqxx-7.10.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1330,7 +1322,6 @@ 94DE4F772C8C3E7C00FE48FF /* include */, 9470B5A22C8C5AD0007D9CC6 /* source */, 9470B5AD2C8C5B99007D9CC6 /* tests */, - 948A9CEC2C906ADB00E23669 /* resources */, 944D0DCF2C8C3704004DD0FC /* sonar-project.properties */, 944D0DD32C8C3704004DD0FC /* CMakeLists.txt */, 944D0DC82C8C3704004DD0FC /* LICENSE.MD */, @@ -1422,17 +1413,10 @@ path = tests; sourceTree = ""; }; - 948A9CEC2C906ADB00E23669 /* resources */ = { - isa = PBXGroup; - children = ( - 948A9CED2C906AFE00E23669 /* 2020.csv */, - ); - path = resources; - sourceTree = ""; - }; 94B8C7932D3D770800E17EB6 /* utilities */ = { isa = PBXGroup; children = ( + 94C331A02FA899A8006BD690 /* decimal_json.hpp */, 94280BA12D2FC00200F1CF56 /* base64.hpp */, ); path = utilities; @@ -3781,19 +3765,23 @@ CODE_SIGN_STYLE = Automatic; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ( + "\"$(SRCROOT)/include\"", "\"$(SRCROOT)/external/libpqxx/include\"", "\"$(SRCROOT)/external/libpqxx/include/pqxx/internal\"", + "\"$(SRCROOT)/external/libpqxx/build/include\"", "\"$(SRCROOT)/external/\"", "\"$(SRCROOT)/external/boost-decimal/include\"", ); INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = ""; LIBRARY_SEARCH_PATHS = ( "\"$(SRCROOT)/external/libpqxx/build/src\"", - "/opt/homebrew/Cellar/postgresql@18/18.3/lib/postgresql", - "\"$(SRCROOT)/external/boost-decimal/build\"", + "/opt/homebrew/opt/postgresql@18/lib/postgresql", ); MACOSX_DEPLOYMENT_TARGET = 26.0; - OTHER_LDFLAGS = ""; + OTHER_LDFLAGS = ( + "-lpq", + "-lpqxx", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_NAME = "$(TARGET_NAME)"; SECTORDER_FLAGS = ""; @@ -3806,19 +3794,23 @@ CODE_SIGN_STYLE = Automatic; FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ( + "\"$(SRCROOT)/include\"", "\"$(SRCROOT)/external/libpqxx/include\"", "\"$(SRCROOT)/external/libpqxx/include/pqxx/internal\"", + "\"$(SRCROOT)/external/libpqxx/build/include\"", "\"$(SRCROOT)/external/\"", "\"$(SRCROOT)/external/boost-decimal/include\"", ); INCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = ""; LIBRARY_SEARCH_PATHS = ( "\"$(SRCROOT)/external/libpqxx/build/src\"", - "/opt/homebrew/Cellar/postgresql@18/18.3/lib/postgresql", - "\"$(SRCROOT)/external/boost-decimal/build\"", + "/opt/homebrew/opt/postgresql@18/lib/postgresql", ); MACOSX_DEPLOYMENT_TARGET = 26.0; - OTHER_LDFLAGS = ""; + OTHER_LDFLAGS = ( + "-lpq", + "-lpqxx", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_NAME = "$(TARGET_NAME)"; SECTORDER_FLAGS = ""; @@ -3832,18 +3824,23 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = ( + "\"$(SRCROOT)/include\"", + "\"$(SRCROOT)/external/\"", "\"$(SRCROOT)/external/libpqxx/include\"", "\"$(SRCROOT)/external/libpqxx/include/pqxx/internal\"", - "\"$(SRCROOT)/external/\"", + "\"$(SRCROOT)/external/libpqxx/build/include\"", "\"$(SRCROOT)/external/boost-decimal/include\"", ); LIBRARY_SEARCH_PATHS = ( "\"$(SRCROOT)/external/libpqxx/build/src\"", - "/opt/homebrew/Cellar/postgresql@18/18.3/lib/postgresql", - "\"$(SRCROOT)/external/boost-decimal/build\"", + "/opt/homebrew/opt/postgresql@18/lib/postgresql", ); MACOSX_DEPLOYMENT_TARGET = 26.0; MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = ( + "-lpq", + "-lpqxx", + ); PRODUCT_BUNDLE_IDENTIFIER = com.mccaffers.tests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = NO; @@ -3857,18 +3854,23 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = ( + "\"$(SRCROOT)/include\"", + "\"$(SRCROOT)/external/\"", "\"$(SRCROOT)/external/libpqxx/include\"", "\"$(SRCROOT)/external/libpqxx/include/pqxx/internal\"", - "\"$(SRCROOT)/external/\"", + "\"$(SRCROOT)/external/libpqxx/build/include\"", "\"$(SRCROOT)/external/boost-decimal/include\"", ); LIBRARY_SEARCH_PATHS = ( "\"$(SRCROOT)/external/libpqxx/build/src\"", - "/opt/homebrew/Cellar/postgresql@18/18.3/lib/postgresql", - "\"$(SRCROOT)/external/boost-decimal/build\"", + "/opt/homebrew/opt/postgresql@18/lib/postgresql", ); MACOSX_DEPLOYMENT_TARGET = 26.0; MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = ( + "-lpq", + "-lpqxx", + ); PRODUCT_BUNDLE_IDENTIFIER = com.mccaffers.tests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = NO; diff --git a/include/operations.hpp b/include/operations.hpp index cdb7cec..0a65f1d 100644 --- a/include/operations.hpp +++ b/include/operations.hpp @@ -7,9 +7,11 @@ #pragma once #include #include "models/priceData.hpp" +#include "trading_definitions/configuration.hpp" class Operations { - + public: - static void run(const std::vector& priceData); + static void run(const std::vector& priceData, + const trading_definitions::Configuration& config); }; diff --git a/include/trading_definitions/trading_variables.hpp b/include/trading_definitions/trading_variables.hpp index 08b6dd7..5a9fa8c 100644 --- a/include/trading_definitions/trading_variables.hpp +++ b/include/trading_definitions/trading_variables.hpp @@ -6,14 +6,16 @@ #pragma once #include +#include #include +#include "utilities/decimal_json.hpp" namespace trading_definitions { struct TradingVariables { std::string STRATEGY; - double STOP_DISTANCE_IN_PIPS; - double LIMIT_DISTANCE_IN_PIPS; - double TRADING_SIZE; + boost::decimal::decimal64_t STOP_DISTANCE_IN_PIPS; + boost::decimal::decimal64_t LIMIT_DISTANCE_IN_PIPS; + boost::decimal::decimal64_t TRADING_SIZE; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(TradingVariables, STRATEGY, diff --git a/include/utilities/decimal_json.hpp b/include/utilities/decimal_json.hpp new file mode 100644 index 0000000..2c56de3 --- /dev/null +++ b/include/utilities/decimal_json.hpp @@ -0,0 +1,51 @@ +// Backtesting Engine in C++ +// +// (c) 2026 Ryan McCaffery | https://mccaffers.com +// This code is licensed under MIT license (see LICENSE.txt for details) +// --------------------------------------- + +#pragma once + +#include +#include +#include +#include +#include +#include + +// Bridge boost::decimal::decimal64_t into nlohmann::json. Without this, +// NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE on structs containing decimal64_t fields +// fails to compile because the library can't find a (de)serializer for the type. +// +// Values move through JSON as strings (e.g. "0.0001") and are parsed with +// boost::decimal::from_chars. Going via a string skips the binary-float +// detour, so a literal like 0.1 in the source JSON survives the round-trip +// without snapping to the nearest IEEE-754 double. +// +// nlohmann's recommended way to add support for a third-party type is to +// specialize adl_serializer rather than injecting free functions into someone +// else's namespace. The C# analogue would be writing a custom JsonConverter +// and registering it on the serializer options. +namespace nlohmann { +template <> +struct adl_serializer { + static void to_json(json& j, const boost::decimal::decimal64_t& value) { + // 64 chars is comfortably above the longest possible decimal64_t + // representation (16 significant digits + sign + point + exponent). + char buffer[64]; + const auto result = boost::decimal::to_chars(buffer, buffer + sizeof(buffer), value); + if (result.ec != std::errc{}) { + throw std::runtime_error("decimal_json: to_chars failed serializing decimal64_t"); + } + j = std::string(buffer, result.ptr); + } + + static void from_json(const json& j, boost::decimal::decimal64_t& value) { + const auto& str = j.get_ref(); + const auto result = boost::decimal::from_chars(str.data(), str.data() + str.size(), value); + if (result.ec != std::errc{}) { + throw std::runtime_error("decimal_json: from_chars failed parsing '" + str + "'"); + } + } +}; +} diff --git a/resources/2020.csv b/resources/2020.csv deleted file mode 100644 index 66ea68b..0000000 --- a/resources/2020.csv +++ /dev/null @@ -1,500 +0,0 @@ -UTC,AskPrice,BidPrice -2020-01-01T22:01:12.821+00:00,1.1216,1.12106 -2020-01-01T22:01:17.176+00:00,1.1216,1.1212 -2020-01-01T22:01:18.545+00:00,1.1216,1.12117 -2020-01-01T22:01:19.145+00:00,1.12161,1.12123 -2020-01-01T22:01:19.246+00:00,1.12161,1.1212 -2020-01-01T22:01:21.124+00:00,1.12161,1.12122 -2020-01-01T22:01:21.274+00:00,1.1216,1.12126 -2020-01-01T22:01:21.324+00:00,1.12171,1.12126 -2020-01-01T22:01:21.455+00:00,1.12172,1.12126 -2020-01-01T22:01:21.506+00:00,1.12175,1.1213 -2020-01-01T22:01:21.785+00:00,1.12172,1.1213 -2020-01-01T22:01:21.836+00:00,1.12172,1.12126 -2020-01-01T22:01:21.937+00:00,1.12178,1.12126 -2020-01-01T22:01:22.069+00:00,1.12179,1.12126 -2020-01-01T22:01:22.119+00:00,1.12172,1.12126 -2020-01-01T22:01:22.396+00:00,1.12181,1.12126 -2020-01-01T22:01:22.449+00:00,1.12171,1.12126 -2020-01-01T22:01:22.559+00:00,1.12172,1.12126 -2020-01-01T22:01:22.716+00:00,1.12185,1.12126 -2020-01-01T22:01:27.502+00:00,1.12172,1.12126 -2020-01-01T22:01:27.846+00:00,1.1218,1.12126 -2020-01-01T22:01:28.396+00:00,1.12179,1.12126 -2020-01-01T22:01:37.499+00:00,1.12172,1.12126 -2020-01-01T22:01:40.500+00:00,1.12172,1.12125 -2020-01-01T22:01:45.244+00:00,1.12172,1.12134 -2020-01-01T22:01:45.345+00:00,1.12172,1.12135 -2020-01-01T22:02:52.348+00:00,1.12172,1.12136 -2020-01-01T22:02:52.624+00:00,1.12171,1.12137 -2020-01-01T22:02:52.675+00:00,1.12174,1.12137 -2020-01-01T22:02:52.776+00:00,1.12179,1.12137 -2020-01-01T22:02:57.414+00:00,1.12178,1.12137 -2020-01-01T22:02:57.474+00:00,1.12178,1.12139 -2020-01-01T22:02:57.575+00:00,1.12172,1.12138 -2020-01-01T22:02:58.166+00:00,1.12172,1.12139 -2020-01-01T22:03:00.209+00:00,1.12171,1.12135 -2020-01-01T22:03:01.261+00:00,1.12172,1.12132 -2020-01-01T22:03:01.311+00:00,1.12172,1.12134 -2020-01-01T22:03:01.440+00:00,1.12172,1.12135 -2020-01-01T22:03:01.744+00:00,1.12172,1.12132 -2020-01-01T22:03:03.086+00:00,1.12172,1.1213 -2020-01-01T22:03:07.562+00:00,1.12172,1.12132 -2020-01-01T22:03:14.453+00:00,1.12172,1.12132 -2020-01-01T22:03:34.696+00:00,1.12172,1.1212 -2020-01-01T22:03:41.249+00:00,1.12172,1.1212 -2020-01-01T22:03:41.475+00:00,1.12171,1.1212 -2020-01-01T22:03:41.626+00:00,1.12172,1.1212 -2020-01-01T22:03:42.006+00:00,1.12171,1.1212 -2020-01-01T22:03:43.153+00:00,1.12171,1.1212 -2020-01-01T22:03:45.256+00:00,1.12171,1.12122 -2020-01-01T22:03:47.509+00:00,1.12172,1.12122 -2020-01-01T22:03:54.499+00:00,1.12172,1.12122 -2020-01-01T22:04:03.124+00:00,1.12171,1.12122 -2020-01-01T22:04:05.077+00:00,1.12171,1.12125 -2020-01-01T22:04:08.430+00:00,1.12172,1.12125 -2020-01-01T22:04:08.655+00:00,1.12151,1.12125 -2020-01-01T22:04:10.030+00:00,1.12151,1.12125 -2020-01-01T22:04:19.536+00:00,1.12151,1.12125 -2020-01-01T22:04:23.784+00:00,1.12151,1.12125 -2020-01-01T22:05:04.031+00:00,1.12151,1.12125 -2020-01-01T22:05:08.815+00:00,1.12172,1.12125 -2020-01-01T22:05:11.422+00:00,1.1216,1.12125 -2020-01-01T22:05:11.787+00:00,1.12159,1.12125 -2020-01-01T22:05:26.132+00:00,1.12159,1.12125 -2020-01-01T22:05:32.614+00:00,1.12159,1.12127 -2020-01-01T22:05:35.163+00:00,1.12159,1.12127 -2020-01-01T22:05:45.948+00:00,1.12159,1.12127 -2020-01-01T22:05:56.712+00:00,1.12159,1.12127 -2020-01-01T22:06:01.664+00:00,1.12159,1.12127 -2020-01-01T22:06:10.046+00:00,1.12158,1.12127 -2020-01-01T22:06:11.046+00:00,1.12159,1.12127 -2020-01-01T22:06:11.950+00:00,1.12169,1.12127 -2020-01-01T22:06:26.423+00:00,1.12174,1.12127 -2020-01-01T22:06:26.644+00:00,1.12172,1.12127 -2020-01-01T22:06:27.664+00:00,1.12174,1.12127 -2020-01-01T22:06:27.993+00:00,1.12141,1.12127 -2020-01-01T22:06:40.199+00:00,1.12143,1.12127 -2020-01-01T22:06:44.018+00:00,1.12135,1.12127 -2020-01-01T22:06:44.123+00:00,1.12134,1.12127 -2020-01-01T22:06:44.226+00:00,1.12135,1.12127 -2020-01-01T22:06:51.614+00:00,1.1214,1.12127 -2020-01-01T22:07:51.616+00:00,1.12149,1.12127 -2020-01-01T22:07:51.946+00:00,1.12159,1.12127 -2020-01-01T22:07:54.047+00:00,1.12175,1.12127 -2020-01-01T22:08:09.824+00:00,1.12133,1.12127 -2020-01-01T22:08:29.146+00:00,1.12146,1.12127 -2020-01-01T22:08:29.303+00:00,1.1215,1.12127 -2020-01-01T22:09:09.888+00:00,1.12158,1.12127 -2020-01-01T22:09:14.440+00:00,1.12168,1.12127 -2020-01-01T22:09:20.078+00:00,1.12168,1.12127 -2020-01-01T22:09:32.852+00:00,1.12169,1.12127 -2020-01-01T22:09:32.953+00:00,1.12168,1.12127 -2020-01-01T22:09:35.008+00:00,1.12167,1.12127 -2020-01-01T22:09:35.534+00:00,1.12168,1.12127 -2020-01-01T22:09:36.619+00:00,1.12162,1.12127 -2020-01-01T22:09:37.546+00:00,1.1216,1.12127 -2020-01-01T22:09:45.214+00:00,1.12168,1.12127 -2020-01-01T22:09:51.225+00:00,1.1216,1.12127 -2020-01-01T22:09:54.745+00:00,1.12159,1.12127 -2020-01-01T22:09:55.265+00:00,1.12158,1.12127 -2020-01-01T22:09:57.286+00:00,1.12159,1.12127 -2020-01-01T22:10:00.093+00:00,1.12158,1.12127 -2020-01-01T22:10:00.338+00:00,1.12157,1.12127 -2020-01-01T22:10:00.439+00:00,1.12158,1.12127 -2020-01-01T22:10:01.245+00:00,1.12157,1.12127 -2020-01-01T22:10:01.856+00:00,1.12159,1.12127 -2020-01-01T22:10:10.765+00:00,1.12158,1.12127 -2020-01-01T22:10:14.386+00:00,1.12153,1.12127 -2020-01-01T22:10:32.247+00:00,1.12152,1.12127 -2020-01-01T22:10:35.596+00:00,1.1213,1.12127 -2020-01-01T22:10:35.697+00:00,1.12124,1.12123 -2020-01-01T22:10:35.748+00:00,1.12126,1.12125 -2020-01-01T22:10:35.799+00:00,1.12151,1.12127 -2020-01-01T22:10:35.995+00:00,1.12152,1.12127 -2020-01-01T22:11:29.542+00:00,1.12146,1.12127 -2020-01-01T22:12:03.340+00:00,1.12149,1.12127 -2020-01-01T22:12:03.391+00:00,1.12162,1.12127 -2020-01-01T22:12:03.493+00:00,1.12154,1.12127 -2020-01-01T22:12:17.080+00:00,1.12162,1.12127 -2020-01-01T22:12:27.089+00:00,1.1216,1.12127 -2020-01-01T22:12:36.681+00:00,1.12162,1.12127 -2020-01-01T22:12:50.735+00:00,1.12161,1.12127 -2020-01-01T22:12:50.787+00:00,1.12152,1.12127 -2020-01-01T22:13:01.458+00:00,1.12159,1.12127 -2020-01-01T22:13:01.742+00:00,1.12158,1.12127 -2020-01-01T22:13:01.843+00:00,1.12157,1.12127 -2020-01-01T22:13:01.944+00:00,1.12155,1.12127 -2020-01-01T22:13:02.863+00:00,1.12154,1.12127 -2020-01-01T22:13:03.557+00:00,1.12153,1.12127 -2020-01-01T22:13:05.385+00:00,1.12154,1.12127 -2020-01-01T22:13:07.684+00:00,1.12152,1.12127 -2020-01-01T22:13:09.552+00:00,1.12153,1.12127 -2020-01-01T22:13:09.745+00:00,1.12152,1.12127 -2020-01-01T22:13:13.565+00:00,1.12154,1.12127 -2020-01-01T22:13:14.430+00:00,1.12153,1.12127 -2020-01-01T22:13:15.254+00:00,1.12154,1.12127 -2020-01-01T22:13:20.370+00:00,1.1215,1.12127 -2020-01-01T22:13:21.859+00:00,1.12149,1.12127 -2020-01-01T22:13:28.663+00:00,1.12148,1.12127 -2020-01-01T22:13:31.318+00:00,1.12155,1.12127 -2020-01-01T22:13:31.598+00:00,1.12154,1.12127 -2020-01-01T22:13:33.070+00:00,1.12151,1.12127 -2020-01-01T22:13:37.539+00:00,1.1215,1.12127 -2020-01-01T22:13:44.892+00:00,1.12151,1.12127 -2020-01-01T22:14:03.373+00:00,1.12148,1.12127 -2020-01-01T22:14:04.946+00:00,1.12147,1.12127 -2020-01-01T22:14:05.430+00:00,1.12151,1.12127 -2020-01-01T22:14:05.531+00:00,1.12152,1.12127 -2020-01-01T22:14:05.633+00:00,1.1215,1.12127 -2020-01-01T22:14:10.244+00:00,1.12151,1.12127 -2020-01-01T22:14:39.546+00:00,1.12152,1.12127 -2020-01-01T22:14:52.289+00:00,1.12151,1.12127 -2020-01-01T22:14:57.884+00:00,1.12152,1.12127 -2020-01-01T22:15:04.456+00:00,1.1215,1.12127 -2020-01-01T22:15:04.704+00:00,1.12152,1.12127 -2020-01-01T22:15:08.689+00:00,1.12144,1.12127 -2020-01-01T22:15:08.740+00:00,1.12146,1.12127 -2020-01-01T22:15:09.800+00:00,1.12144,1.12127 -2020-01-01T22:15:11.165+00:00,1.12145,1.12127 -2020-01-01T22:15:11.630+00:00,1.12147,1.12127 -2020-01-01T22:15:11.681+00:00,1.12145,1.12127 -2020-01-01T22:15:12.394+00:00,1.12147,1.12127 -2020-01-01T22:15:12.496+00:00,1.12145,1.12127 -2020-01-01T22:15:12.647+00:00,1.12146,1.12127 -2020-01-01T22:15:12.836+00:00,1.12145,1.12127 -2020-01-01T22:15:13.779+00:00,1.12146,1.12127 -2020-01-01T22:15:14.083+00:00,1.12145,1.12127 -2020-01-01T22:15:14.206+00:00,1.12146,1.12127 -2020-01-01T22:15:14.893+00:00,1.12144,1.12127 -2020-01-01T22:15:15.548+00:00,1.12145,1.12127 -2020-01-01T22:15:16.769+00:00,1.12146,1.12127 -2020-01-01T22:15:17.578+00:00,1.12145,1.12127 -2020-01-01T22:15:21.708+00:00,1.12146,1.12127 -2020-01-01T22:15:22.259+00:00,1.12145,1.12127 -2020-01-01T22:15:24.092+00:00,1.12146,1.12127 -2020-01-01T22:15:24.385+00:00,1.12145,1.12127 -2020-01-01T22:15:26.971+00:00,1.12146,1.12127 -2020-01-01T22:15:27.671+00:00,1.12145,1.12127 -2020-01-01T22:15:29.336+00:00,1.12146,1.12127 -2020-01-01T22:15:30.395+00:00,1.12145,1.12127 -2020-01-01T22:15:31.075+00:00,1.12146,1.12127 -2020-01-01T22:15:31.277+00:00,1.12145,1.12127 -2020-01-01T22:15:31.430+00:00,1.12148,1.12127 -2020-01-01T22:15:31.481+00:00,1.12159,1.12135 -2020-01-01T22:15:31.532+00:00,1.12152,1.12135 -2020-01-01T22:15:31.582+00:00,1.12152,1.12127 -2020-01-01T22:15:32.015+00:00,1.1215,1.12127 -2020-01-01T22:15:32.415+00:00,1.12149,1.12127 -2020-01-01T22:15:32.915+00:00,1.1215,1.12127 -2020-01-01T22:15:33.415+00:00,1.12152,1.12127 -2020-01-01T22:15:33.876+00:00,1.12158,1.12127 -2020-01-01T22:15:35.865+00:00,1.12157,1.12127 -2020-01-01T22:15:36.365+00:00,1.12158,1.12127 -2020-01-01T22:15:36.898+00:00,1.12157,1.12127 -2020-01-01T22:15:36.949+00:00,1.12159,1.12127 -2020-01-01T22:15:37.050+00:00,1.1216,1.12127 -2020-01-01T22:15:37.395+00:00,1.12159,1.12127 -2020-01-01T22:15:37.539+00:00,1.12158,1.12127 -2020-01-01T22:15:37.590+00:00,1.1216,1.12127 -2020-01-01T22:15:37.693+00:00,1.12157,1.12127 -2020-01-01T22:15:43.523+00:00,1.12156,1.12127 -2020-01-01T22:15:43.625+00:00,1.12157,1.12127 -2020-01-01T22:15:44.607+00:00,1.12158,1.12127 -2020-01-01T22:16:03.424+00:00,1.12156,1.12127 -2020-01-01T22:16:03.526+00:00,1.12149,1.12127 -2020-01-01T22:17:29.219+00:00,1.12149,1.12128 -2020-01-01T22:17:29.270+00:00,1.1216,1.12152 -2020-01-01T22:17:29.321+00:00,1.12166,1.12154 -2020-01-01T22:17:29.372+00:00,1.12166,1.12144 -2020-01-01T22:17:29.473+00:00,1.12166,1.12143 -2020-01-01T22:17:31.326+00:00,1.12166,1.12152 -2020-01-01T22:17:31.428+00:00,1.12166,1.12143 -2020-01-01T22:17:33.372+00:00,1.12166,1.12151 -2020-01-01T22:17:34.332+00:00,1.12166,1.12148 -2020-01-01T22:17:35.312+00:00,1.12166,1.12154 -2020-01-01T22:17:35.514+00:00,1.12166,1.12152 -2020-01-01T22:18:03.232+00:00,1.12155,1.12152 -2020-01-01T22:18:03.333+00:00,1.12155,1.12151 -2020-01-01T22:18:03.384+00:00,1.12155,1.12148 -2020-01-01T22:18:04.293+00:00,1.12155,1.12154 -2020-01-01T22:18:04.520+00:00,1.12153,1.12151 -2020-01-01T22:18:59.521+00:00,1.12154,1.12151 -2020-01-01T22:19:04.466+00:00,1.12169,1.12151 -2020-01-01T22:19:04.517+00:00,1.12154,1.12151 -2020-01-01T22:19:07.750+00:00,1.12151,1.12146 -2020-01-01T22:19:07.801+00:00,1.12151,1.12145 -2020-01-01T22:19:07.851+00:00,1.12147,1.12143 -2020-01-01T22:19:07.952+00:00,1.12146,1.12142 -2020-01-01T22:19:12.414+00:00,1.12144,1.12135 -2020-01-01T22:19:12.567+00:00,1.12146,1.12142 -2020-01-01T22:19:12.719+00:00,1.12143,1.12135 -2020-01-01T22:19:12.771+00:00,1.12145,1.12142 -2020-01-01T22:19:12.822+00:00,1.12143,1.12135 -2020-01-01T22:19:19.465+00:00,1.12143,1.12136 -2020-01-01T22:19:19.922+00:00,1.12143,1.12137 -2020-01-01T22:19:23.464+00:00,1.12151,1.12143 -2020-01-01T22:19:23.566+00:00,1.12151,1.12144 -2020-01-01T22:19:25.329+00:00,1.12151,1.12145 -2020-01-01T22:19:25.775+00:00,1.12151,1.12145 -2020-01-01T22:19:37.961+00:00,1.12151,1.12146 -2020-01-01T22:19:38.163+00:00,1.12151,1.12146 -2020-01-01T22:19:38.214+00:00,1.12151,1.12146 -2020-01-01T22:19:38.265+00:00,1.12151,1.12145 -2020-01-01T22:19:38.678+00:00,1.12151,1.12146 -2020-01-01T22:19:38.779+00:00,1.12151,1.12145 -2020-01-01T22:19:38.830+00:00,1.12151,1.12146 -2020-01-01T22:19:38.881+00:00,1.12151,1.12145 -2020-01-01T22:19:47.593+00:00,1.12151,1.12146 -2020-01-01T22:19:47.695+00:00,1.12151,1.12146 -2020-01-01T22:19:47.796+00:00,1.12151,1.12146 -2020-01-01T22:19:47.897+00:00,1.12151,1.12146 -2020-01-01T22:19:49.838+00:00,1.12151,1.12146 -2020-01-01T22:19:50.142+00:00,1.12151,1.12146 -2020-01-01T22:19:52.157+00:00,1.1215,1.12145 -2020-01-01T22:19:52.259+00:00,1.12151,1.12146 -2020-01-01T22:19:52.411+00:00,1.12151,1.12146 -2020-01-01T22:19:52.461+00:00,1.12151,1.12146 -2020-01-01T22:19:52.512+00:00,1.12151,1.12146 -2020-01-01T22:19:52.563+00:00,1.12151,1.12146 -2020-01-01T22:19:52.664+00:00,1.12151,1.12146 -2020-01-01T22:20:05.343+00:00,1.12151,1.12144 -2020-01-01T22:20:05.488+00:00,1.12151,1.12139 -2020-01-01T22:20:06.055+00:00,1.12151,1.12144 -2020-01-01T22:20:06.106+00:00,1.12151,1.1214 -2020-01-01T22:20:06.311+00:00,1.12151,1.12144 -2020-01-01T22:20:06.362+00:00,1.12151,1.1214 -2020-01-01T22:20:08.954+00:00,1.12152,1.1214 -2020-01-01T22:20:09.923+00:00,1.12152,1.12138 -2020-01-01T22:20:16.497+00:00,1.12152,1.12139 -2020-01-01T22:20:17.494+00:00,1.12151,1.12139 -2020-01-01T22:20:37.485+00:00,1.12151,1.12141 -2020-01-01T22:20:37.866+00:00,1.12151,1.12144 -2020-01-01T22:20:37.916+00:00,1.12151,1.12141 -2020-01-01T22:20:37.967+00:00,1.12151,1.12144 -2020-01-01T22:20:38.018+00:00,1.12151,1.12141 -2020-01-01T22:20:38.069+00:00,1.12151,1.12144 -2020-01-01T22:20:38.119+00:00,1.12151,1.12141 -2020-01-01T22:20:38.375+00:00,1.12151,1.12145 -2020-01-01T22:20:38.426+00:00,1.12151,1.12139 -2020-01-01T22:20:38.527+00:00,1.12152,1.12139 -2020-01-01T22:20:38.966+00:00,1.12152,1.12138 -2020-01-01T22:20:39.067+00:00,1.12151,1.12138 -2020-01-01T22:20:39.875+00:00,1.12151,1.12142 -2020-01-01T22:20:47.544+00:00,1.12151,1.12141 -2020-01-01T22:20:47.645+00:00,1.12151,1.1214 -2020-01-01T22:20:50.204+00:00,1.12151,1.12141 -2020-01-01T22:20:50.305+00:00,1.12151,1.1214 -2020-01-01T22:20:57.585+00:00,1.12151,1.12144 -2020-01-01T22:20:57.641+00:00,1.12151,1.1214 -2020-01-01T22:20:57.691+00:00,1.1215,1.12143 -2020-01-01T22:20:57.742+00:00,1.12151,1.1214 -2020-01-01T22:20:57.945+00:00,1.1215,1.12144 -2020-01-01T22:20:57.995+00:00,1.12151,1.1214 -2020-01-01T22:20:58.756+00:00,1.12151,1.12141 -2020-01-01T22:20:58.857+00:00,1.12151,1.12144 -2020-01-01T22:20:58.908+00:00,1.12151,1.1214 -2020-01-01T22:20:59.010+00:00,1.12151,1.12143 -2020-01-01T22:20:59.061+00:00,1.12151,1.1214 -2020-01-01T22:20:59.162+00:00,1.12151,1.12143 -2020-01-01T22:20:59.364+00:00,1.12151,1.1214 -2020-01-01T22:21:00.180+00:00,1.12151,1.12139 -2020-01-01T22:21:01.186+00:00,1.1215,1.12139 -2020-01-01T22:21:01.288+00:00,1.12151,1.12139 -2020-01-01T22:21:01.797+00:00,1.1215,1.12139 -2020-01-01T22:21:01.898+00:00,1.12151,1.12139 -2020-01-01T22:21:02.253+00:00,1.1215,1.12139 -2020-01-01T22:21:02.355+00:00,1.12151,1.12139 -2020-01-01T22:21:03.567+00:00,1.1215,1.12139 -2020-01-01T22:21:03.669+00:00,1.12151,1.12139 -2020-01-01T22:21:03.871+00:00,1.1215,1.12139 -2020-01-01T22:21:04.022+00:00,1.12151,1.12139 -2020-01-01T22:21:04.427+00:00,1.1215,1.12139 -2020-01-01T22:21:04.528+00:00,1.12151,1.12139 -2020-01-01T22:21:04.832+00:00,1.1215,1.12139 -2020-01-01T22:21:04.983+00:00,1.12151,1.12139 -2020-01-01T22:21:05.186+00:00,1.1215,1.12139 -2020-01-01T22:21:05.287+00:00,1.12151,1.12139 -2020-01-01T22:21:05.389+00:00,1.1215,1.12139 -2020-01-01T22:21:05.491+00:00,1.12151,1.12139 -2020-01-01T22:21:07.542+00:00,1.12152,1.12139 -2020-01-01T22:21:07.644+00:00,1.12152,1.12141 -2020-01-01T22:21:07.746+00:00,1.12152,1.12139 -2020-01-01T22:21:07.811+00:00,1.12151,1.12141 -2020-01-01T22:21:07.913+00:00,1.12152,1.12141 -2020-01-01T22:21:08.117+00:00,1.12152,1.12137 -2020-01-01T22:21:08.270+00:00,1.12151,1.12137 -2020-01-01T22:21:08.373+00:00,1.12151,1.12138 -2020-01-01T22:21:09.084+00:00,1.12151,1.12139 -2020-01-01T22:21:11.173+00:00,1.12152,1.12139 -2020-01-01T22:21:11.225+00:00,1.1215,1.12139 -2020-01-01T22:21:11.283+00:00,1.12152,1.12139 -2020-01-01T22:21:11.486+00:00,1.12151,1.12139 -2020-01-01T22:21:11.587+00:00,1.12152,1.12139 -2020-01-01T22:21:11.892+00:00,1.12152,1.12141 -2020-01-01T22:21:11.993+00:00,1.12151,1.12141 -2020-01-01T22:21:12.095+00:00,1.12152,1.12141 -2020-01-01T22:21:12.246+00:00,1.12151,1.12141 -2020-01-01T22:21:12.651+00:00,1.12151,1.1214 -2020-01-01T22:21:12.752+00:00,1.12151,1.12142 -2020-01-01T22:21:12.803+00:00,1.12151,1.1214 -2020-01-01T22:21:13.119+00:00,1.12151,1.12139 -2020-01-01T22:21:13.323+00:00,1.12152,1.12139 -2020-01-01T22:21:13.906+00:00,1.12151,1.12139 -2020-01-01T22:21:14.007+00:00,1.12152,1.12139 -2020-01-01T22:21:14.159+00:00,1.12151,1.12139 -2020-01-01T22:21:14.260+00:00,1.12152,1.12139 -2020-01-01T22:21:14.665+00:00,1.12151,1.12139 -2020-01-01T22:21:14.767+00:00,1.12152,1.12139 -2020-01-01T22:21:16.921+00:00,1.12151,1.12139 -2020-01-01T22:21:18.903+00:00,1.12152,1.12148 -2020-01-01T22:21:19.004+00:00,1.12164,1.12149 -2020-01-01T22:21:19.394+00:00,1.12164,1.12147 -2020-01-01T22:21:19.965+00:00,1.12164,1.12146 -2020-01-01T22:21:34.096+00:00,1.12167,1.12147 -2020-01-01T22:21:34.147+00:00,1.12164,1.12147 -2020-01-01T22:21:40.160+00:00,1.12167,1.12146 -2020-01-01T22:21:40.261+00:00,1.12167,1.12147 -2020-01-01T22:21:51.404+00:00,1.12164,1.12147 -2020-01-01T22:22:07.565+00:00,1.12166,1.12147 -2020-01-01T22:22:14.127+00:00,1.12164,1.12147 -2020-01-01T22:22:22.327+00:00,1.12166,1.12147 -2020-01-01T22:22:25.066+00:00,1.12164,1.12147 -2020-01-01T22:22:35.208+00:00,1.12165,1.12147 -2020-01-01T22:23:01.150+00:00,1.12165,1.12151 -2020-01-01T22:23:01.201+00:00,1.12164,1.12146 -2020-01-01T22:23:13.507+00:00,1.12166,1.12146 -2020-01-01T22:23:24.298+00:00,1.12166,1.12147 -2020-01-01T22:23:25.320+00:00,1.12164,1.12147 -2020-01-01T22:23:30.176+00:00,1.12164,1.12145 -2020-01-01T22:24:01.846+00:00,1.12165,1.12146 -2020-01-01T22:24:04.905+00:00,1.12164,1.12146 -2020-01-01T22:24:11.804+00:00,1.12166,1.12146 -2020-01-01T22:24:12.846+00:00,1.12168,1.12146 -2020-01-01T22:24:12.947+00:00,1.12166,1.12146 -2020-01-01T22:24:13.129+00:00,1.12168,1.12146 -2020-01-01T22:24:13.180+00:00,1.12166,1.12146 -2020-01-01T22:24:13.351+00:00,1.12168,1.12146 -2020-01-01T22:24:13.452+00:00,1.12166,1.12146 -2020-01-01T22:24:13.503+00:00,1.12168,1.12146 -2020-01-01T22:24:13.554+00:00,1.12165,1.12146 -2020-01-01T22:24:13.604+00:00,1.12168,1.12146 -2020-01-01T22:24:13.655+00:00,1.12166,1.12146 -2020-01-01T22:24:13.706+00:00,1.12168,1.12146 -2020-01-01T22:24:13.757+00:00,1.12165,1.12146 -2020-01-01T22:24:13.807+00:00,1.12168,1.12146 -2020-01-01T22:24:13.858+00:00,1.12166,1.12146 -2020-01-01T22:24:14.868+00:00,1.12166,1.12153 -2020-01-01T22:24:14.919+00:00,1.12168,1.12153 -2020-01-01T22:24:14.970+00:00,1.12166,1.12147 -2020-01-01T22:24:15.021+00:00,1.12168,1.12147 -2020-01-01T22:24:15.072+00:00,1.12166,1.12147 -2020-01-01T22:24:15.122+00:00,1.12168,1.12147 -2020-01-01T22:24:15.173+00:00,1.12165,1.12147 -2020-01-01T22:24:15.224+00:00,1.12168,1.12147 -2020-01-01T22:24:15.667+00:00,1.12165,1.12147 -2020-01-01T22:24:15.869+00:00,1.12166,1.12147 -2020-01-01T22:24:16.196+00:00,1.12168,1.12147 -2020-01-01T22:24:16.297+00:00,1.12166,1.12147 -2020-01-01T22:24:16.449+00:00,1.12168,1.12147 -2020-01-01T22:24:16.499+00:00,1.12166,1.12147 -2020-01-01T22:24:16.601+00:00,1.12168,1.12147 -2020-01-01T22:24:16.652+00:00,1.12165,1.12147 -2020-01-01T22:24:16.703+00:00,1.12168,1.12147 -2020-01-01T22:24:16.754+00:00,1.12166,1.12147 -2020-01-01T22:24:16.805+00:00,1.12168,1.12147 -2020-01-01T22:24:16.856+00:00,1.12166,1.12147 -2020-01-01T22:24:16.906+00:00,1.12168,1.12147 -2020-01-01T22:24:18.143+00:00,1.12166,1.12147 -2020-01-01T22:24:28.233+00:00,1.12164,1.12147 -2020-01-01T22:24:30.667+00:00,1.12166,1.12152 -2020-01-01T22:24:30.718+00:00,1.12164,1.12147 -2020-01-01T22:24:30.819+00:00,1.12164,1.12146 -2020-01-01T22:24:30.870+00:00,1.12164,1.12153 -2020-01-01T22:24:30.921+00:00,1.12164,1.12146 -2020-01-01T22:24:30.972+00:00,1.12164,1.12152 -2020-01-01T22:24:31.022+00:00,1.12164,1.12148 -2020-01-01T22:24:31.124+00:00,1.12164,1.12146 -2020-01-01T22:24:31.225+00:00,1.12164,1.12147 -2020-01-01T22:24:31.327+00:00,1.12164,1.12146 -2020-01-01T22:24:31.630+00:00,1.12164,1.12147 -2020-01-01T22:24:31.732+00:00,1.12164,1.12146 -2020-01-01T22:24:32.735+00:00,1.12162,1.12146 -2020-01-01T22:24:36.031+00:00,1.12164,1.12146 -2020-01-01T22:25:36.303+00:00,1.12168,1.12146 -2020-01-01T22:25:40.332+00:00,1.12167,1.12146 -2020-01-01T22:26:11.024+00:00,1.12169,1.12146 -2020-01-01T22:26:21.689+00:00,1.12169,1.12147 -2020-01-01T22:26:42.181+00:00,1.12164,1.12141 -2020-01-01T22:27:37.187+00:00,1.12163,1.12141 -2020-01-01T22:28:07.559+00:00,1.12163,1.12142 -2020-01-01T22:28:12.672+00:00,1.12163,1.12139 -2020-01-01T22:28:32.185+00:00,1.12164,1.12139 -2020-01-01T22:29:27.190+00:00,1.12163,1.12139 -2020-01-01T22:29:35.369+00:00,1.12163,1.12144 -2020-01-01T22:29:35.912+00:00,1.12162,1.12142 -2020-01-01T22:29:39.892+00:00,1.12163,1.12144 -2020-01-01T22:29:41.310+00:00,1.12162,1.12142 -2020-01-01T22:29:42.335+00:00,1.12162,1.12144 -2020-01-01T22:29:42.639+00:00,1.12162,1.12142 -2020-01-01T22:29:44.514+00:00,1.12162,1.12144 -2020-01-01T22:29:51.789+00:00,1.12162,1.12142 -2020-01-01T22:29:52.801+00:00,1.12163,1.12144 -2020-01-01T22:29:53.818+00:00,1.12163,1.12146 -2020-01-01T22:30:00.040+00:00,1.12166,1.12147 -2020-01-01T22:30:00.091+00:00,1.12164,1.12147 -2020-01-01T22:30:00.142+00:00,1.12166,1.12147 -2020-01-01T22:30:01.125+00:00,1.12164,1.12147 -2020-01-01T22:30:02.039+00:00,1.12162,1.12147 -2020-01-01T22:30:02.089+00:00,1.12164,1.12147 -2020-01-01T22:30:02.191+00:00,1.1216,1.12147 -2020-01-01T22:30:02.241+00:00,1.12163,1.12147 -2020-01-01T22:30:02.343+00:00,1.12161,1.12147 -2020-01-01T22:30:03.326+00:00,1.12162,1.12147 -2020-01-01T22:30:11.345+00:00,1.12168,1.12146 -2020-01-01T22:30:11.396+00:00,1.1216,1.12138 -2020-01-01T22:30:11.497+00:00,1.12163,1.1215 -2020-01-01T22:30:11.649+00:00,1.12163,1.12146 -2020-01-01T22:30:17.493+00:00,1.12164,1.12146 -2020-01-01T22:30:19.602+00:00,1.12165,1.12146 -2020-01-01T22:30:36.454+00:00,1.12165,1.12151 -2020-01-01T22:30:36.690+00:00,1.12165,1.12146 -2020-01-01T22:30:37.498+00:00,1.12164,1.12146 -2020-01-01T22:30:39.612+00:00,1.12165,1.12146 -2020-01-01T22:30:47.493+00:00,1.12164,1.12146 -2020-01-01T22:30:54.560+00:00,1.12162,1.1215 -2020-01-01T22:30:54.611+00:00,1.12162,1.12146 -2020-01-01T22:31:09.644+00:00,1.12163,1.12146 -2020-01-01T22:31:11.473+00:00,1.12163,1.12144 -2020-01-01T22:31:12.156+00:00,1.12164,1.12144 -2020-01-01T22:31:12.207+00:00,1.12164,1.12148 -2020-01-01T22:31:17.428+00:00,1.12163,1.12148 -2020-01-01T22:31:18.529+00:00,1.12164,1.12148 -2020-01-01T22:31:19.705+00:00,1.12163,1.12148 -2020-01-01T22:31:29.605+00:00,1.12161,1.12148 -2020-01-01T22:31:29.655+00:00,1.12162,1.12146 -2020-01-01T22:31:37.493+00:00,1.12163,1.12146 -2020-01-01T22:31:49.646+00:00,1.12164,1.12148 -2020-01-01T22:31:58.245+00:00,1.12164,1.12147 -2020-01-01T22:31:58.347+00:00,1.12163,1.12147 -2020-01-01T22:32:39.659+00:00,1.12161,1.12147 -2020-01-01T22:32:44.359+00:00,1.12162,1.12147 -2020-01-01T22:32:44.409+00:00,1.12164,1.12147 -2020-01-01T22:32:47.495+00:00,1.12163,1.12147 -2020-01-01T22:32:49.641+00:00,1.12164,1.12152 -2020-01-01T22:32:49.794+00:00,1.12164,1.12148 -2020-01-01T22:32:57.494+00:00,1.12163,1.12148 -2020-01-01T22:33:07.492+00:00,1.12161,1.12148 -2020-01-01T22:33:07.594+00:00,1.12162,1.12147 -2020-01-01T22:33:09.641+00:00,1.12161,1.12147 -2020-01-01T22:33:17.493+00:00,1.12162,1.12147 -2020-01-01T22:33:37.530+00:00,1.12162,1.12145 -2020-01-01T22:34:04.615+00:00,1.12164,1.12151 -2020-01-01T22:34:04.717+00:00,1.12164,1.12149 -2020-01-01T22:34:07.493+00:00,1.12162,1.12149 -2020-01-01T22:34:07.544+00:00,1.12162,1.12146 -2020-01-01T22:34:29.655+00:00,1.12164,1.12147 -2020-01-01T22:34:32.420+00:00,1.12163,1.12147 -2020-01-01T22:34:37.493+00:00,1.12162,1.12147 -2020-01-01T22:34:39.775+00:00,1.1216,1.12146 -2020-01-01T22:34:41.474+00:00,1.12159,1.12146 \ No newline at end of file diff --git a/scripts/local_test_coverage.sh b/scripts/local_test_coverage.sh index a122e30..91d2e25 100644 --- a/scripts/local_test_coverage.sh +++ b/scripts/local_test_coverage.sh @@ -13,9 +13,6 @@ xcodebuild \ -resultBundlePath TestResult/ \ -enableCodeCoverage YES \ -derivedDataPath "/tmp" \ -HEADER_SEARCH_PATHS="./external/libpqxx/include/pqxx/internal ./external/libpqxx/include/ ./external/libpqxx/build/include/ ./external/" \ -LIBRARY_SEARCH_PATHS="./external/libpqxx/src/ ./external/libpqxx/build/src/" \ -OTHER_LDFLAGS="-L./external/libpqxx/build/src -lpqxx -lpq -L/opt/homebrew/Cellar/pkgconf/2.3.0_1/lib -L/opt/homebrew/Cellar/pkgconf/2.3.0_1/lib/pkgconfig -L/opt/homebrew/Cellar/postgresql@14/14.15/lib/postgresql@14 -L/opt/homebrew/Cellar/postgresql@14/14.15/lib/postgresql@14/pgxs -L/opt/homebrew/Cellar/postgresql@14/14.15/lib/postgresql@14/pkgconfig" \ clean build test bash ./.github/workflows/xccov-to-sonarqube-generic.sh *.xcresult/ > sonarqube-generic-coverage.xml \ No newline at end of file diff --git a/scripts/run.sh b/scripts/run.sh index e6231e4..70fe50b 100644 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -21,16 +21,16 @@ fi # "SYMBOLS": "EURUSD,AUSIDXAUD", json='{ - "RUN_ID": "UNIQUE_IDENTIFER", + "RUN_ID": "UNIQUE_IDENTIFIER", "SYMBOLS": "EURUSD", "LAST_MONTHS": 1, "STRATEGY": { "UUID": "", "TRADING_VARIABLES": { "STRATEGY": "OHLC_RSI", - "STOP_DISTANCE_IN_PIPS": 1, - "LIMIT_DISTANCE_IN_PIPS": 1, - "TRADING_SIZE": 1 + "STOP_DISTANCE_IN_PIPS": "1.5", + "LIMIT_DISTANCE_IN_PIPS": "1.5", + "TRADING_SIZE": "0.01" }, "OHLC_VARIABLES": [ { @@ -38,7 +38,7 @@ json='{ "OHLC_MINUTES": 100 } ], - "STRATEGY_VARIABLES" : { + "STRATEGY_VARIABLES": { "OHLC_RSI_VARIABLES": { "RSI_LONG": 60, "RSI_SHORT": 40 diff --git a/source/main.cpp b/source/main.cpp index 782e0f9..e1277dc 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -20,7 +20,7 @@ #include "serviceA.hpp" #include "databaseConnection.hpp" #include "base64.hpp" -#include "trading_definitions.hpp" // For everything +#include "trading_definitions.hpp" #include "tradeManager.hpp" #include "jsonParser.hpp" #include "sqlManager.hpp" @@ -51,11 +51,15 @@ int main(int argc, const char * argv[]) { for (std::string token; std::getline(ss, token, ',');) { symbols.push_back(token); } + + // Stream all the tick data into a vector std::vector ticks = SqlManager::streamPriceData(db, symbols, config.LAST_MONTHS); + + // TODO add a condition, if tick.size == zero printf("Total ticks streamed: %zu\n", ticks.size()); // Execute the backtest by replaying all ticks through the strategy logic - Operations::run(ticks); + Operations::run(ticks, config); return 0; diff --git a/source/operations.cpp b/source/operations.cpp index b35a22a..0a9b8ef 100644 --- a/source/operations.cpp +++ b/source/operations.cpp @@ -16,7 +16,8 @@ #include #include "tradeManager.hpp" -void Operations::run(const std::vector& ticks) { +void Operations::run(const std::vector& ticks, + const trading_definitions::Configuration& config) { // Create auto tradeManager = new TradeManager(); @@ -27,10 +28,7 @@ void Operations::run(const std::vector& ticks) { // this would be strategy invoke point if (openTrades == 0) { - // decimal64_t's int constructor is `explicit`, so the literal `1` - // can't implicitly convert — unlike C# where `1m` produces a - // decimal directly. Construct it explicitly via braced init. - std::string tradeId = tradeManager->openTrade(tick, boost::decimal::decimal64_t{1}, Direction::LONG); + std::string tradeId = tradeManager->openTrade(tick, config.STRATEGY.TRADING_VARIABLES.TRADING_SIZE, Direction::LONG); std::cout << "Opened trade: " << tradeId << std::endl; } diff --git a/tests/jsonParser.mm b/tests/jsonParser.mm index 4829238..d7dadc9 100644 --- a/tests/jsonParser.mm +++ b/tests/jsonParser.mm @@ -31,9 +31,9 @@ - (void)testValidJsonParsing { "UUID": "", "TRADING_VARIABLES": { "STRATEGY": "OHLC_RSI", - "STOP_DISTANCE_IN_PIPS": 1, - "LIMIT_DISTANCE_IN_PIPS": 1, - "TRADING_SIZE": 1 + "STOP_DISTANCE_IN_PIPS": "1", + "LIMIT_DISTANCE_IN_PIPS": "1", + "TRADING_SIZE": "1" }, "OHLC_VARIABLES": [ {