GMOコインAPI×PythonでBTCを月1自動積立(Lambda+EventBridge)

PythonでBTCを自動購入するBot(GMOコインAPI×AWS Lambda/EventBridge)のイメージ図 仮想通貨
毎月25日9:00(JST)にBTCを自動購入する仕組み(Python+Lambda+EventBridge)
スポンサーリンク

この記事は、GMOコインの取引所(現物取引)でビットコインを定期購入するための、シンプルなPython Botを作った記録です。
もともとは自分用メモですが、あとから他の人でも再現できる手順として整えました。

まず結論として、この記事では「月1回の自動購入」を作ります。
次にローカルで動作確認し、問題なければAWSに載せ替える流れとなります。


できること:

  • BTCの現在価格を取得
  • GMOコインの資産残高を取得
  • 指定した予算(円)でBTCを成行購入
  • AWS Lambda + EventBridgeで毎月25日 09:00に自動実行
  • (任意)実行結果をAWS SNSメール通知で受け取る

免責・注意(大事)

  • これは投資助言ではありません。最終判断は自己責任でお願いします。
  • 自動購入は、誤作動・API障害・価格急変などのリスクがあります。
  • そのため、最初は必ず少額でテストしてください。
  • また、APIキーは流出すると危険です。絶対に公開しないでください。

今回の設定(この記事の前提)

  • 対象:BTCのみ
  • 購入方法:GMOコインの暗号資産APIで、BTCを成行(MARKET)注文
    (※本記事では「現物のBTCを買う」という意味で書いています。取引の区分や仕様は変更される可能性があるため、詳細は公式ドキュメントも併せて確認してください)
  • 購入金額:5,000円 / 回
  • 実行頻度:毎月25日 09:00(日本時間)
  • 通知:基本はGMOコインから届く「注文約定のお知らせ」メール

必要なもの

  • GMOコインの口座
  • GMOコインのAPIキー
  • PC(Windows / Mac)
  • Python
  • AWSアカウント

ステップ1:GMOコインでAPIキーを作成する

まず、GMOコインにログインします。
続いてメニューから「暗号資産API(APIキー管理)」を開きます。
そのうえでAPIキーを新規作成してください。

GMOコインのAPI設定画面

権限は最小限でOKです。
具体的には、資産残高取得と注文だけを許可します。

  • 資産残高を取得(例:Account / Assets)
  • 注文(Order)

GMOコインのAPIキー作成画面


ステップ2:ローカルで動作確認(Windows / Mac)

AWSに上げる前に、まずはローカルで動作を確認します。
ここでは「価格取得」と「残高取得」が動けばOKです。

2-1. Pythonが入っているか確認

Windows(PowerShell)

python --version

Mac(Terminal)

python3 --version
Windows PowerShell を使用してpythonのバージョンを確認する方法

例)Windows PowerShellの場合

2-2. 作業フォルダを作成

どこでも構いませんが、ローカルのどこかに btc-bot というフォルダを作ります。
この中にコードと設定ファイルを置きます。

2-3. 仮想環境(venv)を作る(おすすめ)

依存関係で詰まりにくくなるので、初心者ほどおすすめです。

Windows(PowerShell)

cd path\to\btc-bot
python -m venv .venv
.\.venv\Scripts\Activate.ps1

Mac(Terminal)

cd /path/to/btc-bot
python3 -m venv .venv
source .venv/bin/activate

うまく有効化できると、プロンプトの先頭に (.venv) が付くはずです。
それぞれ、「path/to」の部分を自分が決めたフォルダを指定してください。

2-4. 必要ライブラリをインストール

ローカルでは requestspython-dotenv を使います。

Windows

python -m pip install requests python-dotenv

Mac

python3 -m pip install requests python-dotenv

2-5. .env を作成(APIキーを保存)

作業フォルダ直下に .env というファイルを作り、以下を入れます。
値はあなたのものに置き換えてください。

GMO_API_KEY=xxxxxxxxxxxxxxxx
GMO_SECRET_KEY=yyyyyyyyyyyyyyyyyyyy

.env

は絶対に公開しないでください。


ステップ3:価格と資産残高を取得する

続けて、作業フォルダ内に test_bot.py を作って、以下を丸ごと貼り付けます。

import time
import hmac
import hashlib
import json
import requests
import os
from dotenv import load_dotenv

load_dotenv()

API_KEY = os.getenv("GMO_API_KEY")
API_SECRET = os.getenv("GMO_SECRET_KEY")

BASE_URL = "https://api.coin.z.com/private"
PUBLIC_URL = "https://api.coin.z.com/public"

def get_header(method, path, body=None):
    timestamp = str(int(time.time() * 1000))
    body_str = json.dumps(body) if body else ""
    text = timestamp + method + path + body_str

    signature = hmac.new(
        API_SECRET.encode("ascii"),
        text.encode("ascii"),
        hashlib.sha256
    ).hexdigest()

    return {
        "API-KEY": API_KEY,
        "API-TIMESTAMP": timestamp,
        "API-SIGN": signature
    }

def check_price():
    path = "/v1/ticker?symbol=BTC"
    res = requests.get(PUBLIC_URL + path)
    data = res.json()
    price = float(data["data"][0]["last"])
    print(f"現在のBTC価格: {int(price):,} 円")

def check_balance():
    path = "/v1/account/assets"
    headers = get_header("GET", path)

    res = requests.get(BASE_URL + path, headers=headers)
    data = res.json()

    if res.status_code != 200 or data.get("status") != 0:
        print("残高取得エラー:", data)
        return

    print("=== 資産状況(0より大きいものだけ表示)===")
    for asset in data["data"]:
        amount = float(asset["amount"])
        if amount > 0:
            print(f'{asset["symbol"]}: {amount}')

if __name__ == "__main__":
    check_price()
    print("-----")
    check_balance()

次に実行します。

Windows

python test_bot.py

Mac

python3 test_bot.py

価格と、保有がある通貨(JPYやBTCなど)が出ればOKです。

Windowsフォルダ構成

ここまでのWindowsフォルダ構成

Windows PowerShellにてtest_bot.pyを実行した結果

Windows PowerShellにてtest_bot.pyを実行した結果


ステップ4:BTCを成行で購入する(ローカル)

ここからは実際に注文を行いますので、最初は必ず少額でテストしてください。

以下のソースのとおり、# 1回あたりの購入金額(円)という部分に金額を設定します。
BUY_BUDGET_JPY = 5000 と書かれているので、1回の注文で5,000円分のBTCを購入するという設定になっています。もし不安なら、金額を安く変更してください。

なお、最低注文数量(最小注文単位)が決まっているため、購入金額が小さすぎると注文できません。
BTC価格によって円換算の必要額は変動するので、エラーが出た場合は購入金額を上げて再実行してください。

以下のコードを作業フォルダに buy_btc.py を作って貼り付けます。

import time
import hmac
import hashlib
import json
import requests
import os
import math
from dotenv import load_dotenv

load_dotenv()

# 1回あたりの購入金額(円)
BUY_BUDGET_JPY = 5000

API_KEY = os.getenv("GMO_API_KEY")
API_SECRET = os.getenv("GMO_SECRET_KEY")

BASE_URL = "https://api.coin.z.com/private"
PUBLIC_URL = "https://api.coin.z.com/public"

def get_header(method, path, body=None):
    timestamp = str(int(time.time() * 1000))
    body_str = json.dumps(body) if body else ""
    text = timestamp + method + path + body_str

    signature = hmac.new(
        API_SECRET.encode("ascii"),
        text.encode("ascii"),
        hashlib.sha256
    ).hexdigest()

    return {
        "API-KEY": API_KEY,
        "API-TIMESTAMP": timestamp,
        "API-SIGN": signature
    }

def get_ask_price():
    path = "/v1/ticker?symbol=BTC"
    res = requests.get(PUBLIC_URL + path)
    data = res.json()
    return float(data["data"][0]["ask"])

def buy_btc():
    ask_price = get_ask_price()
    print(f"現在のレート(ask): {int(ask_price):,} 円/BTC")

    # 予算 / レート でBTC量を計算し、最小単位(0.0001 BTC)に合わせて切り捨て
    amount = BUY_BUDGET_JPY / ask_price
    amount = math.floor(amount * 10000) / 10000

    print(f"予算: {BUY_BUDGET_JPY} 円 -> 注文数量: {amount} BTC")

    if amount < 0.0001:
        print("エラー: 注文数量が少なすぎます(このコードでは0.0001 BTC未満は弾いています)。購入金額を増やしてください。")
        return

    path = "/v1/order"
    body = {
        "symbol": "BTC",
        "side": "BUY",
        "executionType": "MARKET",
        "size": str(amount)
    }

    headers = get_header("POST", path, body)

    res = requests.post(BASE_URL + path, headers=headers, json=body)
    data = res.json()

    if res.status_code == 200 and data.get("status") == 0:
        print("注文成功!")
        print("注文ID:", data.get("data"))
        print("GMOコインから約定メールが届くはずです。")
    else:
        print("注文失敗:", data)

if __name__ == "__main__":
    buy_btc()

実行:

Windows

python buy_btc.py

Mac

python3 buy_btc.py

実行すると、現在価格の取得 → 注文数量の計算 → 注文発注、という流れでログが出ます。


$ python buy_btc.py
現在のレート(ask): 9,845,000 円/BTC
予算: 5000 円 -> 注文数量: 0.0005 BTC
注文成功!
注文ID: ****123456
GMOコインから約定メールが届くはずです。

残高不足の場合

[ERROR] Insufficient funds: JPY balance is less than budget_jpy.

対処方法:購入金額を下げるか、入金してください。

最小注文数量に満たない場合

[ERROR] size_final is below minimum order size.

対処方法:購入金額を上げてください。


ステップ5:AWS Lambdaに移植してクラウド実行する

ローカルで動いたら、次はAWS Lambdaで動かします。

5-1. Lambda関数を作成

  • AWS Lambda → 「関数の作成」
  • 一から作成
  • 関数名:btc-monthly-bot(例)
  • ランタイム:Python 3.1x(3.14にて動作は確認済み)

5-2. 環境変数を設定

Lambda → 設定 → 環境変数 に以下を追加:

  • GMO_API_KEY
  • GMO_SECRET_KEY

AWS Lambdaにて、作成した関数の設定で、環境変数を設定する方法

5-3. Lambdaコード(lambda_function.py)

次に、Lambdaのエディタで lambda_function.py を以下に置き換えます。
※新規作成ではなく、既存の lambda_function.py を置き換えてください。

import time
import hmac
import hashlib
import json
import urllib.request
import urllib.error
import os
import math

BUY_BUDGET_JPY = 5000

BASE_URL = "https://api.coin.z.com/private"
PUBLIC_URL = "https://api.coin.z.com/public"

def get_header(method, path, body=None):
    api_key = os.environ["GMO_API_KEY"]
    api_secret = os.environ["GMO_SECRET_KEY"]

    timestamp = str(int(time.time() * 1000))
    body_str = json.dumps(body) if body else ""
    text = timestamp + method + path + body_str

    signature = hmac.new(
        api_secret.encode("ascii"),
        text.encode("ascii"),
        hashlib.sha256
    ).hexdigest()

    return {
        "API-KEY": api_key,
        "API-TIMESTAMP": timestamp,
        "API-SIGN": signature,
        "Content-Type": "application/json",
    }

def get_ask_price():
    path = "/v1/ticker?symbol=BTC"
    url = PUBLIC_URL + path
    with urllib.request.urlopen(url) as res:
        data = json.loads(res.read().decode("utf-8"))
        return float(data["data"][0]["ask"])

def lambda_handler(event, context):
    try:
        ask_price = get_ask_price()
        print(f"現在のレート(ask): {int(ask_price):,} 円/BTC")

        amount = BUY_BUDGET_JPY / ask_price
        amount = math.floor(amount * 10000) / 10000
        print(f"予算: {BUY_BUDGET_JPY} 円 -> 注文数量: {amount} BTC")

        if amount < 0.0001:
            return {"statusCode": 400, "body": json.dumps("予算不足(最低0.0001 BTC)")}

        path = "/v1/order"
        body = {
            "symbol": "BTC",
            "side": "BUY",
            "executionType": "MARKET",
            "size": str(amount),
        }

        headers = get_header("POST", path, body)
        req = urllib.request.Request(
            BASE_URL + path,
            data=json.dumps(body).encode("utf-8"),
            headers=headers,
            method="POST",
        )

        with urllib.request.urlopen(req) as res:
            res_json = json.loads(res.read().decode("utf-8"))
            print("GMOレスポンス:", res_json)

            if res_json.get("status") == 0:
                return {"statusCode": 200, "body": json.dumps("注文成功!")}
            else:
                return {"statusCode": 500, "body": json.dumps(res_json)}

    except urllib.error.HTTPError as e:
        err_body = e.read().decode("utf-8")
        print("HTTPError:", err_body)
        return {"statusCode": 500, "body": json.dumps(err_body)}
    except Exception as e:
        print("Exception:", str(e))
        return {"statusCode": 500, "body": json.dumps(str(e))}

5-4. タイムアウトを30秒にする

最後に、Lambda → 設定 → 一般設定 で、タイムアウトを 30秒 にします。


参考(公式):


ステップ6:EventBridgeで自動実行設定を行う

最後に、Lambdaにトリガーを追加して、EventBridgeのスケジュールで月1実行にします。
ここまで完了すれば、後は自動で購入してくれます。あと少し!

  • Lambda → 「+ トリガーを追加 (Add trigger)」
  • ソースの選択:「EventBridge (CloudWatch Events)」
  • ルール:新規ルールの作成(Create a new rule)
  • ルール名:任意
  • ルールの説明:任意
  • ルールタイプ:スケジュール式(Schedule expression)
  • スケジュール式(Schedule expression):cron(0 0 25 * ? *)

※EventBridge の cron は基本的に UTC で解釈されます。
そのため cron(0 0 25 * ? *) は「毎月25日 00:00(UTC)」=「毎月25日 09:00(JST)」の指定です。
実行したい時刻が日本時間ベースで変わる場合は、UTCに換算して調整してください。

AWS Lamdbaのトリガーを設定する方法


(オプション)AWS SNSで成功/失敗をメール通知する

GMOコインから約定メールが来るので基本は不要です。ご興味がある方は試してみてください。


よくある詰まりポイント

  • Macでpythonが見つからない: python3 を使う
  • dotenvがない: pip install python-dotenv
  • Lambdaのログ: CloudWatch Logsで確認

おわりに

半自動とはいえ、一度仕組みができると、あとは毎月勝手に購入してくれるので、とても便利です。
できれば、入金~コールドウォレットへ送金までできれば最高なのですが、まだそこまでは難しそうです。

もし、わからないことがありましたら、X(旧Twitter)にてお気軽にご連絡ください。
一緒にbotライフを楽しみましょう!

仮想通貨投資
スポンサーリンク
シェアする
hamunekoをフォローする
スポンサーリンク

コメント