优化交易的止盈亏损问题
This commit is contained in:
parent
922a8f3820
commit
f8eca1ed59
41
analyze_bad_trades.py
Normal file
41
analyze_bad_trades.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
import json
|
||||
import sys
|
||||
|
||||
def analyze_trades(file_path):
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
trades = json.load(f)
|
||||
except Exception as e:
|
||||
print(f"Error reading file: {e}")
|
||||
return
|
||||
|
||||
print(f"Analyzing {len(trades)} trades...")
|
||||
|
||||
tp_losses = []
|
||||
sync_exits = []
|
||||
|
||||
for t in trades:
|
||||
pnl = t.get('盈亏', 0)
|
||||
reason = t.get('离场原因', '')
|
||||
duration = t.get('持仓时长分钟')
|
||||
|
||||
if reason == 'take_profit' and pnl < 0:
|
||||
tp_losses.append(t)
|
||||
|
||||
if reason == 'sync' and duration == 0:
|
||||
sync_exits.append(t)
|
||||
|
||||
print("\n[Anomalies 1: Negative PnL with 'take_profit' reason]")
|
||||
for t in tp_losses:
|
||||
print(f"ID: {t.get('交易ID')} | Symbol: {t.get('交易对')} | Side: {t.get('方向')} | "
|
||||
f"Entry: {t.get('入场价')} | Exit: {t.get('出场价')} | "
|
||||
f"PnL: {t.get('盈亏')} | TP Price: {t.get('止盈价')}")
|
||||
|
||||
print("\n[Anomalies 2: Immediate Sync Exits (Duration 0)]")
|
||||
for t in sync_exits:
|
||||
print(f"ID: {t.get('交易ID')} | Symbol: {t.get('交易对')} | PnL: {t.get('盈亏')} | "
|
||||
f"Entry Time: {t.get('入场时间')} | Exit Time: {t.get('平仓时间')}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
analyze_trades('/Users/vivian/work/python/auto_trade_sys/交易记录_2026-02-04T06-46-43.json')
|
||||
|
|
@ -2040,7 +2040,41 @@ class PositionManager:
|
|||
logger.warning(f"{symbol} [状态同步] ⚠️ 数据库中没有找到open状态的交易记录,跳过")
|
||||
continue
|
||||
|
||||
logger.info(f"{symbol} [状态同步] 找到 {len(trades)} 条open状态的交易记录,开始更新...")
|
||||
# 过滤掉刚刚开仓的交易(给予60秒的同步缓冲期)
|
||||
# 避免因API延迟导致刚开的仓位被误判为"丢失"从而被错误关闭
|
||||
import time
|
||||
now_ts = int(time.time())
|
||||
recent_trades = []
|
||||
valid_trades = []
|
||||
|
||||
for t in trades:
|
||||
try:
|
||||
entry_time = t.get('entry_time')
|
||||
if entry_time:
|
||||
# 处理 entry_time 可能是 datetime 对象或时间戳的情况
|
||||
entry_ts = 0
|
||||
if hasattr(entry_time, 'timestamp'):
|
||||
entry_ts = int(entry_time.timestamp())
|
||||
elif isinstance(entry_time, (int, float)):
|
||||
entry_ts = int(entry_time)
|
||||
# 如果是刚刚开仓(60秒内),跳过同步关闭
|
||||
if now_ts - entry_ts < 60:
|
||||
recent_trades.append(t)
|
||||
continue
|
||||
except Exception as e:
|
||||
logger.debug(f"{symbol} [状态同步] 检查开仓时间出错: {e}")
|
||||
|
||||
valid_trades.append(t)
|
||||
|
||||
if recent_trades:
|
||||
logger.info(f"{symbol} [状态同步] 发现 {len(recent_trades)} 个刚刚开仓的交易(<60s),跳过同步关闭(防止误杀)")
|
||||
|
||||
if not valid_trades:
|
||||
if not recent_trades:
|
||||
logger.warning(f"{symbol} [状态同步] 没有符合条件的交易记录需要更新")
|
||||
continue
|
||||
|
||||
logger.info(f"{symbol} [状态同步] 找到 {len(valid_trades)} 条open状态的交易记录,开始更新...")
|
||||
except Exception as get_trades_error:
|
||||
logger.error(
|
||||
f"{symbol} [状态同步] ❌ 获取交易记录失败: "
|
||||
|
|
@ -2050,7 +2084,7 @@ class PositionManager:
|
|||
logger.debug(f"{symbol} [状态同步] 错误详情:\n{traceback.format_exc()}")
|
||||
continue
|
||||
|
||||
for trade in trades:
|
||||
for trade in valid_trades:
|
||||
trade_id = trade.get('id')
|
||||
if not trade_id:
|
||||
logger.warning(f"{symbol} [状态同步] ⚠️ 交易记录缺少ID字段,跳过: {trade}")
|
||||
|
|
@ -3072,7 +3106,11 @@ class PositionManager:
|
|||
take_profit_1_pct_margin = take_profit_1_pct_margin_config * 100 # 转换为百分比
|
||||
|
||||
# 直接比较当前盈亏百分比与第一目标(基于保证金,使用配置值)
|
||||
if pnl_percent_margin >= take_profit_1_pct_margin:
|
||||
# ⚠️ 2026-02-04 修复:增加最小盈利检查,防止因配置过低或滑点导致负盈利
|
||||
# 手续费估算:0.05% * 2 = 0.1% 价格变动。10x杠杆下约1%保证金。保留2%作为安全边际。
|
||||
min_profit_margin = 2.0
|
||||
|
||||
if pnl_percent_margin >= take_profit_1_pct_margin and pnl_percent_margin > min_profit_margin:
|
||||
take_profit_pct_config = config.TRADING_CONFIG.get('TAKE_PROFIT_1_PERCENT', 0.15)
|
||||
if take_profit_pct_config > 1:
|
||||
take_profit_pct_config = take_profit_pct_config / 100.0
|
||||
|
|
@ -3135,7 +3173,8 @@ class PositionManager:
|
|||
remaining_pnl_pct_margin = (remaining_pnl_amount / remaining_margin * 100) if remaining_margin > 0 else 0
|
||||
|
||||
# 直接比较剩余仓位盈亏百分比与第二目标(基于保证金)
|
||||
if remaining_pnl_pct_margin >= take_profit_2_pct_margin:
|
||||
# ⚠️ 2026-02-04 修复:增加最小盈利检查
|
||||
if remaining_pnl_pct_margin >= take_profit_2_pct_margin and remaining_pnl_pct_margin > 2.0:
|
||||
should_close = True
|
||||
# ⚠️ 2026-01-27优化:细分状态,区分"第一目标止盈后第二目标止盈"
|
||||
exit_reason = 'take_profit_partial_then_take_profit'
|
||||
|
|
@ -3182,7 +3221,8 @@ class PositionManager:
|
|||
)
|
||||
|
||||
# 直接比较当前盈亏百分比与止盈目标(基于保证金,使用配置值)
|
||||
if pnl_percent_margin >= take_profit_pct_margin:
|
||||
# ⚠️ 2026-02-04 修复:增加最小盈利检查
|
||||
if pnl_percent_margin >= take_profit_pct_margin and pnl_percent_margin > 2.0:
|
||||
should_close = True
|
||||
exit_reason = 'take_profit'
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user