Bot mmnot 開発ログ

🛠️開発記録#210(2025/5/5)MMbot 開発ログ16「含み損 DD ガード & Slack 要約通知を実装して“安全運転”を強化!」

2025年5月5日

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

注意
本記事は筆者の個人的な開発実験をまとめた技術メモです。投資助言ではありません。購入・売却その他の投資判断は各自の責任でお願いします。


1. はじめに — フェーズ 2 “安全に稼ぐ” へのアップシフト

  • 目的:マーケットメイク bot (以下 MMbot) を “資金を極端に溶かさない” 仕様に仕立てる
  • 本日のメインタスク
    1. 未実現損益(Unrealised PnL)を取り込んだ DD(ドローダウン)リミッター
    2. WARN 以上のログを Slack にサマリ通知

これで 確定 + 含み損 を同時監視でき、想定以上のマイナスに傾いたらポジションを閉じて自動停止。心理負担が一気に減りました。


2. 今日のハイライト

✔️内容メモ
get_unreal_pnl() 追加Bybit v5 Position API で未確定損益を取得
DD ガード(確定 + 未確定 ≤ -max_loss で停止)Slack へ :fire: 通知して即 exit
Loguru level='WARNING' を Slack 要約に流す主要サイクルだけを 1 行サマリ
max_cycles=∞ でロングラン検証へ移行👈今ココlot=0.001/max_loss=5 USD の超小ロット

3. 実装ポイント(機密をぼかした擬似コード)

async def dd_guard(realised, sess, cfg, symbol, limit=-5):
    """
    realised : float  # 累積確定 PnL
    limit    : float  # マイナス許容ライン (USD)
    """
    unrealised = await get_unreal_pnl(sess, cfg, symbol)  # ← v5/position/list
    if realised + unrealised <= -limit:
        logger.error(f"DD hit: {realised:+.4f} {unrealised:+.4f}")
        await close_all_positions(sess, cfg, symbol)  # ←詳細ロジックは未公開
        await notify_slack(cfg["slack_webhook_url"],
            f":fire: *MMBot* DD guard hit\n"
            f"Realised `{realised:+.4f}`  Unreal `{unrealised:+.4f}`")
        raise SystemExit            # きれいに停止

🔒 秘匿ポイント

  • close_all_positions() の実装と署名生成 (create_signature) の完全版は非公開
  • 実 API キー/Webhook URL は .env へ退避

4. フォワードテスト結果(ミニマム実弾)

MetricValue
テスト時間1 h 13 m
サイクル数85
確定 PnL+0.0337 USD
最大含み損-2.25 USD
DD ガード発火1 回(発火後、自動停止を確認)
API エラー0 (WARN 通知 3 回)

Slack に流れてくるのはこんな感じの通知です。

📈 MMBot cycle 82
spread 0.00000
Buy  @94389 → Fill
Sell @94390 → Fill
Cycle PnL +0.0010
Total PnL +0.0327

発火時は:

🔥 MMBot DD guard hit
Realised +0.0337  Unreal -2.2453
Yodaka

最大含み損を加味してbotが停止したことが停止したことが分かります。


5. 今日得られた学び

  1. 含み損も見るだけで安心感が段違い
    • 実装行数は <30 行だが、心理的レバレッジは約 10 倍。
  2. 通知は“1 サイクル = 1 行”に集約
    • ノイズが減り、スマホでも概要を瞬時に把握。
  3. WARN レベル閾値 を設けると「ちょっと嫌な挙動」を早期検知できる。

6. 次のタスク(明日以降)

優先タスク目的
🟢 close_all_positions() の網羅テスト強制決済の信頼性を 100 % に
🟡 warn.log と debug.log を分離本番運用でのログ見やすさ向上
🟡 pytest → get_unreal_pnl() ユニットテストAPI レスポンスのパース崩れ防止
🟠 手動オフセット入力 UI“買いポジ残ってる? → -qty” を即座に入れられる
🟠 タグ付き Slack チャンネル分割DEV / PROD を完全に分ける

7. 全体ロードマップでの現在地

Phase 0  ✔️ ブートストラップ(板取得・両建て)
Phase 1  ✔️ ミニマム実弾 & 手動監視
Phase 2  🟢 安全装置・自動停止 ← **Now!**
Phase 3  ⏳ ロット増 / マルチペア化
Phase 4  ⏳ 戦略 AB テスト / パラメータ自動最適化
Phase 5  ⏳ “安定して稼げる” モードで 24/7 稼働

フェーズ 2 の安全装置は 70 % 完了。残るはポジション自動クローズと総合リトライ戦略。


8. まとめ

TL;DR
“DD ガード” と “Slack 要約通知” を実装し、含み損を含めたリスク管理を強化。テストでは想定通りガードが発動し、自動停止を確認。今後は 強制クローズの信頼性向上ログ分離 に着手予定。

おまけ:なぜ「最大 含み損」がマーケットメイク戦略では命綱になるのか

(ビギナー向け解説)

用語カンタンに言うと…
確定損益すでに約定して“お財布”に反映された損益。
→ もう増減しない“済んだ話”。
含み損益まだクローズしていないポジションが
もし今すぐ決済されたら発生する損益。
→ “これからどうにでも動く”数字。

1️⃣ マーケットメイクは「在庫ビジネス」

MMbot は 買いと売りを交互に並べ、“買って⇒売る” を高速で繰り返します。
ところが板が片寄ると 買いだけ成立して“在庫”(ポジション)が溜まりがち。

イメージ:
フリマで「仕入れ値 100 円/売値 101 円」の品を並べていたら
買い手だけ来て在庫を抱えた状態。


2️⃣ “在庫” がある限り 相場変動は丸かぶり

価格がすとーんと下がると、手元の在庫価値も一緒に下落。
この時点では 確定のマイナスはゼロ でも、
含み損 が大きくなり “資金拘束” が増えます。


3️⃣ 証拠金強制ロスカット の壁

  • 取引所は「含み損が一定以上に膨らむと追加証拠金」を要求
  • 対応しないと 強制決済(ロスカット) → もっと不利な価格で処分され損失確定

だから “今は見た目プラス”でも
含み損が大きいと 実は危険信号 なのです!


4️⃣ DD ガード は “命のブレーキ”

  • 確定 + 含み損 をつねに合算し
  • 設定した ―● USD を下回った瞬間に 自動停止
    • 追加発注ストップ
    • まだ残っている在庫をフラットに戻す(手仕舞い)
    • Slack へ緊急通知

これで

“気づいたら口座が空っぽ”
“寝ているあいだにロスカット”

といった ワーストシナリオ を防ぐことができます。


5️⃣ まとめ

  1. マーケットメイク=両替屋 ⇒ 在庫を常に持つ可能性がある
  2. 在庫を抱えたまま相場が急変すると 含み損が爆増 する
  3. 含み損も監視して即ブレーキ を踏む仕組みが “生存の最低条件”

💡 ポイント
「含み損を数える=負けを認める」ではなく、
“次も戦える残高を守る” 安全装置 と考えよう!


※本記事は技術検証の共有であり、投資助言ではありません。リスク管理はご自身の判断と責任でお願いします。

👇ラジオで話したこと

MMBot開発ログ16|“DDガード&Slack通知”でBotの安全運転に本格対応!


こんにちは、よだかです。
今回のテーマは、MMBotを「安全に稼ぐBot」へ進化させるアップグレードについて。

ついにこのBotも【フェーズ2:安全運転フェーズ】に入りました。
Botが知らぬ間に資金を溶かさないよう、DDガード(最大ドローダウン制御)とSlack要約通知を入れたことで、
動かしながらも安心感が段違いになった……そんな開発ログをお届けします。


✅ 1. フェーズ2は「守りの強化」がテーマ

MMBotはマーケットメイク型のBotなので、
板の両側に注文を出して、“買って→売る” を繰り返す両替屋さんのような存在です。

ただ、在庫(ポジション)を持ったまま相場が急落すると、
「今は確定損失がないけど、含み損だけズドンと膨らむ」
ということが起きます。

そこで、今回やったのが以下の2つ:

  1. 含み損を含めた最大損失ガード(=DDガード)
  2. Slackへの要約通知で、“何が起きたか”をすぐ確認できる設計

✅ 2. DDガード:確定 + 含み損で強制停止

if realised + unrealised <= -limit:
    await close_all_positions(...)
    await notify_slack(...DD hit...)
    raise SystemExit

これが今回の実装の核です。

  • BybitのポジションAPIから未実現損益(含み損)を取得
  • 累積の確定損失と合計して、設定値を下回ったらポジションを手仕舞い+Bot停止

通知はSlackへ:

🔥 MMBot DD guard hit
Realised +0.0337  Unreal -2.2453

この瞬間にBotが止まり、Slackに“危険信号”が飛びます。


✅ 3. Slack要約通知:1サイクル1行に集約

ログを読まなくても概要が分かるように、通知はこうなります:

📈 MMBot cycle 82
spread 0.00000
Buy  @94389 → Fill
Sell @94390 → Fill
Cycle PnL +0.0010
Total PnL +0.0327

さらにLoguruのWARNINGレベル以上だけSlackに流すことで、
「ちょっと嫌な挙動」を早期検知できる仕組みが完成。

通知の“質”を整えると、スマホからでも運用状況が把握しやすくなります。


✅ 4. 実弾テスト結果:DDガード発火も確認

テスト環境で実際にDDガードが動いた結果はこちら:

指標
テスト時間1時間13分
サイクル数85
確定PnL+0.0337 USD
最大含み損-2.25 USD
DDガード発火1回(その後Bot停止)
APIエラー0(Warning通知3回)

→ 実際に含み損が想定以上に膨らんだら、Botが自動で止まりました。
これで、「気づいたら口座が空っぽ」みたいな事態はほぼ回避できます。


✅ 5. 今日の学び:30行で得た安心感は10倍

  • 含み損を加味するだけで、「Bot任せの不安」が一気に減る
  • 通知は1サイクル1行にまとめると、ログが読みやすい
  • WARNINGレベルをSlack通知の閾値にするだけで異変に気付きやすくなる

実装は30行足らずでしたが、心理的レバレッジは10倍以上
「今何が起きているか分かる」という安心感は、数字以上に価値があります。


✅ 6. 次のタスクと今いる地点

今の開発は、フェーズごとに進めています:

✔️ フェーズ0:板取得&両建て  
✔️ フェーズ1:実弾ミニマムテスト  
🟢 フェーズ2:安全装置・自動停止 ← 今ココ  
⏳ フェーズ3:ロット増 / 複数ペア化  
⏳ フェーズ4:戦略ABテスト / 自動最適化  
⏳ フェーズ5:24/7の安定運用へ

今後は:

  • 強制手仕舞いロジックの網羅テスト
  • warn.log / debug.logの分離
  • Slack通知の環境ごとのチャンネル分割

などを進めていく予定です。


✅ 7. おまけ:なぜ「含み損ガード」がマーケットメイクBotの命綱なのか?

ここからは初心者向けに、なぜ“含み損”が重要なのか、マーケットメイクBotの仕組みと合わせて簡単に解説します


🧠 マーケットメイク=両替屋さん

  • 「買い」と「売り」の両側に注文を出して、差額で少しずつ稼ぐ
  • でも、板が偏ると「買い」だけ約定して、ポジションが溜まる(=在庫が増える)

🧨 在庫を持ったまま相場が落ちると…

  • 含み損がどんどん膨らむ
  • 確定損はまだゼロでも、ロスカット寸前というケースもある
  • 追加証拠金を入れないと、強制決済されるリスクが高まる

🛑 DDガード=“命のブレーキ”

  • 確定 + 含み損 が設定値を超えたら
    全ポジションを閉じて、自動停止 + 通知
    → 寝てる間でも、最悪のケースを防げる

含み損をカウントするのは負けを認めるんじゃなくて、
“次も戦える残高を守る”ための戦略的な防衛ラインなんです。


まとめ:

  • 今回は DDガードとSlack通知の実装で“安全運転”を実現しました
  • Botが含み損を抱えすぎたら自動で止まり、異常はSlackで即時通知
  • 心理的に安心してロットを上げられる「環境整備」ができてきました


“攻め”の前に“守り”を整えることが、長くBotを動かす鍵だと改めて実感しています。
次回はその先――マルチペア化や自動戦略最適化に進んでいく予定です。
またお会いしましょう!安全で強い開発を。ではまた!よだかでした。🎤

-Bot, mmnot, 開発ログ