Crypto trading bot: engine, brokers, backtester, dashboard, deploy
FastAPI backend with a single-strategy async engine, paper and Binance brokers, pure-python indicators, a backtester that shares the engine's portfolio math, and a Vue dashboard with a live WebSocket feed. Adds the Gitea Actions CI/CD workflow that deploys to Traefik via docker_default.
This commit is contained in:
1 parent
98028248c2
commit
9c3bee87ac
73 files changed
+9759
-1
No files matched your search
@@ -0,0 +1,38 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from app.broker.base import Broker, Fill
|
||||
from app.models import OrderSide, utcnow
|
||||
|
||||
|
||||
class PaperBroker(Broker):
|
||||
"""Simulated fills against a reference price, with fees and slippage.
|
||||
|
||||
Buys fill slightly above and sells slightly below the reference price to
|
||||
approximate adverse slippage.
|
||||
"""
|
||||
|
||||
def __init__(self, fee_bps: float = 10.0, slippage_bps: float = 5.0) -> None:
|
||||
self.fee_bps = fee_bps
|
||||
self.slippage_bps = slippage_bps
|
||||
|
||||
def _fee(self, notional: float) -> float:
|
||||
return abs(notional) * self.fee_bps / 10_000
|
||||
|
||||
def fill(self, symbol: str, side: OrderSide, qty: float, ref_price: float) -> Fill:
|
||||
"""Synchronous fill used by the backtester (same model as buy/sell)."""
|
||||
direction = 1 if side == OrderSide.BUY else -1
|
||||
price = ref_price * (1 + direction * self.slippage_bps / 10_000)
|
||||
return Fill(
|
||||
symbol=symbol,
|
||||
side=side,
|
||||
qty=qty,
|
||||
price=price,
|
||||
fee=self._fee(qty * price),
|
||||
ts=utcnow(),
|
||||
)
|
||||
|
||||
async def buy(self, symbol: str, qty: float, ref_price: float) -> Fill:
|
||||
return self.fill(symbol, OrderSide.BUY, qty, ref_price)
|
||||
|
||||
async def sell(self, symbol: str, qty: float, ref_price: float) -> Fill:
|
||||
return self.fill(symbol, OrderSide.SELL, qty, ref_price)
|
||||
Reference in new issue
Block a user