소스 검색

feat(交易策略): 添加创建订单并发送交易的统一方法

将订单创建和交易发送逻辑封装到单独方法中,提高代码复用性
移除main函数中的冗余代码,使用新方法简化订单创建流程
skyfffire 1 주 전
부모
커밋
a21fdb2236
1개의 변경된 파일88개의 추가작업 그리고 39개의 파일을 삭제
  1. 88 39
      src/record/strategy.py

+ 88 - 39
src/record/strategy.py

@@ -13,6 +13,8 @@ import lighter
 import json
 import time
 
+from lighter.models import tx_hash
+
 
 # 配置日志
 logs_dir = "logs"
@@ -174,52 +176,99 @@ class TradingStrategy:
         # 平仓完成后回到空闲监听状态
         self.state = StrategyState.IDLE_MONITORING
         logger.info("状态转换: POSITION_CLOSED -> IDLE_MONITORING")
+        
+    async def create_order_and_send_tx(self, orderbook, quantity, price, is_ask=True, reduce_only=False):
+        """
+        创建订单接口
+        
+        Args:
+            orderbook: 市场信息,等价于之前的doge_market
+            quantity: 下单数量
+            price: 下单价格
+            is_ask: 是否为卖单,True为卖,False为买
+            reduce_only: 是否为只减仓单
+            
+        Returns:
+            tuple: (tx_info, error) 交易信息和错误信息
+        """
+        try:
+            # 计算实际下单数量和价格(根据精度转换)
+            base_amount = int(quantity * (10 ** orderbook.get('supported_size_decimals', 0)))
+            formatted_price = int(price * (10 ** orderbook.get('supported_price_decimals', 6)))
+            
+            # 生成客户端订单ID
+            client_order_index = int(time.time() * 1000)
+            
+            # 记录下单参数
+            logger.info(f"创建订单 - 市场: {orderbook.get('symbol')}(ID:{orderbook.get('market_id')})")
+            logger.info(f"订单参数 - 数量: {quantity}, 价格: {price}, 方向: {'卖出' if is_ask else '买入'}, 只减仓: {reduce_only}")
+            logger.info(f"格式化参数 - base_amount: {base_amount}, price: {formatted_price}, client_order_index: {client_order_index}")
+            
+            # 签名创建订单
+            tx_info, error = self.signer_client.sign_create_order(
+                market_index=orderbook.get("market_id"),
+                client_order_index=client_order_index,
+                base_amount=base_amount,
+                price=formatted_price,
+                is_ask=is_ask,
+                order_type=self.signer_client.ORDER_TYPE_MARKET,
+                time_in_force=self.signer_client.ORDER_TIME_IN_FORCE_IMMEDIATE_OR_CANCEL,
+                reduce_only=reduce_only,
+                trigger_price=0,
+                order_expiry=0,  # 所有市价单(包括减仓市价单)都必须使用NilOrderExpiry (0)
+            )
+            
+            if error is not None:
+                logger.error(f"订单签名失败: {error}")
+                return None, error
+                
+            logger.info(f"订单签名成功,准备发送交易", tx_info)
+            
+            # 发送交易
+            tx_response = await self.transaction_api.send_tx(self.signer_client.TX_TYPE_CREATE_ORDER, tx_info)
+            
+            # 检查返回状态码
+            if tx_response.code != 200:
+                error_msg = f"交易发送失败: code={tx_response.code}, message={tx_response.message}, tx_hash={tx_response.tx_hash}"
+                logger.error(error_msg)
+                raise Exception(error_msg)
+            
+            tx_hash = tx_response.tx_hash
+            logger.info(f"交易发送成功: tx_hash={tx_hash}")
+            return tx_hash, None
+            
+        except Exception as e:
+            logger.error(f"创建订单时发生错误: {str(e)}")
+            return None, str(e)
 
 async def main():    
     strategy = TradingStrategy()
     # account = await strategy.account_api.account(by="index", value=f"{strategy.account_index}")
 
     # [AccountPosition(market_id=3, symbol='DOGE', initial_margin_fraction='10.00', open_order_count=0, pending_order_count=0, position_tied_order_count=0, sign=1, position='1', avg_entry_price='0.194368', position_value='0.194360', unrealized_pnl='-0.000008', realized_pnl='0.000000', liquidation_price='0', total_funding_paid_out=None, margin_mode=0, allocated_margin='0.000000', additional_properties={})]
-    # print(account.accounts[0].positions)
-
-    doge_market = {
-        "symbol": "DOGE",
-        "market_id": 3,
-        "status": "active",
-        "taker_fee": "0.0000",
-        "maker_fee": "0.0000",
-        "liquidation_fee": "1.0000",
-        "min_base_amount": "10",
-        "min_quote_amount": "10.000000",
-        "order_quote_limit": "",
-        "supported_size_decimals": 0,
-        "supported_price_decimals": 6,
-        "supported_quote_decimals": 6
-    }
-
-    base_amount = int(1 * (10 ** doge_market['supported_size_decimals']))
-    avg_execution_price = int(0.180000 * (10 ** doge_market['supported_price_decimals']))
-    
-    client_order_index = int(time.time() * 1000)    
-    tx_info, error = strategy.signer_client.sign_create_order(
-        market_index=doge_market["market_id"],
-        client_order_index=client_order_index,
-        base_amount=base_amount,
-        price=avg_execution_price,
-        is_ask=True,
-        order_type=strategy.signer_client.ORDER_TYPE_MARKET,
-        time_in_force=strategy.signer_client.ORDER_TIME_IN_FORCE_IMMEDIATE_OR_CANCEL,
-        reduce_only=True,
-        trigger_price=0,
-        order_expiry=0, # 所有市价单(包括减仓市价单)都必须使用NilOrderExpiry (0)
-    )
-    if error is not None:
-        print(f"Error signing first order (first batch): {error}")
-        return
+    print(account.accounts[0].positions)
+
+    # doge_market = {
+    #     "symbol": "DOGE",
+    #     "market_id": 3,
+    #     "status": "active",
+    #     "taker_fee": "0.0000",
+    #     "maker_fee": "0.0000",
+    #     "liquidation_fee": "1.0000",
+    #     "min_base_amount": "10",
+    #     "min_quote_amount": "10.000000",
+    #     "order_quote_limit": "",
+    #     "supported_size_decimals": 0,
+    #     "supported_price_decimals": 6,
+    #     "supported_quote_decimals": 6
+    # }
+
+    # tx_response, error = await strategy.create_order_and_send_tx(doge_market, 1, 0.1, is_ask=True, reduce_only=True)
+    # if error is not None:
+    #     print(f"Error sending first order (first batch): {error}")
+    #     return
     
-    print(tx_info)
-    # tx_responnse = await strategy.transaction_api.send_tx(strategy.signer_client.TX_TYPE_CREATE_ORDER, tx_info)
-    # print(tx_responnse)
+    # print(tx_response)
 
 if __name__ == '__main__':
     import asyncio