Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
with:
fetch-depth: 0
- name: Install dependencies
run: sudo apt install -y libssl-dev libpq-dev
run: sudo apt install -y libssl-dev libpq-dev libcurl4-openssl-dev
# Ubuntu's apt Boost (1.83 on 24.04) predates Boost.Redis, which was added
# in Boost 1.84, so <boost/redis.hpp> is absent. Install a newer Boost.
# Boost.Redis/Asio are header-only, so we only need the headers plus the
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ endif()
find_package(Boost REQUIRED CONFIG)
find_package(OpenSSL REQUIRED)
find_package(Threads REQUIRED)
find_package(CURL REQUIRED)
target_link_libraries(BacktestingEngineLib PUBLIC
Boost::headers
OpenSSL::SSL
OpenSSL::Crypto
Threads::Threads)
Threads::Threads
CURL::libcurl)

add_subdirectory(external/boost-decimal)
target_link_libraries(BacktestingEngineLib PUBLIC Boost::decimal)
Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,28 @@ Xcode - Library Path

`bash ./scripts/build.sh`

### Environment variables

The engine reads its connection configuration from the environment. The following variables are **required** — `scripts/run.sh` validates them up front and aborts if any are missing or empty:

| Variable | Used for |
| --- | --- |
| `ELASTIC_HOST` | Elasticsearch base URL that trading results are PUT to (e.g. `https://elastic.example.com:9200`) |
| `ELASTIC_USER` | Elasticsearch HTTP basic-auth username |
| `ELASTIC_USER_PASSWORD` | Elasticsearch HTTP basic-auth password |
| `REDIS_HOST` | Redis host for the `strategy_queue` list |

I manage these secrets with [Infisical](https://infisical.com/), which injects them into the process environment at runtime, so I run the engine with:

```
infisical run -- sh ./scripts/run.sh
```

If you're not using Infisical, export the variables yourself (e.g. via your shell profile or a sourced `.env`) before invoking the script.

### Run via terminal

`bash ./scripts/run.sh` builds the project, then, if `redis-cli ping` reaches a local Redis, enqueues an inline JSON strategy via `load` and executes it via `run localhost`. If Redis is unreachable the script prints a message and exits cleanly (see `scripts/run.sh:22-25`), so first-time users without Redis still get a clear signal.
`bash ./scripts/run.sh` builds the project, then, if `redis-cli ping` reaches a local Redis, enqueues an inline JSON strategy via `load` and executes it via `run localhost`. If Redis is unreachable the script prints a message and exits cleanly (see `scripts/run.sh:22-25`), so first-time users without Redis still get a clear signal. The script requires the [environment variables](#environment-variables) listed above; with Infisical that becomes `infisical run -- sh ./scripts/run.sh`.

The `BacktestingEngine` binary exposes a subcommand CLI:

Expand Down
40 changes: 35 additions & 5 deletions backtesting-engine-cpp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
942EC56A2FBEF95000CCBB5D /* backtestRunner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942EC5642FBEF95000CCBB5D /* backtestRunner.cpp */; };
942EC56B2FBEF95000CCBB5D /* redisLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942EC5652FBEF95000CCBB5D /* redisLoader.cpp */; };
942EC56C2FBEF95000CCBB5D /* redisRunner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942EC5662FBEF95000CCBB5D /* redisRunner.cpp */; };
942FDDE02FC5C8B20096F318 /* tradingResults.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942FDDDF2FC5C8B20096F318 /* tradingResults.cpp */; };
942FDDE12FC5C8B20096F318 /* elasticClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942FDDDE2FC5C8B20096F318 /* elasticClient.cpp */; };
942FDDE22FC5C8B20096F318 /* tradingResults.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942FDDDF2FC5C8B20096F318 /* tradingResults.cpp */; };
942FDDE32FC5C8B20096F318 /* elasticClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 942FDDDE2FC5C8B20096F318 /* elasticClient.cpp */; };
942FDDE52FC5C9D30096F318 /* libcurl.4.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 942FDDE42FC5C9D30096F318 /* libcurl.4.tbd */; };
942FDDE62FC5C9DB0096F318 /* libcurl.4.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 942FDDE42FC5C9D30096F318 /* libcurl.4.tbd */; };
943398242D57E53400287A2D /* jsonParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 943398232D57E53400287A2D /* jsonParser.cpp */; };
943398252D57E53400287A2D /* jsonParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 943398232D57E53400287A2D /* jsonParser.cpp */; };
943398272D57E54000287A2D /* jsonParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 943398262D57E54000287A2D /* jsonParser.mm */; };
Expand All @@ -41,6 +47,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 */; };
94829FC52FCC1D1A00710E6E /* env.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94829FC42FCC1D1A00710E6E /* env.cpp */; };
94829FC62FCC1D1A00710E6E /* env.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94829FC42FCC1D1A00710E6E /* env.cpp */; };
94CD8BA02D2E8CE500041BBA /* databaseConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD8B9F2D2E8CE500041BBA /* databaseConnection.cpp */; };
94CD8BA12D2E8CE500041BBA /* databaseConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CD8B9F2D2E8CE500041BBA /* databaseConnection.cpp */; };
94D3A7262FC1B3AD00EBEA32 /* loadCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D3A7242FC1B3AD00EBEA32 /* loadCommand.cpp */; };
Expand Down Expand Up @@ -90,6 +98,11 @@
942EC5642FBEF95000CCBB5D /* backtestRunner.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = backtestRunner.cpp; sourceTree = "<group>"; };
942EC5652FBEF95000CCBB5D /* redisLoader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = redisLoader.cpp; sourceTree = "<group>"; };
942EC5662FBEF95000CCBB5D /* redisRunner.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = redisRunner.cpp; sourceTree = "<group>"; };
942FDDDC2FC5C8950096F318 /* elasticClient.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = elasticClient.hpp; sourceTree = "<group>"; };
942FDDDD2FC5C8A30096F318 /* tradingResults.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = tradingResults.hpp; sourceTree = "<group>"; };
942FDDDE2FC5C8B20096F318 /* elasticClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = elasticClient.cpp; sourceTree = "<group>"; };
942FDDDF2FC5C8B20096F318 /* tradingResults.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = tradingResults.cpp; sourceTree = "<group>"; };
942FDDE42FC5C9D30096F318 /* libcurl.4.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.4.tbd; path = usr/lib/libcurl.4.tbd; sourceTree = SDKROOT; };
943398222D57E52900287A2D /* jsonParser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = jsonParser.hpp; sourceTree = "<group>"; };
943398232D57E53400287A2D /* jsonParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = jsonParser.cpp; sourceTree = "<group>"; };
943398262D57E54000287A2D /* jsonParser.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = jsonParser.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -119,6 +132,8 @@
9470B5AC2C8C5B99007D9CC6 /* tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
94724A822F8B92C10029B940 /* operations.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = operations.cpp; sourceTree = "<group>"; };
94724A852F8B92E30029B940 /* operations.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = operations.hpp; sourceTree = "<group>"; };
94829FC32FCC1D1200710E6E /* env.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = env.hpp; sourceTree = "<group>"; };
94829FC42FCC1D1A00710E6E /* env.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = env.cpp; sourceTree = "<group>"; };
948A9CCD2C906A5600E23669 /* CONVENTIONS.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONVENTIONS.md; sourceTree = "<group>"; };
94BBA4512D2EA2640010E04D /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = "<group>"; };
94C331A02FA899A8006BD690 /* decimal_json.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = decimal_json.hpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1296,13 +1311,15 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
942FDDE62FC5C9DB0096F318 /* libcurl.4.tbd in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
9470B5A92C8C5B99007D9CC6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
942FDDE52FC5C9D30096F318 /* libcurl.4.tbd in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1333,6 +1350,7 @@
94280BA72D2FC29F00F1CF56 /* utilities */ = {
isa = PBXGroup;
children = (
94829FC42FCC1D1A00710E6E /* env.cpp */,
942EC5612FBEF94700CCBB5D /* redisConnection.cpp */,
94280BA22D2FC00200F1CF56 /* base64.cpp */,
943398232D57E53400287A2D /* jsonParser.cpp */,
Expand Down Expand Up @@ -1436,6 +1454,8 @@
94280BA72D2FC29F00F1CF56 /* utilities */,
942EC5642FBEF95000CCBB5D /* backtestRunner.cpp */,
942EC5652FBEF95000CCBB5D /* redisLoader.cpp */,
942FDDDE2FC5C8B20096F318 /* elasticClient.cpp */,
942FDDDF2FC5C8B20096F318 /* tradingResults.cpp */,
942EC5662FBEF95000CCBB5D /* redisRunner.cpp */,
9470B5A32C8C5AD0007D9CC6 /* main.cpp */,
940A61112C92CE210083FEB8 /* configManager.cpp */,
Expand All @@ -1461,6 +1481,7 @@
94B8C7932D3D770800E17EB6 /* utilities */ = {
isa = PBXGroup;
children = (
94829FC32FCC1D1200710E6E /* env.hpp */,
942EC55D2FBEF92F00CCBB5D /* redisConnection.hpp */,
94C331A02FA899A8006BD690 /* decimal_json.hpp */,
94280BA12D2FC00200F1CF56 /* base64.hpp */,
Expand Down Expand Up @@ -2218,6 +2239,7 @@
94CD87342D2D2EE100041BBA /* Frameworks */ = {
isa = PBXGroup;
children = (
942FDDE42FC5C9D30096F318 /* libcurl.4.tbd */,
94CD8B982D2DCDD800041BBA /* libpqxx-7.10.a */,
94CD8B9A2D2DCF6E00041BBA /* libpqxx-7.10.a */,
94CD8B712D2D34C800041BBA /* config */,
Expand Down Expand Up @@ -3579,17 +3601,19 @@
isa = PBXGroup;
children = (
94D3A7232FC1B3A600EBEA32 /* commands */,
942EC55E2FBEF93A00CCBB5D /* backtestRunner.hpp */,
942EC55F2FBEF93A00CCBB5D /* redisLoader.hpp */,
942EC5602FBEF93A00CCBB5D /* redisRunner.hpp */,
94D601132FA9CD890066F51A /* strategies */,
94674B842D533B2F00973137 /* trading */,
942966D72D48E84100532862 /* models */,
94674B842D533B2F00973137 /* trading */,
94D601132FA9CD890066F51A /* strategies */,
94B8C7932D3D770800E17EB6 /* utilities */,
941B548F2D3BBA3B00E3BF64 /* trading_definitions */,
941B549C2D3BBFB900E3BF64 /* trading_definitions.hpp */,
942EC55E2FBEF93A00CCBB5D /* backtestRunner.hpp */,
942EC55F2FBEF93A00CCBB5D /* redisLoader.hpp */,
942EC5602FBEF93A00CCBB5D /* redisRunner.hpp */,
940A61162C92CE960083FEB8 /* serviceA.hpp */,
942FDDDC2FC5C8950096F318 /* elasticClient.hpp */,
943398222D57E52900287A2D /* jsonParser.hpp */,
942FDDDD2FC5C8A30096F318 /* tradingResults.hpp */,
940A61122C92CE210083FEB8 /* configManager.hpp */,
941408B02D59F954000ED1F9 /* sqlManager.hpp */,
94724A852F8B92E30029B940 /* operations.hpp */,
Expand Down Expand Up @@ -3695,9 +3719,12 @@
94D3A7272FC1B3AD00EBEA32 /* loadCommand.cpp in Sources */,
9470B5A42C8C5AD0007D9CC6 /* main.cpp in Sources */,
943398252D57E53400287A2D /* jsonParser.cpp in Sources */,
942FDDE02FC5C8B20096F318 /* tradingResults.cpp in Sources */,
942FDDE12FC5C8B20096F318 /* elasticClient.cpp in Sources */,
94D3A72A2FC1B41500EBEA32 /* runCommand.cpp in Sources */,
942EC56A2FBEF95000CCBB5D /* backtestRunner.cpp in Sources */,
942EC56B2FBEF95000CCBB5D /* redisLoader.cpp in Sources */,
94829FC52FCC1D1A00710E6E /* env.cpp in Sources */,
942EC56C2FBEF95000CCBB5D /* redisRunner.cpp in Sources */,
94280BA32D2FC00200F1CF56 /* base64.cpp in Sources */,
94674B8E2D533E7800973137 /* trade.cpp in Sources */,
Expand Down Expand Up @@ -3732,11 +3759,14 @@
94D3A7292FC1B41500EBEA32 /* runCommand.cpp in Sources */,
94D601102FA9CD700066F51A /* randomStrategy.cpp in Sources */,
94674B8A2D533BDA00973137 /* tradeManager.mm in Sources */,
94829FC62FCC1D1A00710E6E /* env.cpp in Sources */,
94724A832F8B92C10029B940 /* operations.cpp in Sources */,
940A61182C92CE960083FEB8 /* serviceA.cpp in Sources */,
94674B882D533B4000973137 /* tradeManager.cpp in Sources */,
946EFF7F2FB9F44E008D9647 /* reporting.cpp in Sources */,
943398272D57E54000287A2D /* jsonParser.mm in Sources */,
942FDDE22FC5C8B20096F318 /* tradingResults.cpp in Sources */,
942FDDE32FC5C8B20096F318 /* elasticClient.cpp in Sources */,
9470B5B62C8C5BFD007D9CC6 /* main.cpp in Sources */,
94364CB62D416D8D00F35B55 /* db.mm in Sources */,
940A61142C92CE210083FEB8 /* configManager.cpp in Sources */,
Expand Down
18 changes: 18 additions & 0 deletions include/elasticClient.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// 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 "tradingResults.hpp"

// Minimal Elasticsearch HTTP client — PUT-only, for indexing TradingResults.
// Host is read from $ELASTIC_HOST (default http://localhost:9200) with optional
// HTTP basic auth from $ELASTIC_USER / $ELASTIC_USER_PASSWORD; docs land in
// index "trading_results" with a freshly generated UUID per put.
class ElasticClient {
public:
static int putTradingResults(const TradingResults& results);
};
8 changes: 4 additions & 4 deletions include/strategies/strategy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "models/trade.hpp"

// Forward declaration. We only refer to `TradeManager` by reference in
// this header, so the compiler doesn't need its full definition here
// this header, so the compiler doesn't need its full definition here,
// just to know "it's a class". Pulling in the full header would drag
// every TradeManager dependency into every strategy. C# doesn't really
// have an equivalent because it resolves types at the assembly level
Expand All @@ -25,7 +25,7 @@ class TradeManager;
// - This is the C++ equivalent of a C# `interface`. C++ has no
// dedicated `interface` keyword, so you express it as a class
// whose methods are all pure virtual (the `= 0` suffix). The
// `I` prefix is borrowed from C# C++ has no fixed convention,
// `I` prefix is borrowed from C#, C++ has no fixed convention,
// but it's a useful hint because C++ classes routinely mix
// virtual and concrete methods, so "is this an interface?" isn't
// always obvious from the keyword alone.
Expand All @@ -34,7 +34,7 @@ class TradeManager;
// destructor would skip the derived destructor and leak resources.
// C# handles this for you; in C++ you opt in.
// - `= 0` makes a method pure virtual, which makes the class
// abstract you cannot instantiate `IStrategy` directly, only
// abstract, you cannot instantiate `IStrategy` directly, only
// concrete subclasses. Same behaviour as a C# interface.
// - Derived classes annotate their implementations with `override`
// (see `RandomStrategy`). It's optional in C++ but catches
Expand All @@ -52,7 +52,7 @@ class IStrategy {
// reference so strategies can both inspect open positions
// (`tradeManager.getActiveTrades()`) and act on them
// (`closeTrade`, future scale/adjust hooks). A reference signals
// "borrow, don't own" the strategy must not delete it. The C#
// "borrow, don't own", the strategy must not delete it. The C#
// analogue is just passing the manager as a parameter; C# has no
// distinction between reference and pointer so the by-ref nature
// is implicit there.
Expand Down
2 changes: 2 additions & 0 deletions include/trading/reporting.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

#pragma once
#include "tradeManager.hpp"
#include "tradingResults.hpp"

class Reporting {

public:
static TradingResultsStats collect(const TradeManager& tradeManager);
static void summarise(const TradeManager& tradeManager);
};
46 changes: 46 additions & 0 deletions include/tradingResults.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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 <cstddef>
#include <optional>
#include <string>

#include <boost/decimal.hpp>
#include <nlohmann/json.hpp>

#include "utilities/decimal_json.hpp"
#include "trading_definitions.hpp"

// Per-run summary mirroring what Reporting::summarise prints today.
struct TradingResultsStats {
boost::decimal::decimal64_t finalPnl;
std::size_t tradesOpened;
std::size_t tradesClosed;
std::size_t openedLong;
std::size_t openedShort;
std::size_t closedLong;
std::size_t closedShort;
std::size_t winners;
std::size_t losers;
std::size_t breakeven;
std::optional<boost::decimal::decimal64_t> avgPnl;
};

// Wire shape pushed to Elasticsearch: the input Configuration plus the run's
// output stats. Serialises the timestamp as `@timestamp` for Kibana.
struct TradingResults {
std::string RUN_ID;
std::string timestamp;
trading_definitions::Configuration config;
TradingResultsStats results;

static std::string nowIsoUtc();
};

void to_json(nlohmann::json& j, const TradingResultsStats& s);
void to_json(nlohmann::json& j, const TradingResults& r);
16 changes: 16 additions & 0 deletions include/utilities/env.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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 <string>

namespace env {

// Returns $name, or `fallback` when the variable is unset or empty.
std::string getOr(const char* name, std::string fallback);

} // namespace env
14 changes: 10 additions & 4 deletions scripts/run.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
#!/bin/bash
# This executes the run script

required_vars=(ELASTIC_HOST ELASTIC_USER ELASTIC_USER_PASSWORD REDIS_HOST)
missing=()
for var in "${required_vars[@]}"; do
[[ -z "${!var}" ]] && missing+=("$var")
done
if [[ ${#missing[@]} -gt 0 ]]; then
echo "Error: missing required environment variables: ${missing[*]}"
exit 1
fi

current_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# Build the source code
Expand All @@ -24,10 +34,6 @@ if ! redis-cli -h localhost ping >/dev/null 2>&1; then
exit 0
fi

if ! ./"$BUILD_DIR/$EXECUTABLE_NAME" load; then
exit 1
fi

start_time=$(date +%s%N)
# Invoke the `run` subcommand: BacktestingEngine pops a Base64-encoded
# strategy off the Redis `strategy_queue` and executes it against the
Expand Down
3 changes: 3 additions & 0 deletions source/backtestRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@

int runBacktest(const std::string& questdbHost,
const trading_definitions::Configuration& config) {

DatabaseConnection db(questdbHost, 8812, "qdb", "admin", "quest");

// Get a list of symbols
std::vector<std::string> symbols;
std::istringstream ss(config.SYMBOLS);
for (std::string token; std::getline(ss, token, ',');) {
symbols.push_back(token);
}

// Get all the tick data out of QuestDB for these symbols
std::vector<PriceData> ticks =
SqlManager::streamPriceData(db, symbols, config.LAST_MONTHS);

Expand Down
3 changes: 2 additions & 1 deletion source/commands/loadCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <boost/decimal/literals.hpp>
#include <nlohmann/json.hpp>

#include "env.hpp"
#include "redisLoader.hpp"
#include "trading_definitions.hpp"

Expand Down Expand Up @@ -38,5 +39,5 @@ int LoadCommand::run() {
};

const nlohmann::json j = config;
return RedisLoader::load(j.dump());
return RedisLoader::load(j.dump(), env::getOr("REDIS_HOST", "127.0.0.1"));
}
Loading
Loading