2026-02-10: プロジェクト開始 - 仕様読み込み・API調査
仕様書 (chisiki_bot_specification.md)、PM作業ログ (PM_work_log.md)、引き継ぎメモ (handoff_fromPM.md) を精読
VPS環境確認:
Python 3.8.10 (default), Python 3.10.17 (利用可能) → SDKが3.10+要求のため3.10を使用
Node.js v20.20.0
aiohttp, websockets等は既にインストール済み
Extended API ドキュメント・Python SDK 調査 (詳細は下記)
項目
仕様書の想定
実際のAPI仕様
シンボル名
BTC-PERP
BTC-USD (要確認)
成行注文
成行 (market)
ネイティブ市場注文なし : IOC limit で模倣 (buy: best_ask * 1.0075, sell: best_bid * 0.9925)
SL注文
conditional → market
conditional注文あり (triggerPrice + direction指定)。executionPriceTypeにLIMIT指定
TPSL
別注文方式 (方式1)
ネイティブTPSL注文あり (ORDER型/POSITION型)。ただし各leg個別にStark署名が必要
reduce-only
対応前提
reduceOnly: true で対応
avg_price
取得方法不明
注文レスポンスに averagePrice フィールドあり
fee
省略可能想定
必須パラメータ (max acceptable fee as decimal)
expiry
省略可能想定
必須パラメータ (expiryEpochMillis)
Layer 1 : API Key (X-Api-Key ヘッダー) + User-Agent ヘッダー → 読み取り専用
Layer 2 : Stark署名 (SNIP12 / StarkNet版EIP-712) → 注文発行に必要
必要情報: api_key, public_key, private_key, vault_id
利用可能 : StarkNet Sepolia上
REST: https://api.starknet.sepolia.extended.exchange/api/v1
WS: wss://starknet.sepolia.extended.exchange/stream.extended.exchange/v1
テストUSDC: 1時間あたり$1,000/ウォレットで請求可能
注文有効期限: 最大28日
pip install x10-python-trading-starknet
Python 3.10+ 必須
完全非同期 (asyncio/aiohttp)
主要クラス: PerpetualTradingClient, PerpetualStreamClient, StarkPerpetualAccount
注文作成: create_order_object() で署名・nonce・フォーマットを一括処理
標準: 1,000リクエスト/分/IP
HTTP 429 で制限通知
エントリー: IOC limit で模倣 OK
SL: IOCではなくネイティブTPSLを使う方針に変更(サーバー側で発火)
テストネット不使用、メインネットで開発・実取引
認証情報: .env に保存済み
レバレッジ: 50倍固定
最大DD制限: なし
途中決済: v0では実装しない
クールダウン: なし(チェック完了後即次サイクル)
Discord: Webhook未準備
分解ルール: ほぼ半分に分割(端数は後ろに寄せる)
項目
値
シンボル名
BTC-USD (確定)
tick size (min_price_change)
1 USD (整数価格)
step size (min_order_size)
0.0001 BTC
min_order_size_change
0.00001 BTC
price_precision
0 (小数なし)
quantity_precision
5
max_leverage
50x
現在のレバレッジ
10x (→50xに変更必要)
残高
$29.99 USD
ポジション
なし
未決注文
なし
maker fee
0.0 (無料)
taker fee
0.000225 (0.0225%)
bid/ask spread
~1 USD
limit_price_cap/floor
0.05 (5%)
POSITION型TPSL: 未実装 (NotImplementedError)
MARKET price_type (TPSL): 未実装 (NotImplementedError)
Market注文: SDKは常にLIMIT型で作成
Conditional注文: create_order_objectでは作成不可
→ 採用方式 : ORDER型TPSL をエントリー注文に付与
TP: LIMIT price_type (指値で正確に約定)
SL: LIMIT price_type + 攻撃的価格 (trigger - 500 USD等 → 実質market)
エントリーはIOC LIMIT (ask * 1.0075 でBUY)
create_order_object でIOCエントリー + ORDER型TPSL (TP/SL付き) のオーダーオブジェクトを正常作成
送信はしていない
SL_USD = 20 (確定)
レバレッジ = 50x (確定・変更済み)
メインネットで実注文テストOK
Discord通知は後回し
Test 1: IOC BUY/SELL (TPSL無し)
BUY: 0.0001 BTC @ ask+10 (IOC) → 成功 (fill at ask price)
SELL: 0.0001 BTC @ bid-10 (IOC, reduce-only) → 成功
PlacedOrderModel: id と external_id のみ返却 (avg_price等は無し)
avg_priceはpositions API経由 (open_price) で取得可能
TP単体: 成功 (IOC BUY + TP)
SL単体: 成功 (IOC BUY + SL, trigger - 500 USD で攻撃的LIMIT)
TP+SL: 成功 (IOC BUY + TP + SL)
全てORDER型TPSLで動作確認
order.type は常にLIMITで送信されるが、TPSL付きで正常受理
SDK問題: get_open_orders() パースエラー
TPSL子注文 (UNTRIGGERED TP/SL) は price フィールドが無い
SDKの OpenOrderModel が price を必須としているためパース失敗
対策 : Raw REST API (/user/orders) で直接取得する実装が必要
round_price(ask * 1.0075) で生成した価格が "Invalid price value" エラー
ask + 10 での単純加算は成功
→ エントリー価格は ask + buffer 方式を採用 (乗算より安定)
mass_cancel → IOC SELL (reduce-only) で全ポジ/注文を清掃
残高: $29.96
Phase 1: Foundation (config, logger, DMC, strategy, price_calc, state store) — 35ユニットテスト全通過
Phase 2-3: Exchange adapter (read/write) + Reconciliation
Phase 4-7: Main loop, Discord stub, SL retry, hardening
合計: 14ファイル実装、テスト35件パス
仕様箇所
内容
状態
§5.2.3 / §8.4
DMC数列: bet_units=左+右, 勝ち→両端削除, 負け→右端追加, 空→reset [0,1], 1要素→分解
✅
§5.1
逆張り型: TP→flip, SL→keep
✅
§6.A
エントリー: 成行(IOC LIMIT), 初回BUY
✅
§6.B
TP_USD = SL_USD + 7 = 27, SL_USD = 20
✅
§6.E
1単位 = 0.0001 BTC, QTY = UNIT × bet_units
✅
§6.G
丸め: 全てfloor (価格=tick, 数量=step)
✅
§6.J
SLリトライ: 無限, 0.2→0.5→1.0s backoff, 成功時のみ通知
✅
§8.2
bot_state.json: 全フィールド実装, atomic save (tmpfile→rename)
✅
§8.3
状態機械: FLAT→ENTRY_PENDING→ENTERED→EXITING→FLAT + ERROR_RECOVERING
✅
§8.5 / §6.I
Reconciliation: 取引所truthで補正、残注文処理
✅ (主要ケース)
§10
Discord通知: イベント種別全実装 (stub mode)
✅
仕様箇所
仕様の記載
実装
理由
§6.H
方式1 (TP/SL別注文 + 手動OCO)
ORDER型TPSL (取引所ネイティブOCO)
取引所がOCOを保証するため、手動キャンセルより安全。仕様書も「参考」として認知済み
§11.1.2
TP/SL基準価格 = avg_price (約定価格)
ask/bid (発注時の参照価格)
ORDER型TPSLはエントリー注文と同時に提出するため、約定前に価格決定が必要。ズレは0-5 USD程度でSL=20/TP=27に対し許容範囲
§11.2.2
WS優先 + RESTフォールバック
REST polling (5秒) のみ
SDKのWSもTPSL子注文パースバグあり。v0ではREST pollingのみで十分
途中決済 (§5.4): v0では実装しない
Move-catcher (§5.5): v1スコープ
Funding Rate考慮 (§6.F): 無視
サイクル
Side
Entry
TP
SL
結果
Sequence変化
1
BUY
68460
68487
68440
TP
[0,1] → 空 → reset [0,1]
2
SELL
-
-
-
IOC expired
retry (正常動作)
3
SELL
68567
68534
68581
SL
[0,1] → [0,1,1]
4
SELL
68586
68555
68602
TP
[0,1,1] → [1] → decompose [0,1]
5
BUY
68541
68568
68521
TP
[0,1] → 空 → reset [0,1] (1周期完了! )
6
SELL
68587
68556
68603
SL
[0,1] → [0,1,1]
7
SELL
68633
68606
68653
SL
[0,1,1] → [0,1,1,1]
8+
SELL
...
...
...
連続SL
数列成長中 (BTC上昇トレンド)
サイクル17まで進行
現在: SELL @ 68688, TP=68661, SL=68708
数列: [1,1,2,3,4], bet_units=5, qty=0.0005 BTC
BTC上昇中(68460→68688)のため、SELL側が連続SL → 数列成長 → ベット増加
DMC法が設計通りに動作 : 連敗時にロットを段階的に上げて損失回収を狙う
✅ エントリー (IOC LIMIT + ORDER型TPSL)
✅ TP/SL検知 (order history → TPSL_OTHER_SIDE_FILLED 判定)
✅ Mean reversion: TP → flip side, SL → keep side
✅ DMC sequence: win→両端削除, loss→追加, 単要素→decompose, 空→reset
✅ bet_units増加によるロットアップ (0.0001 → 0.0005 BTC)
✅ DMC 1周期完了 (+1単位利益, サイクル5)
✅ IOC fill失敗 → FLAT復帰 → 再エントリー
✅ SDK parse bug → raw API fallback
✅ State persistence (cycle毎にatomic save)
✅ Reconciliation on restart (state補正)
✅ SIGTERM graceful shutdown
get_orders_history(): SDK→raw API fallback時にrate limit hitで~7秒delay
Discord通知: stub mode (Webhook未設定、ユーザー確認後に有効化)
TP/SL基準価格がask/bidのため、SELL側でfill価格とのズレ(0-5 USD)が発生する場合あり