From 33b14aaa2344b0fd95d1629627c3d135b24ae102 Mon Sep 17 00:00:00 2001 From: TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> Date: Wed, 1 Apr 2026 15:56:35 +0900 Subject: feat: initial trading platform implementation Binance spot crypto trading platform with microservices architecture: - shared: Pydantic models, Redis Streams broker, asyncpg DB layer - data-collector: Binance WebSocket/REST market data collection - strategy-engine: Plugin-based strategy execution (RSI, Grid) - order-executor: Order execution with risk management - portfolio-manager: Position tracking and PnL calculation - backtester: Historical strategy testing with simulator - cli: Click-based CLI for all operations - Docker Compose orchestration with Redis and PostgreSQL - 24 test files covering all modules --- cli/src/trading_cli/__init__.py | 0 cli/src/trading_cli/commands/__init__.py | 0 cli/src/trading_cli/commands/backtest.py | 26 +++++++++++++++++++++++ cli/src/trading_cli/commands/data.py | 31 +++++++++++++++++++++++++++ cli/src/trading_cli/commands/portfolio.py | 20 ++++++++++++++++++ cli/src/trading_cli/commands/service.py | 29 +++++++++++++++++++++++++ cli/src/trading_cli/commands/strategy.py | 20 ++++++++++++++++++ cli/src/trading_cli/commands/trade.py | 35 +++++++++++++++++++++++++++++++ cli/src/trading_cli/main.py | 22 +++++++++++++++++++ 9 files changed, 183 insertions(+) create mode 100644 cli/src/trading_cli/__init__.py create mode 100644 cli/src/trading_cli/commands/__init__.py create mode 100644 cli/src/trading_cli/commands/backtest.py create mode 100644 cli/src/trading_cli/commands/data.py create mode 100644 cli/src/trading_cli/commands/portfolio.py create mode 100644 cli/src/trading_cli/commands/service.py create mode 100644 cli/src/trading_cli/commands/strategy.py create mode 100644 cli/src/trading_cli/commands/trade.py create mode 100644 cli/src/trading_cli/main.py (limited to 'cli/src/trading_cli') diff --git a/cli/src/trading_cli/__init__.py b/cli/src/trading_cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cli/src/trading_cli/commands/__init__.py b/cli/src/trading_cli/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cli/src/trading_cli/commands/backtest.py b/cli/src/trading_cli/commands/backtest.py new file mode 100644 index 0000000..40617b6 --- /dev/null +++ b/cli/src/trading_cli/commands/backtest.py @@ -0,0 +1,26 @@ +import click + + +@click.group() +def backtest(): + """Backtesting commands.""" + pass + + +@backtest.command() +@click.option("--strategy", required=True, help="Strategy name to backtest") +@click.option("--symbol", required=True, help="Trading symbol (e.g. BTCUSDT)") +@click.option("--from", "from_date", required=True, help="Start date (ISO format)") +@click.option("--to", "to_date", default=None, help="End date (ISO format, defaults to now)") +@click.option("--balance", default=10000.0, show_default=True, help="Initial balance in USDT") +def run(strategy, symbol, from_date, to_date, balance): + """Run a backtest for a strategy.""" + to_label = to_date or "now" + click.echo(f"Running backtest: strategy={strategy}, symbol={symbol}, {from_date} → {to_label}, balance={balance}...") + + +@backtest.command() +@click.option("--id", "backtest_id", required=True, help="Backtest run ID") +def report(backtest_id): + """Show a backtest report by ID.""" + click.echo(f"Showing backtest report for ID: {backtest_id}...") diff --git a/cli/src/trading_cli/commands/data.py b/cli/src/trading_cli/commands/data.py new file mode 100644 index 0000000..1fa5e30 --- /dev/null +++ b/cli/src/trading_cli/commands/data.py @@ -0,0 +1,31 @@ +import click + + +@click.group() +def data(): + """Data collection and management commands.""" + pass + + +@data.command() +@click.option("--symbol", required=True, help="Trading symbol (e.g. BTCUSDT)") +@click.option("--timeframe", default="1m", show_default=True, help="Candle timeframe") +def collect(symbol, timeframe): + """Start collecting live market data for a symbol.""" + click.echo(f"Starting data collection for {symbol} at {timeframe} timeframe...") + + +@data.command() +@click.option("--symbol", required=True, help="Trading symbol (e.g. BTCUSDT)") +@click.option("--timeframe", default="1m", show_default=True, help="Candle timeframe") +@click.option("--from", "since", default=None, help="Start date (ISO format)") +@click.option("--limit", default=1000, show_default=True, help="Number of candles to fetch") +def history(symbol, timeframe, since, limit): + """Download historical market data for a symbol.""" + click.echo(f"Downloading {limit} {timeframe} candles for {symbol}" + (f" since {since}" if since else "") + "...") + + +@data.command("list") +def list_(): + """List available data streams and symbols.""" + click.echo("Fetching available data streams and collected symbols...") diff --git a/cli/src/trading_cli/commands/portfolio.py b/cli/src/trading_cli/commands/portfolio.py new file mode 100644 index 0000000..9389bac --- /dev/null +++ b/cli/src/trading_cli/commands/portfolio.py @@ -0,0 +1,20 @@ +import click + + +@click.group() +def portfolio(): + """Portfolio management commands.""" + pass + + +@portfolio.command() +def show(): + """Show the current portfolio holdings and balances.""" + click.echo("Fetching current portfolio...") + + +@portfolio.command() +@click.option("--days", default=30, show_default=True, help="Number of days of history") +def history(days): + """Show PnL history for the portfolio.""" + click.echo(f"Fetching PnL history for the last {days} days...") diff --git a/cli/src/trading_cli/commands/service.py b/cli/src/trading_cli/commands/service.py new file mode 100644 index 0000000..d01eaae --- /dev/null +++ b/cli/src/trading_cli/commands/service.py @@ -0,0 +1,29 @@ +import subprocess +import click + + +@click.group() +def service(): + """Docker service management commands.""" + pass + + +@service.command() +def up(): + """Start all services with docker compose.""" + click.echo("Starting all services...") + subprocess.run(["docker", "compose", "up", "-d"], check=True) + + +@service.command() +def down(): + """Stop all services with docker compose.""" + click.echo("Stopping all services...") + subprocess.run(["docker", "compose", "down"], check=True) + + +@service.command() +@click.option("--name", required=True, help="Service name to follow logs for") +def logs(name): + """Follow logs for a specific service.""" + subprocess.run(["docker", "compose", "logs", "-f", name], check=True) diff --git a/cli/src/trading_cli/commands/strategy.py b/cli/src/trading_cli/commands/strategy.py new file mode 100644 index 0000000..68ffeee --- /dev/null +++ b/cli/src/trading_cli/commands/strategy.py @@ -0,0 +1,20 @@ +import click + + +@click.group() +def strategy(): + """Strategy management commands.""" + pass + + +@strategy.command("list") +def list_(): + """List all available trading strategies.""" + click.echo("Fetching available strategies...") + + +@strategy.command() +@click.option("--name", required=True, help="Strategy name") +def info(name): + """Show detailed information about a strategy.""" + click.echo(f"Fetching details for strategy: {name}...") diff --git a/cli/src/trading_cli/commands/trade.py b/cli/src/trading_cli/commands/trade.py new file mode 100644 index 0000000..f90e0ed --- /dev/null +++ b/cli/src/trading_cli/commands/trade.py @@ -0,0 +1,35 @@ +import click + + +@click.group() +def trade(): + """Trading bot management commands.""" + pass + + +@trade.command() +@click.option("--strategy", required=True, help="Strategy name to run") +@click.option("--symbol", required=True, help="Trading symbol (e.g. BTCUSDT)") +def start(strategy, symbol): + """Start a trading bot for a strategy and symbol.""" + click.echo(f"Starting trading bot: strategy={strategy}, symbol={symbol}...") + + +@trade.command() +@click.option("--strategy", required=True, help="Strategy name to stop") +def stop(strategy): + """Stop a running trading bot.""" + click.echo(f"Stopping trading bot for strategy: {strategy}...") + + +@trade.command() +def status(): + """Show status of all running trading bots.""" + click.echo("Fetching running bots status...") + + +@trade.command("stop-all") +def stop_all(): + """Stop all running trading bots.""" + click.confirm("Are you sure you want to stop all running bots?", abort=True) + click.echo("Stopping all running trading bots...") diff --git a/cli/src/trading_cli/main.py b/cli/src/trading_cli/main.py new file mode 100644 index 0000000..db3c282 --- /dev/null +++ b/cli/src/trading_cli/main.py @@ -0,0 +1,22 @@ +import click +from trading_cli.commands.data import data +from trading_cli.commands.trade import trade +from trading_cli.commands.backtest import backtest +from trading_cli.commands.portfolio import portfolio +from trading_cli.commands.strategy import strategy +from trading_cli.commands.service import service + + +@click.group() +@click.version_option(version="0.1.0") +def cli(): + """Trading Platform CLI — Binance spot crypto trading""" + pass + + +cli.add_command(data) +cli.add_command(trade) +cli.add_command(backtest) +cli.add_command(portfolio) +cli.add_command(strategy) +cli.add_command(service) -- cgit v1.2.3