PDT Guardian¶
PDT(Pattern Day Trader)ルール管理モジュール。$25,000未満の口座でのデイトレード制限を管理します。
概要¶
PDTルールとは¶
FINRA Rule 4210
$25,000未満の口座で5営業日に4回以上のデイトレードを行うと、口座が90日間凍結されます。
デイトレードの定義¶
同一銘柄を同一営業日にエントリー(買い/売りオープン)とエグジット(売り/買いクローズ)すること。
PDTGuardian の機能¶
| 機能 | 説明 |
|---|---|
| 週単位カウンター | 5営業日(月〜金)で3回までのデイトレードを許可 |
| $25k超で自動解除 | 口座残高が$25,000を超えると制限が自動解除 |
| 緊急時例外 | VIX > 30 または損失 > 30%で即決済可能 |
| 記録保持 | デイトレード履歴を14日間保持 |
定数設定¶
# core/risk_guardian.py
PDT_THRESHOLD_USD = 25000.0 # この金額以上でPDTルール解除
PDT_MAX_DAY_TRADES_PER_WEEK = 3 # 5営業日で最大3回
PDT_EMERGENCY_VIX_THRESHOLD = 30.0 # 緊急時VIX閾値
PDT_EMERGENCY_LOSS_PCT = 0.30 # 緊急時損失閾値(30%)
判定フロー¶
flowchart TD
A[同日決済リクエスト] --> B{同日か?}
B -->|No| C[✅ 許可]
B -->|Yes| D{口座 ≥ $25k?}
D -->|Yes| E[✅ 許可<br>PDT_UNRESTRICTED]
D -->|No| F{VIX ≥ 30?}
F -->|Yes| G[✅ 許可<br>EMERGENCY_VIX]
F -->|No| H{損失 ≥ 30%?}
H -->|Yes| I[✅ 許可<br>EMERGENCY_LOSS]
H -->|No| J{週のデイトレード < 3回?}
J -->|Yes| K[✅ 許可<br>PDT_ALLOWED]
J -->|No| L[❌ ブロック<br>PDT_LIMIT_REACHED]
使用方法¶
初期化¶
from core.risk_guardian import PDTGuardian, create_pdt_guardian
# $13k口座でPDTGuardianを作成
pdt = create_pdt_guardian(initial_equity=13000.0)
毎日の更新¶
# 口座残高を更新($25k超で自動的に制限解除)
pdt.update_equity(portfolio.equity())
# VIXを更新(緊急時判定用)
pdt.update_vix(current_vix)
同日決済のチェック¶
# スプレッドのエントリー日を取得
entry_date = spread.opened_at
# エグジット前にPDTチェック
can_exit, reason = pdt.can_exit_same_day(
symbol="AAPL",
entry_date=entry_date,
current_date=today,
current_loss_pct=current_loss / max_loss, # 損失率
)
if can_exit:
# 決済実行
execute_exit()
# 同日の場合は記録
if entry_date == today:
pdt.record_day_trade(
symbol="AAPL",
trade_date=today,
entry_time=entry_time,
exit_time=datetime.now(),
is_emergency=(reason.startswith("EMERGENCY")),
)
else:
# 翌日まで待機
logger.warning(f"PDT制限: {reason}")
状態確認¶
# PDT状態のサマリー
summary = pdt.get_summary()
print(f"制限状態: {summary['status']}")
print(f"残りデイトレード: {summary['remaining_day_trades']}回")
# 残り回数を直接取得
remaining = pdt.get_remaining_day_trades(today)
if remaining == -1:
print("無制限($25k以上)")
else:
print(f"今週残り{remaining}回")
戦略への影響¶
Beat Shield¶
影響: 極めて低い
- エントリー時DTE = 30-60日
- 満期7日前に決済
- → 最短でも23日保有のためデイトレードにならない
Sunacchan Spear¶
影響: 中程度(要注意)
- エントリー時DTE = 7-30日
- モメンタム反転や損切りで同日決済の可能性あり
- → PDTGuardianで管理
$13k口座での動作例¶
月曜: AAPL Spear → モメンタム反転 → 同日決済(1回目 ✅)
火曜: MSFT Spear → 損切り → 同日決済(2回目 ✅)
水曜: NVDA Spear → 利確 → 同日決済(3回目 ✅ 最後の枠)
木曜: TSLA Spear → 反転 → 週4回目 → ❌ ブロック(翌日まで待機)
金曜: TSLA → 翌日決済OK ✅
→ 週明けでカウンターリセット → また3回使える
API リファレンス¶
PDTGuardian クラス¶
class PDTGuardian:
def __init__(self, initial_equity: float = 13000.0):
"""初期化"""
def update_equity(self, equity: float) -> None:
"""口座残高を更新"""
def update_vix(self, vix: float) -> None:
"""VIXを更新"""
@property
def is_pdt_restricted(self) -> bool:
"""PDT制限が適用されるか"""
@property
def pdt_status(self) -> str:
"""PDT状態 ('RESTRICTED' or 'UNRESTRICTED')"""
def can_exit_same_day(
self,
symbol: str,
entry_date: date,
current_date: date,
current_loss_pct: float = 0.0,
) -> tuple[bool, str]:
"""同日決済が可能かチェック"""
def record_day_trade(
self,
symbol: str,
trade_date: date,
entry_time: datetime,
exit_time: datetime,
is_emergency: bool = False,
) -> None:
"""デイトレードを記録"""
def get_remaining_day_trades(self, current_date: date) -> int:
"""今週の残りデイトレード可能回数"""
def get_summary(self) -> Dict[str, Any]:
"""PDT状態のサマリー"""
def cleanup_old_records(self, keep_days: int = 14) -> int:
"""古い記録を削除"""
関連ファイル¶
core/risk_guardian.py- PDTGuardianクラス実装strategies/beat_shield.py- Beat Shield戦略strategies/sunacchan_spear.py- Sunacchan Spear戦略