kabuステーション®APIを使った簡単なロジックの自動売買プログラムの作り方【株の自動売買プログラムをPythonで自作しよう⑤】

この記事には広告を含む場合があります。

記事内で紹介する商品を購入することで、当サイトに売り上げの一部が還元されることがあります。

前回の記事でkabuステーション®APIの使い方を学びました。

今回はkabuステーション®APIを使って簡単な自動売買プログラムを作成します。ここから本番環境での開発になるので、資金管理には注意してください。

購入する銘柄は、日本電信電話(NTT)にしたいと思います。この銘柄は1株150円程度(2024年8月)なので、1単元でも1万5千円程度で購入できます。出来高が多いので急な価格変動が起きにくく、作成したプログラムの検証をするにはいいと思います。

この記事で、自動売買のプログラミングの流れを理解していただければ思います。

プログラムのフローチャート

作成するプログラムは、株の板情報を取得して設定した価格以下の売り注文が出されたら、成行き注文を出して買うというような、指値注文のようなプログラムにします。

まずはプログラムのフローチャートを作ります。

フローチャートとは、プログラムの処理の流れをイメージ化したもので、プログラマーを始めとしたプログラムの設計者にとっては必要不可欠なツールです。

フローチャートの流れ
  • プログラム開始
  • 現在の板情報を取得する
  • 売り注文の価格が設定した価格を下回らなければ、5秒待って再度板情報を取得する
  • 売り注文の価格が設定した価格を下回れば、成行き注文を出して買う
  • プログラム終了

それでは実際に作成します。

プログラムの解説

フローチャートの内容でプログラムを作成すると次のようになります。

Python
import time
import urllib.request
import pprint
import json

# 設定項目
api_password = 'YOUR_PASSWORD'
order_password = 'YOUR_PASSWORD'
symbol = '9432'
buy_price = 150


# トークンを発行する関数
def generate_token():
    obj = {'APIPassword': api_password}
    json_data = json.dumps(obj).encode('utf8')

    url = 'http://localhost:18080/kabusapi/token'
    req = urllib.request.Request(url, json_data, method='POST')
    req.add_header('Content-Type', 'application/json')

    try:
        with urllib.request.urlopen(req) as res:
            content = json.loads(res.read())
            token_value = content.get('Token')
    except urllib.error.HTTPError as e:
        print(e)

    return token_value


# 板情報を取得する関数
def get_board_information(token):
    url = 'http://localhost:18080/kabusapi/board/' + symbol + '@1'
    req = urllib.request.Request(url, method='GET')
    req.add_header('Content-Type', 'application/json')
    req.add_header('X-API-KEY', token)

    try:
        with urllib.request.urlopen(req) as res:
            print(res.status, res.reason)
            for header in res.getheaders():
                print(header)
            print()
            content = json.loads(res.read())
            pprint.pprint(content)
    except urllib.error.HTTPError as e:
        print(e)
        content = json.loads(e.read())
        pprint.pprint(content)
    except Exception as e:
        print(e)

    return content


# 注文を出す関数
def kabusapi_sendorder_cash(token):
    obj = {'Password': order_password,  # 注文パスワード
           'Symbol': symbol,  # 銘柄コード
           'Exchange': 1,  # 市場コード
           'SecurityType': 1,  # 商品種別
           'Side': '2',  # 売買区分
           'CashMargin': 1,  # 信用区分
           'DelivType': 2,  # 受渡区分
           'FundType': 'AA',  # 資産区分(預り区分)
           'AccountType': 4,  # 口座種別
           'Qty': 100,  # 注文数量
           'FrontOrderType': 10,  # 執行条件
           'Price': 0,  # 注文価格
           'ExpireDay': 0  # 注文有効期限
           }
    json_data = json.dumps(obj).encode('utf-8')

    url = 'http://localhost:18080/kabusapi/sendorder'
    req = urllib.request.Request(url, json_data, method='POST')
    req.add_header('Content-Type', 'application/json')
    req.add_header('X-API-KEY', token)

    try:
        with urllib.request.urlopen(req) as res:
            print(res.status, res.reason)
            for header in res.getheaders():
                print(header)
            print()
            content = json.loads(res.read())
            pprint.pprint(content)
    except urllib.error.HTTPError as e:
        print(e)
        content = json.loads(e.read())
        pprint.pprint(content)
    except Exception as e:
        print(e)


# メイン処理
token_value = generate_token()

while True:
    board_information = get_board_information(token_value)
    sell_price = (board_information['Sell1']['Price'])

    if sell_price <= buy_price:
        kabusapi_sendorder_cash(token_value)
        break

    else:
        time.sleep(5)

それではポイントを解説します。

ライブラリのインポート

Python
import time
import urllib.request
import pprint
import json

まずは必要なライブラリをインポートします。

設定項目

Python
# 設定項目
api_password = 'YOUR_PASSWORD'
order_password = 'YOUR_PASSWORD'
symbol = '9432'
buy_price = 150

api_passwordには、kabuステーション®のAPIシステム設定で設定したAPIパスワードを記入します。

order_passwordには、auカブコム証券のログインパスワードを記入してください。APIパスワードではないので注意してください。

symbolは、証券コードを記入します。今回はNTTの9432です。

buy_priceは、購入したい価格です。

トークンを発行する関数

Python
# トークンを発行する関数
def generate_token():
    obj = {'APIPassword': api_password}
    json_data = json.dumps(obj).encode('utf8')

    url = 'http://localhost:18080/kabusapi/token'
    req = urllib.request.Request(url, json_data, method='POST')
    req.add_header('Content-Type', 'application/json')

    try:
        with urllib.request.urlopen(req) as res:
            content = json.loads(res.read())
            token_value = content.get('Token')
    except urllib.error.HTTPError as e:
        print(e)

    return token_value

def 文を用いて関数(function)を定義することができます。

関数とは、与えられた値をもとに一定の処理をして、その結果を返す命令のことです。関数に定義しておくことで、同じようなプログラムを何度も書く必要がなくなります。

トークンとは、APIを利用するためのパスワードのようなものです。初めにトークンを発行して、各APIのヘッダーに記載します。

板情報を取得する関数

Python
# 板情報を取得する関数
def get_board_information(token):
    url = 'http://localhost:18080/kabusapi/board/' + symbol + '@1'
    req = urllib.request.Request(url, method='GET')
    req.add_header('Content-Type', 'application/json')
    req.add_header('X-API-KEY', token)

    try:
        with urllib.request.urlopen(req) as res:
            print(res.status, res.reason)
            for header in res.getheaders():
                print(header)
            print()
            content = json.loads(res.read())
            pprint.pprint(content)
    except urllib.error.HTTPError as e:
        print(e)
        content = json.loads(e.read())
        pprint.pprint(content)
    except Exception as e:
        print(e)

    return content

この関数は、kabuステーション®APIで板情報を取得しています。

tryexceptはひとまとまりで例外処理と言います。

価格を取得する時に何かしらの理由でエラーが返ってくるとプログラムが止まってしまいます。例外処理は、エラーが返ってきた場合にエラー内容を表示して、プログラムが途中で止まらないようにしています。

成行注文を出す関数

Python
# 注文を出す関数
def kabusapi_sendorder_cash(token):
    obj = {'Password': order_password,  # 注文パスワード
           'Symbol': symbol,  # 銘柄コード
           'Exchange': 1,  # 市場コード
           'SecurityType': 1,  # 商品種別
           'Side': '2',  # 売買区分
           'CashMargin': 1,  # 信用区分
           'DelivType': 2,  # 受渡区分
           'FundType': 'AA',  # 資産区分(預り区分)
           'AccountType': 4,  # 口座種別
           'Qty': 100,  # 注文数量
           'FrontOrderType': 10,  # 執行条件
           'Price': 0,  # 注文価格
           'ExpireDay': 0  # 注文有効期限
           }
    json_data = json.dumps(obj).encode('utf-8')

    url = 'http://localhost:18080/kabusapi/sendorder'
    req = urllib.request.Request(url, json_data, method='POST')
    req.add_header('Content-Type', 'application/json')
    req.add_header('X-API-KEY', token)

    try:
        with urllib.request.urlopen(req) as res:
            print(res.status, res.reason)
            for header in res.getheaders():
                print(header)
            print()
            content = json.loads(res.read())
            pprint.pprint(content)
    except urllib.error.HTTPError as e:
        print(e)
        content = json.loads(e.read())
        pprint.pprint(content)
    except Exception as e:
        print(e)

公式の注文発注のサンプルコードを成行注文に変更しています。objFrontOrderTypeを10に変更することで成行き注文になります。

メイン処理

Python
# メイン処理
token_value = generate_token()

while True:
    board_information = get_board_information(token_value)
    sell_price = (board_information['Sell1']['Price'])

    if sell_price <= buy_price:
        kabusapi_sendorder_cash(token_value)
        break

    else:
        time.sleep(5)

初めにトークンを発行する関数で、トークンを入手します。

while文は、条件が満たされている間は処理を繰り返します。

このプログラムの場合は、get_board_information()の関数で板情報を取得して、最も低い売値をsell_priceに代入しています。

そして、if文でsell_pricebuy_priceを比較します。

sell_priceがbuy_price以下であれば5秒待って再度価格を取得します。

設定価格を下回ると、kabusapi_sendorder_cash()の関数で成行注文を出して、breakでプログラムは終了します。

注文が成立した場合は、ポジションが残っているので手動で決済してください。

おわりに

お疲れさまでした。

価格の条件を満たせば注文を出すプログラムの流れは理解できたでしょうか。

今回は成行注文を出せはプログラムは終了しますが、自動売買を継続させるには売りの条件を満たせば売りの注文を出して、プログラムをループさせる必要があります。

次回は、売買の戦略を考えて自動売買が継続するプログラムを作成していきます。

auカブコム証券

auカブコム証券 口座開設

信用格付は主要ネット証券No.1「AA」MUFGグループならではの信頼感

  • APIによる株の全自動取り引きに対応
  • 「kabuステーション®」や「カブナビ®」など、用途に合わせた各種の自社開発ツールを利用可能
  • 1日100万円まで手数料無料

\無料登録はこちらから!/