From 8886b0302187b18561935f58a08db55272cfb992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=96=87=E8=96=87=E5=AE=89?= Date: Sun, 18 Jan 2026 00:16:40 +0800 Subject: [PATCH] a --- .../database/add_stop_take_profit_prices.sql | 39 +++++++++++++++++++ backend/database/models.py | 33 ++++++++++++---- frontend/src/components/StatsDashboard.css | 16 ++++++++ 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 backend/database/add_stop_take_profit_prices.sql diff --git a/backend/database/add_stop_take_profit_prices.sql b/backend/database/add_stop_take_profit_prices.sql new file mode 100644 index 0000000..ee998d1 --- /dev/null +++ b/backend/database/add_stop_take_profit_prices.sql @@ -0,0 +1,39 @@ +-- 为 trades 表添加止损止盈价格字段 +-- 用于存储实际使用的止损止盈价格(考虑了ATR等动态计算) + +-- 检查字段是否存在,如果不存在则添加 +SET @dbname = DATABASE(); +SET @tablename = 'trades'; +SET @columnname = 'stop_loss_price'; +SET @preparedStatement = (SELECT IF( + ( + SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS + WHERE + (TABLE_SCHEMA = @dbname) + AND (TABLE_NAME = @tablename) + AND (COLUMN_NAME = @columnname) + ) > 0, + "SELECT 'Column stop_loss_price already exists.' AS result;", + CONCAT("ALTER TABLE ", @tablename, " ADD COLUMN ", @columnname, " DECIMAL(20, 8) NULL COMMENT '实际使用的止损价格(考虑了ATR等动态计算)';") +)); +PREPARE alterIfNotExists FROM @preparedStatement; +EXECUTE alterIfNotExists; +DEALLOCATE PREPARE alterIfNotExists; + +SET @columnname2 = 'take_profit_price'; +SET @preparedStatement2 = (SELECT IF( + ( + SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS + WHERE + (TABLE_SCHEMA = @dbname) + AND (TABLE_NAME = @tablename) + AND (COLUMN_NAME = @columnname2) + ) > 0, + "SELECT 'Column take_profit_price already exists.' AS result;", + CONCAT("ALTER TABLE ", @tablename, " ADD COLUMN ", @columnname2, " DECIMAL(20, 8) NULL COMMENT '实际使用的止盈价格(考虑了ATR等动态计算)';") +)); +PREPARE alterIfNotExists2 FROM @preparedStatement2; +EXECUTE alterIfNotExists2; +DEALLOCATE PREPARE alterIfNotExists2; + +SELECT 'Migration completed: Added stop_loss_price and take_profit_price columns to trades table.' AS result; diff --git a/backend/database/models.py b/backend/database/models.py index 5ac9d81..96fed02 100644 --- a/backend/database/models.py +++ b/backend/database/models.py @@ -88,7 +88,7 @@ class Trade: """交易记录模型""" @staticmethod - def create(symbol, side, quantity, entry_price, leverage=10, entry_reason=None, entry_order_id=None): + def create(symbol, side, quantity, entry_price, leverage=10, entry_reason=None, entry_order_id=None, stop_loss_price=None, take_profit_price=None): """创建交易记录(使用北京时间) Args: @@ -99,14 +99,33 @@ class Trade: leverage: 杠杆 entry_reason: 入场原因 entry_order_id: 币安开仓订单号(可选,用于对账) + stop_loss_price: 实际使用的止损价格(考虑了ATR等动态计算) + take_profit_price: 实际使用的止盈价格(考虑了ATR等动态计算) """ entry_time = get_beijing_time() - db.execute_update( - """INSERT INTO trades - (symbol, side, quantity, entry_price, leverage, entry_reason, status, entry_time, entry_order_id) - VALUES (%s, %s, %s, %s, %s, %s, 'open', %s, %s)""", - (symbol, side, quantity, entry_price, leverage, entry_reason, entry_time, entry_order_id) - ) + + # 检查字段是否存在(兼容旧数据库schema) + try: + db.execute_one("SELECT stop_loss_price FROM trades LIMIT 1") + has_stop_take_fields = True + except: + has_stop_take_fields = False + + if has_stop_take_fields: + db.execute_update( + """INSERT INTO trades + (symbol, side, quantity, entry_price, leverage, entry_reason, status, entry_time, entry_order_id, stop_loss_price, take_profit_price) + VALUES (%s, %s, %s, %s, %s, %s, 'open', %s, %s, %s, %s)""", + (symbol, side, quantity, entry_price, leverage, entry_reason, entry_time, entry_order_id, stop_loss_price, take_profit_price) + ) + else: + # 兼容旧schema + db.execute_update( + """INSERT INTO trades + (symbol, side, quantity, entry_price, leverage, entry_reason, status, entry_time, entry_order_id) + VALUES (%s, %s, %s, %s, %s, %s, 'open', %s, %s)""", + (symbol, side, quantity, entry_price, leverage, entry_reason, entry_time, entry_order_id) + ) return db.execute_one("SELECT LAST_INSERT_ID() as id")['id'] @staticmethod diff --git a/frontend/src/components/StatsDashboard.css b/frontend/src/components/StatsDashboard.css index 40e5025..574e1e2 100644 --- a/frontend/src/components/StatsDashboard.css +++ b/frontend/src/components/StatsDashboard.css @@ -335,6 +335,22 @@ color: #666; font-size: 0.8rem; font-style: italic; + display: inline-flex; + align-items: center; + gap: 4px; +} + +.actual-price-badge { + display: inline-block; + background-color: #4CAF50; + color: white; + font-size: 10px; + font-weight: bold; + padding: 2px 4px; + border-radius: 3px; + margin-left: 4px; + cursor: help; + font-style: normal; } .close-btn {