見出し画像

bitflyerの約定通知の遅延を測った

from argparse import ArgumentParser

import asyncio
import math
import pybotters
from datetime import datetime
from collections import deque
from loguru import logger


class ExecutionLatencyMonitor:
    def __init__(self, buffer=1000, report_interval=10):
        self._q = deque(maxlen=buffer)
        self._report_interval = report_interval
        self._task = asyncio.create_task(self._auto_report())

    async def _auto_report(self):
        while True:
            await asyncio.sleep(self._report_interval)
            if len(self._q):
                begin = self._q[0][0]
                end = self._q[-1][0]
                latency = [(item[0] - item[1]).total_seconds() for item in self._q]
                mu = sum(latency) / len(latency)
                sigma = math.sqrt(sum([(l-mu) * (l-mu) for l in latency])/len(latency))
                ma = max(latency)
                mi = min(latency)
                logger.info(f"|{len(latency)}|{begin}|{end}|{mu:.10f}|{sigma:.10f}|{ma:.6f}|{mi:.6f}|")

    def onmessage(self, msg, ws):
        if "params" in msg:
            now = datetime.utcnow()
            for m in msg["params"]["message"]:
                e_date = datetime.strptime(m["exec_date"][:-2], "%Y-%m-%dT%H:%M:%S.%f")
                self._q.append((now, e_date))


async def main(args):
    async with pybotters.Client() as client:

        monitor = ExecutionLatencyMonitor()
        await client.ws_connect(
            "wss://ws.lightstream.bitflyer.com/json-rpc",
            send_json=[
                {
                    "method": "subscribe",
                    "params": {"channel": f"lightning_executions_{args.symbol}"},
                    "id": 1,
                },
            ],
            hdlr_json=monitor.onmessage,
        )

        while True:
            await asyncio.sleep(1)


if __name__ == "__main__":
    parser = ArgumentParser()

    parser.add_argument("--symbol", default="FX_BTC_JPY")

    args = parser.parse_args()
    try:
        asyncio.run(main(args))
    except KeyboardInterrupt:
        pass
  • 一定時間経過ごとに直近n個の遅延誤差の平均・標準・最大値・最小値をログ

  • pybottersのwatchを使いたいところだが、bitflyerの約定通知はまとめてくるので、watchを使うとそれらが別物として扱われてしまう

# AWSの東京リージョン
2022-09-07 13:58:48.201 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:53:18.835268|2022-09-07 13:58:47.018776|0.0596268050|0.0421290103|0.683196|0.027049|
2022-09-07 13:58:58.204 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:53:30.359711|2022-09-07 13:58:56.777739|0.0595688420|0.0420924232|0.683196|0.027049|
2022-09-07 13:59:08.206 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:53:30.685243|2022-09-07 13:59:05.367340|0.0595357040|0.0421000592|0.683196|0.027049|
2022-09-07 13:59:18.208 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:54:00.152217|2022-09-07 13:59:17.420288|0.0584478110|0.0414388235|0.683196|0.026602|
2022-09-07 13:59:28.210 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:54:18.955208|2022-09-07 13:59:27.420732|0.0586771420|0.0413571288|0.683196|0.026602|
2022-09-07 13:59:38.213 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:54:21.992611|2022-09-07 13:59:37.473156|0.0585555590|0.0413499163|0.683196|0.026602|
2022-09-07 13:59:48.214 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:54:25.162477|2022-09-07 13:59:48.138442|0.0585088490|0.0413560639|0.683196|0.026602|
2022-09-07 13:59:58.216 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:54:30.125641|2022-09-07 13:59:57.653028|0.0585370920|0.0414107161|0.683196|0.026602|
# 自宅
2022-09-07 22:58:46.975 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:53:18.581778|2022-09-07 13:58:46.935919|0.0634665990|0.0543972803|0.736953|0.012844|
2022-09-07 22:58:56.978 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:53:30.344611|2022-09-07 13:58:56.852462|0.0625516410|0.0540536836|0.736953|0.012844|
2022-09-07 22:59:06.982 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:53:30.674314|2022-09-07 13:59:05.401354|0.0627119550|0.0541814215|0.736953|0.012844|
2022-09-07 22:59:16.986 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:53:58.384756|2022-09-07 13:59:16.641317|0.0606454580|0.0535296265|0.736953|0.012844|
2022-09-07 22:59:26.989 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:54:18.269110|2022-09-07 13:59:26.876786|0.0607995420|0.0532579510|0.736953|0.012844|
2022-09-07 22:59:36.992 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:54:20.800654|2022-09-07 13:59:35.477337|0.0605663220|0.0531636329|0.736953|0.012844|
2022-09-07 22:59:46.996 | INFO     | __main__:_auto_report:28 - |1000|2022-09-07 13:54:23.515795|2022-09-07 13:59:46.245475|0.0606818380|0.0532357478|0.736953|0.012844
  • 東京リージョンの方がわずかーーーーに遅延が少ない(0.058~0.059秒 vs. 0.060~0.063秒)

  • 東京リージョンの方がわずかーーーーに分散が小さい(0.04秒 vs. 0.05秒)

自宅(nuro光+HUAWEIのrouter HG8045Q)意外と頑張ってるな、と思った。

速度テストやったら結構でてた。無線でこれはなかなか素晴らしいのでは。

nuro光オススメ記事になってしまった。

(注意)AWSはt2.microで手元はM1 mac なのでマシンパワーでどうにかなってる気がしないでもない。

いいなと思ったら応援しよう!