Files

142 lines
3.7 KiB
Python
Raw Permalink Normal View History

2026-03-20 07:49:42 +09:00
"""Entry point for the ICT Smart Money Concepts Trading Bot.
Usage:
python main.py # Start live/sandbox trading
python main.py --paper # Paper trading mode (no API keys needed)
python main.py --backtest # Run backtest
python main.py --dashboard # Launch Streamlit dashboard only
"""
from __future__ import annotations
import argparse
import asyncio
import os
import subprocess
import sys
import threading
from pathlib import Path
# Suppress SMC startup message (avoids encoding issues on non-UTF8 terminals)
os.environ.setdefault("SMC_CREDIT", "0")
os.environ.setdefault("PYTHONIOENCODING", "utf-8")
from loguru import logger
# Ensure project root on path
sys.path.insert(0, str(Path(__file__).resolve().parent))
def setup_logging():
"""Configure loguru logging."""
from config import settings
logger.remove()
logger.add(sys.stderr, level=settings.LOG_LEVEL)
log_path = Path(settings.LOG_FILE)
log_path.parent.mkdir(parents=True, exist_ok=True)
logger.add(
str(log_path),
rotation="10 MB",
retention="30 days",
level=settings.LOG_LEVEL,
)
def ensure_dirs():
"""Create required directories."""
Path("data").mkdir(exist_ok=True)
Path("logs").mkdir(exist_ok=True)
async def run_bot(paper_mode: bool = False):
"""Start the trading bot."""
from core.bot import ICTBot
bot = ICTBot(paper_mode=paper_mode)
await bot.start()
async def run_backtest():
"""Run a backtest using historical data."""
from backtest.backtester import Backtester
from backtest.data_loader import DataLoader
from execution.paper_exchange import PaperExchangeClient
logger.info("Starting backtest...")
client = PaperExchangeClient()
await client.connect()
loader = DataLoader(client)
data = await loader.fetch_from_exchange(
symbol="BTC/USDT",
timeframe="1h",
since="2025-01-01",
limit=2000,
)
await client.disconnect()
if data.empty:
logger.error("No data loaded for backtest")
return
bt = Backtester()
result = bt.run(data, initial_balance=1000.0)
print(Backtester.generate_report(result))
def run_dashboard():
"""Launch the Streamlit dashboard."""
dashboard_path = Path(__file__).parent / "dashboard" / "app.py"
subprocess.run([sys.executable, "-m", "streamlit", "run", str(dashboard_path),
"--server.port", "8501", "--server.headless", "true"])
def launch_dashboard_background():
"""Launch dashboard in a background thread."""
t = threading.Thread(target=run_dashboard, daemon=True)
t.start()
logger.info("Dashboard launched at http://localhost:8501")
return t
def main():
parser = argparse.ArgumentParser(
description="ICT Smart Money Concepts Crypto Trading Bot"
)
parser.add_argument(
"--backtest", action="store_true", help="Run backtest mode"
)
parser.add_argument(
"--dashboard", action="store_true", help="Launch Streamlit dashboard only"
)
parser.add_argument(
"--paper", action="store_true", help="Paper trading mode (no API keys needed)"
)
parser.add_argument(
"--no-dashboard", action="store_true", help="Disable auto-launching dashboard"
)
args = parser.parse_args()
setup_logging()
ensure_dirs()
if args.paper:
os.environ["SANDBOX_MODE"] = "true"
if args.backtest:
asyncio.run(run_backtest())
elif args.dashboard:
run_dashboard()
else:
# Launch dashboard alongside the bot unless disabled
if not args.no_dashboard:
launch_dashboard_background()
asyncio.run(run_bot(paper_mode=args.paper))
if __name__ == "__main__":
main()