auto_trade_sys/fix_db_positions.py
薇薇安 a38f5ff05d 1
2026-02-05 19:38:18 +08:00

132 lines
4.7 KiB
Python

import asyncio
import sys
import os
from pathlib import Path
# Add project root to path
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))
sys.path.insert(0, str(project_root / 'backend'))
from database.connection import db
from database.models import Trade
from trading_system import config
from trading_system.risk_manager import RiskManager
async def fix_missing_sltp():
print("Checking for open trades with missing SL/TP across all accounts...")
all_open_trades = []
# Iterate through potential account IDs
for account_id in [1, 2, 3, 4]:
print(f"\nChecking Account {account_id}...")
try:
# Check if Trade.get_all supports account_id argument
trades = Trade.get_all(status='open', account_id=account_id)
except TypeError:
print(f"Warning: Trade.get_all might not support account_id. Checking default.")
trades = Trade.get_all(status='open')
if account_id > 1: break
if trades:
print(f"Found {len(trades)} open trades for Account {account_id}.")
all_open_trades.extend(trades)
else:
print(f"No open trades found for Account {account_id}.")
open_trades = all_open_trades
if not open_trades:
print("No open trades found.")
return
print(f"Found {len(open_trades)} open trades total.")
# Initialize RiskManager (lightweight)
# We don't need a real client if we just use basic calculation
rm = RiskManager(None)
updates = 0
for trade in open_trades:
t_id = trade['id']
symbol = trade['symbol']
entry_price = float(trade['entry_price'] or 0)
quantity = float(trade['quantity'] or 0)
side = trade['side']
leverage = int(trade['leverage'] or 10)
sl = trade.get('stop_loss_price')
tp = trade.get('take_profit_price')
if entry_price <= 0:
print(f"Skipping trade {t_id} ({symbol}): Invalid entry price {entry_price}")
continue
needs_update = False
# Calculate defaults
# Config defaults: SL 3%, TP 10% (or 30%?)
# Logic from position_manager:
stop_loss_pct = config.TRADING_CONFIG.get('STOP_LOSS_PERCENT', 0.03)
if stop_loss_pct > 1: stop_loss_pct /= 100.0
take_profit_pct = config.TRADING_CONFIG.get('TAKE_PROFIT_PERCENT', 0.10)
if take_profit_pct > 1: take_profit_pct /= 100.0
# Calculate SL
if sl is None or float(sl) <= 0:
print(f"Trade {t_id} ({symbol}) missing SL. Calculating...")
# Use RiskManager logic manually or call it
# We'll use the basic margin-based logic
position_value = entry_price * quantity
margin = position_value / leverage if leverage > 0 else position_value
stop_loss_amount = margin * stop_loss_pct
if side == 'BUY':
new_sl = entry_price - (stop_loss_amount / quantity)
else:
new_sl = entry_price + (stop_loss_amount / quantity)
sl = new_sl
needs_update = True
print(f" -> Calculated SL: {sl:.4f} (Margin: {margin:.2f}, SL Amount: {stop_loss_amount:.2f})")
# Calculate TP
if tp is None or float(tp) <= 0:
print(f"Trade {t_id} ({symbol}) missing TP. Calculating...")
# Use basic logic
# Default TP is usually SL distance * 3 or fixed pct
# Position manager uses config TAKE_PROFIT_PERCENT
if take_profit_pct is None or take_profit_pct == 0:
take_profit_pct = stop_loss_pct * 3.0
tp_price = rm.get_take_profit_price(
entry_price, side, quantity, leverage,
take_profit_pct=take_profit_pct,
atr=None,
stop_distance=abs(entry_price - float(sl))
)
tp = tp_price
needs_update = True
print(f" -> Calculated TP: {tp:.4f}")
if needs_update:
try:
db.execute_update(
"UPDATE trades SET stop_loss_price = %s, take_profit_price = %s WHERE id = %s",
(sl, tp, t_id)
)
print(f"✓ Updated trade {t_id} ({symbol})")
updates += 1
except Exception as e:
print(f"❌ Failed to update trade {t_id}: {e}")
else:
print(f"Trade {t_id} ({symbol}) OK.")
print(f"Fixed {updates} trades.")
if __name__ == "__main__":
asyncio.run(fix_missing_sltp())