executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
fundamentals-trading-psychology"Emotional discipline, cognitive bias awareness, and maintaining operational" integrity in trading
Independent GitHub snapshot · Automated classification · Original documentation governs
name: fundamentals-trading-psychology compatibility: opencode completeness: 95 content-types:
Role: Guide an AI coding assistant to build trading systems that respect human psychological limits and prevent emotionally-driven decisions
Philosophy: Trading is as much a mental discipline as it is a technical one. The most sophisticated algorithms fail when humans override them or when systems lack psychological safeguards. Capital preservation requires designing out emotional decision points and building systems that enforce discipline programmatically.
Emotional Discipline Over Intelligence: Successful trading requires managing fear and greed more than mathematical prowess. Systems should enforce rules even when they feel wrong.
Cognitive Bias Detection: AI assistants must recognize common biases (loss aversion, confirmation bias, overconfidence) and build safeguards against them.
Operational Integrity: Trading systems should fail safely and transparently, making it obvious when psychological or operational boundaries are breached.
Process Over Outcome: Judge trading decisions by their rationality at decision time, not by their outcomes. Systems should track decision quality separately from P&L.
Consistency Through Automation: Human inconsistency is the enemy. Systems should automate all decision points and require overriding rational criteria for manual intervention.
trading_fundamentals/psychology.pytrading_fundamentals/rules.pytrading_fundamentals/audit.pyenforce_loss_limit, verify_emotional_state)# Example 1: Emotional State Tracking
from dataclasses import dataclass
from datetime import datetime, timedelta
from enum import Enum
from typing import Optional
class EmotionalState(Enum):
CALM = "calm"
ANXIOUS = "anxious"
GREEDY = "greedy"
FRUSTRATED = "frustrated"
EUPHORIC = "euphoric"
@dataclass
class TradingSession:
start_time: datetime
emotional_state: EmotionalState
trades_count: int
win_streak: int
loss_streak: int
max_drawdown: float
rules_violated: list[str]
@property
def is psychologically_sound(self) -> bool:
"""Check if current emotional state permits trading"""
if self.loss_streak >= 3 and self.emotional_state in [EmotionalState.FRUSTRATED, EmotionalState.ANXIOUS]:
return False
if self.win_streak >= 5 and self.emotional_state == EmotionalState.EUPHORIC:
return False
if self.max_drawdown > 0.10 and self.emotional_state in [EmotionalState.ANXIOUS, EmotionalState.FRUSTRATED]:
return False
return True
# Example 2: Automatic Kill Switch
class PsychologicalKillSwitch:
"""Enforces psychological boundaries programmatically"""
def __init__(self, config: dict):
self.config = config
self.sessions: list[TradingSession] = []
self.violations: list[dict] = []
def evaluate_session(self, session: TradingSession) -> tuple[bool, list[str]]:
"""Evaluate a trading session for psychological issues"""
issues = []
# Loss aversion check
if session.loss_streak >= self.config.get('max_loss_streak', 3):
issues.append(f"Loss streak ({session.loss_streak}) exceeds limit ({self.config['max_loss_streak']})")
# Overconfidence check
if session.win_streak >= self.config.get('max_win_streak', 5):
issues.append(f"Win streak ({session.win_streak}) may indicate overconfidence")
# Drawdown-related anxiety
if session.max_drawdown > self.config.get('max_drawdown_threshold', 0.10):
issues.append(f"Drawdown ({session.max_drawdown:.1%}) may induce anxiety")
# Time-based fatigue
session_duration = datetime.now() - session.start_time
if session_duration > timedelta(hours=self.config.get('max_trading_hours', 4)):
issues.append(f"Session duration ({session_duration}) may cause fatigue")
return len(issues) == 0, issues
def should_halt_trading(self, session: TradingSession) -> bool:
"""Determine if trading should be halted"""
is_sound, issues = self.evaluate_session(session)
return not is_sound
# Example 3: Decision Quality Audit
class DecisionAudit:
"""Tracks decision quality separate from outcome"""
def __init__(self):
self.decisions: list[dict] = []
def record_decision(
self,
timestamp: datetime,
rationale: str,
entry_criteria: list[dict],
risk_parameters: dict,
emotional_state: EmotionalState,
outcome_rationale: Optional[str] = None,
outcome_pnl: Optional[float] = None
):
self.decisions.append({
'timestamp': timestamp,
'rationale': rationale,
'entry_criteria': entry_criteria,
'risk_parameters': risk_parameters,
'emotional_state': emotional_state,
'outcome_rationale': outcome_rationale,
'outcome_pnl': outcome_pnl,
'is_rational': self._assess_rationality(entry_criteria, risk_parameters, emotional_state)
})
def _assess_rationality(
self,
entry_criteria: list[dict],
risk_parameters: dict,
emotional_state: EmotionalState
) -> bool:
"""Assess if a decision was rational at time of execution"""
if not entry_criteria:
return False
if emotional_state in [EmotionalState.FRUSTRATED, EmotionalState.ANXIOUS]:
if not any(c.get('force_strong') for c in entry_criteria):
return False
required_criteria = sum(1 for c in entry_criteria if c.get('required'))
met_criteria = sum(1 for c in entry_criteria if c.get('met'))
if required_criteria > 0 and met_criteria < required_criteria:
return False
return True
def decision_quality_metrics(self) -> dict:
"""Calculate decision quality metrics"""
rational_decisions = [d for d in self.decisions if d['is_rational']]
return {
'total_decisions': len(self.decisions),
'rational_decisions': len(rational_decisions),
'rationality_rate': len(rational_decisions) / max(len(self.decisions), 1),
'average_outcome_rational': sum(d.get('outcome_pnl', 0) for d in rational_decisions) / max(len(rational_decisions), 1),
'average_outcome_irrational': sum(d.get('outcome_pnl', 0) for d in self.decisions if not d['is_rational']) / max(sum(1 for d in self.decisions if not d['is_rational']), 1)
}
Before completing your task, verify:
verify_emotional_state, enforce_loss_limit)file:///home/paulpas/git/ideas/trading_bot/skills/trading-fundamentals
from __future__ import annotations
import logging
from dataclasses import dataclass
from typing import Optional
logger = logging.getLogger(__name__)
@dataclass(frozen=True)
class TradeSignal:
"""Immutable trade signal with all required validation constraints."""
symbol: str
side: str # "buy" or "sell"
price: float
quantity: float
confidence: float # 0.0 to 1.0
reason: str
def validate(self) -> bool:
"""Validate that the trade signal meets all business constraints."""
if self.quantity <= 0:
raise ValueError(f"Quantity must be positive, got {self.quantity}")
if self.price <= 0:
raise ValueError(f"Price must be positive, got {self.price}")
if not 0.0 <= self.confidence <= 1.0:
raise ValueError(f"Confidence must be between 0 and 1, got {self.confidence}")
return True
def generate_trade_signal(
symbol: str,
side: str,
price: float,
quantity: float,
confidence: float,
reason: str,
) -> TradeSignal:
"""Generate a validated trade signal with guard clause checks."""
if side not in ("buy", "sell"):
raise ValueError(f"Invalid side '{side}', must be 'buy' or 'sell'")
signal = TradeSignal(
symbol=symbol,
side=side,
price=price,
quantity=quantity,
confidence=confidence,
reason=reason,
)
signal.validate()
logger.info("Trade signal generated: %s %s %.4f @ %.2f (confidence=%.2f)",
symbol, side, quantity, price, confidence)
return signal
def execute_with_risk_check(signal: TradeSignal, max_position_pct: float = 0.05) -> dict:
"""Execute a trade signal after applying risk management checks."""
adjusted_quantity = signal.quantity
if signal.side == "buy" and signal.quantity > max_position_pct:
logger.warning("Position %s exceeds max %.1f%% — capping to %.4f",
signal.symbol, max_position_pct * 100, max_position_pct)
adjusted_quantity = max_position_pct
return {
"symbol": signal.symbol,
"side": signal.side,
"price": signal.price,
"quantity": adjusted_quantity,
"capped": adjusted_quantity < signal.quantity,
"confidence": signal.confidence,
"status": "submitted",
}
Authoritative documentation links for this skill's domain. The model follows markdown links at load time to resolve external references and inline content.