我只是尝试根据实时 Polygon.io 数据流中的特定条件自动化盈透证券中的一些交易(请参见下面的示例)。我已经看到了有关此主题的各种其他问题/答案,并尝试全部实施,但有时我的订单仍然会被跳过(特别是订单陷入“预提交”状态)。
我尝试过在不同的时间点进入睡眠状态(ib.sleep 和 time.sleep),但没有任何方法 100% 有效。如果我能了解如何让通过 API 提交的订单始终得到执行,我将不胜感激。
from polygon import WebSocketClient
from polygon.websocket.models import WebSocketMessage
from typing import List
import pandas as pd
import numpy as np
import datetime
import time
from ib_insync import IB, Stock, LimitOrder, Order
import asyncio
import nest_asyncio
nest_asyncio.apply()
t = 'AAPL'
client = WebSocketClient("xxx") # hardcoded api_key is used
client.subscribe("AM." + t) # all aggregates
#Connect IBKR
ib = IB()
ib.connect('127.0.0.1', 7496, clientId=0) #Change for paper
async def handle_msg(msgs: List[WebSocketMessage]):
for m in msgs:
data = {'ticker': [m.symbol], 'close': [m.close], 'vwap': [m.vwap], 'start_timestamp': [m.start_timestamp], 'end_timestamp': [m.end_timestamp]}
data['start_timestamp'] = pd.to_datetime(data['start_timestamp'], unit='ms')
data['end_timestamp'] = pd.to_datetime(data['end_timestamp'], unit='ms')
data['gtd_buy'] = data['end_timestamp'] + pd.Timedelta(seconds=58)
data['gtd_buy'] = data['gtd_buy'].astype(str).str.replace('-', '')
gtd = data['gtd_buy'][0]
df = pd.DataFrame(data)
buy = np.where(df.close < df.vwap, 1, 0)
print(df.head(1), buy[0])
pos = pd.DataFrame(ib.positions())
#Buy
if buy[0] == 1:
if pos.shape[0] == 0:
contract = Stock(t, 'SMART', 'USD')
ib.qualifyContracts(contract)
curr_dt = datetime.datetime.now()
order = LimitOrder('BUY', totalQuantity = 1, lmtPrice = m.close, tif = 'GTD', goodTillDate = gtd, hidden=True)
order.orderId = int(curr_dt.timestamp())
print('Buy Triggered', order.orderId)
trade = ib.placeOrder(contract, order)
else:
if pos.shape[0] > 0:
contract = Stock(t, 'SMART', 'USD')
ib.qualifyContracts(contract)
curr_dt = datetime.datetime.now()
order = LimitOrder('SELL', totalQuantity = 1, lmtPrice = m.close, tif = 'GTD', goodTillDate = gtd, hidden=True)
order.orderId = int(curr_dt.timestamp())
print('Sell Triggered', order.orderId)
trade = ib.placeOrder(contract, order)
await asyncio.sleep(30)
async def main():
await asyncio.gather(client.connect(handle_msg))
if __name__ == "__main__":
asyncio.run(main())
对于异步函数,我相信您需要添加
timeout()
才能工作
# sample of timeout
async def timeout():
await asyncio.sleep(1)
print("unsubscribe_all")
client.unsubscribe_all()
await asyncio.sleep(1)
print("close")
await client.close()
async def main():
await asyncio.gather(client.connect(handle_msg), timeout())
我已经阅读了 Polygon(link)中的文档,发现
WebSocketClient
异步函数略有不同。您可以在这里看到详细信息:https://github.com/polygon-io/client-python/blob/master/examples/websocket/async.py