142 lines
3.7 KiB
Python
142 lines
3.7 KiB
Python
"""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()
|