|
@@ -24,11 +24,12 @@ class StrategyState(Enum):
|
|
|
"""策略状态枚举"""
|
|
"""策略状态枚举"""
|
|
|
WAITING_INIT = 1 # 等待初始化
|
|
WAITING_INIT = 1 # 等待初始化
|
|
|
IDLE_MONITORING = 2 # 空闲状态监听价差
|
|
IDLE_MONITORING = 2 # 空闲状态监听价差
|
|
|
- EXECUTING_TRADE = 3 # 价差达成触发交易
|
|
|
|
|
- WAITING_CONVERGENCE = 4 # 交易完成等待价差收敛
|
|
|
|
|
- EXECUTING_CLOSE = 5 # 执行平仓操作
|
|
|
|
|
- CHECKING_CLOSE = 6 # 检查平仓结果
|
|
|
|
|
- POSITION_CLOSED = 7 # 平仓完成
|
|
|
|
|
|
|
+ EXECUTING_OPEN = 3 # 执行开仓操作
|
|
|
|
|
+ CHECKING_OPEN = 4 # 检查开仓结果
|
|
|
|
|
+ WAITING_CONVERGENCE = 5 # 交易完成等待价差收敛
|
|
|
|
|
+ EXECUTING_CLOSE = 6 # 执行平仓操作
|
|
|
|
|
+ CHECKING_CLOSE = 7 # 检查平仓结果
|
|
|
|
|
+ POSITION_CLOSED = 8 # 平仓完成
|
|
|
|
|
|
|
|
|
|
|
|
|
class TradingStrategy:
|
|
class TradingStrategy:
|
|
@@ -112,8 +113,10 @@ class TradingStrategy:
|
|
|
await self._handle_waiting_init()
|
|
await self._handle_waiting_init()
|
|
|
elif self.state == StrategyState.IDLE_MONITORING:
|
|
elif self.state == StrategyState.IDLE_MONITORING:
|
|
|
await self._handle_idle_monitoring(market_data)
|
|
await self._handle_idle_monitoring(market_data)
|
|
|
- elif self.state == StrategyState.EXECUTING_TRADE:
|
|
|
|
|
- await self._handle_executing_trade(market_data)
|
|
|
|
|
|
|
+ elif self.state == StrategyState.EXECUTING_OPEN:
|
|
|
|
|
+ await self._handle_executing_open(market_data)
|
|
|
|
|
+ elif self.state == StrategyState.CHECKING_OPEN:
|
|
|
|
|
+ await self._handle_checking_open(market_data)
|
|
|
elif self.state == StrategyState.WAITING_CONVERGENCE:
|
|
elif self.state == StrategyState.WAITING_CONVERGENCE:
|
|
|
await self._handle_waiting_convergence(market_data)
|
|
await self._handle_waiting_convergence(market_data)
|
|
|
elif self.state == StrategyState.EXECUTING_CLOSE:
|
|
elif self.state == StrategyState.EXECUTING_CLOSE:
|
|
@@ -175,15 +178,31 @@ class TradingStrategy:
|
|
|
if price_diff_bps > self.entry_price_bps:
|
|
if price_diff_bps > self.entry_price_bps:
|
|
|
# 做空:价差过大,lighter价格高于binance,卖出lighter
|
|
# 做空:价差过大,lighter价格高于binance,卖出lighter
|
|
|
logger.info(f"触发做空条件:价差={price_diff_bps:.2f}bps > {self.entry_price_bps}bps")
|
|
logger.info(f"触发做空条件:价差={price_diff_bps:.2f}bps > {self.entry_price_bps}bps")
|
|
|
- await self._open_position(orderbook, binance_price_float, is_ask=True, side='short')
|
|
|
|
|
|
|
+ self.position_side = 'short'
|
|
|
|
|
+ self.state = StrategyState.EXECUTING_OPEN
|
|
|
|
|
+ logger.info(f"状态转换: IDLE_MONITORING -> EXECUTING_OPEN")
|
|
|
elif price_diff_bps < -self.entry_price_bps:
|
|
elif price_diff_bps < -self.entry_price_bps:
|
|
|
# 做多:价差过小(负值),lighter价格低于binance,买入lighter
|
|
# 做多:价差过小(负值),lighter价格低于binance,买入lighter
|
|
|
logger.info(f"触发做多条件:价差={price_diff_bps:.2f}bps < -{self.entry_price_bps}bps")
|
|
logger.info(f"触发做多条件:价差={price_diff_bps:.2f}bps < -{self.entry_price_bps}bps")
|
|
|
- await self._open_position(orderbook, binance_price_float, is_ask=False, side='long')
|
|
|
|
|
|
|
+ self.position_side = 'long'
|
|
|
|
|
+ self.state = StrategyState.EXECUTING_OPEN
|
|
|
|
|
+ logger.info(f"状态转换: IDLE_MONITORING -> EXECUTING_OPEN")
|
|
|
|
|
|
|
|
- async def _open_position(self, orderbook, price, is_ask, side):
|
|
|
|
|
|
|
+ async def _open_position(self, orderbook, binance_price):
|
|
|
"""开仓"""
|
|
"""开仓"""
|
|
|
- logger.info(f"开始开仓:方向={'做空' if side == 'short' else '做多'},数量={self.trade_quantity},价格={price}")
|
|
|
|
|
|
|
+ # 确定开仓方向和价格
|
|
|
|
|
+ if self.position_side == 'long':
|
|
|
|
|
+ # 做多:在Lighter买入(使用ask价格)
|
|
|
|
|
+ price = binance_price
|
|
|
|
|
+ is_ask = True
|
|
|
|
|
+ side_desc = '做多'
|
|
|
|
|
+ else: # short
|
|
|
|
|
+ # 做空:在Lighter卖出(使用bid价格)
|
|
|
|
|
+ price = binance_price
|
|
|
|
|
+ is_ask = False
|
|
|
|
|
+ side_desc = '做空'
|
|
|
|
|
+
|
|
|
|
|
+ logger.info(f"开始开仓:方向={side_desc},数量={self.trade_quantity},价格={price}")
|
|
|
|
|
|
|
|
tx_hash, error = await self.create_order_and_send_tx(
|
|
tx_hash, error = await self.create_order_and_send_tx(
|
|
|
orderbook=orderbook,
|
|
orderbook=orderbook,
|
|
@@ -195,19 +214,42 @@ class TradingStrategy:
|
|
|
|
|
|
|
|
if error:
|
|
if error:
|
|
|
logger.error(f"开仓失败: {error}")
|
|
logger.error(f"开仓失败: {error}")
|
|
|
|
|
+ logger.info(f"状态转换: EXECUTING_OPEN -> IDLE_MONITORING")
|
|
|
|
|
+ self.state = StrategyState.IDLE_MONITORING
|
|
|
|
|
+ # 开仓失败,保持在 EXECUTING_OPEN 状态,等待重试
|
|
|
return
|
|
return
|
|
|
|
|
|
|
|
- # 记录开仓时间和持仓方向
|
|
|
|
|
|
|
+ # 记录开仓时间
|
|
|
self.last_trade_time = time.time()
|
|
self.last_trade_time = time.time()
|
|
|
- self.position_side = side
|
|
|
|
|
|
|
|
|
|
- # 转换状态到执行交易
|
|
|
|
|
- self.state = StrategyState.EXECUTING_TRADE
|
|
|
|
|
- logger.info(f"状态转换: IDLE_MONITORING -> EXECUTING_TRADE,交易哈希={tx_hash}")
|
|
|
|
|
|
|
+ # 转换状态到检查开仓
|
|
|
|
|
+ self.state = StrategyState.CHECKING_OPEN
|
|
|
|
|
+ logger.info(f"状态转换: EXECUTING_OPEN -> CHECKING_OPEN,交易哈希={tx_hash}")
|
|
|
logger.info(f"等待1秒后检查持仓...")
|
|
logger.info(f"等待1秒后检查持仓...")
|
|
|
|
|
|
|
|
- async def _handle_executing_trade(self, market_data):
|
|
|
|
|
- """处理执行交易状态 - 等待1秒后检查持仓"""
|
|
|
|
|
|
|
+ async def _handle_executing_open(self, market_data):
|
|
|
|
|
+ """处理执行开仓状态 - 执行开仓操作"""
|
|
|
|
|
+ symbol = market_data.get('symbol')
|
|
|
|
|
+ if symbol != self.target_symbol:
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ orderbook = market_data.get('orderbook')
|
|
|
|
|
+ if not orderbook:
|
|
|
|
|
+ logger.warning("缺少市场信息,无法执行开仓")
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ binance_price = market_data.get('binance_price')
|
|
|
|
|
+ lighter_price = market_data.get('lighter_price')
|
|
|
|
|
+
|
|
|
|
|
+ if binance_price is None or lighter_price is None:
|
|
|
|
|
+ logger.warning("价格数据不完整,无法执行开仓")
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ # 执行开仓操作
|
|
|
|
|
+ await self._open_position(orderbook, binance_price)
|
|
|
|
|
+
|
|
|
|
|
+ async def _handle_checking_open(self, market_data):
|
|
|
|
|
+ """处理检查开仓状态 - 等待1秒后检查持仓"""
|
|
|
# 检查是否已经等待了至少1秒
|
|
# 检查是否已经等待了至少1秒
|
|
|
if time.time() - self.last_trade_time < 1.0:
|
|
if time.time() - self.last_trade_time < 1.0:
|
|
|
return
|
|
return
|
|
@@ -233,13 +275,12 @@ class TradingStrategy:
|
|
|
self.current_position = position
|
|
self.current_position = position
|
|
|
self.state = StrategyState.WAITING_CONVERGENCE
|
|
self.state = StrategyState.WAITING_CONVERGENCE
|
|
|
logger.info(f"检测到持仓:方向={'做多' if position.sign == 1 else '做空'},数量={position.position}")
|
|
logger.info(f"检测到持仓:方向={'做多' if position.sign == 1 else '做空'},数量={position.position}")
|
|
|
- logger.info(f"状态转换: EXECUTING_TRADE -> WAITING_CONVERGENCE")
|
|
|
|
|
|
|
+ logger.info(f"状态转换: CHECKING_OPEN -> WAITING_CONVERGENCE")
|
|
|
else:
|
|
else:
|
|
|
- # 没有持仓,回到空闲状态
|
|
|
|
|
- logger.warning(f"开仓后未检测到持仓,回到空闲状态")
|
|
|
|
|
|
|
+ # 没有持仓,回到检测状态
|
|
|
|
|
+ logger.warning(f"开仓后未检测到持仓,回到检测状态")
|
|
|
self.state = StrategyState.IDLE_MONITORING
|
|
self.state = StrategyState.IDLE_MONITORING
|
|
|
- self.position_side = None
|
|
|
|
|
- logger.info(f"状态转换: EXECUTING_TRADE -> IDLE_MONITORING")
|
|
|
|
|
|
|
+ logger.info(f"状态转换: CHECKING_OPEN -> IDLE_MONITORING")
|
|
|
|
|
|
|
|
async def _handle_waiting_convergence(self, market_data):
|
|
async def _handle_waiting_convergence(self, market_data):
|
|
|
"""处理等待收敛状态 - 等待价差回归到0轴"""
|
|
"""处理等待收敛状态 - 等待价差回归到0轴"""
|