株のシステムトレードをしよう - 1から始める株自動取引システムの作り方

株式をコンピュータに売買させる仕組みを少しずつ作っていきます。できあがってから公開ではなく、書いたら途中でも記事として即掲載して、後から固定ページにして体裁を整える方式で進めていきます。

asyncioは close() する前に cancel() する必要がある?

how-to-make-stock-trading-system.dogwood008.com

上記の記事に沿ってやってみたが、うまく行かなかった。

わかりやすいように、Ctrl+Cを押した時点で Close websocket と表示するようにしたスクリプトが、下記のものである。

try:
  # 受信開始
  api.websocket.run()
except KeyboardInterrupt:
  print('Close websocket')

これを実行した結果が、次のもの。メッセージ自体は流れてきているが、 Close websocket の直後で Task was destroyed but it is pending! というメッセージが出ている。

$ pipenv run python kabusapi_test.py
{'RegistList': [{'Exchange': 1, 'Symbol': '7974'}]}
----------------
{'OverSellQty': 122400.0, 'UnderBuyQty': 101700.0, 'TotalMarketValue': 7073258680000.0, 'MarketOrderSellQty': 0.0, 'MarketOrderBuyQty': 0.0, 'BidTime': '2021-09-01T15:00:00+09:00', 'AskTime': '2021-09-01T15:00:00+09:00', 'Exchange': 1, 'ExchangeName': '東証1部', 'TradingVolume': 786400.0, 'TradingVolumeTime': '2021-09-01T15:00:00+09:00', 'VWAP': 53524.5575, 'TradingValue': 42091712000.0, 'BidQty': 600.0, 'BidPrice': 53720.0, 'BidSign': '0101', 'Sell1': {'Price': 53720.0, 'Qty': 600.0, 'Sign': '0101', 'Time': '2021-09-01T15:00:00+09:00'}, 'Sell2': {'Price': 53730.0, 'Qty': 400.0}, 'Sell3': {'Price': 53740.0, 'Qty': 2700.0}, 'Sell4': {'Price': 53750.0, 'Qty': 3100.0}, 'Sell5': {'Price': 53760.0, 'Qty': 800.0}, 'Sell6': {'Price': 53770.0, 'Qty': 1300.0}, 'Sell7': {'Price': 53780.0, 'Qty': 3800.0}, 'Sell8': {'Price': 53790.0, 'Qty': 800.0}, 'Sell9': {'Price': 53800.0, 'Qty': 3500.0}, 'Sell10': {'Price': 53810.0, 'Qty': 4200.0}, 'AskQty': 1400.0, 'AskPrice': 53680.0, 'AskSign': '0101', 'Buy1': {'Price': 53680.0, 'Qty': 1400.0, 'Sign': '0101', 'Time': '2021-09-01T15:00:00+09:00'}, 'Buy2': {'Price': 53670.0, 'Qty': 1000.0}, 'Buy3': {'Price': 53660.0, 'Qty': 300.0}, 'Buy4': {'Price': 53650.0, 'Qty': 2200.0}, 'Buy5': {'Price': 53640.0, 'Qty': 600.0}, 'Buy6': {'Price': 53630.0, 'Qty': 2300.0}, 'Buy7': {'Price': 53620.0, 'Qty': 600.0}, 'Buy8': {'Price': 53610.0, 'Qty': 600.0}, 'Buy9': {'Price': 53600.0, 'Qty': 4300.0}, 'Buy10': {'Price': 53590.0, 'Qty': 400.0}, 'Symbol': '7974', 'SymbolName': '任天堂', 'CurrentPrice': 53720.0, 'CurrentPriceTime': '2021-09-01T15:00:00+09:00', 'CurrentPriceChangeStatus': '0061', 'CurrentPriceStatus': 1, 'CalcPrice': 53720.0, 'PreviousClose': 52900.0, 'PreviousCloseTime': '2021-08-31T00:00:00+09:00', 'ChangePreviousClose': 820.0, 'ChangePreviousClosePer': 1.55, 'OpeningPrice': 53360.0, 'OpeningPriceTime': '2021-09-01T09:00:00+09:00', 'HighPrice': 53840.0, 'HighPriceTime': '2021-09-01T12:36:49+09:00', 'LowPrice': 53110.0, 'LowPriceTime': '2021-09-01T10:15:05+09:00', 'SecurityType': 1} / 7974 任天堂 53720.0
^CClose websocket
Task was destroyed but it is pending!
task: <Task pending name='Task-1' coro=<EntitySpec.__call__.<locals>.stream() running at /Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/kabusapi/websocket.py:19> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10ea4fbb0>()]>>
Exception ignored in: <coroutine object EntitySpec.__call__.<locals>.stream at 0x10e734bc0>
Traceback (most recent call last):
  File "/Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/kabusapi/websocket.py", line 24, in stream
    self.loop.stop()
  File "/Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/websockets/legacy/client.py", line 612, in __aexit__
    await self.protocol.close()
  File "/Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 599, in close
    await asyncio.wait_for(
  File "/Users/kit/.pyenv/versions/3.9.4/lib/python3.9/asyncio/tasks.py", line 435, in wait_for
    loop = events.get_running_loop()
RuntimeError: no running event loop
sys:1: RuntimeWarning: coroutine 'WebSocketCommonProtocol.write_close_frame' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Task was destroyed but it is pending!
task: <Task pending name='Task-2' coro=<WebSocketCommonProtocol.transfer_data() running at /Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/websockets/legacy/protocol.py:750> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10ea4fd30>()]> cb=[<TaskWakeupMethWrapper object at 0x10ea4fcd0>()]>
Task was destroyed but it is pending!
task: <Task pending name='Task-3' coro=<WebSocketCommonProtocol.keepalive_ping() running at /Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/websockets/legacy/protocol.py:1043> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10ea4fca0>()]>>
Task was destroyed but it is pending!
task: <Task pending name='Task-4' coro=<WebSocketCommonProtocol.close_connection() running at /Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/websockets/legacy/protocol.py:1095> wait_for=<Task pending name='Task-2' coro=<WebSocketCommonProtocol.transfer_data() running at /Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/websockets/legacy/protocol.py:750> wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at 0x10ea4fd30>()]> cb=[<TaskWakeupMethWrapper object at 0x10ea4fcd0>()]>>
Exception ignored in: <coroutine object WebSocketCommonProtocol.close_connection at 0x10ea259c0>
Traceback (most recent call last):
  File "/Users/kit/.local/share/virtualenvs/stock-trading-system-vApIpUVA/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 1134, in close_connection
    self.transport.close()
  File "/Users/kit/.pyenv/versions/3.9.4/lib/python3.9/asyncio/selector_events.py", line 700, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "/Users/kit/.pyenv/versions/3.9.4/lib/python3.9/asyncio/base_events.py", line 746, in call_soon
    self._check_closed()
  File "/Users/kit/.pyenv/versions/3.9.4/lib/python3.9/asyncio/base_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

いくつか、参考になりそうな記事があったので挙げておく。次は、このエラーを解消するところから始めることとする。

docs.python.org

stackoverflow.com

(C) 2020 dogwood008 禁無断転載 不許複製 Reprinting, reproducing are prohibited.