前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。
前回(#212)では Loguru × Makefile で WARN だけをリアルタイム監視 する方法を紹介しました。
今回はその続きとして 「まず安全」 を徹底するために入れた ミニ改善 と、実際に テストネットを 20 サイクル回してみた結果_ をまとめます。
🎯 対象読者
- VS Code & Docker で Python を書き始めたばかりの方
- 「まず動く」「まず安全」に興味がある仮想通貨 Bot 初学者
目次
- この記事で学べること
- Makefile改造──任意パラメータを一発で切替
- DD(ドローダウン)ガード & Slack 通知を安全装備
- テストネット 20 周の実測レポート
- “見落としがち” 追加チェックリスト
- 今日の学び・まとめ
1. この記事で学べること
| トピック | ざっくり一言 | 
|---|---|
| make runを1 行で自由にチューニング | make run LOT=0.001 MAX_NOTIONAL_USD=50 … | 
| DD ガード + Slack で“即死”を回避 | 実損 + 未実損を監視し、閾値で自動停止 | 
| Slack ノイズを減らす Tips | SLACK_LEVEL変数で WARN をミュート | 
| テストネット 20 サイクルのリアルデータ | +1.757 USDT、DD -0.00 USDT で完走 | 
| 実弾前に仕込むと安心な 5 つの保険 | Checklist 付き | 
2. Makefile 改造──任意パラメータを一発で切替
# 抜粋 run: $(CONFIG) set -a && source $(ENV) && set +a && \ docker compose run --rm --entrypoint "" $(SERVICE) \ python -m MMbotbybit.MMbotbybit \ --mode $(MMBOT_MODE) \ --config /app/$(CONFIG) \ --s_entry $(S_ENTRY) \ --max_loss_usd $(LOSS) \ --lot $(LOT) \ --max_cycles $(CYCLES) \ --timeout $(TIMEOUT)
- ポイント
- TIMEOUT,- LOSS,- MAX_NOTIONAL_USDなど、後ろに =- 値を付けるだけで変更可能
- make run ENV=.env.test LOT=0.001 LOSS=20 MAX_NOTIONAL_USD=50のように 1 行実行
 
3. DD ガード & Slack 通知を安全装備
3-1. Code Diff(概念)
# ─ new: get_unreal_pnl()
if realised + unreal <= -max_loss_usd:
    logger.error("DD guard hit → exit")
    await notify_slack(":fire: DD guard hit", ...)
    return
- 実現損益 + 未実現損益 を常時計算
- 閾値を超えたら 注文を全 cancel → ループ停止 → Slack 通知
3-2. Slack でこう見える
:fire: *MMBot* DD guard hit Realised +0.0000 Unreal -9.5648
※ Webhook URL は
.env.*に置き、config_*.jsonは envsubst で注入。
プライベートキー・URL をリポジトリに 書かない 方針です。
4. テストネット 20 周の実測レポート
| 指標 | 値 | 
|---|---|
| サイクル数 | 20 | 
| Lot | 0.001 BTC | 
| Spread 条件 | 0.000001 (= 0.1 bps) | 
| DD ガード | -20 USDT | 
| 所要時間 | ~56 min | 
| 累計 PnL | +1.757 USDT | 
| 最大 DD | -0.00 USDT (Guard未発火) | 
ログ全量は
logs/mm_bot_*.log、DB はmmtrades_testnet.dbに保存。tools/agg.py(次節)で CSV → グラフ化予定。
5. “見落としがち” 追加チェックリスト
| ✅ チェック | なぜ必要? | 具体アクション | 
|---|---|---|
| Testnet / Mainnet 切替を完全分離 | 誤発注保険 | ENV ?= .env.testをデフォ、make mainnet-loopのみに.env.prod | 
| Slack ノイズ制御 | 夜中の通知嵐防止 | SLACK_LEVEL=ERRORで WARNING を黙らせる | 
| 残高上限 Guard | 急変相場で破産を防ぐ | get_wallet_balance< reserve → 即 Exit | 
| DB / ログ回転 | ストレージ枯渇防止 | loguru rotation 済→ DB を日次 VACUUM | 
| 集計スクリプト | 事後検証を 5 分に短縮 | tools/agg.pyでpandas集計→Markdown 出力 | 
6. 今日の学び・まとめ
| 学び | 初心者に刺さる要点 | 
|---|---|
| パラメータは Makefile に集約 | “1 行実行” = 試行回数 が増える | 
| DD ガードは実損 + 未実損の合算で | 含み損を見逃さない | 
| Webhook は環境変数で注入 | 秘密情報をレポに 残さない文化 | 
| 小さな commit × 多い push | リカバリが秒で終わる | 
| Slack は LEVEL ごとに分流 | “静かな成功” と “響く失敗” を分ける | 
次の一歩(Tomorrow’s To-Do)
- pytest 導入 → 緑ランプが 0 件でもまず回る状態を作る
- GitHub Actions で pytest + gitleaks自動スキャン
- README に Quick Start(10 行)を追記
- tools/agg.py 雛形コミット → 実弾前に PnL 分布を可視化
- Mainnet ミニマム運用 (lot=0.0001, loss=10 USD, cycles=10)を 24 h 回す
「まず安全・まず可視化」——小さな保険を積み上げれば、
深夜 3 時に鳴るスマホ通知も“想定内”になります。
みなさんも DD ガード + Slack を 10 行でいいので試してみてください! 🚀
この記事は自分用ログを兼ねた学習アウトプットです。
サンプルコードは MIT License で公開、利用は自己責任で!
👇ラジオで話したこと
きょうの放送は “事故らないテスト運用” がテーマ。
まず全体像をさっと──Makefile のパラメータ上書きで「1 行チューニング」→ DD(ドローダウン)ガードと Slack 通知で“即死”ブレーキ→ 20 周テストの数字を公開──という流れでお送りします。途中 tail -F や Webhook って何?など初歩キーワードもかみ砕いて入れていきます。
0️⃣ ウォームアップ ─ 用語を 30 秒で
| 用語 | 超ざっくり | 
|---|---|
| DD(ドローダウン) | 口座残高が「ピーク→谷」で減った幅。投資の体力測定値。Investopedia | 
| Makefile | 「どうビルド/実行するか」を書いた台本。後ろで VAR=値を付けると上書きできる(?= 演算子も)Stack Overflow | 
| Loguru | import logging_setup1 行で高機能ログが使える軽量ライブラリ。Better Stack | 
| tail -F | ファイルの末尾を“追尾”表示。ローテーションで名前が変わっても付いて行く Fオプションが肝。Super User | 
| Webhook | URL へ POST するだけで Slack 等に通知を飛ばせる仕組み。Python なら slack_sdk.webhook.WebhookClientが楽。Slack開発者ツール | 
1️⃣ Makefile を“パラメータスイッチ”化
1 行実行デモ
make run ENV=.env.test LOT=0.001 LOSS=20 MAX_NOTIONAL_USD=50
- ENV=.env.testで テストネット用の鍵セットを読み込み
- LOT=0.001は最小ロット
- どの変数も Makefile 側は ?=でデフォルト、コマンド行は後勝ち。
変数を即上書きできるから“仮説→実行→数字確認”のサイクルが爆速になります。Stack Overflow
2️⃣ DD ガード × Slack ― 安全装備の心臓部
仕組み
- Bybit API /v5/position/listで未実現損益(unrealised PnL)を取得。bybit-exchange.github.io
- 累積確定損益と足し算。「-20 USDT を超えたら abort」という if。
- await notify_slack(":fire: DD guard hit …")─ Slack Webhook が火を吹く。
Slack に出るメッセージ例 ↓
🔥 MMBot DD guard hit Realised +0.0000 Unreal -9.5648
URL は .env に隠し、envsubst で config に注入──鍵は絶対コミットしないのが鉄則。Slack開発者ツール
3️⃣ テストネット 20 周実走レポート
| 指標 | 値 | 
|---|---|
| サイクル数 | 20 | 
| ロット | 0.001 BTC | 
| スプレッド条件 | 0.1 bps | 
| DD ガード | -20 USDT | 
| 所要時間 | 約 56 分 | 
| 累計 PnL | +1.757 USDT | 
| 最大 DD | 0.00 USDT(ガード未発火) | 
- Testnet と Mainnet の完全分離は超重要。テストネットは板が薄く、約定仕様も違う──でも“通信・ロジック健全性”はここでしか安全に確かめられない。Trust Wallet
- 全ログは logs/mm_bot_*.log、DB はmmtrades_testnet.db。日次でVACUUMを回してサイズを圧縮。Stack Overflow
4️⃣ “見落としがち” チェックリスト
| ✅ チェック | ねらい | 1 行アクション | 
|---|---|---|
| Test vs Main 完全分離 | 誤発注防止 | ENV ?= .env.testをデフォルトに | 
| Slack ノイズ制御 | 睡眠妨害回避 | SLACK_LEVEL=ERRORで WARN ミュート | 
| 残高上限 Guard | 破産防止 | if balance < reserve: exit() | 
| DB / ログ回転 | ディスク枯渇防止 | Loguru rotation+ VACUUM日次 | 
| 集計スクリプト | 後検証 5 分化 | tools/agg.py > report.md | 
5️⃣ 今日の学び
- パラメータは Makefile ─ コピペ・手打ちミスが激減。
- DD ガードは“実損+含み損”で評価 ─ 見かけプラスでも爆死を防ぐ。
- Webhook URL は環境変数で注入 ─ レポに秘密を残さない文化。
- 小さなコミットを多数 ─ git revertで秒ロールバック。
- Slack はレベル別チャンネル分流 ─ “静かな成功”と“響く失敗”を分ける。
6️⃣ 次の一歩
- pytest を入れて「テスト 0 件でもグリーン」な土台をまず作る。
- GitHub Actions + gitleaks で「push した瞬間キー混入チェック」。GitHub
- tools/agg.pyに pandas 集計を仕込み、PnL 分布を可視化。
- Mainnet ミニマム(lot 0.0001)で 24 h 放置テスト。
7️⃣ wrap-up(番組締め)
“まず安全・まず可視化”──DD ガードと Slack が 10 行で組めると、
深夜 3 時にスマホが鳴っても「はい想定内」と言えるメンタルシールドが手に入ります。
次回は pytest 自動テスト × GitHub Actions で “壊さない開発ループ” を作り込む予定です。
また次回の放送でお会いしましょう。よだかでした。
おまけ:"分かっていそうで分かっていない用語"解説
① Makefile まわり
| 用語 | 読み⾳ | 意味 & ひとこと | 
|---|---|---|
| VAR=値 | ばー・いこーる・あたい | シェル変数の一時設定。 PORT=8080 python app.pyのようにコマンド行だけ上書きできる。GeeksforGeeks | 
| ?= | はてな・いこーる | **「値が未設定なら代入」**という GNU make の演算子。環境変数やコマンド行で渡されたものが優先=“後勝ち”。GNUStack Overflow | 
| “デフォルトは ?=” | – | Makefile側は LOT ?= 0.001と書き標準値を用意→LOT=0.003 make runで即差し替え可。 | 
| 「コマンド行は後勝ち」 | こうまんど‐ぎょう… | 変数の優先順位ルール:①明示した環境変数 > ②コマンド行 > ③Makefile本体 > ④ ?=デフォルト。Stack Overflow | 
② ログ監視小技
| 用語 | 読み⾳ | ひとこと | 
|---|---|---|
| tail -F | ている・だっしゅ・えふ | **ファイル末尾を“Follow”**し続ける。 -Fは Logrotate などでファイル名が変わっても追従。Super User | 
| Fオプション | えふ・おぷしょん | 上と同じ。“Follow by name”。 -fは inode 追跡 /-Fは名前追跡+リトライ。 | 
| Loguru | ろぐる | Python の高機能ロガー。 logger.add(file, level="WARNING")1 行で warn.log 切り出し。GNU | 
| warn.log / debug.log | うぉーん・ろぐ / でばっぐ・ろぐ | レベル別ファイル:warn.log は WARNING↑の要注意、debug.log は開発時の詳細トレース。 | 
③ 環境変数とテンプレ
| 用語 | 読み⾳ | ひとこと | 
|---|---|---|
| envsubst | えんぶさぶすと | テキスト中の $VARを実際の環境変数に置換するコマンド。Docker で config を量産するとき定番。Baeldung | 
| 環境変数庫 (Secrets Store) | しーくれっつ・すとあ | GitHub Secrets など暗号保存の鍵置き場。YAML で secrets.API_KEYと呼び出す。 | 
④ SQLite & ディスク
| 用語 | 読み⾳ | ひとこと | 
|---|---|---|
| VACUUM | ばきゅーむ | SQLite のファイル再編成コマンド。不要領域を詰めてサイズ縮小=「ディスク枯渇」防止。SQLite | 
| ディスク枯渇 | でぃすく‐こかつ | ログや DB が膨張→ 容量ゼロ で Bot 停止。Logrotate / VACUUM で回避。Support Portal | 
⑤ Git & セキュリティ
| 用語 | 読み⾳ | ひとこと | 
|---|---|---|
| git revert | ぎっと・りばーと | “悪いコミットを逆向きに1個作って取り消す” 安全な巻き戻し。履歴は残る。Git | 
| キー混入スキャナ | きー‐こんにゅう… | gitleaks などで APIキーを含むパターンを自動検出。CI に挟んで防御。Jit | 
MEMO
- MAX_NOTIONAL_USDなど巨大数値をコマンド行で変えるときは- "MAX_NOTIONAL_USD=50"のようにクォート不要。
- VAR=valueのシェル書式は「そのコマンドの実行環境だけに一時設定」。export とは別。GeeksforGeeks
