Bot

仮想通貨botの開発を本格的に始めてみる#8(2023/9/8)

前回の記事に続いて、今回も仮想通貨botの開発状況をまとめていきます。

今回は「ccxtを使ってbitFlyerでの注文の出し方をマスターする」の続きです。

注文状況のデータを取得する

まずは、前回の記事で書いたコードを実行して、2件の買い注文を出します。

そして、注文状況のデータを取得します。

実行したのは以下のコードです。

import ccxt
from pprint import pprint

bitflyer = ccxt.bitflyer()
bitflyer.apiKey = 'APIキー'
bitflyer.secret = 'APIシークレット'

orders = bitflyer.fetch_open_orders(
symbol = "BTC/JPY:JPY",
params = { "product_code" : "FX_BTC_JPY" })
pprint( orders )

すると以下の文字列が表示されます。

[{'amount': 0.01,
'average': None,
'clientOrderId': None,
'cost': 0.0,
'datetime': '2023-09-06T14:12:22.000Z',
'fee': {'cost': 0.0, 'currency': None, 'rate': None},
'fees': [{'cost': 0.0, 'currency': None, 'rate': None}],
'filled': 0.0,
'id': 'JRF20230906-141221-004167',
'info': {'average_price': '0.0',
'cancel_size': '0.0',
'child_order_acceptance_id': 'JRF20230906-141221-004167',
'child_order_date': '2023-09-06T14:12:22',
'child_order_id': 'JFX20230906-141222-778456F',
'child_order_state': 'ACTIVE',
'child_order_type': 'LIMIT',
'executed_size': '0.0',
'expire_date': '2023-10-06T14:12:21',
'id': '0',
'outstanding_size': '0.01',
'price': '3000000.0',
'product_code': 'FX_BTC_JPY',
'side': 'BUY',
'size': '0.01',
'time_in_force': 'GTC',
'total_commission': '0.0'},
'lastTradeTimestamp': None,
'postOnly': None,
'price': 3000000.0,
'remaining': 0.01,
'side': 'buy',
'status': 'open',
'stopPrice': None,
'symbol': 'BTC/JPY:JPY',
'timeInForce': None,
'timestamp': 1694009542000,
'trades': [],
'triggerPrice': None,
'type': 'limit'},
{'amount': 0.01,
'average': None,
'clientOrderId': None,
'cost': 0.0,
'datetime': '2023-09-06T14:27:58.000Z',
'fee': {'cost': 0.0, 'currency': None, 'rate': None},
'fees': [{'cost': 0.0, 'currency': None, 'rate': None}],
'filled': 0.0,
'id': 'JRF20230906-142758-004993',
'info': {'average_price': '0.0',
'cancel_size': '0.0',
'child_order_acceptance_id': 'JRF20230906-142758-004993',
'child_order_date': '2023-09-06T14:27:58',
'child_order_id': 'JFX20230906-142758-001344F',
'child_order_state': 'ACTIVE',
'child_order_type': 'LIMIT',
'executed_size': '0.0',
'expire_date': '2023-10-06T14:27:58',
'id': '0',
'outstanding_size': '0.01',
'price': '3000000.0',
'product_code': 'FX_BTC_JPY',
'side': 'BUY',
'size': '0.01',
'time_in_force': 'GTC',
'total_commission': '0.0'},
'lastTradeTimestamp': None,
'postOnly': None,
'price': 3000000.0,
'remaining': 0.01,
'side': 'buy',
'status': 'open',
'stopPrice': None,
'symbol': 'BTC/JPY:JPY',
'timeInForce': None,
'timestamp': 1694010478000,
'trades': [],
'triggerPrice': None,
'type': 'limit'}]

これだけだと、余分な情報も表示されているため、注文idに限定して情報を表示させます。

import ccxt
from pprint import pprint

bitflyer = ccxt.bitflyer()
bitflyer.apiKey = 'APIキー'
bitflyer.secret = 'APIシークレット'

orders = bitflyer.fetch_open_orders(
symbol = "BTC/JPY:JPY",
params = { "product_code" : "FX_BTC_JPY" })

for o in orders:
pprint( o["id"] )

最後の2行では、for文が出てきたので過去記事でおさらい。

先ほどpprintの処理で表示したものはorder = [ ]というデータです。(前提としてorder=というデータであることを忘れていたため、調べるのに手間取りました。前提知識の重要性がここでも効いてきますね)

特にこの部分が引っかかったため、念入りにおさらいしておきます。

for o in orders:
pprint( o["id"] )

上記のコードでordersという要素の一つずつに順番に「o」という要素を入れて、idだけを限定して書き出せという指示を出しています。

for文の意味を改めて理解できたため、こちらの記事で調べ直してみて良かったです。

注文状況の取得:応用編

複数の注文を取得するために、以下のコードを実行します。

import ccxt
from pprint import pprint

bitflyer = ccxt.bitflyer()
bitflyer.apiKey = 'APIキー'
bitflyer.secret = 'APIシークレット'

orders = bitflyer.fetch_orders(
symbol = "BTC/JPY:JPY",
params = {"priduct_code" : "FX_BTC_JPY",
"count" : 10})

for o in orders:
print( o["id"] + " : 注文状況 " + o["status"] )

ordersの中に"count" : 10を入れることで「10個の注文状況を取得する」という設定にしています。

最後の1行もかなり重要です。

for o in orders:
print( o["id"] + " : 注文状況 " + o["status"] )

ここでは「+」を使うことで、表示される情報を複数指定することができます。

「””」で囲んだ要素であれば文字列としてそのまま書き出すこともできるので、「 " : 注文状況 "」というコードを書いておくことで、表示される注文情報を見やすくすることもできます。

「”〇〇”」の中は「スペースや文字」を自由に入れることができるため、見やすいデータを表示する小技としても有効です。

実際に、表示された注文情報は「:」で区切られていて見やすいです。

注文をキャンセルする

注文のキャンセルに使ったコードは以下の通り。

解説サイトに掲載されていたコードは最後の4行だけ表示されていたため、初めはコードを走らせることができず、またしても色々と調べることに...。

そして、こちらの記事を参考に、適切なコードを書くことができました。

import ccxt

bitflyer = ccxt.bitflyer()
bitflyer.apiKey = 'APIキー'
bitflyer.secret = 'APIシークレット'

bitflyer.cancel_order(
symbol = "BTC/JPY:JPY",
id = "注文ID",
params = { "product_code" : "FX_BTC_JPY" })

ccxtのインポートとbitflyer・APIキー・APIシークレットの定義を飛ばしていたことが原因でした。

プログラミングの初心者だと、こんな簡単なことにもいちいち躓いてしまうのです。

そのプログラムが何を定義して下準備しているのかを意識しなければなりませんね。

注文のキャンセル:応用編

以下のコードで、最新の注文をキャンセルすることができます。

import ccxt

bitflyer = ccxt.bitflyer()
bitflyer.apiKey = 'APIキー'
bitflyer.secret = 'APIシークレット'

orders = bitflyer.fetch_open_orders(
symbol = "BTC/JPY:JPY",
params = { "product_code" : "FX_BTC_JPY"})

bitflyer.cancel_order(
symbol = "BTC/JPY:JPY",
id = orders[-1]["id"],
params = { "product_code" : "FX_BTC_JPY" })

追加されたのは赤字の部分です。

太字の部分でordersを定義して、bitflyer.cancel_order()で注文をキャンセルしています。

id = orders[-1]["id"]

このコードが意味するのは、「idの中から最新のもの=一番後ろにあるものを取得しなさい」という約束です。

つまり、特定したいデータが「後ろから何番目なのか」を指定するときには「-(マイナス)」を使うということです。

まとめ

そろそろコードも複雑になってきました。

疑問に思ったことがすぐに解決できないこともあり、進み具合がゆっくりになってきている気がします。

前提となっていることを認識しないまま学習を進めても、応用が効かなくなるのでここはグッと堪えて地道に進めていこうと思います。

また、調べる過程で他のサイトでは同じことをやっていても、その取り組み方が少しずつ違っているという発見がありました。

bitFlyerのAPIを活用する方法や、コードの書き方がわずかに違ったり、処理の仕方や処理の結果を表記する方法にもわずかな違いがあって参考になります。

それと同時に、どのサイトにも同じように使われてるコードも存在するため、共通して使用されるものの重要性もなんとなく感じ取ることができるようになってきました。

さらに、各記号「,」「""」「''」「=」「==」など)の読み方と意味にも興味が出てきました。その点はこちらのサイトが参考になりました。

次回は、練習課題に取り組んでいきながら理解を深めていきます。

-Bot