deploy: 2026-03-20 07:49
This commit is contained in:
141
main.py
Normal file
141
main.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user