|
|
@@ -114,13 +114,7 @@ class TradingStrategy:
|
|
|
# 平仓订单相关变量
|
|
|
self.closing_order_id = None # 当前平仓订单ID
|
|
|
self.last_closing_price = None # 上次挂单价格,用于判断是否需要replace
|
|
|
-
|
|
|
- # 预签名交易相关变量(做多和做空各一笔)
|
|
|
- self.presigned_long_tx = None # 预签名的做多交易信息
|
|
|
- self.presigned_short_tx = None # 预签名的做空交易信息
|
|
|
- self.presigned_prices = None # 存储预签名时的binance_price
|
|
|
- self.presigned_bps_threshold = 5 # 价格变动超过此bps时重新签名
|
|
|
-
|
|
|
+
|
|
|
# WebSocket连接引用(由listener设置)
|
|
|
self.websocket_connection = None
|
|
|
|
|
|
@@ -173,84 +167,8 @@ class TradingStrategy:
|
|
|
|
|
|
return True
|
|
|
|
|
|
- def _calculate_bps_change(self, current_price, prev_price):
|
|
|
- """计算价格变化的bps"""
|
|
|
- if prev_price == 0:
|
|
|
- return float('inf')
|
|
|
- return abs((current_price - prev_price) / prev_price) * 10000
|
|
|
-
|
|
|
- async def _presign_open_orders(self, market_info, binance_price):
|
|
|
- """
|
|
|
- 预签名开仓订单(做多和做空各一笔)
|
|
|
- 当binance_price变动超过5bps时重新签名
|
|
|
-
|
|
|
- Args:
|
|
|
- market_info: 市场信息
|
|
|
- binance_price: binance价格
|
|
|
- """
|
|
|
- binance_price_float = float(binance_price) if isinstance(binance_price, str) else binance_price
|
|
|
-
|
|
|
- # 检查是否需要重新签名
|
|
|
- need_presign = False
|
|
|
-
|
|
|
- # 首次签名
|
|
|
- if self.presigned_prices is None:
|
|
|
- need_presign = True
|
|
|
- else:
|
|
|
- # 检查价格变化(与签名时的binance_price对比)
|
|
|
- price_change = self._calculate_bps_change(binance_price_float, self.presigned_prices)
|
|
|
-
|
|
|
- if price_change >= self.presigned_bps_threshold:
|
|
|
- need_presign = True
|
|
|
-
|
|
|
- if not need_presign:
|
|
|
- return
|
|
|
-
|
|
|
- try:
|
|
|
- # 计算开仓价格(往不利方向)
|
|
|
- # 做多:在binance_price基础上往上加bps(更高的价格)
|
|
|
- long_price = binance_price_float * (1 + self.entry_price_bps / 10000)
|
|
|
- # 做空:在binance_price基础上往下减bps(更低的价格)
|
|
|
- short_price = binance_price_float * (1 - self.entry_price_bps / 10000)
|
|
|
-
|
|
|
- # 签名做多订单(买入)
|
|
|
- long_tx_info, long_oid, error = await self.create_order_tx(
|
|
|
- market_info=market_info,
|
|
|
- quantity=self.trade_quantity,
|
|
|
- price=long_price,
|
|
|
- is_ask=False, # 买入
|
|
|
- reduce_only=False,
|
|
|
- order_type=self.signer_client.ORDER_TYPE_MARKET,
|
|
|
- )
|
|
|
-
|
|
|
- if error:
|
|
|
- self.presigned_long_tx = None
|
|
|
- else:
|
|
|
- # 存储: (tx_info, oid, quantity, price, is_ask)
|
|
|
- self.presigned_long_tx = (long_tx_info, long_oid, self.trade_quantity, long_price, False)
|
|
|
-
|
|
|
- # 签名做空订单(卖出)
|
|
|
- short_tx_info, short_oid, error = await self.create_order_tx(
|
|
|
- market_info=market_info,
|
|
|
- quantity=self.trade_quantity,
|
|
|
- price=short_price,
|
|
|
- is_ask=True, # 卖出
|
|
|
- reduce_only=False,
|
|
|
- order_type=self.signer_client.ORDER_TYPE_MARKET,
|
|
|
- )
|
|
|
-
|
|
|
- if error:
|
|
|
- self.presigned_short_tx = None
|
|
|
- else:
|
|
|
- # 存储: (tx_info, oid, quantity, price, is_ask)
|
|
|
- self.presigned_short_tx = (short_tx_info, short_oid, self.trade_quantity, short_price, True)
|
|
|
-
|
|
|
- # 保存签名时的binance_price
|
|
|
- self.presigned_prices = binance_price_float
|
|
|
-
|
|
|
- except Exception as e:
|
|
|
- logger.error(f"预签名订单时发生错误: {str(e)}")
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
def _check_price_change_threshold(self, market_data):
|
|
|
"""
|
|
|
检查价格变动是否超过阈值
|
|
|
@@ -493,115 +411,41 @@ class TradingStrategy:
|
|
|
symbol = market_data.get('symbol')
|
|
|
if symbol != self.target_symbol:
|
|
|
return
|
|
|
-
|
|
|
+
|
|
|
market_info = market_data.get('market_info')
|
|
|
binance_price = market_data.get('binance_price')
|
|
|
-
|
|
|
+
|
|
|
if not market_info or not binance_price:
|
|
|
return
|
|
|
-
|
|
|
- # 定期预签名开仓订单(做多和做空各一笔)
|
|
|
- await self._presign_open_orders(market_info, binance_price)
|
|
|
-
|
|
|
+
|
|
|
# 使用存储的ask_bps和bid_bps进行开单逻辑判断
|
|
|
# 是否卖出由bid_bps决定,是否买入由ask_bps决定
|
|
|
-
|
|
|
+
|
|
|
# 检查是否触发开仓条件
|
|
|
if self.current_bid_bps is not None and self.current_bid_bps > self.entry_price_bps:
|
|
|
# 检查交易间隔
|
|
|
if not self._can_trade():
|
|
|
return
|
|
|
-
|
|
|
+
|
|
|
# 做空:bid价差过大,lighter买价高于binance,卖出lighter
|
|
|
logger.info(f"触发做空条件:bid_bps={self.current_bid_bps:.2f}bps > {self.entry_price_bps}bps")
|
|
|
self.position_side = 'short'
|
|
|
- await self._open_position_with_presigned(market_info, binance_price, 'short')
|
|
|
+ await self._open_position(market_info, binance_price)
|
|
|
elif self.current_ask_bps is not None and self.current_ask_bps < -self.entry_price_bps:
|
|
|
# 检查交易间隔
|
|
|
if not self._can_trade():
|
|
|
return
|
|
|
-
|
|
|
+
|
|
|
# 做多:ask价差过小(负值),lighter卖价低于binance,买入lighter
|
|
|
logger.info(f"触发做多条件:ask_bps={self.current_ask_bps:.2f}bps < -{self.entry_price_bps}bps")
|
|
|
self.position_side = 'long'
|
|
|
- await self._open_position_with_presigned(market_info, binance_price, 'long')
|
|
|
-
|
|
|
- async def _open_position_with_presigned(self, market_info, binance_price, direction):
|
|
|
- """使用预签名交易开仓
|
|
|
-
|
|
|
- Args:
|
|
|
- market_info: 市场信息
|
|
|
- binance_price: binance价格
|
|
|
- direction: 开仓方向 ('long' 或 'short')
|
|
|
- """
|
|
|
- side_desc = '做多' if direction == 'long' else '做空'
|
|
|
-
|
|
|
- # 获取对应方向的预签名交易
|
|
|
- if direction == 'long' and self.presigned_long_tx:
|
|
|
- tx_info, oid, quantity, price, is_ask = self.presigned_long_tx
|
|
|
- elif direction == 'short' and self.presigned_short_tx:
|
|
|
- tx_info, oid, quantity, price, is_ask = self.presigned_short_tx
|
|
|
- else:
|
|
|
- logger.warning(f"没有可用的预签名{side_desc}交易,回退到普通开仓")
|
|
|
await self._open_position(market_info, binance_price)
|
|
|
- return
|
|
|
-
|
|
|
- # 记录开仓时间
|
|
|
- self.last_trade_time = time.time()
|
|
|
-
|
|
|
- # 直接发送预签名交易
|
|
|
- try:
|
|
|
- # 在发送前打印订单信息
|
|
|
- side_type = '卖出' if is_ask else '买入'
|
|
|
- logger.info(f"发送预签名{side_desc}交易: 方向={side_type}, 数量={quantity}, 价格={price}, oid={oid}")
|
|
|
- tx_hash, error = await self.send_order_tx(tx_info)
|
|
|
-
|
|
|
- if error:
|
|
|
- logger.error(f"发送预签名{side_desc}交易失败: {error}")
|
|
|
- # 回退到普通开仓
|
|
|
- await self._open_position(market_info, binance_price)
|
|
|
- return
|
|
|
-
|
|
|
- logger.info(f"预签名{side_desc}交易已发送,交易哈希={tx_hash}")
|
|
|
|
|
|
- # 记录开仓事件到数据库
|
|
|
- event_type = 'open_long' if direction == 'long' else 'open_short'
|
|
|
- binance_price_float = float(binance_price) if isinstance(binance_price, str) else binance_price
|
|
|
- self.database.record_trading_event(
|
|
|
- symbol=market_info.get('symbol'),
|
|
|
- event_type=event_type,
|
|
|
- price=price,
|
|
|
- quantity=quantity,
|
|
|
- side=direction,
|
|
|
- strategy_state=self.state.name if self.state else None,
|
|
|
- binance_price=binance_price_float,
|
|
|
- order_id=str(oid),
|
|
|
- tx_hash=tx_hash,
|
|
|
- success=True,
|
|
|
- metadata={
|
|
|
- 'is_ask': is_ask,
|
|
|
- 'ask_bps': self.current_ask_bps,
|
|
|
- 'bid_bps': self.current_bid_bps,
|
|
|
- 'order_type': 'presigned_market'
|
|
|
- }
|
|
|
- )
|
|
|
-
|
|
|
- # 清空已使用的预签名交易
|
|
|
- if direction == 'long':
|
|
|
- self.presigned_long_tx = None
|
|
|
- else:
|
|
|
- self.presigned_short_tx = None
|
|
|
-
|
|
|
- except Exception as e:
|
|
|
- logger.error(f"发送预签名{side_desc}交易时出错: {str(e)}")
|
|
|
- # 回退到普通开仓
|
|
|
- await self._open_position(market_info, binance_price)
|
|
|
-
|
|
|
async def _open_position(self, market_info, binance_price):
|
|
|
- """开仓(备选方案,当预签名交易失败时使用)"""
|
|
|
+ """开仓"""
|
|
|
# 直接使用binance_price作为交易价格
|
|
|
binance_price_float = float(binance_price) if isinstance(binance_price, str) else binance_price
|
|
|
-
|
|
|
+
|
|
|
# 确定开仓方向和价格
|
|
|
if self.position_side == 'long':
|
|
|
# 做多:在Lighter买入
|
|
|
@@ -613,9 +457,9 @@ class TradingStrategy:
|
|
|
price = binance_price_float
|
|
|
is_ask = True
|
|
|
side_desc = '做空'
|
|
|
-
|
|
|
- logger.info(f"开始开仓(备选):方向={side_desc},数量={self.trade_quantity},价格={price}")
|
|
|
-
|
|
|
+
|
|
|
+ logger.info(f"开始开仓:方向={side_desc},数量={self.trade_quantity},价格={price}")
|
|
|
+
|
|
|
tx_hash, oid, error = await self.create_order_and_send_tx(
|
|
|
market_info=market_info,
|
|
|
quantity=self.trade_quantity,
|
|
|
@@ -624,23 +468,23 @@ class TradingStrategy:
|
|
|
reduce_only=False,
|
|
|
order_type=self.signer_client.ORDER_TYPE_MARKET,
|
|
|
)
|
|
|
-
|
|
|
+
|
|
|
if error:
|
|
|
- logger.error(f"备选开仓失败: {error}")
|
|
|
+ logger.error(f"开仓失败: {error}")
|
|
|
logger.info(f"状态转换: EXECUTING_OPEN -> IDLE_MONITORING")
|
|
|
self.state = StrategyState.IDLE_MONITORING
|
|
|
return
|
|
|
-
|
|
|
+
|
|
|
# 记录开仓时间
|
|
|
self.last_trade_time = time.time()
|
|
|
- logger.info(f"备选开仓交易已发送,交易哈希={tx_hash}")
|
|
|
+ logger.info(f"开仓交易已发送,交易哈希={tx_hash}")
|
|
|
|
|
|
- # 记录开仓事件到数据库
|
|
|
+ # 记录开仓事件到数据库,使用binance_price作为price
|
|
|
event_type = 'open_long' if self.position_side == 'long' else 'open_short'
|
|
|
self.database.record_trading_event(
|
|
|
symbol=market_info.get('symbol'),
|
|
|
event_type=event_type,
|
|
|
- price=price,
|
|
|
+ price=binance_price_float, # 使用binance_price
|
|
|
quantity=self.trade_quantity,
|
|
|
side=self.position_side,
|
|
|
strategy_state=self.state.name if self.state else None,
|
|
|
@@ -652,7 +496,7 @@ class TradingStrategy:
|
|
|
'is_ask': is_ask,
|
|
|
'ask_bps': self.current_ask_bps,
|
|
|
'bid_bps': self.current_bid_bps,
|
|
|
- 'order_type': 'fallback_market'
|
|
|
+ 'order_type': 'market'
|
|
|
}
|
|
|
)
|
|
|
|