Add daily model training scripts and terminal UI for live trading
- Introduced `train_daily.sh` for automating daily model retraining, including data download and model training steps. - Added `install_cron.sh` for setting up a cron job to run the daily training script. - Created `setup_schedule.sh` for configuring Systemd timers for daily training tasks. - Implemented a terminal UI using Rich for real-time monitoring of trading performance, including metrics display and log handling. - Updated `pyproject.toml` to include the `rich` dependency for UI functionality. - Enhanced `.gitignore` to exclude model and log files. - Added database support for trade persistence and metrics calculation. - Updated README with installation and usage instructions for the new features.
This commit is contained in:
@@ -3,16 +3,21 @@ Position Manager for Live Trading.
|
||||
|
||||
Tracks open positions, manages risk, and handles SL/TP logic.
|
||||
"""
|
||||
import csv
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from dataclasses import dataclass, field, asdict
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
from dataclasses import dataclass, asdict
|
||||
|
||||
from .okx_client import OKXClient
|
||||
from .config import TradingConfig, PathConfig
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .db.database import TradingDatabase
|
||||
from .db.models import Trade
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -78,11 +83,13 @@ class PositionManager:
|
||||
self,
|
||||
okx_client: OKXClient,
|
||||
trading_config: TradingConfig,
|
||||
path_config: PathConfig
|
||||
path_config: PathConfig,
|
||||
database: Optional["TradingDatabase"] = None,
|
||||
):
|
||||
self.client = okx_client
|
||||
self.config = trading_config
|
||||
self.paths = path_config
|
||||
self.db = database
|
||||
self.positions: dict[str, Position] = {}
|
||||
self.trade_log: list[dict] = []
|
||||
self._load_positions()
|
||||
@@ -249,16 +256,55 @@ class PositionManager:
|
||||
return trade_record
|
||||
|
||||
def _append_trade_log(self, trade_record: dict) -> None:
|
||||
"""Append trade record to CSV log file."""
|
||||
import csv
|
||||
"""Append trade record to CSV and SQLite database."""
|
||||
# Write to CSV (backup/compatibility)
|
||||
self._append_trade_csv(trade_record)
|
||||
|
||||
# Write to SQLite (primary)
|
||||
self._append_trade_db(trade_record)
|
||||
|
||||
def _append_trade_csv(self, trade_record: dict) -> None:
|
||||
"""Append trade record to CSV log file."""
|
||||
file_exists = self.paths.trade_log_file.exists()
|
||||
|
||||
with open(self.paths.trade_log_file, 'a', newline='') as f:
|
||||
writer = csv.DictWriter(f, fieldnames=trade_record.keys())
|
||||
if not file_exists:
|
||||
writer.writeheader()
|
||||
writer.writerow(trade_record)
|
||||
try:
|
||||
with open(self.paths.trade_log_file, 'a', newline='') as f:
|
||||
writer = csv.DictWriter(f, fieldnames=trade_record.keys())
|
||||
if not file_exists:
|
||||
writer.writeheader()
|
||||
writer.writerow(trade_record)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to write trade to CSV: {e}")
|
||||
|
||||
def _append_trade_db(self, trade_record: dict) -> None:
|
||||
"""Append trade record to SQLite database."""
|
||||
if self.db is None:
|
||||
return
|
||||
|
||||
try:
|
||||
from .db.models import Trade
|
||||
|
||||
trade = Trade(
|
||||
trade_id=trade_record['trade_id'],
|
||||
symbol=trade_record['symbol'],
|
||||
side=trade_record['side'],
|
||||
entry_price=trade_record['entry_price'],
|
||||
exit_price=trade_record.get('exit_price'),
|
||||
size=trade_record['size'],
|
||||
size_usdt=trade_record['size_usdt'],
|
||||
pnl_usd=trade_record.get('pnl_usd'),
|
||||
pnl_pct=trade_record.get('pnl_pct'),
|
||||
entry_time=trade_record['entry_time'],
|
||||
exit_time=trade_record.get('exit_time'),
|
||||
hold_duration_hours=trade_record.get('hold_duration_hours'),
|
||||
reason=trade_record.get('reason'),
|
||||
order_id_entry=trade_record.get('order_id_entry'),
|
||||
order_id_exit=trade_record.get('order_id_exit'),
|
||||
)
|
||||
self.db.insert_trade(trade)
|
||||
logger.debug(f"Trade {trade.trade_id} saved to database")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to write trade to database: {e}")
|
||||
|
||||
def update_positions(self, current_prices: dict[str, float]) -> list[dict]:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user