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
48 changes: 30 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
cmake_minimum_required(VERSION 3.30)

# CMAKE_OSX_SYSROOT is a macOS-specific setting that specifies the SDK path.
# This is ignored on non-Apple platforms, so it's safe to include in cross-platform builds.
execute_process(
COMMAND xcrun --show-sdk-path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(APPLE)
execute_process(
COMMAND xcrun --show-sdk-path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()

project(BacktestingEngine)

Expand Down Expand Up @@ -34,8 +35,19 @@ set(CMAKE_MESSAGE_LOG_LEVEL "WARNING")
# Build libpqxx from source
add_subdirectory(external/libpqxx EXCLUDE_FROM_ALL)

# Include directories
include_directories(
# Collect all .cpp files in the src directory
file(GLOB_RECURSE SOURCES "source/*.cpp")

# main.cpp belongs to the executable only — keeping it in the library too
# means it gets compiled twice and the lib carries a competing main().
list(REMOVE_ITEM SOURCES ${CMAKE_SOURCE_DIR}/source/main.cpp)

# Create a library of your project's code
add_library(BacktestingEngineLib STATIC ${SOURCES})

# Include directories — PUBLIC so they propagate to the executable (and any
# other consumer) through target_link_libraries.
target_include_directories(BacktestingEngineLib PUBLIC
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/include/commands
${CMAKE_SOURCE_DIR}/include/utilities
Expand All @@ -47,22 +59,23 @@ include_directories(
${CMAKE_SOURCE_DIR}/external
)

# Collect all .cpp files in the src directory
file(GLOB_RECURSE SOURCES "source/*.cpp")

# Create a library of your project's code
add_library(BacktestingEngineLib STATIC ${SOURCES})

# Configure OpenMP. On Apple, provide Homebrew libomp hints before discovery.
# brew --prefix resolves the right location on both Apple Silicon
# (/opt/homebrew) and Intel (/usr/local).
if(APPLE)
execute_process(
COMMAND brew --prefix libomp
OUTPUT_VARIABLE LIBOMP_PREFIX
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(OpenMP_C_FLAGS "-Xclang -fopenmp")
set(OpenMP_CXX_FLAGS "-Xclang -fopenmp")
set(OpenMP_C_LIB_NAMES "omp")
set(OpenMP_CXX_LIB_NAMES "omp")
set(OpenMP_omp_LIBRARY /opt/homebrew/opt/libomp/lib/libomp.dylib)
find_package(OpenMP REQUIRED)
target_include_directories(BacktestingEngineLib PRIVATE /opt/homebrew/opt/libomp/include)
set(OpenMP_omp_LIBRARY ${LIBOMP_PREFIX}/lib/libomp.dylib)
target_include_directories(BacktestingEngineLib PRIVATE ${LIBOMP_PREFIX}/include)
endif()
find_package(OpenMP REQUIRED)

# Boost (Homebrew) — Boost.Redis is header-only but its implementation is
# compiled into one dedicated TU via <boost/redis/src.hpp> (source/
Expand All @@ -82,7 +95,6 @@ target_link_libraries(BacktestingEngineLib PUBLIC
add_subdirectory(external/boost-decimal)
target_link_libraries(BacktestingEngineLib PUBLIC Boost::decimal)

find_package(OpenMP REQUIRED)
target_link_libraries(BacktestingEngineLib PUBLIC pqxx OpenMP::OpenMP_CXX)

# Main executable
Expand Down
22 changes: 0 additions & 22 deletions backtesting-engine-cpp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
objects = {

/* Begin PBXBuildFile section */
940A61132C92CE210083FEB8 /* configManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940A61112C92CE210083FEB8 /* configManager.cpp */; };
940A61142C92CE210083FEB8 /* configManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940A61112C92CE210083FEB8 /* configManager.cpp */; };
940A61172C92CE960083FEB8 /* serviceA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940A61152C92CE960083FEB8 /* serviceA.cpp */; };
940A61182C92CE960083FEB8 /* serviceA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940A61152C92CE960083FEB8 /* serviceA.cpp */; };
941408AE2D59F93F000ED1F9 /* sqlManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 941408AD2D59F93F000ED1F9 /* sqlManager.cpp */; };
941408AF2D59F93F000ED1F9 /* sqlManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 941408AD2D59F93F000ED1F9 /* sqlManager.cpp */; };
941B549A2D3BBADE00E3BF64 /* trading_definitions_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 941B54992D3BBADD00E3BF64 /* trading_definitions_json.cpp */; };
Expand Down Expand Up @@ -41,8 +37,6 @@
94674B872D533B4000973137 /* tradeManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94674B852D533B4000973137 /* tradeManager.cpp */; };
94674B882D533B4000973137 /* tradeManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94674B852D533B4000973137 /* tradeManager.cpp */; };
94674B8A2D533BDA00973137 /* tradeManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 94674B892D533BDA00973137 /* tradeManager.mm */; };
94674B8D2D533E7800973137 /* trade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94674B8B2D533E7800973137 /* trade.cpp */; };
94674B8E2D533E7800973137 /* trade.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94674B8B2D533E7800973137 /* trade.cpp */; };
946EFF7E2FB9F44E008D9647 /* reporting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946EFF7D2FB9F44E008D9647 /* reporting.cpp */; };
946EFF7F2FB9F44E008D9647 /* reporting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 946EFF7D2FB9F44E008D9647 /* reporting.cpp */; };
9470B5A42C8C5AD0007D9CC6 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9470B5A32C8C5AD0007D9CC6 /* main.cpp */; };
Expand Down Expand Up @@ -75,10 +69,6 @@

/* Begin PBXFileReference section */
9409A61B2FAA6411002C30FF /* strategy.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = strategy.hpp; sourceTree = "<group>"; };
940A61112C92CE210083FEB8 /* configManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = configManager.cpp; sourceTree = "<group>"; };
940A61122C92CE210083FEB8 /* configManager.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = configManager.hpp; sourceTree = "<group>"; };
940A61152C92CE960083FEB8 /* serviceA.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = serviceA.cpp; sourceTree = "<group>"; };
940A61162C92CE960083FEB8 /* serviceA.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = serviceA.hpp; sourceTree = "<group>"; };
941408AD2D59F93F000ED1F9 /* sqlManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = sqlManager.cpp; sourceTree = "<group>"; };
941408B02D59F954000ED1F9 /* sqlManager.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = sqlManager.hpp; sourceTree = "<group>"; };
941B54902D3BBA4900E3BF64 /* ohlc_variables.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ohlc_variables.hpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -126,7 +116,6 @@
94674B832D533B2F00973137 /* tradeManager.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = tradeManager.hpp; sourceTree = "<group>"; };
94674B852D533B4000973137 /* tradeManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = tradeManager.cpp; sourceTree = "<group>"; };
94674B892D533BDA00973137 /* tradeManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = tradeManager.mm; sourceTree = "<group>"; };
94674B8B2D533E7800973137 /* trade.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = trade.cpp; sourceTree = "<group>"; };
94674BA02D533B2F00973137 /* exitRules.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = exitRules.hpp; sourceTree = "<group>"; };
94674BA12F8B92C10029B940 /* reviewStopAndLimit.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = reviewStopAndLimit.hpp; sourceTree = "<group>"; };
94685CCE2D384A8B00863D04 /* json.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = json.hpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1455,7 +1444,6 @@
94674B8C2D533E7800973137 /* models */ = {
isa = PBXGroup;
children = (
94674B8B2D533E7800973137 /* trade.cpp */,
);
path = models;
sourceTree = "<group>";
Expand Down Expand Up @@ -1484,8 +1472,6 @@
942FDDDF2FC5C8B20096F318 /* tradingResults.cpp */,
942EC5662FBEF95000CCBB5D /* redisRunner.cpp */,
9470B5A32C8C5AD0007D9CC6 /* main.cpp */,
940A61112C92CE210083FEB8 /* configManager.cpp */,
940A61152C92CE960083FEB8 /* serviceA.cpp */,
94CD8B9F2D2E8CE500041BBA /* databaseConnection.cpp */,
941408AD2D59F93F000ED1F9 /* sqlManager.cpp */,
94724A822F8B92C10029B940 /* operations.cpp */,
Expand Down Expand Up @@ -3641,10 +3627,8 @@
942EC55E2FBEF93A00CCBB5D /* backtestRunner.hpp */,
942EC55F2FBEF93A00CCBB5D /* redisLoader.hpp */,
942EC5602FBEF93A00CCBB5D /* redisRunner.hpp */,
940A61162C92CE960083FEB8 /* serviceA.hpp */,
943398222D57E52900287A2D /* jsonParser.hpp */,
942FDDDD2FC5C8A30096F318 /* tradingResults.hpp */,
940A61122C92CE210083FEB8 /* configManager.hpp */,
941408B02D59F954000ED1F9 /* sqlManager.hpp */,
94724A852F8B92E30029B940 /* operations.hpp */,
94CD8B9E2D2E8CE500041BBA /* databaseConnection.hpp */,
Expand Down Expand Up @@ -3757,16 +3741,13 @@
94829FC52FCC1D1A00710E6E /* env.cpp in Sources */,
942EC56C2FBEF95000CCBB5D /* redisRunner.cpp in Sources */,
94280BA32D2FC00200F1CF56 /* base64.cpp in Sources */,
94674B8E2D533E7800973137 /* trade.cpp in Sources */,
943770402FD42FC000317424 /* elasticClient.cpp in Sources */,
941B549B2D3BBADE00E3BF64 /* trading_definitions_json.cpp in Sources */,
946EFF7E2FB9F44E008D9647 /* reporting.cpp in Sources */,
94674B872D533B4000973137 /* tradeManager.cpp in Sources */,
94CD8BA02D2E8CE500041BBA /* databaseConnection.cpp in Sources */,
942EC5622FBEF94700CCBB5D /* redisConnection.cpp in Sources */,
940A61132C92CE210083FEB8 /* configManager.cpp in Sources */,
94724A842F8B92C10029B940 /* operations.cpp in Sources */,
940A61172C92CE960083FEB8 /* serviceA.cpp in Sources */,
94D601112FA9CD700066F51A /* randomStrategy.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -3785,23 +3766,20 @@
94D3A7262FC1B3AD00EBEA32 /* loadCommand.cpp in Sources */,
942EC5692FBEF95000CCBB5D /* redisRunner.cpp in Sources */,
94280BA42D2FC00200F1CF56 /* base64.cpp in Sources */,
94674B8D2D533E7800973137 /* trade.cpp in Sources */,
943770462FD4396F00317424 /* boostRedisImpl.cpp in Sources */,
941B549A2D3BBADE00E3BF64 /* trading_definitions_json.cpp in Sources */,
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 */,
9437703F2FD42FC000317424 /* elasticClient.cpp in Sources */,
9470B5B62C8C5BFD007D9CC6 /* main.cpp in Sources */,
94364CB62D416D8D00F35B55 /* db.mm in Sources */,
940A61142C92CE210083FEB8 /* configManager.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
27 changes: 0 additions & 27 deletions include/configManager.hpp

This file was deleted.

1 change: 0 additions & 1 deletion include/databaseConnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class DatabaseConnection {
const std::string& user = "admin",
const std::string& password = "");

void printResults(const std::vector<PriceData>& results) const;
std::vector<PriceData> executeQuery(const std::string& query) const;

const std::string& getConnectionString() const {
Expand Down
18 changes: 0 additions & 18 deletions include/elasticClient.hpp

This file was deleted.

18 changes: 17 additions & 1 deletion include/models/trade.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,25 @@ struct Trade {
// Pip-PnL = price difference * scalingFactor * size (sign flipped for SHORT).
boost::decimal::decimal64_t pnl;

// Mark-to-market state while the trade is open, maintained by
// TradeManager: the most recent close-side price seen for this symbol and
// the floating PnL at that price. Feeds the account loss limit, and
// lastMarkPrice is the liquidation price if the run is cut off.
// floatingPnl is zeroed on close — its value has been realized into pnl.
boost::decimal::decimal64_t lastMarkPrice;
boost::decimal::decimal64_t floatingPnl;

// True when the close was forced by the account loss limit (liquidation
// at the last marked price) rather than earned via SL/TP or strategy
// logic — lets reporting separate forced closes from organic ones.
bool liquidated = false;

// Default constructor
Trade() : entryPrice(0), entryBid(0), entryAsk(0), size(0), direction(Direction::LONG),
scalingFactor(0), stopDistancePips(0), limitDistancePips(0),
exitReferencePrice(0),
closePrice(0), pnl(0),
lastMarkPrice(0), floatingPnl(0),
openTime(std::chrono::system_clock::now()) {}

// Copy constructor
Expand All @@ -65,7 +79,9 @@ struct Trade {
stopDistancePips(0),
limitDistancePips(0),
exitReferencePrice(0),
pnl(0) {
pnl(0),
lastMarkPrice(0),
floatingPnl(0) {
}

};
8 changes: 5 additions & 3 deletions include/reporting/elasticClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@

#include "tradingResults.hpp"

// Minimal Elasticsearch HTTP client — PUT-only, for indexing TradingResults.
// Minimal Elasticsearch HTTP client — PUT-only, for indexing run outcomes.
// 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.
// HTTP basic auth from $ELASTIC_USER / $ELASTIC_USER_PASSWORD. Completed runs
// land in index "trading_results"; runs cut off early (loss limit) land in
// "trading_failures". Each doc gets a freshly generated UUID.
class ElasticClient {
public:
static int putTradingResults(const TradingResults& results);
static int putTradingFailure(const TradingFailure& failure);
};
23 changes: 0 additions & 23 deletions include/serviceA.hpp

This file was deleted.

Loading
Loading