# Hyperliquid取引・ボット

## 概要

Hyperliquid DEXでの仮想通貨取引ダッシュボードおよび自動売買ボット機能。ウォレット管理、注文執行、MA/RSI/AI/ドンチアン/EMA10戦略による自動トレーディングをサポートする。

## 使い方

### ダッシュボード
1. `/hyperliquid` にアクセス
2. ウォレット残高・ポジション・注文履歴を確認
3. 手動で注文を作成・執行

### 自動売買ボット
1. `/hyperliquid/bot` にアクセス
2. 取引戦略を選択（MA: 移動平均、RSI、AI分析、ドンチアンブレイクアウト、EMA10）
3. パラメータを設定してボットを起動
4. バックグラウンドでPythonプロセスとして実行される
5. バックテスト結果画面からURLクエリパラメータ経由で設定を自動流し込み可能

## 技術構成

### Controllers

- `HyperliquidController` - ダッシュボード、ウォレット管理、注文執行
- `HyperliquidBotController` - 自動売買ボットの管理・制御

### Traits

- `ManagesBackgroundProcess` - Pythonボットプロセスのバックグラウンド管理

### Views

- `hyperliquid/index.blade.php` - 取引ダッシュボード
- `hyperliquid/bot.blade.php` - ボット管理画面
- `hyperliquid/bot_containers.blade.php` - コンテナ管理画面（Bot停止・削除機能付き）
- `hyperliquid/bot_detail.blade.php` - Docker コンテナ Bot の閲覧専用詳細ビュー

### バックグラウンドプロセス

- Pythonスクリプトによる自動売買ボット
- MA（移動平均線）、RSI、AI（Anthropic API）、ドンチアンブレイクアウト、EMA10 の5戦略

## 必要な環境変数

| 変数名 | config()キー | 説明 |
|--------|-------------|------|
| `HYPERLIQUID_WALLET_ADDRESS` | `services.hyperliquid.wallet_address` | Hyperliquid Master ウォレットアドレス（資金が置かれている口座）。Agent (API) 運用時は秘密鍵から導出されない別アドレスになるので必ず設定する |
| `HYPERLIQUID_PRIVATE_KEY` | `services.hyperliquid.private_key` | 取引署名に使う秘密鍵。Hyperliquid の「API Wallet」で発行した Agent 鍵を使うのが安全（メイン鍵を漏らさず取引委任できる）。設定しないと UI のフォールバック表示にも使われる |
| `HYPERLIQUID_TESTNET` | `services.hyperliquid.testnet` | true=テストネット / false=本番 |

> **Agent ウォレット運用時の注意**:
> Hyperliquid の API Wallet（Agent）機能を使う場合、秘密鍵は Agent のもので、資金は別の Master ウォレットにある。
> `HYPERLIQUID_WALLET_ADDRESS` に Master アドレスを設定しないと、ボットは Agent アドレス
> （資金 $0）に対して残高/ポジションをクエリしてしまい「残高不足」スキップが発生する。
> Web UI に表示されるアドレスと残高は `HYPERLIQUID_WALLET_ADDRESS` に基づくので、UI と Python ボットを同じアドレスに揃えるためには両方が同じ環境変数を参照する必要がある（本リポジトリでは対応済み）。
| `ANTHROPIC_API_KEY` | `services.anthropic.api_key` | Anthropic APIキー（AI戦略用） |
| `DISCORD_ERROR_WEBHOOK_URL` | `services.discord.error_webhook` | エラー通知用Discord Webhook |
| `PYTHON_BIN` | `services.python.bin` | Python実行パス（デフォルト: python3） |
| `HYPERLIQUID_BOT_REMOTE_URL` | `services.hyperliquid.bot_remote_url` | リモート参照モード用URL（設定すると読み取り専用でNAS等の Bot 状態を表示） |
| `INTERNAL_API_TOKEN` | `services.internal_api.token` | リモート参照用の内部APIトークン（ローカルとNASで同一値を共有） |

> **注**: すべての環境変数は `config/services.php` 経由で取得。`env()` は `config:cache` 後に動作しないため直接使用しない。

## ペアトレード（統計的裁定）

### 概要

相関の高い2銘柄間のスプレッドを利用した統計的裁定取引。Z-scoreの閾値でエントリー/エグジットを判断する。

### バックテスト

```bash
python python/hyperliquid/hl_pair_backtest.py --coin-a BTC --coin-b ETH --window 100 --z-entry 2.0 --z-exit 0.5
```

| パラメータ | 説明 | デフォルト |
|-----------|------|-----------|
| `--coin-a` / `--coin-b` | ペアの2銘柄 | BTC / ETH |
| `--window` | ローリング統計ウィンドウ | 100 |
| `--z-entry` | エントリーZ-score閾値 | 2.0 |
| `--z-exit` | エグジットZ-score閾値 | 0.5 |
| `--beta-mode` | ベータ計算方式（`rolling` / `ols`） | rolling |
| `--leverage` | レバレッジ | 1 |
| `--interval` | ローソク足間隔（`1h` / `4h` / `1d`） | 1h |
| `--days` | バックテスト期間（日） | 90 |

出力: 累積リターン、シャープレシオ、最大ドローダウン、勝率、トレード一覧

### ライブボット

```bash
python python/hyperliquid/hl_pair_bot.py --coin-a BTC --coin-b ETH --size 100
```

| パラメータ | 説明 |
|-----------|------|
| `--size` | 1レッグあたりのUSD建てサイズ |
| `--stop-loss` | 損切りスプレッド幅 |
| `--max-hold` | 最大保有時間（時間） |

動作:
- 指定間隔でスプレッドをチェック
- Z-scoreが閾値を超えたらペアエントリー（ロング/ショート同時）
- Z-scoreが閾値内に戻ったらエグジット
- エラーはログに記録し、Discord Webhook で通知（10分以内の重複通知を抑制）

### ファイル構成

```
python/hyperliquid/
├── hl_pair_backtest.py    # ペアトレード バックテスト
├── hl_pair_backtest.bat   # Windows用起動バッチ
├── hl_pair_bot.py         # ペアトレード ライブボット
└── hl_pair_bot.bat        # Windows用起動バッチ
```

### 追加の環境変数

| 変数名 | 説明 |
|--------|------|
| `DISCORD_ERROR_WEBHOOK_URL` | エラー通知用Discord Webhook URL |

## コンテナ管理（複数ボット並行稼働）

### 概要

複数の Hyperliquid ボットを Docker コンテナで並行稼働させるためのヘルスチェック・セットアップ機能。`/hyperliquid/bot/containers` で稼働状況を一元管理する。

### 使い方

1. `/hyperliquid/bot/containers` にアクセス
2. 各ボットコンテナのヘルス情報（稼働状態・起動時刻・エラー）を確認
3. セットアップガイドに従い Docker Compose でボットを追加

### 技術構成

- `HyperliquidBotHealthService`（`app/Services/Finance/HyperliquidBotHealthService.php`）
  - `docker inspect` でコンテナの稼働状態を取得
  - 各コンテナのヘルスチェック情報を JSON で返却
- `bot_containers.blade.php` — コンテナ一覧・ヘルス表示・セットアップ手順

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | `/hyperliquid/bot/containers` | コンテナ管理画面 |
| GET | `/hyperliquid/bot/containers/health` | ヘルスチェックJSON（AJAX） |
| GET | `/hyperliquid/bot/containers/{id}` | Bot 詳細ビュー（閲覧専用） |
| POST | `/hyperliquid/bot/containers/{id}/stop` | Bot 停止（legacy: PID kill / Docker: `docker stop`） |
| DELETE | `/hyperliquid/bot/containers/{id}` | Botランタイムファイル削除（staleかつコンテナ停止時のみ） |

## ボットプリセット管理

### 概要

頻繁に使う設定パターンをプリセットとして保存・呼び出し可能。

### 使い方

1. `/hyperliquid/bot/presets` にアクセス
2. 現在の設定をプリセットとして保存
3. プリセット一覧から選択して即座にボットを起動

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | `/hyperliquid/bot/presets` | プリセット一覧画面 |
| POST | `/hyperliquid/bot/presets` | プリセット保存 |
| GET | `/hyperliquid/bot/presets/{id}` | プリセット取得（JSON） |
| DELETE | `/hyperliquid/bot/presets/{id}` | プリセット削除 |
| POST | `/hyperliquid/bot/presets/{id}/start` | プリセットで起動 |

## ドンチアンチャネル バックテスト

### 概要

ドンチアンチャネルブレイクアウト戦略の過去データ検証ページ。Hyperliquid の OHLCV データを使い、各種パラメータを調整しながらパフォーマンスを確認できる。パラメータ分析・全銘柄一括分析も備える。

### 使い方

1. `/hyperliquid/bot/donchian-backtest` にアクセス
2. 通貨・時間足・日数・初期資金・ドンチアンパラメータを設定
3. 「バックテスト実行」ボタンを押す（非同期実行）
4. パフォーマンスサマリー・エクイティカーブ・トレード履歴を確認
5. 「パラメータ分析」ボタンで複数パラメータ組み合わせの一括検証が可能

### パラメータ

| パラメータ | 説明 | デフォルト |
|-----------|------|-----------|
| 通貨 | BTC / ETH / SOL など14銘柄 | BTC |
| 時間足 | 15m / 30m / 1h / 4h / 8h / 1d | 1h |
| テスト日数 | 7〜730日 | 180 |
| 初期資金 ($) | バックテスト開始時の資金 | 1000 |
| 買いブレイク期間 | ドンチアンチャネル上限の計算期間 | 20 |
| 売りブレイク期間 | ドンチアンチャネル下限の計算期間 | 10 |
| 判定方法 | 高値/安値で判定 または 終値で判定 | 高値/安値 |
| ATR期間 | ストップロス計算のATR期間 | 14 |
| ATR倍率 | ストップロス幅（ATR × 倍率） | 2.0 |
| リスク率 (%) | 1トレードあたりのリスク割合 | 2.0 |
| トレイリングストップ | パラボリックSARによるトレイリングストップ | 有効 |
| トレンドフィルター | SMAを利用したトレンド方向フィルター | 無効 |
| トレンドSMA期間 | トレンドフィルター用SMAの期間 | 50 |
| 最大積み増し回数 | ピラミッディングの最大回数 | 1 |
| ATR倍率（積み増し閾値） | 積み増しエントリーの価格移動閾値 | 0.5 |
| トレード方向 | 両方 / ロングのみ / ショートのみ | 両方 |

### 結果表示

- トータルリターン・年率リターン・シャープレシオ・最大ドローダウン
- 勝率・取引回数・プロフィットファクター・最終資産
- エクイティカーブ（Chart.js）
- トレード履歴（直近50件）：方向・エントリー/エグジット時刻・サイズ・損益

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | `/hyperliquid/bot/donchian-backtest` | バックテスト画面 |
| POST | `/hyperliquid/bot/donchian-backtest/run` | バックテスト実行（JSON） |
| GET | `/hyperliquid/bot/donchian-backtest/result` | 直近結果取得（JSON） |
| GET | `/hyperliquid/bot/donchian-backtest/status` | 実行ステータス取得（JSON） |
| GET | `/hyperliquid/bot/donchian-backtest/logs` | 実行ログ取得（JSON） |
| POST | `/hyperliquid/bot/donchian-backtest/clear-log` | ログクリア |
| GET | `/hyperliquid/bot/donchian-backtest/analysis` | パラメータ分析画面 |
| POST | `/hyperliquid/bot/donchian-backtest/analysis/run` | パラメータ分析実行（JSON） |
| GET | `/hyperliquid/bot/donchian-backtest/analysis/result` | パラメータ分析結果取得（JSON） |
| POST | `/hyperliquid/bot/donchian-backtest/all-coins/run` | 全銘柄一括分析実行（JSON） |
| GET | `/hyperliquid/bot/donchian-backtest/all-coins/result` | 全銘柄分析結果取得（JSON） |

### 技術構成

- `DonchianBacktestController`（`app/Http/Controllers/Finance/DonchianBacktestController.php`）
- `donchian_backtest.blade.php` — バックテスト画面
- `resources/js/finance/hyperliquid-donchian-backtest.js` — 非同期実行・Chart.js描画

## EMA10 バックテスト

### 概要

EMA10 × ローソク足パターン認識戦略のバックテストページ。EMA10 に価格がクロス後にタッチしたローソク足が反転パターンを示したとき、次足でエントリーする戦略を検証する。利確は直近高値、損切りは直近安値を使用する。

### 使い方

1. `/hyperliquid/bot/ema10-backtest` にアクセス
2. 通貨・時間足・日数・初期資金・EMAパラメータを設定
3. 使用するローソク足パターンを選択
4. 「バックテスト実行」ボタンを押す
5. パフォーマンスサマリー・エクイティカーブ・トレード履歴を確認

### パラメータ

| パラメータ | 説明 | デフォルト |
|-----------|------|-----------|
| 通貨 | BTC / ETH / SOL など14銘柄 | BTC |
| 時間足 | 5m / 15m / 30m / 1h / 4h / 8h / 1d | 15m |
| テスト日数 | 7〜730日 | 180 |
| 初期資金 ($) | バックテスト開始時の資金 | 1000 |
| EMA期間 | EMAの計算期間 | 10 |
| 直近高安ルックバック | 利確・損切り価格の参照バー数 | 10 |
| ポジションサイズ (%) | 資金に対するポジション割合 | 100 |
| ローソク足パターン | ハンマー/流れ星・包み足・ピンバー・丸坊主（複数選択可） | 全て有効 |
| トレード方向 | 両方 / ロングのみ / ショートのみ | 両方 |

### 結果表示

ドンチアンバックテストと同一のサマリー・エクイティカーブ・トレード履歴を表示する。汎用バックテスト（`/hyperliquid/bot/backtest`）の結果ストレージを共有しているため、他の戦略で上書きされた場合は再実行が必要。

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | `/hyperliquid/bot/ema10-backtest` | EMA10バックテスト画面 |
| POST | `/hyperliquid/bot/backtest/run` | バックテスト実行（汎用・JSON） |
| GET | `/hyperliquid/bot/backtest/result` | 直近結果取得（汎用・JSON） |

### 技術構成

- `HlBacktestController`（`app/Http/Controllers/Finance/HlBacktestController.php`）— `indexEma10()` メソッド
- `ema10_backtest.blade.php` — バックテスト画面
- `resources/js/finance/hyperliquid-ema10-backtest.js` — 非同期実行・Chart.js描画

## autofixLog（自動修正ログ）

### 概要

ボットが自動修正（autofix）を実行した際のログを JSON 形式で返却するエンドポイント。`storage/app/hl_bot_autofix_log.json` に蓄積されたログを取得・削除するために使用する。

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | `/hyperliquid/bot/autofix-log` | 自動修正ログ取得（JSON） |
| DELETE | `/hyperliquid/bot/autofix-log/clear` | 自動修正ログ削除（JSONファイルを消去。次回 `bot:watchdog` 実行時に再生成） |

### レスポンス

ログファイルが存在する場合はその内容を配列で返す。ファイルが存在しない場合は空配列 `[]` を返す。

### 技術構成

- `HyperliquidBotController::autofixLog()`（`app/Http/Controllers/Finance/HyperliquidBotController.php`）
- `HyperliquidBotController::clearAutofixLog()` — ログファイルを削除（次回 `bot:watchdog` 実行時に再生成される）
- ログファイル: `storage/app/hl_bot_autofix_log.json`

## バックテスト→ボット連携（URLクエリパラメータ）

### 概要

バックテスト分析ページ等からURLクエリパラメータで戦略パラメータをボット設定フォームに自動流し込みする機能。DB/config.json には保存せず、ユーザーが「保存」or「起動」したときに永続化される。

### 対応パラメータ

| URL キー | config キー | 型 |
|---------|-----------|-----|
| `strategy` | `strategy` | string |
| `coin` | `coin` | string |
| `interval` | `candle_interval` | string |
| `position_size_usd` | `position_size_usd` | float |
| `check_interval_sec` | `check_interval_sec` | int |
| `buy_term` | `dc_buy_term` | int |
| `sell_term` | `dc_sell_term` | int |
| `trailing_stop` | `dc_trailing_stop` | bool |
| `trend_filter` | `dc_trend_filter` | bool |
| `label` | 表示用ラベル | string |

その他: `ma_fast`, `ma_slow`, `rsi_period`, `rsi_oversold`, `rsi_overbought`, `ema_period`, `swing_lookback`, `ema10_patterns` 等も対応。

## ボット戦略一覧

| 戦略 | 説明 |
|------|------|
| `ma_crossover` | 移動平均線クロスオーバー（MA Fast/Slow） |
| `rsi` | RSI の売られ過ぎ/買われ過ぎで判断 |
| `ai` | Anthropic Claude AI が市場分析して判断 |
| `donchian_breakout` | ドンチアンチャネルブレイクアウト |
| `ema10` | EMA10 + ローソク足パターン認識 |

## リモート参照モード

### 概要

`HYPERLIQUID_BOT_REMOTE_URL` を設定すると、ローカル（Homestead等）の `/hyperliquid/bot` 画面から NAS など別ホストで稼働中の Bot の状態を**読み取り専用**で参照できる。起動・停止・プリセット保存等の操作は NAS 側 UI から行う。

### 動作

- `HyperliquidBotController` が `proxyGet()` で NAS の内部 API を叩いてデータを取得
- 書き込み操作は `rejectIfRemote()` で HTTP 503 を返す
- フロントエンド側でも `remoteMode` フラグにより操作ボタンを無効化
- NAS に接続できない場合は `remote_unreachable` フラグで UI に警告を表示

### セキュリティ

- `botRemoteUrl()` は `http` / `https` スキーマのみ許可（SSRF 防止）
- 内部 API ルート（`api/internal/*`）経由の場合はリモートプロキシを無効化（再帰ループ防止）
- `proxyGet()` の通信エラーはデバッグログに記録

### 内部 API（NAS 側で公開）

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | `/api/internal/hyperliquid/bot/status` | Bot ステータス |
| GET | `/api/internal/hyperliquid/bot/balance` | 残高情報 |
| GET | `/api/internal/hyperliquid/bot/logs` | ログ末尾 |
| GET | `/api/internal/hyperliquid/bot/autofix-log` | 自動修正ログ |
| GET | `/api/internal/hyperliquid/bot/containers/health` | コンテナヘルス |
| POST | `/api/internal/hyperliquid/bot/trade` | トレード結果取り込み（DB永続化） |

認証: `VerifyInternalApiToken` ミドルウェア（`X-Internal-Token` ヘッダー）

### セットアップ

```env
# ローカル側 .env
HYPERLIQUID_BOT_REMOTE_URL=http://100.x.x.x   # Tailscale IP or LAN IP
INTERNAL_API_TOKEN=your-shared-secret-token

# NAS 側 .env
INTERNAL_API_TOKEN=your-shared-secret-token     # ローカルと同一値
```

## 残高取得

### 概要

Hyperliquid アカウントの取引可能残高・口座評価額・使用証拠金を AJAX ポーリングで表示する機能。

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | `/hyperliquid/bot/balance` | 残高情報JSON（30秒キャッシュ） |

### 技術構成

- `HyperliquidBotController::balance()` — Hyperliquid Info API (`clearinghouseState`) を呼び出し
- ウォレットアドレスは `HYPERLIQUID_WALLET_ADDRESS` を優先、未設定なら `HYPERLIQUID_PRIVATE_KEY` から `HyperliquidSigningService::deriveAddress()` で導出
- 30秒のキャッシュ（`hl_bot_balance:{network}:{address}`）
- フロントエンドは30秒間隔でポーリング

### レスポンス

```json
{
  "address": "0x...",
  "account_value": 1234.56,
  "withdrawable": 1000.00,
  "total_margin_used": 234.56,
  "total_raw_usd": 1234.56,
  "is_testnet": false,
  "fetched_at": "2026-04-30T12:00:00+09:00"
}
```

## PnL トラッキング（収支サマリー）

### 概要

Bot の取引損益をリアルタイムで追跡し、UI に収支サマリーと資産推移チャートを表示する機能。

### 追跡項目

| 項目 | 説明 |
|------|------|
| 実現損益 (total_realized_pnl) | クローズ済み取引の累計損益（手数料控除前） |
| 含み損益 (total_unrealized_pnl) | 現在のオープンポジションの含み損益（ミッド価格ベース） |
| 勝率 (win_count / loss_count) | クローズ取引のうち利益/損失の回数 |
| 純損益 | 実現損益 + 含み損益 - 累計手数料 |
| 現在のポジション | coin / side / size / entry_px / mark_px |

### UI 表示

- **ポジションカード** — 現在のポジション（銘柄・方向・サイズ・エントリー価格・想定額・含み損益%・損切ライン・SARトレイル・ピラミッド段数）を専用カードで表示。ポーリングで自動更新
- **収支サマリーカード** — 純損益・実現損益・含み損益・手数料・勝率を横並び表示
- **資産推移チャート** — Chart.js によるクローズ毎の累計損益グラフ（含み損益は破線で表示）
- **トレード履歴テーブル** — 各トレードの損益（PnL）列を追加

### Python ボット側

- `_record_trade()` でクローズ取引時に実現損益を計算（`close_pos` のエントリー価格と約定価格の差分）
- `_compute_pnl_extras()` で含み損益と現在ポジションを毎ループ計算
- `update_status()` に `total_realized_pnl`, `total_unrealized_pnl`, `win_count`, `loss_count`, `current_position` を追加

## Discord エラー通知

### 概要

Bot のエラー通知はレート制限付きで Discord Webhook に送信される。10分以内の重複通知を抑制し、スパムを防止する。

### 動作

- `DISCORD_ERROR_WEBHOOK_URL` 環境変数が設定されている場合のみ通知
- 前回の通知から10分以内は新規通知を抑制
- メッセージは2000文字で切り詰め（Discord の制限）
- Watchdog のクラッシュ検知通知には環境名（`app.env`）とホスト名（`gethostname()`）を付記

## 一過性ネットワークエラーハンドリング

### 概要

Hyperliquid API への ConnectionError / Timeout 等の一過性エラーは、単発では Discord 通知せずカウンタを増やすだけとし、3回連続で失敗したときのみ通知する（瞬断によるスパム防止）。

> **注:** `discord_error_notify()` は10分のレート制限付きで有効化済み。`DISCORD_ERROR_WEBHOOK_URL` 環境変数が設定されている場合に通知が送信される。

### 判定基準

- `requests.exceptions.ConnectionError` / `Timeout` / `ChunkedEncodingError`
- `ConnectionResetError` / `urllib3.exceptions.ProtocolError`
- メッセージに `Connection aborted`, `RemoteDisconnected`, `Max retries exceeded`, `Read timed out` を含む

### 動作

1. 一過性エラー検出 → `_transient_fail_count += 1`、status は `running` のまま
2. 3回連続失敗 → Discord 通知（レート制限あり）+ カウンタリセット
3. 正常終了 → カウンタリセット
4. 非一過性エラー → 即座に `error` status + Discord 通知（レート制限あり）

## szDecimals 丸め処理

### 概要

Hyperliquid SDK の `float_to_wire` は許容小数桁数を超える端数があるとエラーを投げる。各銘柄の `szDecimals`（数量の許容小数桁数）を Hyperliquid の `/info` API から取得・キャッシュし、注文前に `_round_size()` で丸めることでエラーを回避する。

`hl_bot.py` と `hl_pair_bot.py` の両方に実装済み。取得失敗時は安全側に倒し `szDecimals = 4` を使用。

## 残高不足チェック

### 概要

新規発注前に Hyperliquid アカウントの `withdrawable`（自由証拠金）を確認し、証拠金不足の場合は発注をスキップする。Discord に残高不足通知を送信（1時間に1回まで）。

### 動作

- `_has_sufficient_margin(notional)` で `withdrawable` と必要証拠金（`notional / 3x × 1.2 バッファ`）を比較
- 不足時: 発注スキップ + Discord 通知（`_notify_low_balance()`、1時間レート制限）
- API 取得失敗時: 安全側に倒して発注続行（残高がないとは限らないため）
- クローズ注文はマージンを消費しないためチェックをスキップ

## ピラミッディング上限

### 概要

ドンチアン戦略のピラミッディング（積み増し）回数を `dc_pyramid_max` で制限する。`_pyramid_count` で同一ポジション内の追加発注回数をトラッキングし、上限到達後は一切追加発注しない。ポジション解消・方向転換でカウンタをリセットする。

## Bot 詳細ビュー（コンテナ）

### 概要

Docker コンテナ Bot の状態を閲覧専用で表示する詳細ページ。コンテナ管理ページから各 Bot の「→ 詳細」リンクで遷移する。

### 表示内容

- ステータス・対象通貨/戦略
- 累計手数料・実現損益・勝敗
- 現在ポジション（サイド・数量・エントリー価格・現在価格）
- 損切ライン（ATR ストップ / パラボリック SAR トレイル）
- 設定一覧（`config.json` の全キー）
- 直近トレード履歴（最新30件）
- ログ末尾200行

### 損切ライン表示

Bot の `status.json` にある `current_position` に以下のフィールドが含まれる場合に表示:

| フィールド | 説明 |
|-----------|------|
| `stop_price` | ATR ストップの損切価格 |
| `stop_atr_mult` | ATR 倍率 |
| `stop_atr` | 直近 ATR 値 |
| `sar_price` | パラボリック SAR のトレイリング価格 |
| `sar_trend` | SAR のトレンド方向（`up` / `down`） |

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| GET | `/hyperliquid/bot/containers/{id}` | Bot 詳細ビュー |

## トレード DB 永続化

### 概要

Python Bot のトレード結果を Laravel 側の `hyperliquid_bot_trades` テーブルに永続保存する機能。Bot の `status.json` は再起動やクリア操作で消えるため、別途 DB に履歴を残す。

### 動作

1. Python Bot の `_record_trade()` がトレード確定ごとに `post_trade_to_laravel()` を呼び出す
2. `LARAVEL_API_BASE` / `INTERNAL_API_TOKEN` 環境変数が設定されている場合にのみ送信（未設定なら無視）
3. Laravel 側の `ingestTrade()` がバリデーション後に `HyperliquidBotTrade::create()` で永続化
4. 通信失敗はログのみで握りつぶす（取引フローを止めない）

### データベース

#### hyperliquid_bot_trades テーブル

| カラム | 型 | 説明 |
|--------|-----|------|
| id | bigint | 主キー |
| bot_id | string(50) | Bot ID（`legacy` or `storage/app/hl_bots/{id}` の id） |
| coin | string(20) | 取引銘柄 |
| side | string(20) | 売買方向（買い(Long) / 売り(Short) / Close 等） |
| is_close | boolean | クローズ取引かどうか |
| size | decimal(24,8) | 取引サイズ |
| price | decimal(24,8) | 約定価格 |
| fee | decimal(24,8) | 手数料 |
| pnl | decimal(24,8) nullable | クローズ取引の実現損益 |
| status | string(20) | OK / FAILED / ERROR |
| strategy | string(50) nullable | 取引戦略名 |
| testnet | boolean | テストネットかどうか |
| error | text nullable | エラーメッセージ |
| executed_at | datetime | 取引実行日時 |

インデックス: `bot_id`, `status`, `executed_at`, `(bot_id, executed_at)`, `(coin, executed_at)`

### 必要な環境変数（Python Bot 側）

Bot 起動時に `launchBot()` から自動的に渡される:

| 変数名 | 説明 |
|--------|------|
| `LARAVEL_API_BASE` | Laravel アプリの URL（例: `http://localhost`） |
| `INTERNAL_API_TOKEN` | 内部 API トークン |

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| POST | `/api/internal/hyperliquid/bot/trade` | トレード結果取り込み（`VerifyInternalApiToken` 認証） |

## ライブ設定変更（update-live-config）

### 概要

稼働中の Bot の設定を停止・再起動なしで変更する機能。`config.json` を直接更新し、Bot の次のループで反映される。

### ルート

| メソッド | URL | 説明 |
|---------|-----|------|
| POST | `/hyperliquid/bot/update-live-config` | ライブ設定変更（JSON） |

### 変更可能なパラメータ

`position_size_usd`, `check_interval_sec`, `dc_atr_multiplier`, `dc_trailing_stop`, `dc_trend_filter`, `dc_pyramid_max` 等。Bot のメインループで毎回 `config.json` を再読み込みするため、次のループから新設定が適用される。

---

## デプロイ時の Bot 自動起動制御

### 概要

`deploy-nas.yml` では、ユーザーが Web UI で意図的に停止した Bot をデプロイ時に勝手に再起動しないよう制御する。

### 動作

Bot コンテナを3分類して操作する:

| 状態 | 操作 |
|------|------|
| 未作成（初回） | ビルド + 起動 |
| 稼働中 | コード変更時にビルド / 再起動 |
| 停止中 | ビルドのみ（起動しない。Web UI から手動起動可能） |
