Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GMO コイン用の DataStore を一部実装する #74

Merged
merged 7 commits into from Jul 28, 2021

Conversation

supermomonga
Copy link
Contributor

@supermomonga supermomonga commented Jul 18, 2021

related: #60



  • できるだけエディタの支援を効かせるため、積極的に型を書いています。
    • 値の一覧が既知のプロパティについては列挙型を定義しています。(レファレンス > パラメータ など)
    • 各データは TypedDict として実装してあります。独自クラスではなく TypedDict 型を採用した理由は、現状データストアが取り扱うデータの型が Dict[str, Any] である Item であるため、既存データストアの実装を変更せずに互換性を持たせられるためです。(データの出し入れ時に Item 型との cast をしています)
  • GMO コインは REST API と WebSocket API で同じ種類のデータについても返却データの型が一致していないため、片方にしか存在しないプロパティは Optional 型になっています。

@supermomonga supermomonga changed the base branch from main to develop July 18, 2021 13:34
@supermomonga
Copy link
Contributor Author

自分がシストレで利用したいデータについて実装したものですので、現状 Public WebSocket の 「最新レート」「取引履歴」は未実装です。こちらは時間が取れた際に実装する気持ちはありますが、いつになるかわからないためひとまず現状できている部分で Pull Request を立てました。

@supermomonga
Copy link
Contributor Author

注文情報について

Private WebSocket の注文情報通知チャンネルではなぜか注文がキャンセルされたことは検知できても約定したことは検知できない仕様になっているため(なぜそんな仕様に…?)、約定情報通知チャンネルのデータも用いて注文情報の更新・削除を行っています。

@MtkN1 MtkN1 self-assigned this Jul 19, 2021
@MtkN1 MtkN1 self-requested a review July 19, 2021 15:46
@MtkN1 MtkN1 added the enhancement New feature or request label Jul 19, 2021
@MtkN1
Copy link
Member

MtkN1 commented Jul 19, 2021

素晴らしい完成度のコードですね。本当にありがとうございます。
理解を進めているところですので数日お待ちください。

@MtkN1
Copy link
Member

MtkN1 commented Jul 19, 2021

クラス設計の理解

  • Enum 継承クラス
    • ApiType, Channel, MessageType, Symbol, OrderSide, ExecutionType, TimeInForce, SettleType, OrderType, OrderStatus, CancelType
    • リファレンスの既知のプロパティに基づいた列挙型
    • TypedDict の型に使ったり、WebSocketデータについてのif条件に使う
  • TypedDict 継承クラス (dataclassデコレータ)
    • Ticker, OrderLevel, OrderBook, Trade, Execution, Order, Position, PositionSummary
    • DataStore の Item に対する TypedDict 型
  • DataStore 継承クラス
    • OrderBookStore, OrderStore, ExecutionStore, PositionStore, PositionSummaryStore
    • 従来のストアクラス
    • データ挿入の際はcastを行っている
  • MessageHelper クラス
    • スタティックメソッド to_xxxxx で Item を TypedDict に変換するヘルパークラス
    • initializeやonmessage内で利用
  • DataStoreInterface 継承クラス
    • 従来のストアインターフェースクラス

@supermomonga
Copy link
Contributor Author

MessageHelper の static メソッドは本当は各データ型自身(Order, Execution など)に持たせたかったのですが、 TypedDict している関係で(実態は単なる辞書なので)ヘルパークラスに外だしせざるを得ませんでした。もっと良い方法があればいいのですが…

Copy link
Member

@MtkN1 MtkN1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@supermomonga
確認・テストを行いました。
いくつかSuggestionを出していますが、動かない箇所もあったので修正コードを書いてあります。
Suggestion内容に問題なければ修正コードをこちらでコミットしようかと思います。(Decimalの修正量が多かったので)

pybotters/models/gmocoin.py Outdated Show resolved Hide resolved
pybotters/models/gmocoin.py Outdated Show resolved Hide resolved
pybotters/models/gmocoin.py Outdated Show resolved Hide resolved
pybotters/models/gmocoin.py Outdated Show resolved Hide resolved
pybotters/models/gmocoin.py Outdated Show resolved Hide resolved
pybotters/models/gmocoin.py Outdated Show resolved Hide resolved
pybotters/models/gmocoin.py Outdated Show resolved Hide resolved
Copy link
Member

@MtkN1 MtkN1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

もう一点追記します。

pybotters/models/gmocoin.py Outdated Show resolved Hide resolved
@MtkN1
Copy link
Member

MtkN1 commented Jul 23, 2021

テストコード

import asyncio

import pybotters
from rich.console import Console

console = Console()


async def main():
    async with pybotters.Client(base_url='https://api.coin.z.com') as client:
        # test for public websocket(板情報を1度表示する)
        store = pybotters.GMOCoinDataStore()
        console.rule('public')
        wstask = await client.ws_connect(
            'wss://api.coin.z.com/ws/public/v1',
            send_json={'command': 'subscribe', 'channel': 'orderbooks', 'symbol': 'XRP_JPY'},
            hdlr_json=store.onmessage,
        )
        while not len(store.orderbooks):
            await store.orderbooks.wait()
        console.print(store.orderbooks.sorted())

        # test for initialize
        store = pybotters.GMOCoinDataStore()
        await store.initialize(
            client.get('/private/v1/latestExecutions?symbol=XRP_JPY'),
            client.get('/private/v1/activeOrders?symbol=XRP_JPY'),
            client.get('/private/v1/openPositions?symbol=XRP_JPY'),
            client.get('/private/v1/positionSummary?symbol=XRP_JPY'),
        )
        console.rule('initialize')
        console.print(
            {
                'executions': store.executions.find(),
                'orders': store.orders.find(),
                'positions': store.positions.find(),
                'position_summary': store.position_summary.find(),
            }
        )

        # test for private websocket(無限ループ、Web画面で取引して確認する)
        console.rule('private')
        r = await client.post('/private/v1/ws-auth')
        data = await r.json()
        token = data['data']
        wstask = await client.ws_connect(
            f'wss://api.coin.z.com/ws/private/v1/{token}',
            send_json=[
                {'command': 'subscribe', 'channel': 'executionEvents'},
                {'command': 'subscribe', 'channel': 'orderEvents'},
                {'command': 'subscribe', 'channel': 'positionEvents'},
                {'command': 'subscribe', 'channel': 'positionSummaryEvents'},
            ],
            hdlr_json=store.onmessage,
        )
        while True:
            console.print(
                {
                    'executions': store.executions.find(),
                    'orders': store.orders.find(),
                    'positions': store.positions.find(),
                    'position_summary': store.position_summary.find(),
                }
            )
            await store.wait()


try:
    asyncio.run(main())
except KeyboardInterrupt:
    pass

@supermomonga
Copy link
Contributor Author

@MtkN1

確認・テストを行いました。
いくつかSuggestionを出していますが、動かない箇所もあったので修正コードを書いてあります。
Suggestion内容に問題なければ修正コードをこちらでコミットしようかと思います。(Decimalの修正量が多かったので)

レビューありがとうございます!
Suggestion の件、一部こちらでコミットしてしまった部分があるので、それ以外の部分の追加をお願いできればと思います🙏

@supermomonga
Copy link
Contributor Author

また、 _onmessage などが非同期になってたりなってなかったりで統一できてない部分に気づいたのでどちらかに寄せて頂ければ… 🙇

@MtkN1
Copy link
Member

MtkN1 commented Jul 23, 2021

直接コミットしました。 しっかり動作してますね!
特に異議なければMergeさせて頂きます。

@supermomonga
Copy link
Contributor Author

あ、すみません通知見落としてました。大丈夫だと思います!

@MtkN1 MtkN1 merged commit 8d8dbba into pybotters:develop Jul 28, 2021
@supermomonga supermomonga deleted the datastore-gmocoin branch August 15, 2021 11:38
@MtkN1 MtkN1 mentioned this pull request Aug 15, 2021
MtkN1 added a commit that referenced this pull request Aug 15, 2021
✨v0.6.0リリース

## Issues
✅ 対応取引所の追加(Phemex、Coincheck) #52
✅ GMO コインの DataStore を実装する #60
✅ リリース表記をPreview版にする #73
✅ FTXDataStore の orders チャネルにおける close されたオーダーの取り扱いについて #75
✅ DataStoreInterfaceのクラス名を変更する #79
## Pull requests
✅ GMO コイン用の DataStore を一部実装する #74
✅ DataStore のレコード削除メソッドのサンプル実装 #76
✅ DataStore の wait メソッドが変更されたデータを返す実装 #77
✅ Sphinxのドキュメントを追加 #78
@MtkN1 MtkN1 mentioned this pull request Jan 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GMO コインの DataStore を実装する
2 participants