Initial commit: TradeMind – Krypto-Trading-Bot mit Lernmodus
Per Podman deploybarer Bot, der Käufe und Verkäufe simuliert ausführt und sich aus den Ergebnissen weiter antrainiert. Aufbau - Einheitliche Bar-Verarbeitung für paper, backtest und live; ausgetauscht werden nur Datenquelle und Broker. - Börsenanbindung über ccxt: rund 100 Börsen allein über exchange.id erreichbar. Zugangsdaten kommen über ENV-Platzhalter, der Live-Modus ist doppelt abgesichert. - Paper-Broker mit Gebühren, Slippage, Börsenpräzision und Volumengrenzen. - Online trainierte logistische Regression bewertet jedes Einstiegssignal. Sie lernt aus realen Trade-Ergebnissen, aus Shadow-Labels aller Kandidaten – auch der abgelehnten – und aus Hintergrund-Stichproben; beim Kaltstart wird sie aus der Kurshistorie vorgelernt. - Risikomanagement: Positions- und Exposure-Grenzen, ATR-Stops, Cooldown sowie Tagesverlust- und Drawdown-Notbremsen. - SQLite-Persistenz, HTTP-Status mit Prometheus-Metriken und Dashboard, Webhooks. Deployment - Containerfile (zweistufig, non-root UID 10001), podman-compose, systemd-Quadlet. - Modell und Datenbank liegen im Volume /data und überleben Neustarts. 128 Tests, ruff sauber. Verifiziert gegen echte Marktdaten sowie im gebauten Container inklusive Healthcheck und Zustandswiederherstellung.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""Gemeinsame Fixtures: synthetische Kursverläufe ohne Netzwerkzugriff."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from trademind.config import Config, PaperConfig, RiskConfig, RuleConfig
|
||||
from trademind.models import Candles
|
||||
|
||||
BAR_MS = 300_000 # 5 Minuten
|
||||
|
||||
|
||||
def make_candles(
|
||||
symbol: str = "BTC/USDT",
|
||||
n: int = 600,
|
||||
start_price: float = 30_000.0,
|
||||
trend: float = 0.0002,
|
||||
noise: float = 0.002,
|
||||
cycle: float = 0.0,
|
||||
cycle_period: int = 80,
|
||||
seed: int = 7,
|
||||
timeframe: str = "5m",
|
||||
start_ts: int = 1_700_000_000_000,
|
||||
) -> Candles:
|
||||
"""Erzeugt eine plausible OHLCV-Serie (geometrischer Random Walk plus optionale Welle)."""
|
||||
rng = np.random.default_rng(seed)
|
||||
steps = rng.normal(loc=trend, scale=noise, size=n)
|
||||
if cycle:
|
||||
steps += cycle * np.sin(2 * np.pi * np.arange(n) / cycle_period)
|
||||
close = start_price * np.exp(np.cumsum(steps))
|
||||
|
||||
open_ = np.concatenate([[start_price], close[:-1]])
|
||||
spread = np.abs(rng.normal(0.0, noise * 0.8, size=n)) * close
|
||||
high = np.maximum(open_, close) + spread
|
||||
low = np.minimum(open_, close) - spread
|
||||
low = np.maximum(low, close * 0.5)
|
||||
volume = rng.lognormal(mean=3.0, sigma=0.4, size=n)
|
||||
timestamp = start_ts + np.arange(n, dtype=np.int64) * BAR_MS
|
||||
|
||||
return Candles(
|
||||
symbol=symbol,
|
||||
timeframe=timeframe,
|
||||
timestamp=timestamp,
|
||||
open=open_,
|
||||
high=high,
|
||||
low=low,
|
||||
close=close,
|
||||
volume=volume,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def candles() -> Candles:
|
||||
return make_candles()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rules() -> RuleConfig:
|
||||
return RuleConfig()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def paper_config() -> PaperConfig:
|
||||
return PaperConfig(starting_balance=10_000.0, fee_rate=0.001, slippage_bps=5.0)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def risk_config() -> RiskConfig:
|
||||
return RiskConfig(max_open_positions=2, max_position_pct=0.25, cooldown_bars_after_exit=0)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def base_config(tmp_path) -> Config:
|
||||
return Config.model_validate(
|
||||
{
|
||||
"mode": "backtest",
|
||||
"market": {"symbols": ["BTC/USDT"], "timeframe": "5m", "history_bars": 300},
|
||||
"paper": {"starting_balance": 10_000.0},
|
||||
"storage": {"database_path": str(tmp_path / "test.sqlite3")},
|
||||
"server": {"enabled": False},
|
||||
"strategy": {"learner": {"model_path": str(tmp_path / "model.npz"), "warmup_samples": 20}},
|
||||
}
|
||||
)
|
||||
Reference in New Issue
Block a user