|
@@ -13,6 +13,8 @@ import lighter
|
|
|
import json
|
|
import json
|
|
|
import time
|
|
import time
|
|
|
|
|
|
|
|
|
|
+from lighter.models import tx_hash
|
|
|
|
|
+
|
|
|
|
|
|
|
|
# 配置日志
|
|
# 配置日志
|
|
|
logs_dir = "logs"
|
|
logs_dir = "logs"
|
|
@@ -174,52 +176,99 @@ class TradingStrategy:
|
|
|
# 平仓完成后回到空闲监听状态
|
|
# 平仓完成后回到空闲监听状态
|
|
|
self.state = StrategyState.IDLE_MONITORING
|
|
self.state = StrategyState.IDLE_MONITORING
|
|
|
logger.info("状态转换: POSITION_CLOSED -> 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():
|
|
async def main():
|
|
|
strategy = TradingStrategy()
|
|
strategy = TradingStrategy()
|
|
|
# account = await strategy.account_api.account(by="index", value=f"{strategy.account_index}")
|
|
# 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={})]
|
|
# [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__':
|
|
if __name__ == '__main__':
|
|
|
import asyncio
|
|
import asyncio
|