132 lines
4.7 KiB
Python
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())
|