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 .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "Trading Platform Dev",
"name": "Trading Framework Dev",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Clear and concise description of the issue.

## Environment

- Trading Platform version:
- Trading Framework version:
- Python version:
- Execution mode (local / cloud):
- Strategy used:
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to Semantic Versioning.

## [0.1.0] - 2026-02-17

Initial public release of the trading platform backtest core.
Initial public release of the trading framework backtest core.

### Added

Expand Down
23 changes: 10 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
# Trading Platform
# Trading Framework

![CI](https://github.com/trading-engineering/trading-platform/actions/workflows/tests.yaml/badge.svg)
![CI](https://github.com/trading-engineering/trading-framework/actions/workflows/tests.yaml/badge.svg)
![Python](https://img.shields.io/badge/python-3.11+-blue)
![License](https://img.shields.io/badge/license-MIT-green)

Deterministic, event-driven trading framework built on top of
[hftbacktest](https://github.com/nkaz001/hftbacktest), extending it with
risk management, explicit order state machines, queue semantics and
research orchestration.

Designed for realistic backtesting and production-ready architecture.
Deterministic, event-driven core framework for trading engineering,
built on top of [hftbacktest](https://github.com/nkaz001/hftbacktest), and extended with
explicit risk management, order state machines, queue semantics, and research orchestration.

---

Expand All @@ -19,7 +16,7 @@ This project wraps the open-source `hftbacktest` engine and extends it
into a structured trading framework.

While `hftbacktest` provides a high-performance event-driven simulation
core, this platform adds the missing layers required for realistic
core, this framework adds the missing layers required for realistic
research and strategy development:

- Explicit order state machine
Expand Down Expand Up @@ -99,8 +96,8 @@ No S3, cloud storage or live connectivity required.
A reproducible development environment is provided via a dev container.

```bash
git clone https://github.com/trading-engineering/trading-platform
cd trading-platform
git clone https://github.com/trading-engineering/trading-framework
cd trading-framework
```

Open in an IDE supporting Dev Containers (e.g. VS Code), reopen in
Expand Down Expand Up @@ -151,7 +148,7 @@ These enable:
Entrypoints are located in:

```
trading_platform/backtest/runtime/
trading_framework/backtest/runtime/
```

Infrastructure and orchestration configuration are intentionally kept separate from the core trading framework.
Expand All @@ -160,7 +157,7 @@ Cloud execution currently relies on [Oracle Cloud Infrastructure](https://cloud.
The storage integration is implemented through an S3-compatible adapter in the I/O layer located in:

```
trading_platform/backtest/io/
trading_framework/backtest/io/
```

The runtime entrypoints are designed primarily for [Kubernetes](https://kubernetes.io)-based workloads orchestrated via [Argo Workflows](https://argoproj.github.io/workflows).
Expand Down
4 changes: 2 additions & 2 deletions examples/local/backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
sys.path.insert(0, str(PROJECT_ROOT))

if TYPE_CHECKING:
from trading_platform import BacktestResult
from trading_framework import BacktestResult

from trading_platform import (
from trading_framework import (
HftBacktestConfig,
HftBacktestEngine,
HftEngineConfig,
Expand Down
10 changes: 5 additions & 5 deletions examples/local/local.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"engine": {
"initial_snapshot": null,
"data_files": [
"/workspaces/trading-platform/tests/data/parts/part-000.npz",
"/workspaces/trading-platform/tests/data/parts/part-001.npz",
"/workspaces/trading-platform/tests/data/parts/part-002.npz"
"/workspaces/trading-framework/tests/data/parts/part-000.npz",
"/workspaces/trading-framework/tests/data/parts/part-001.npz",
"/workspaces/trading-framework/tests/data/parts/part-002.npz"
],

"instrument": "BTC_USDC-PERPETUAL",
Expand All @@ -32,8 +32,8 @@
"roi_lb": 40000,
"roi_ub": 80000,

"stats_npz_path": "/workspaces/trading-platform/tests/data/results/stats.npz",
"event_bus_path": "/workspaces/trading-platform/tests/data/results/events.json"
"stats_npz_path": "/workspaces/trading-framework/tests/data/results/stats.npz",
"event_bus_path": "/workspaces/trading-framework/tests/data/results/events.json"
},

"risk": {
Expand Down
4 changes: 2 additions & 2 deletions examples/strategies/debug_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from trading_platform import (
from trading_framework import (
EngineContext,
GateDecision,
MarketEvent,
RiskConstraints,
StrategyState,
)

from trading_platform import (
from trading_framework import (
NewOrderIntent,
OrderIntent,
Price,
Expand Down
30 changes: 15 additions & 15 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ requires = ["setuptools>=69", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "trading-platform"
name = "trading-framework"
version = "0.1.0"
description = "Trading platform."
description = "Trading Framework."
readme = "README.md"
requires-python = ">=3.11"
authors = [{ name = "tradingeng@protonmail.com" }]
Expand Down Expand Up @@ -43,7 +43,7 @@ dev = [
# Explicit package discovery
# --------------------------------------------------
[tool.setuptools.packages.find]
include = ["trading_platform*"]
include = ["trading_framework*"]

# --------------------------------------------------
# Pytest
Expand Down Expand Up @@ -79,39 +79,39 @@ ignore_errors = true
# Import Linter
# --------------------------------------------------
[tool.importlinter]
root_package = "trading_platform"
root_package = "trading_framework"
include_external_packages = true

# Core stays pure
[[tool.importlinter.contracts]]
name = "Core must be pure"
type = "forbidden"
source_modules = ["trading_platform.core"]
source_modules = ["trading_framework.core"]
forbidden_modules = [
"trading_platform.live",
"trading_platform.backtest",
"trading_platform.strategies"
"trading_framework.live",
"trading_framework.backtest",
"trading_framework.strategies"
]

# Strategies use core only
[[tool.importlinter.contracts]]
name = "Strategies may depend on core only"
type = "forbidden"
source_modules = ["trading_platform.strategies"]
source_modules = ["trading_framework.strategies"]
forbidden_modules = [
"trading_platform.live",
"trading_platform.backtest"
"trading_framework.live",
"trading_framework.backtest"
]

# Environments must not mix
[[tool.importlinter.contracts]]
name = "Live and backtest must not mix"
type = "forbidden"
source_modules = ["trading_platform.live"]
forbidden_modules = ["trading_platform.backtest"]
source_modules = ["trading_framework.live"]
forbidden_modules = ["trading_framework.backtest"]

[[tool.importlinter.contracts]]
name = "Backtest must not depend on live"
type = "forbidden"
source_modules = ["trading_platform.backtest"]
forbidden_modules = ["trading_platform.live"]
source_modules = ["trading_framework.backtest"]
forbidden_modules = ["trading_framework.live"]
4 changes: 2 additions & 2 deletions scripts/check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ echo "🔍 Running import-linter..."
lint-imports --verbose

echo "⚡ Running ruff (check only)..."
ruff check trading_platform examples tests
ruff check trading_framework examples tests

echo "🧠 Running mypy..."
mypy trading_platform examples tests
mypy trading_framework examples tests

echo "🧪 Running pytest..."
pytest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

from __future__ import annotations

from trading_platform.core.domain.reject_reasons import RejectReason
from trading_platform.core.domain.state import StrategyState
from trading_platform.core.domain.types import (
from trading_framework.core.domain.reject_reasons import RejectReason
from trading_framework.core.domain.state import StrategyState
from trading_framework.core.domain.types import (
CancelOrderIntent,
NotionalLimits,
)
from trading_platform.core.events.sinks.null_event_bus import NullEventBus
from trading_platform.core.risk.risk_config import RiskConfig
from trading_platform.core.risk.risk_engine import RiskEngine
from trading_framework.core.events.sinks.null_event_bus import NullEventBus
from trading_framework.core.risk.risk_config import RiskConfig
from trading_framework.core.risk.risk_engine import RiskEngine


def test_cancel_for_non_existing_order_is_rejected() -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@

from __future__ import annotations

from trading_platform.core.domain.reject_reasons import RejectReason
from trading_platform.core.domain.state import StrategyState
from trading_platform.core.domain.types import (
from trading_framework.core.domain.reject_reasons import RejectReason
from trading_framework.core.domain.state import StrategyState
from trading_framework.core.domain.types import (
NewOrderIntent,
NotionalLimits,
OrderStateEvent,
Price,
Quantity,
)
from trading_platform.core.events.sinks.null_event_bus import NullEventBus
from trading_platform.core.risk.risk_config import RiskConfig
from trading_platform.core.risk.risk_engine import RiskEngine
from trading_framework.core.events.sinks.null_event_bus import NullEventBus
from trading_framework.core.risk.risk_config import RiskConfig
from trading_framework.core.risk.risk_engine import RiskEngine


def test_duplicate_new_is_rejected_when_working_order_exists() -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@

from __future__ import annotations

from trading_platform.core.domain.state import StrategyState
from trading_platform.core.domain.types import (
from trading_framework.core.domain.state import StrategyState
from trading_framework.core.domain.types import (
NotionalLimits,
OrderStateEvent,
Price,
Quantity,
ReplaceOrderIntent,
)
from trading_platform.core.events.sinks.null_event_bus import NullEventBus
from trading_platform.core.risk.risk_config import RiskConfig
from trading_platform.core.risk.risk_engine import RiskEngine
from trading_framework.core.events.sinks.null_event_bus import NullEventBus
from trading_framework.core.risk.risk_config import RiskConfig
from trading_framework.core.risk.risk_engine import RiskEngine


def test_inflight_blocks_new_intent_and_queues_it() -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

from __future__ import annotations

from trading_platform.core.domain.state import StrategyState
from trading_platform.core.domain.types import (
from trading_framework.core.domain.state import StrategyState
from trading_framework.core.domain.types import (
NotionalLimits,
OrderStateEvent,
Price,
Quantity,
ReplaceOrderIntent,
)
from trading_platform.core.events.sinks.null_event_bus import NullEventBus
from trading_platform.core.risk.risk_config import RiskConfig
from trading_platform.core.risk.risk_engine import RiskEngine
from trading_framework.core.events.sinks.null_event_bus import NullEventBus
from trading_framework.core.risk.risk_config import RiskConfig
from trading_framework.core.risk.risk_engine import RiskEngine


def test_replace_without_effective_change_is_handled_noop() -> None:
Expand Down
6 changes: 3 additions & 3 deletions tests/semantics/models/test_models_against_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from referencing import Registry, Resource
from referencing.jsonschema import DRAFT202012

from trading_platform.core.domain.types import (
from trading_framework.core.domain.types import (
FillEvent,
MarketEvent,
OrderIntent,
Expand All @@ -43,8 +43,8 @@ def load_schema(name: str) -> dict:
"""
global SCHEMA_REGISTRY

root = Path(__file__).parent.parent.parent.parent # /workspaces/trading-platform
name = "trading_platform/core/schemas/" + name
root = Path(__file__).parent.parent.parent.parent # /workspaces/trading-framework
name = "trading_framework/core/schemas/" + name
schema_path = root / name

with schema_path.open("r", encoding="utf-8") as f:
Expand Down
10 changes: 5 additions & 5 deletions tests/semantics/queue_semantics/test_new_queued_on_rate_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

from __future__ import annotations

from trading_platform.core.domain.state import StrategyState
from trading_platform.core.domain.types import (
from trading_framework.core.domain.state import StrategyState
from trading_framework.core.domain.types import (
NewOrderIntent,
NotionalLimits,
OrderRateLimits,
Price,
Quantity,
)
from trading_platform.core.events.sinks.null_event_bus import NullEventBus
from trading_platform.core.risk.risk_config import RiskConfig
from trading_platform.core.risk.risk_engine import RiskEngine
from trading_framework.core.events.sinks.null_event_bus import NullEventBus
from trading_framework.core.risk.risk_config import RiskConfig
from trading_framework.core.risk.risk_engine import RiskEngine


def test_new_is_queued_when_rate_limit_blocks() -> None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@

from __future__ import annotations

from trading_platform.core.domain.state import StrategyState
from trading_platform.core.domain.types import (
from trading_framework.core.domain.state import StrategyState
from trading_framework.core.domain.types import (
CancelOrderIntent,
NewOrderIntent,
NotionalLimits,
OrderRateLimits,
Price,
Quantity,
)
from trading_platform.core.events.sinks.null_event_bus import NullEventBus
from trading_platform.core.risk.risk_config import RiskConfig
from trading_platform.core.risk.risk_engine import RiskEngine
from trading_framework.core.events.sinks.null_event_bus import NullEventBus
from trading_framework.core.risk.risk_config import RiskConfig
from trading_framework.core.risk.risk_engine import RiskEngine


def test_cancel_dominates_queued_new() -> None:
Expand Down
4 changes: 2 additions & 2 deletions tests/semantics/state_transitions/test_new_to_working.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

from __future__ import annotations

from trading_platform.core.domain.state import StrategyState
from trading_platform.core.events.sinks.null_event_bus import NullEventBus
from trading_framework.core.domain.state import StrategyState
from trading_framework.core.events.sinks.null_event_bus import NullEventBus


def test_new_transitions_to_working() -> None:
Expand Down
Loading