-
Notifications
You must be signed in to change notification settings - Fork 28
Home
少し行儀の悪い方法ですが、おそらく一番トラブルの少ない方法です。
- パスの通っている場所を調べる。
$ python3 -c 'import sys; print(sys.path)'
['', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload',
'/home/sk/.local/lib/python3.8/site-packages', '/usr/lib/python3.8/site-packages']
- どこでも良いので(できれば管理者権限の必要ないディレクトリ)にbotfwのシンボリックリンクを作成。
$ cd /home/sk/.local/lib/python3.8/site-packages # pip install --user で使われるディレクトリ
$ ln -s /path/to/btc_bot_framework/botfw botfw
使用しているシェルの設定ファイル(.bashrc, .zshrc等)にPYTHONPATHを追加します。
正しい作法ですが、IDEによってはlinterのエラーがでたり、自動補完が効かなかったりします
export PYTHONPATH="/path/to/btc_bot_framework:$PYTHONPATH"
プロジェクト内に直接コードを書いて、プロジェクトルートからモジュールとして実行する場合は
特にインストール作業は必要ありません。
例えば、samples/bitflyer/orderbook.pyなら以下のように実行できます。(__init__.pyが必要かも)
$ python3 -m samples.bitflyer.orderbook
定数値(の内部値)はccxtとの一貫性や親和性のため取引所固有の値ではなく、ccxtに準拠しています。
- 'FX_BTC_JPY'(bitflyer) -> 'FX_BTC_JPY'(ccxt)
- 'BTC_JPY(bitflyer) -> 'BTC/JPY'(ccxt)
- 'BUY'(bitflyer), 'Buy'(bitmex), 'BUY'(binance) -> 'buy'(ccxt)
- 'LIMIT'(bitflyer), 'Limit'(bitmex), 'LIMIT'(binance) -> 'limit'(ccxt)
具体的な実装例はsamples内のファイルを参照してください。
- samples/simple_bot.py 簡単なbot。あくまで使い方を確認する用。
- samples/bitlyfer/trade.py 約定データを取得して表示します。
- samples/bitflyer/orderbook.py 板情報を取得して表示します。
trade.pyとorderbook.pyで利用されているtest_trade()とtest_orderbook()は それぞれ'botfw/base/trade.py'と'botfw/base/orderbook.py'内にあります。
ログ情報はすべてlogging(標準ライブラリ)から出力されるので、
はじめにロガーの初期化を行ってください。
ログフォーマットに拘りがなければ、setup_logger()で必要最低限の設定を行えます。
import logging
import botfw
botfw.setup_logger(logging.INFO)
log = logging.getLogger('MyLogger')
log.info('Hello!')
対象の取引所のクラスを生成して、create_trade()に取得したい通貨ペアのシンボルを渡すことでTradeクラスが生成されます。
Tradeは約定情報を受け取るとadd_callback()で設定されたコールバック関数を呼び出します。
引数は前から順にts(タイムスタンプ), price(価格), size(約定サイズ)です。
# Bitflyerの'FX_BTC_JPY'を取得する例
bitflyer = botfw.Bitflyer()
trade = bitflyer.create_trade('FX_BTC_JPY')
trade.add_callback(lambda ts, price, size: print(ts, price, size))
input() # 入力待機してプログラムが終了するのを防ぐ
- 注意点1
概要にもありますが、通貨ペアのシンボルはccxtに準拠します。例えば、Bitmexの'XBTUSD'は'BTC/USD'になります。
ccxtが対応していない取引所、または通貨ぺアについては取引所の表記に従います。 - 注意点2
コールバック関数は別スレッド(受信用のスレッド)から呼び出されるため、関数内部で長時間ブロッキングするような処理は避けてください。 - 注意点3
約定サイズは取引所の仕様に関わらず、Base通貨のサイズになります。
例えば、Bitmexの'BTC/USD'のサイズはQuote通貨(USD)で配信されていますが、Base通貨(BTC)に変換されます。
create_trade()はTradeクラスの無駄な複製を防ぐためのものです。
以下のように取引所クラスを生成せずに直接Tradeクラスを生成しても問題ありません。
trade = botfw.Bitflyer.Trade('FX_BTC_JPY')
コールバック関数は複数の追加・削除が可能です。参考
基本的には約定情報と同じですが、取得したデータを内部に保持するという点で異なります。
買い板、売り板の参照はそれぞれbids(), asks()で取得でき、現在価格に近い順に(best bid, best askが先頭)[price, size]のリスト(ビューオブジェクト)で保存されています。
コールバック関数は板情報が更新されたことを知らせるためのものであり、特に設定は必要ありません。
約定情報の注意点1,2,3が同様に当てはまるのでご注意ください。
# Bitflyerの'FX_BTC_JPY'を取得する例
bitflyer = botfw.Bitflyer()
orderbook = bitflyer.create_orderbook('FX_BTC_JPY')
# orderbook.add_callback(lambda: print('updated'))
while True:
for price, size in orderbook.bids()[:5]:
print('bid', price, size)
for price, size in orderbook.asks()[:5]:
print('ask', price, size)
time.sleep(1)
取引所クラスを生成して、init_account()メソッドにccxt同様のフォーマットでapi_keyとapi_secretを渡します。 この関数は内部でccxtの初期化、注文イベント用のwebsocketの認証などを行い以下の4つの変数を生成します。
-
api
ccxt apiにapiカウントの機能を付け加えたクラスです。 -
websocket
認証済みのwebsocket。注文イベントの受信用。 -
order_manager
注文イベントの処理を行うクラス。基本的に直接利用することはありません。 -
order_group_manager
注文グループを生成・管理するためのクラス。
次に、order_group_manager.create_order_group()に通貨シンボルとグループ名(任意の名称)を渡してorder_groupを生成します。
order_groupは注文をグルーピングするためのクラスで同一のシンボルに対しても複数作成することができます。
これは日本の取引所のように複数アカウントを持つことが難しい取引所において複数のロジックを実行する際に有用です。
注文、キャンセル、ポジション・(未実現)損益の確認はorder_groupを通して行います。
また、注文オブジェクト・ポジション情報の更新は注文イベント受信用のスレッドから非同期に行われます。
bitflyer = botfw.Bitflyer()
bitflyer.init_account({
'apiKey': 'YOUR_API_KEY',
'secret': 'YOUR_API_SECRET',
})
api = bitflyer.api
ogm = bitflyer.order_group_manager
# trade = bitflyer.create_trade('FX_BTC_JPY')
# orderbook = bitflyer.create_orderbook('FX_BTC_JPY')
og = ogm.create_order_group('FX_BTC_JPY', 'group_name_1')
og.set_order_log(logging.getLogger('group_name_1')) # 自動で注文・キャンセルのログを表示
order = og.create_order('limit', 'buy', 0.01, price=700000)
print(order)
og.cancel_order(order)
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
注文形式。create_order()のtypeに指定する値です。
- LIMIT (='limit')
指値注文。priceで価格を指定してください。 - MARKET (='market')
成行注文。priceは不要です。
注文の売り又は買い。create_order()のsideに指定する値です。
- BUY (='buy')
買い注文。 - SELL (='sell')
売り注文。
注文クラスのstate変数にセットされる値。
- OPEN (='open')
注文が有効(部分約定含む)である状態。 - CLOSED (='closed')
注文が全て約定した状態。 - CANCELED (='canceled')
注文が失効もしくはキャンセル(部分約定含む)された状態。 - WAIT_OPEN (='wait_open')
注文が送信されて、受付待ちの状態。 - WAIT_CANCEL (='wait_cancel')
注文のキャンセルを送信して、キャンセル待ちの状態。
注文に変化があった際に通知されるイベントです。
- EVENT_EXECUTION (='execution')
(部分)約定通知。 - EVENT_OPEN (='open')
注文の受付完了。 - EVENT_CANCEL (='cancel')
注文のキャンセル完了。 - EVENT_OPEN_FAILED (='open_failed')
注文の受付失敗。 - EVENT_CANCEL_FAILED (='cancel_failed')
注文のキャンセル失敗。 - EVENT_CLOSE (='close')
注文の全約定によるクローズ。取引所によっては通知されません。 - EVENT_ERROR (='error')
エラー通知。
各取引所のクラスは共通のベースクラスを継承して以下のように定義されています。
{Exchange}の部分はそれぞれの取引所の名称に置き換えて考えてください。
TODO
- symbol
- type
- side
- amount
- price
- params
TODO
- id
- filled
- state
- state_ts
- trade_ts
- open_ts
- close_ts
- editing
- external
TODO
- group_name
- event_cb
TODO
- id
- ts
- type
- price
- size
- fee
- message
- info
このクラスは取引所毎に異なるクラスの名称を共通の名前にエイリアスし、初期化処理を共通化するためのものです。
例えば、bitflyerの場合、以下のように定義されています。
class Bitflyer(ExchangeBase):
Api = BitflyerApi
Websocket = BitflyerWebsocket
OrderManager = BitflyerOrderManager
OrderGroupManager = BitflyerOrderGroupManager
Trade = BitflyerTrade
Orderbook = BitflyerOrderbook
ccxtを継承したクラスで通常のccxtメソッドに加えて、追加のメソッドとAPIの呼び出し回数を勘定する機能を提供します。
このクラスは主に内部で使用されるものなので、apiの余力を確認する以外の目的で参照することは基本的にありません。
websocketのコネクションを管理するクラスです。
内部で利用するクラスなので直接利用することはありません。
内部的に注文を管理するためのクラスです。
OrderGroupの生成と管理を行うクラスです。
ポジション管理・損益計算を行うクラスで、OrderGroupの内部で利用されます。
OrderGroupManagerによって生成されるクラスで、このクラスから注文とキャンセルを行います。
約定情報を提供するクラスです。
受信したデータを予め設定したコールバック関数に約定毎に渡します。
- add_callback(cb)
約定データを受信した際に呼び出されるコールバック関数(引数: ts, price, size)を指定します。
コールバック関数は複数追加した場合、登録した順に呼び出されます。 - remove_callback(cb)
add_callbackで追加したコールバック関数を削除します。
メソッドはインスタンス経由で参照する度にidが変わるため、コールバック関数として追加したメソッドを後から削除する場合は、予めadd_callbackに渡す前に変数に控えておいてください。
cb = obj.method
trade.add_callback(cb)
# trade.remove_callback(obj.method) # エラー
trade.remove_callback(cb) # 正常にコールバック関数を削除できる
板情報を提供するクラスです。
受信したデータを買い板(bids)と売り板(asks)に適切にソートして保持します。
- bids() ! 買い板のリスト(正確にはビューオブジェクト)を返します。 価格が高い順(best bidが先頭)に[price, size]の形式で格納されています。
- asks()
売り板のリスト(正確にはビューオブジェクト)を返します。 価格が低い順(best askが先頭)に[price, size]の形式で格納されています。 - add_callback(cb)
板が更新された際に呼び出されるコールバック関数(引数なし)を追加します。 コールバック関数は複数追加可能ですが、websocketのスレッドから登録した順に呼び出されるため、ブロッキングする処理は避けてください。 - remove_callback(cb)
add_callbackで追加したコールバック関数を削除します。 メソッド変数はインスタンス経由で参照する度にidが変わるため、コールバック関数として追加したメソッドを後から削除する場合は、予めadd_callbackする際に変数に控えておいてください。
TODO
-
多少コードが冗長になる場合でも、基本的には設計上の正しさを優先します。
-
フレームワーク部分(botfw)については以下の規則を適用します。
- pep8に準拠。ただし__init__.pyは例外
- コメントを含めて英語(askiiコードのみ)で記述。それ以外のsampleやgitログ等は自由。
-
メソッド名や引数の変数名とその順序、また定数変数(全部大文字の変数)の内部値は可能な限りccxtと揃えます。
- 'FX_BTC_JPY'(bitflyer) -> 'FX_BTC_JPY'(ccxt)
- 'BTC_JPY(bitflyer) -> 'BTC/JPY'(ccxt)
- 'BUY'(bitflyer), 'Buy'(bitmex), 'BUY'(binance) -> 'buy'(ccxt)
- 'LIMIT'(bitflyer), 'Limit'(bitmex), 'LIMIT'(binance) -> 'limit'(ccxt)
-
メソッド名の英単語は省略しませんが、変数名、及び引数名は意味の分かる範囲内で自由に省略します。
-
日本語部分(サンプルコード、README)を含め、全角スペース全面禁止
commit 161 (9537ca0a8404e68d4021eac02c86d675492e0545) ----------
- 注文・キャンセルを非同期(デフォルト)に変更。同期はsync=Trueを引数に渡す。
- simulation mode 実装
- liquid 追加
- OrderGroupの注文一覧(orders)を削除。代わりにget_orders()を追加。
- 変数名commissionをfeeに変更。手数料周りの実装を共通化。
commit 217 (6667332febf181d03ad7f77f15600de9f82a6bb8) ----------
- bitflyer web注文API 削除
commit 251 (b453d933ee80907ff7bfec3b18894f63088d69ae) ----------