1
0

main-hotcoin.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import asyncio
  2. import time
  3. import json
  4. import hashlib
  5. import websockets
  6. from websockets_proxy import Proxy, proxy_connect
  7. import gzip
  8. async def listen_ibit_futures():
  9. uri = f"wss://wcws.hotcoins.cn/"
  10. # 代理服务器地址
  11. proxy_url = "http://127.0.0.1:7899"
  12. proxy = Proxy.from_url(proxy_url)
  13. # 使用代理连接
  14. async with proxy_connect(uri, proxy=proxy) as websocket:
  15. print(f"成功通过代理 {proxy_url} 连接到 {uri}")
  16. # 发送订阅消息
  17. # sub = {"event": "subscribe", "params": {"biz": "perpetual", "type": "tickers", "env": 0, "zip": False, "serialize": False}}
  18. # sub = {"event": "subscribe", "params": {"biz": "deliver", "type": "tickers", "env": 0, "zip": False, "serialize": False}}
  19. # sub = {"event": "subscribe", "params": {"biz": "perpetual", "type": "order_fetch_kline", "granularity": "1min", "env": 0, "zip": False, "serialize": False}}
  20. # sub = {"event": "subscribe", "params": {"type": "depth", "zip": False, "granularity": 100, "serialize": False}}
  21. # sub = {"event": "subscribe", "params": {"type": "tickers", "env": 0, "zip": False, "serialize": False}}
  22. sub = {"event": "subscribe", "params": {"type": "fund_rates", "env": 0, "zip": False, "serialize": False}}
  23. # sub = {"event": "subscribe", "params": {"biz": "portal", "type": "orders", "env": 0, "zip": False, "serialize": False}}
  24. # sub = {"event": "subscribe", "params": {"biz": "perpetual", "type": "new_currency", "serialize": False, "env": 0}}
  25. # sub = {"event": "subscribe", "params": {"biz": "portal", "type": "condition_orders", "env": 0, "zip": False, "serialize": False}}
  26. # sub = {"event": "subscribe", "params": {"biz": "portal", "type": "position", "granularity": "2mode", "env": 0, "zip": False, "serialize": False}}
  27. # sub = {"event": "subscribe", "params": {"biz": "perpetual", "type": "mark_candles", "zip": False, "contractCode": "btcusdt", "serialize": False, "env": 0}}
  28. # sub = {"event": "subscribe", "params": {"biz": "perpetual", "type": "candles", "zip": False, "granularity": "15min", "serialize": False, "env": 0}}
  29. sub = {"event": "subscribe", "params": {"biz": "perpetual", "type": "fund_rate", "zip": False, "contractCode": "btcusdt", "serialize": False, "env": 0}}
  30. # sub = {"event": "subscribe", "params": {"biz": "perpetual", "type": "ticker", "zip": False, "contractCode": "btcusdt", "serialize": False, "env": 0}}
  31. # sub = {"event": "subscribe",
  32. # "params": {"biz": "perpetual", "type": "order_fetch_kline", "contractCode": "btcusdt", "granularity": "1min", "env": 0, "zip": False, "serialize": False}}
  33. # sub = {"event": "subscribe", "params": {"biz": "perpetual", "type": "depth", "contractCode": "btcusdt", "zip": False, "granularity": 100, "serialize": False, "env": 0}}
  34. # sub = {"event": "unsubscribe", "params": {"biz": "perpetual", "type": "order_fetch_kline", "granularity": "1min", "env": 0, "zip": False, "serialize": False}}
  35. # sub = {"event": "unsubscribe", "params": {"type": "tickers", "env": 0, "zip": False, "serialize": False}}
  36. # sub = {"event": "unsubscribe", "params": {"type": "fund_rates", "env": 0, "zip": False, "serialize": False}}
  37. # sub = {"event": "unsubscribe", "params": {"type": "fund_rates", "env": 0, "zip": False, "serialize": False}}
  38. # sub = {"event": "unsubscribe", "params": {"type": "depth", "zip": False, "granularity": 100, "serialize": False}}
  39. # sub = {"event": "subscribe",
  40. # "params": {"biz": "perpetual", "type": "candles", "zip": False, "contractCode": "btcusdt", "granularity": "15min", "serialize": False, "env": 0}}
  41. await websocket.send(json.dumps(sub))
  42. print("已发送订阅消息")
  43. # 定义异步心跳函数
  44. async def send_heartbeat():
  45. while True:
  46. heartbeat_message = {"event": "ping"}
  47. await websocket.send(json.dumps(heartbeat_message))
  48. print(f"发送心跳消息: {heartbeat_message}")
  49. await asyncio.sleep(30)
  50. # 启动异步心跳任务
  51. heartbeat_task = asyncio.create_task(send_heartbeat())
  52. try:
  53. # 接收消息循环
  54. while True:
  55. message = await websocket.recv()
  56. # 处理二进制数据(gzip压缩)
  57. if isinstance(message, bytes):
  58. # 检查是否是gzip压缩数据
  59. if message.startswith(b'\x1f\x8b'):
  60. try:
  61. # 解压gzip数据
  62. decompressed_data = gzip.decompress(message)
  63. message = decompressed_data.decode('utf-8')
  64. except Exception as e:
  65. print(f"解压数据失败: {e}")
  66. print(f"原始数据 (前50字节): {message[:50]}")
  67. continue
  68. else:
  69. # 尝试多种编码解码非gzip二进制数据
  70. decoded = False
  71. # 尝试UTF-8解码
  72. try:
  73. message = message.decode('utf-8')
  74. decoded = True
  75. except UnicodeDecodeError:
  76. pass
  77. # 如果UTF-8解码失败,尝试其他编码或以十六进制形式显示
  78. if not decoded:
  79. try:
  80. message = message.decode('gbk')
  81. decoded = True
  82. except UnicodeDecodeError:
  83. pass
  84. if not decoded:
  85. # 如果所有解码都失败,以十六进制形式显示数据
  86. print(f"无法解码的二进制数据 (前100字节): {message[:100].hex()}")
  87. continue
  88. print(f"接收到消息: {message}")
  89. # 解析JSON数据
  90. try:
  91. data = json.loads(message)
  92. except json.JSONDecodeError as e:
  93. print(f"JSON解析失败: {e}")
  94. print(f"原始消息: {message}")
  95. continue
  96. if 'channel' in data and data['channel'] == 'pong':
  97. continue
  98. # 根据不同频道处理数据
  99. if 'channel' in data:
  100. channel = data['channel']
  101. if channel == 'account' and 'data' in data:
  102. # 账户信息
  103. for account in data['data']:
  104. print(f"账户余额: {account.get('balance', 'N/A')} {account.get('currency', 'N/A')}")
  105. elif channel == 'currentPositions' and 'data' in data:
  106. # 当前持仓
  107. for position in data['data']:
  108. print(f"持仓: {position}")
  109. elif channel in ['openOrders', 'planCloseOrders', 'planOpenOrders'] and 'data' in data:
  110. # 订单信息
  111. for order in data['data']:
  112. # 安全访问 'p' 字段,如果不存在则显示 N/A
  113. price = order.get('p', 'N/A')
  114. print(f"订单价格: {price}")
  115. # 其他频道可以按需添加处理逻辑
  116. except websockets.exceptions.ConnectionClosed as e:
  117. print(f"连接关闭: {e}")
  118. except Exception as e:
  119. print(f"发生错误: {e}")
  120. import traceback
  121. traceback.print_exc()
  122. finally:
  123. # 取消心跳任务
  124. heartbeat_task.cancel()
  125. try:
  126. await heartbeat_task
  127. except asyncio.CancelledError:
  128. pass
  129. async def main():
  130. await listen_ibit_futures()
  131. if __name__ == "__main__":
  132. asyncio.run(main())