build(agent): new-agents-4#58ba63 iteration
This commit is contained in:
parent
92b3b72cf5
commit
747f59cd38
21
README.md
21
README.md
|
|
@ -1 +1,20 @@
|
||||||
# DeltaForge MVP: Real-Time Cross-Asset Strategy Synthesis (Skeleton)
|
# DeltaForge Skeleton MVP
|
||||||
|
|
||||||
|
A minimal, self-contained Python package that demonstrates the core primitives
|
||||||
|
and a deterministic flow for cross-venue hedging concepts. This skeleton is
|
||||||
|
designed to be extended with real adapters and a full ADMM-like coordination layer
|
||||||
|
while providing a concrete starting point for testing, packaging, and integration.
|
||||||
|
|
||||||
|
What this adds
|
||||||
|
- Core DSL primitives: Asset, MarketSignal, StrategyDelta, PlanDelta (in deltaforge_skeleton.core)
|
||||||
|
- Two starter adapters (equity_feed and options_feed) that generate MarketSignal instances
|
||||||
|
- Simple Curator that synthesizes a PlanDelta from signals
|
||||||
|
- Lightweight ExecutionEngine to route plan steps across venues
|
||||||
|
- Toy Backtester to deterministically replay a plan
|
||||||
|
- Packaging metadata via pyproject.toml and a README for distribution
|
||||||
|
|
||||||
|
Usage notes
|
||||||
|
- Import deltaforge_skeleton and instantiate the flow using the included components
|
||||||
|
- Run the test harness in test.sh to verify the wiring and deterministic behavior
|
||||||
|
|
||||||
|
This is a skeleton intended for extension; it is not a production-ready trading engine.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
"""DeltaForge Skeletal MVP
|
||||||
|
|
||||||
|
A minimal, production-friendly Python package skeleton that implements a
|
||||||
|
canonical DSL surface and a toy but deterministic cross-venue workflow for
|
||||||
|
testing and integration with adapters.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .core import Asset, MarketSignal, StrategyDelta, PlanDelta
|
||||||
|
from .adapters.equity_feed import EquityFeedAdapter
|
||||||
|
from .adapters.options_feed import OptionsFeedAdapter
|
||||||
|
from .curator import Curator
|
||||||
|
from .execution import ExecutionEngine
|
||||||
|
from .backtester import Backtester
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Asset",
|
||||||
|
"MarketSignal",
|
||||||
|
"StrategyDelta",
|
||||||
|
"PlanDelta",
|
||||||
|
"EquityFeedAdapter",
|
||||||
|
"OptionsFeedAdapter",
|
||||||
|
"Curator",
|
||||||
|
"ExecutionEngine",
|
||||||
|
"Backtester",
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
"""Adapters package"""
|
||||||
|
|
||||||
|
from .equity_feed import EquityFeedAdapter
|
||||||
|
from .options_feed import OptionsFeedAdapter
|
||||||
|
|
||||||
|
__all__ = ["EquityFeedAdapter", "OptionsFeedAdapter"]
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from deltaforge_skeleton.core import MarketSignal, Asset
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class EquityFeedAdapter:
|
||||||
|
name: str = "EquityFeed"
|
||||||
|
|
||||||
|
def synthesize(self, symbol: str, price: float, timestamp: float) -> MarketSignal:
|
||||||
|
asset = Asset(symbol=symbol, asset_type="equity")
|
||||||
|
return MarketSignal(asset=asset, price=price, timestamp=timestamp, liquidity=1.0)
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from deltaforge_skeleton.core import MarketSignal, Asset
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OptionsFeedAdapter:
|
||||||
|
name: str = "OptionsFeed"
|
||||||
|
|
||||||
|
def synthesize(self, symbol: str, price: float, timestamp: float) -> MarketSignal:
|
||||||
|
asset = Asset(symbol=symbol, asset_type="option")
|
||||||
|
return MarketSignal(asset=asset, price=price, timestamp=timestamp, liquidity=0.8)
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from deltaforge_skeleton.core import PlanDelta
|
||||||
|
|
||||||
|
|
||||||
|
class Backtester:
|
||||||
|
def replay(self, plan: PlanDelta) -> str:
|
||||||
|
# Deterministic replay: encode steps into a single string log
|
||||||
|
if not plan.steps:
|
||||||
|
return "empty plan"
|
||||||
|
return " | ".join(plan.steps)
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Asset:
|
||||||
|
symbol: str
|
||||||
|
asset_type: str = "equity" # or option, future, etc.
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class MarketSignal:
|
||||||
|
asset: Asset
|
||||||
|
price: float
|
||||||
|
timestamp: float
|
||||||
|
liquidity: float = 1.0
|
||||||
|
implied_vol: Optional[float] = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class StrategyDelta:
|
||||||
|
asset: Asset
|
||||||
|
hedge_ratio: float
|
||||||
|
target_pnl: float
|
||||||
|
constraints: Optional[List[str]] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PlanDelta:
|
||||||
|
steps: List[str] = field(default_factory=list)
|
||||||
|
timestamp: float = 0.0
|
||||||
|
provenance: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
# Lightweight placeholders for governance primitives
|
||||||
|
@dataclass
|
||||||
|
class DualVariables:
|
||||||
|
values: List[float] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PrivacyBudget:
|
||||||
|
budget: float = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AuditLog:
|
||||||
|
entries: List[str] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PolicyBlock:
|
||||||
|
name: str
|
||||||
|
rules: List[str] = field(default_factory=list)
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import List
|
||||||
|
from deltaforge_skeleton.core import MarketSignal, PlanDelta, StrategyDelta, Asset
|
||||||
|
|
||||||
|
|
||||||
|
class Curator:
|
||||||
|
def __init__(self):
|
||||||
|
self.audit = []
|
||||||
|
|
||||||
|
def synthesize(self, signals: List[MarketSignal]) -> PlanDelta:
|
||||||
|
# Naive delta-synthesis: for each asset, create a delta hedge with 1x price weight
|
||||||
|
steps = []
|
||||||
|
for s in signals:
|
||||||
|
asset = s.asset
|
||||||
|
# simple heuristic: hedge ratio proportional to liquidity and inverse of price
|
||||||
|
hedge_ratio = max(0.0, min(1.0, 1.0 * (s.liquidity / max(1.0, s.price))))
|
||||||
|
obj = StrategyDelta(asset=asset, hedge_ratio=hedge_ratio, target_pnl=0.0, constraints=[])
|
||||||
|
steps.append(f"HEDGE {asset.symbol} with ratio {hedge_ratio:.3f}")
|
||||||
|
plan = PlanDelta(steps=steps, timestamp=0.0, provenance="deltaforge-skeleton-curation")
|
||||||
|
self.audit.append("synthesized plan from signals")
|
||||||
|
return plan
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import List
|
||||||
|
from deltaforge_skeleton.core import PlanDelta
|
||||||
|
|
||||||
|
|
||||||
|
class ExecutionEngine:
|
||||||
|
def __init__(self):
|
||||||
|
self.log: List[str] = []
|
||||||
|
|
||||||
|
def route(self, plan: PlanDelta) -> List[str]:
|
||||||
|
# Very small mock routing: just annotate steps with a venue tag
|
||||||
|
routed = []
|
||||||
|
for i, step in enumerate(plan.steps or []):
|
||||||
|
venue = "VenueA" if i % 2 == 0 else "VenueB"
|
||||||
|
action = f"{step} -> {venue}"
|
||||||
|
routed.append(action)
|
||||||
|
self.log.append("routed plan across venues")
|
||||||
|
return routed
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=42", "wheel"]
|
requires = ["setuptools>=61.0"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "deltaforge-skeleton"
|
name = "deltaforge-skeleton"
|
||||||
version = "0.1.0"
|
version = "0.0.1"
|
||||||
description = "MVP skeleton for DeltaForge real-time cross-asset strategy synthesis"
|
description = "DeltaForge MVP skeleton: core DSL, adapters, curator, execution, and backtester"
|
||||||
readme = "README.md"
|
authors = [{name = "OpenCode"}]
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.8"
|
||||||
license = { text = "MIT" }
|
readme = "README.md"
|
||||||
authors = [ { name = "OpenCode AI" } ]
|
|
||||||
dependencies = []
|
[tool.setuptools.packages.find]
|
||||||
|
where = ["."]
|
||||||
|
# Include all deltaforge_skeleton packages that live at the project root or subpackages.
|
||||||
|
include = ["deltaforge_skeleton*"]
|
||||||
|
|
||||||
|
# Optionally enable data files to be included in the package build
|
||||||
|
# Note: Avoid top-level [tool.setuptools] configuration that sets include_package_data here.
|
||||||
|
|
|
||||||
58
test.sh
58
test.sh
|
|
@ -1,36 +1,38 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "Running DeltaForge MVP tests..."
|
echo "Running DeltaForge Skeleton tests..."
|
||||||
python3 -m build >/dev/null 2>&1 || true
|
|
||||||
if [ -f dist/*wheel* ]; then
|
|
||||||
echo "Wheel present, installing..."
|
|
||||||
python3 -m pip install dist/*.whl
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Installing package in editable mode..."
|
# Ensure Python is available
|
||||||
python3 -m pip install -e . >/dev/null 2>&1 || true
|
python3 -V
|
||||||
|
pip3 -V
|
||||||
|
|
||||||
echo "Running unit tests..."
|
# Build the package to verify packaging metadata compiles
|
||||||
python3 -m pip install -q pytest || true
|
python3 -m build || { echo "Build failed"; exit 1; }
|
||||||
pytest -q || python3 -m unittest discover -q
|
|
||||||
|
|
||||||
echo "Running deterministic backtest to verify MVP flow..."
|
echo "Running a minimal deterministic flow..."
|
||||||
python3 - <<'PY'
|
python3 - << 'PY'
|
||||||
from deltaforge.dsl import Asset, MarketSignal, StrategyDelta
|
from deltaforge_skeleton.core import Asset, MarketSignal
|
||||||
from deltaforge.core import Curator
|
from deltaforge_skeleton.adapters.equity_feed import EquityFeedAdapter
|
||||||
from deltaforge.backtester import Backtester
|
from deltaforge_skeleton.curator import Curator
|
||||||
from deltaforge.dsl import PlanDelta
|
from deltaforge_skeleton.execution import ExecutionEngine
|
||||||
|
from deltaforge_skeleton.backtester import Backtester
|
||||||
|
|
||||||
asset_a = Asset(id="eq-AAPL", type="equity", symbol="AAPL")
|
apple = Asset(symbol='AAPL')
|
||||||
asset_b = Asset(id="eq-MSFT", type="equity", symbol="MSFT")
|
sig = MarketSignal(asset=apple, price=150.0, timestamp=0.0, liquidity=1.0)
|
||||||
sig = MarketSignal(asset=asset_a, timestamp=0.0, price=150.0)
|
|
||||||
curator = Curator([asset_a, asset_b])
|
curator = Curator()
|
||||||
plan = curator.synthesize_plan([sig], [
|
plan = curator.synthesize([sig])
|
||||||
StrategyDelta(id="s1", assets=[asset_a], objectives={"maximize": "return"}),
|
|
||||||
StrategyDelta(id="s2", assets=[asset_b], objectives={"maximize": "return"}),
|
engine = ExecutionEngine()
|
||||||
])
|
routes = engine.route(plan)
|
||||||
bt = Backtester(initial_cash=1000.0)
|
|
||||||
res = bt.apply([sig], plan)
|
bt = Backtester()
|
||||||
print(res)
|
replay = bt.replay(plan)
|
||||||
|
|
||||||
|
print("PLAN:", plan)
|
||||||
|
print("ROUTES:", routes)
|
||||||
|
print("REPLAY:", replay)
|
||||||
PY
|
PY
|
||||||
|
|
||||||
|
echo "All good. Ready to publish once READY_TO_PUBLISH is created."
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue