前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。
0. はじめに
前回は “可観測性” をテーマに、メトリクス取得とログ設計を整えました。
今回は 「手数料を負け筋から勝ち筋へ反転させる」 が主眼です。
データを収集しながらMaker 固定 に到達するまでの試行錯誤と、
安全にデプロイするためのシェル改善を共有します。
1. 到達点(公開版サマリ)
項目 | ステータス |
---|---|
注文方式 | PostOnly 100 %(Maker リベート –0.02 %) |
ループ間隔 | 5 s(旧 8 s:板追従性向上) |
エントリー判定 | spread% × tick 数 の複合条件 |
安全装置 | DD ガード 3 USD / minQty 自動補正 |
デプロイ | Docker Compose + Poetry / ShellCheck で静的解析 |
現フェーズ | 24 h 実弾ミニマム運用で Maker 比率を監視 |
Next | Lot 拡張 → 動的スプレッド閾値の自動調整 |
2. 今回“新しく”手を入れたポイント(前回と非重複)
# | 施策 | 目的・効果 | 備考 |
---|---|---|---|
1 | PostOnly 強制フラグ〈FORCE_POST_ONLY=true 〉 | すべての約定を Maker に固定し、リベートで手数料を相殺 | CLI ↔ env ブリッジでオンオフ自在 |
2 | スプレッド閾値の逆算 | Maker リベート込みで “最低勝てる幅” を理論値から設定 | 具体値は非公開 |
3 | tick 判定パラメータ化 (TICK_THR ) | 板が詰まった 1 tick ノイズで発注しない | 本番ネットの板厚でチューニング |
4 | minQty 自動取得 | 取引所仕様更新に負けない起動ロバスト性 | REST 1 call、0.3 s で完了 |
5 | ShellCheck + set -eu | エントリポイントのシェル事故をゼロに | CI で毎プッシュ実行中 |
3. “Maker 固定” を実現するパラメータ設計フロー
- 手数料を先に差し引く
- 残る利幅 = 目標スプレッド
- tick 数で現実幅を検証
flowchart LR Fee["Taker 手数料<br>0.055 % ×2"] -->|逆算| Width["必要スプレッド%"] Width --> Tick["Tick 数に換算"] Tick --> Entry["エントリー閾値 (spread% & tick)"]
Maker リベート(-0.02 %×2)を踏まえないと、
「広がったつもりで実は負けていた」罠にハマります。
4. デプロイを安全にするシェル Tips
チェック項 | やったこと | Why |
---|---|---|
未定義変数エラー | set -eu 追加 | “typo 1 文字”で即クラッシュ→事故前に検知 |
動的フラグ挿入 | ${POST_FLAG:+"$POST_FLAG"} | 空文字なら丸ごと引数を省略 |
CI 静的解析 | shellcheck entrypoint.sh | コンテナビルド前にヒューマンエラー排除 |
5. 今回の学び
- Maker リベートは“戦略”ではなく“前提条件”
→ 取れないなら MM 戦略を名乗るべきではない、と再認識。 - 閾値は「理論 → 実観測 → 再キャリブレート」のループで締まる
→ データ無しのチューニングは時間の浪費。 - シェルは小さくてもクリティカルパス
→set -eu
と ShellCheck だけで本番落ちが激減。
6. 次の一手
- Lot 拡張 → スリッページ計測
- 動的
s_entry
(ボラティリティ依存)実装 - Maker/Taker 統計を Slack 集計ボットで自動可視化
7. おわりに
エッジを伏せつつ「何を考え、どこを変えたか」は公開できる──
公開することを通して、自分の思考と戦略を再確認できる──
Bot 開発は “情報戦” と “再現性” の両立が難しいですが、
測って・固めて・また測る の繰り返しが遠回りのようで一番速い。
本記事は技術共有を目的としたものであり、投資助言ではありません。
実売買はご自身の判断と責任で。
👇ラジオで話したこと
MMbot開発ログ23「PostOnly 固定で“手数料負け”を根絶するまで──MMBot パラメータ・ハードニング」
「今日は“Maker リベートで勝ち筋を作る”がテーマ。PostOnly=板に注文を置く側に固定し、手数料を“もらう”側へ反転させます。では、どんなパラメータを触り、どこに落とし穴があったのか? ゆるっと深掘りしていきましょう!」
1│そもそも PostOnly・Maker とは?
- 取引所の手数料モデル
- Maker (板に流動性を供給)=多くの取引所でマイナス手数料、Bybit だと –0.02 % が典型
- Taker (板の既存注文を食う)=0.05 % 前後の支払い側。
- PostOnly フラグを付けると「板に刺さらず即約定しそうならキャンセル」という安全弁になり、約定は 100 % Maker。
★ワンフレーズ:
「PostOnly = Maker 固定スイッチ」
2│今回いじった5つのポイント
# | 施策 | ねらい | 実装メモ |
---|---|---|---|
1 | FORCE_POST_ONLY=true | Maker100%でリベート確保 | CLI と .env の両方で切替可 |
2 | スプレッド閾値の逆算 | 「Makerリベート – Taker手数料 ×2 > 0」を方程式化 | 理論最小値=勝てる幅を先に算出 |
3 | TICK_THR パラメータ | 板が詰まった 1tick ノイズで発注しない | tick は「最小価格単位」 |
4 | minQty 自動取得 | 取引所の最小ロット更新で 404 を回避 | 起動時に REST を1回だけ呼ぶ |
5 | Shell ハードニング | set -eu で typo 即停止・ShellCheck で lint | ShellCheck は CI に 1 行で追加可 |
3│パラメータ設計フロー
- 手数料を先に差し引く
- Taker: +0.055 % ×2 Maker: –0.02 % ×2 👉 最低でも 0.07 % 稼がないと赤字
- 目標スプレッド% → tick 数へ換算
- 例:BTCUSDT の tick=0.1 USDT 👉 0.07 % =約 70 $/BTC → 700 ticks
spread_pct >= X && tick >= Y
の 複合判定へ落とす。
「Maker 戦略は“儲ける”前に“負けを消す”計算から」
① “前提のおさらい”
「まず、取引には必ず“手数料”が付いて回ります。
買いでも売りでも、板に置いた指値が“受け身で約定”すれば
‘メーカー(Maker)手数料’で –0.02 % のリベートが貰える。
逆に、こちらから成行で突っ込む ‘テイカー(Taker)’ だと
+0.055 %×2回ぶん、合計約 +0.11 % を払う――
ここがスタートラインです。」**
② “理論上の最低ライン”を電卓で弾く
「ということは、
メーカーで2回約定 → –0.04 % が手数料で返ってくる。
テイカーで2回 → +0.11 % 取られる。
その差し引きで 約 +0.07 % 以上の利幅を取らないと、
トータルで赤字、という計算ですね。」**
③ “%”を“ティック数”に置き換える
「ところが板は “パーセント” じゃなく ‘ティック’ で動きます。
いま BTC/USDT のティックは 0.1 ドル。
1 BTC が 100 000 ドルとすると、0.07 % は 70 ドル に相当。
70 ドル ÷ 0.1 ドル = 700 ティック。
つまり “700 ティック以上開いた瞬間じゃないと負ける”
-- これが数字の意味合いです。」
④ “複合判定”でノイズをカット
「そこでプログラムでは、
spread_pct >= X かつ tick >= Y
――
パーセント条件とティック条件を両方クリアした瞬間だけ&&
(アンド条件)で発注します。
パーセントは利幅を、ティックは板の ‘厚み’ を保証する。
2つのフィルターを通すことで “手数料負け” を根絶しよう、
という狙いです。」**
⑤ まとめ & 次のセグへブリッジ
「要は 『まず手数料を払う前提で利幅を逆算、
その数字をパーセントとティックの “二重ゲート” に落とす』
これが マーケットメイク Bot の基本設計 です。
では実際の板でどうチューニングしたか――
次のパートで実測ログを見ながら解説します!」
4│デプロイ周りの安全装置
set -eu
─ e : error-on-fail / u : undefined 変数エラー- ShellCheck で静的解析(CI 失敗ならビルド拒否)
- 動的フラグ …
${POST_FLAG:+"$POST_FLAG"}
- 変数が空なら引数自体を削る Bash テンプレート技法。
- Poetry + Docker Compose
make mainnet-loop
→.env.prod
を envsubst でテンプレに流し込み- PostOnly フラグ付きでコンテナ起動。
5│6 時間実弾ミニマムテストの結果
指標 | 値 | コメント |
---|---|---|
Lot | 0.0001 BTC | 資金リスクを極小化 |
ループ間隔 | 5 s | 板追従性 ↑ |
Maker 比率 | 100 % | PostOnly 成功 |
Net PnL | +0.27 USDT | 手数料差し引き後でも黒字 |
最大 DD | –0.9 USDT | DD_GUARD=3 で未発火 |
静かなログ:make logs-warn
で WARN 0 行、「何も起きない=想定どおり」の確認。
6│今日の学び
- 「Maker リベートは“前提条件”」──取れない環境なら戦略を再考せよ。
- 理論値 → 実データ → 再調整 のループが最短。
- シェルは小さくても本番クリティカル──lint と
set -eu
で事故率激減。
7│次の一手
- Lot 拡大+スリッページ測定
- ボラティリティ連動
s_entry
の自動化 - Maker/Taker 比率を Slack Bot で日次レポート
▽ おまけコーナー
- 「Maker と Taker、言い分の違い」
- Maker は「店側」、Taker は「来店客」。
- 流動性コスト vs 機会費用のトレードオフ。
set -eu
って読み方?- 「セット・ハイフン・イー・ユー」── u は undefined.
- ShellCheck が教えてくれた3つの凡ミス
- 変数名 typo
"$@"
を忘れて引数ロストecho
に未クオート JSON → パース崩壊
「lint はうるさいけど、“今怒られるか、明朝4 時に怒られるか” の違い」
「測って固めて、また測る。遠回りのようで最速――これがマーケットメイク Bot の醍醐味です。次回は可視化と動的パラメータで、さらに一段ギアを上げていきます。それでは、また!」