Limiti di sicurezza per rischio e conformità
Limiti per il dimensionamento delle posizioni, controlli sugli strumenti vietati e registrazione per gli audit.
Limiti di sicurezza per rischio e conformità è una lezione AI Agents gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Agents, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Agents include 4 lezioni in totale.
Perché gli agenti finanziari necessitano di vincoli rigidi
Un agente finanziario che possa consigliare qualsiasi operazione senza restrizioni potrebbe esporre gli utenti a perdite catastrofiche o a violazioni normative. A differenza di un consulente umano, un agente esegue la propria logica di raccomandazione in modo coerente: ciò significa che un bug o una configurazione errata avrebbe effetto su ogni utente.
I vincoli rigidi prevengono gli esiti peggiori.
Limiti alle dimensioni delle posizioni
Limiti la quota del portafoglio che l'agente può consigliare di investire in un singolo asset. Una regola comune è che nessuna singola posizione debba superare il 20% del valore totale del portafoglio. In questo modo si previene un rischio di concentrazione catastrofico.
MAX_POSITION_PCT = 0.20 # 20% of portfolio max per asset
def check_position_size(ticker: str, trade_usd: float,
portfolio_value: float) -> dict:
proposed_pct = trade_usd / portfolio_value
if proposed_pct > MAX_POSITION_PCT:
return {
'allowed': False,
'reason': (
f'Position size {proposed_pct:.1%} exceeds limit {MAX_POSITION_PCT:.1%}. '
f'Max trade for this portfolio: USD {portfolio_value * MAX_POSITION_PCT:.0f}'
)
}
return {'allowed': True, 'position_pct': round(proposed_pct, 4)}
if __name__ == '__main__':
print('Large trade:', check_position_size('TSLA', 30000, 100000))
print('Small trade:', check_position_size('TSLA', 10000, 100000))
Elenco degli strumenti vietati
Mantenga un elenco degli strumenti che l'agente non è autorizzato a consigliare: penny stock, ETF con leva elevata, titoli soggetti a sanzioni o strumenti non adatti agli investitori retail.
PROHIBITED_TICKERS = {
'UVXY', # VIX leveraged ETF — too volatile
'TVIX', # Delisted leveraged VIX
'JDST', # 3x leveraged gold miners short
'NUGT', # 3x leveraged gold miners long
'YANG', # 3x China short
}
PROHIBITED_TYPES = {'penny_stock', 'leveraged_3x', 'inverse_volatility'}
def check_prohibited_instrument(ticker: str) -> dict:
if ticker.upper() in PROHIBITED_TICKERS:
return {
'allowed': False,
'reason': f'{ticker} is on the prohibited instruments list'
}
return {'allowed': True}
if __name__ == '__main__':
print("Checking UVXY:", check_prohibited_instrument('UVXY'))
print("Checking AAPL:", check_prohibited_instrument('AAPL'))
Controllo della regola del Pattern Day Trader
Negli Stati Uniti, un conto con meno di 25.000 USD viene classificato come Pattern Day Trader (PDT) se effettua almeno 4 operazioni di andata e ritorno in 5 giorni lavorativi. L'agente deve verificare la frequenza delle operazioni prima di consigliare operazioni intraday.
from datetime import datetime, timedelta, timezone
def check_pdt_rule(account_value_usd: float,
recent_trades: list[dict]) -> dict:
if account_value_usd >= 25_000:
return {'at_risk': False, 'reason': 'Account above PDT threshold'}
cutoff = datetime.now(timezone.utc) - timedelta(days=5)
recent = [
t for t in recent_trades
if datetime.fromisoformat(t['timestamp']) > cutoff
and t.get('is_day_trade', False)
]
if len(recent) >= 3:
return {
'at_risk': True,
'day_trades_in_5_days': len(recent),
'reason': (
f'Account has {len(recent)} day trades in the last 5 days. '
f'A 4th would trigger the PDT restriction.'
)
}
return {'at_risk': False, 'day_trades_in_5_days': len(recent)}
if __name__ == '__main__':
now = datetime.now(timezone.utc)
trades = [
{'timestamp': (now - timedelta(days=1)).isoformat(), 'is_day_trade': True},
{'timestamp': (now - timedelta(days=2)).isoformat(), 'is_day_trade': True},
{'timestamp': (now - timedelta(days=3)).isoformat(), 'is_day_trade': True},
]
result = check_pdt_rule(account_value_usd=10000, recent_trades=trades)
print('PDT rule check:', result)
Dimensionamento delle operazioni in base alla volatilità
Gli asset più volatili comportano un rischio maggiore. Ridimensioni le posizioni in modo inversamente proporzionale alla volatilità: se un asset ha una volatilità doppia rispetto a quella di riferimento, suggerisca una posizione dimezzata.
import yfinance as yf, numpy as np
BASELINE_VOL = 0.15 # 15% annualized vol — S&P 500 average
def volatility_scaled_size(ticker: str, base_allocation_usd: float) -> dict:
hist = yf.Ticker(ticker).history(period='1y')['Close'].pct_change().dropna()
vol = float(hist.std() * np.sqrt(252))
scaling_factor = BASELINE_VOL / max(vol, 0.01)
adjusted_usd = base_allocation_usd * scaling_factor
return {
'ticker': ticker,
'annualized_vol': round(vol, 4),
'scaling_factor': round(scaling_factor, 3),
'adjusted_size_usd': round(adjusted_usd, 2),
'note': 'High-vol asset: position scaled down' if scaling_factor < 1 else 'Normal sizing'
}Registrare ogni raccomandazione a fini di audit
Ogni raccomandazione di trading, accettata o rifiutata, deve essere registrata con il contesto completo: marca temporale, ID utente, azione raccomandata, controlli dei vincoli eseguiti ed esito. In questo modo si crea una traccia di audit completa per la verifica della conformità.
import json, hashlib, time, logging
audit_logger = logging.getLogger('financial_agent.audit')
audit_logger.setLevel(logging.INFO)
def audit_log(user_id: str, action: str, ticker: str,
amount_usd: float, guardrail_results: list[dict],
approved: bool, reason: str):
log_entry = {
'timestamp': time.time(),
'user_id': user_id,
'action': action,
'ticker': ticker,
'amount_usd': amount_usd,
'guardrails': guardrail_results,
'approved': approved,
'reason': reason,
'entry_id': hashlib.md5(f'{user_id}{time.time()}'.encode()).hexdigest()[:12]
}
audit_logger.info(json.dumps(log_entry))
if __name__ == '__main__':
import sys
audit_logger.addHandler(logging.StreamHandler(sys.stdout))
audit_log('user_42', 'BUY', 'AAPL', 5000.0,
[{'check': 'position_size', 'allowed': True}],
True, 'Within limits')
Inserimento automatico del disclaimer
Qualsiasi output finanziario dell'agente deve includere un disclaimer che specifichi che non si tratta di consulenza finanziaria personalizzata. Lo inserisca automaticamente: non si affidi mai all'LLM per aggiungerlo in modo coerente.
FINANCIAL_DISCLAIMER = (
'\n\n---\n'
'DISCLAIMER: This output is generated by an AI agent and is for '
'informational purposes only. It does not constitute personalized financial advice. '
'Past performance does not guarantee future results. '
'Please consult a licensed financial advisor before making investment decisions.'
)
def inject_disclaimer(response: str) -> str:
if 'DISCLAIMER' not in response:
return response + FINANCIAL_DISCLAIMER
return response
if __name__ == '__main__':
response = 'AAPL is currently trading at $150 with strong upward momentum.'
print(inject_disclaimer(response))
Eseguire tutti i vincoli in sequenza
Crei un'unica funzione guardrail_check() che esegua tutti i controlli in ordine e restituisca una decisione di superamento o mancato superamento, insieme alla motivazione. L'agente la chiama prima di finalizzare qualsiasi raccomandazione.
def guardrail_check(user_id: str, ticker: str, action: str,
amount_usd: float, portfolio_value: float,
account_value: float, recent_trades: list[dict]) -> dict:
checks = []
# 1. Prohibited instruments
prohibited = check_prohibited_instrument(ticker)
checks.append({'check': 'prohibited_instrument', **prohibited})
if not prohibited['allowed']:
audit_log(user_id, action, ticker, amount_usd, checks, False, prohibited['reason'])
return {'approved': False, 'reason': prohibited['reason'], 'checks': checks}
# 2. Position size
size_check = check_position_size(ticker, amount_usd, portfolio_value)
checks.append({'check': 'position_size', **size_check})
if not size_check['allowed']:
audit_log(user_id, action, ticker, amount_usd, checks, False, size_check['reason'])
return {'approved': False, 'reason': size_check['reason'], 'checks': checks}
# 3. PDT rule
if action == 'day_trade':
pdt = check_pdt_rule(account_value, recent_trades)
checks.append({'check': 'pdt_rule', **pdt})
if pdt['at_risk']:
return {'approved': False, 'reason': pdt['reason'], 'checks': checks}
audit_log(user_id, action, ticker, amount_usd, checks, True, 'All guardrails passed')
return {'approved': True, 'checks': checks}Verifica dell'adeguatezza in base al profilo di rischio
Adatti la raccomandazione alla tolleranza al rischio dichiarata dall'utente. A un investitore prudente non si dovrebbero consigliare titoli growth con beta elevato; un investitore aggressivo può gestire una volatilità maggiore.
RISK_PROFILES = {
'conservative': {'max_beta': 0.8, 'max_vol_pct': 15},
'moderate': {'max_beta': 1.2, 'max_vol_pct': 25},
'aggressive': {'max_beta': 2.0, 'max_vol_pct': 50},
}
def suitability_check(risk_profile: str, ticker_beta: float,
ticker_vol_pct: float) -> dict:
limits = RISK_PROFILES.get(risk_profile, RISK_PROFILES['moderate'])
if ticker_beta > limits['max_beta']:
return {
'suitable': False,
'reason': f'Beta {ticker_beta:.2f} exceeds {risk_profile} limit {limits["max_beta"]}'
}
if ticker_vol_pct > limits['max_vol_pct']:
return {
'suitable': False,
'reason': f'Volatility {ticker_vol_pct:.1f}% exceeds {risk_profile} limit {limits["max_vol_pct"]}%'
}
return {'suitable': True}
if __name__ == '__main__':
print('Conservative check:', suitability_check('conservative', ticker_beta=1.5, ticker_vol_pct=20))
print('Aggressive check: ', suitability_check('aggressive', ticker_beta=1.5, ticker_vol_pct=20))
Limitare la frequenza delle raccomandazioni
Un agente che genera raccomandazioni di trading troppo frequentemente incoraggia l'overtrading, aumentando costi e rischi. Applichi un periodo di attesa tra le raccomandazioni relative allo stesso asset.
import time
last_recommendation: dict[str, float] = {} # ticker -> timestamp
COOLDOWN_HOURS = 24
def check_recommendation_cooldown(ticker: str) -> dict:
last = last_recommendation.get(ticker, 0)
elapsed_hours = (time.time() - last) / 3600
if elapsed_hours < COOLDOWN_HOURS:
remaining = COOLDOWN_HOURS - elapsed_hours
return {
'allowed': False,
'reason': f'Recommendation cooldown: {remaining:.1f} hours remaining for {ticker}'
}
return {'allowed': True}
def record_recommendation(ticker: str):
last_recommendation[ticker] = time.time()
if __name__ == '__main__':
print('Before recommending:', check_recommendation_cooldown('AAPL'))
record_recommendation('AAPL')
print('Right after recommending:', check_recommendation_cooldown('AAPL'))
Stop-loss e interruttori automatici sul drawdown
Oltre ai limiti per le singole posizioni, implementi un interruttore automatico a livello di portafoglio: se il portafoglio complessivo perde più del X% in un solo giorno, l'agente interrompe le nuove raccomandazioni di acquisto finché una persona non ha esaminato la situazione.
MAX_DAILY_DRAWDOWN_PCT = 0.05 # 5% daily loss limit
def check_daily_drawdown(portfolio_start_of_day: float,
portfolio_current: float) -> dict:
daily_loss = (portfolio_current - portfolio_start_of_day) / portfolio_start_of_day
if daily_loss < -MAX_DAILY_DRAWDOWN_PCT:
return {
'circuit_breaker': True,
'daily_loss_pct': round(daily_loss * 100, 2),
'reason': (
f'Portfolio down {abs(daily_loss)*100:.1f}% today. '
f'Agent suspended — human review required.'
)
}
return {'circuit_breaker': False, 'daily_loss_pct': round(daily_loss * 100, 2)}
if __name__ == '__main__':
print('Small loss day:', check_daily_drawdown(100000, 98000))
print('Big loss day: ', check_daily_drawdown(100000, 92000))
Che cosa limita la regola del Pattern Day Trader (PDT)?
La regola PDT è un requisito normativo statunitense che gli agenti finanziari operanti sul mercato statunitense devono rispettare. Comprenderla evita che gli agenti attivino inavvertitamente restrizioni sui conti a margine.
Riepilogo dei vincoli di sicurezza per rischio e conformità
I vincoli di sicurezza per gli agenti finanziari includono: limiti alle dimensioni delle posizioni, elenco degli strumenti vietati, verifica della regola PDT, dimensionamento in base alla volatilità, corrispondenza con il profilo di rischio, registrazione di audit di ogni raccomandazione e inserimento di disclaimer in tutti gli output.
Eseguire sempre tutti i vincoli di sicurezza prima di finalizzare qualsiasi raccomandazione di trading.
Domande Frequenti
La lezione «Limiti di sicurezza per rischio e conformità» è gratuita?
Sì — il testo completo di «Limiti di sicurezza per rischio e conformità» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Agents, passa a CoddyKit PRO. Il corso AI Agents include 4 lezioni in totale.
Cosa imparerò in «Limiti di sicurezza per rischio e conformità»?
Limiti per il dimensionamento delle posizioni, controlli sugli strumenti vietati e registrazione per gli audit. Eserciti AI Agents con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Agents?
Non è richiesta alcuna esperienza precedente. AI Agents su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Limiti di sicurezza per rischio e conformità»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Agents?
Sì. Ogni lezione AI Agents include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Integrazione delle API per i dati di mercato
- Strumenti dell’agente per l’analisi dei portafogli
- Limiti di sicurezza per rischio e conformità
- Backtesting delle decisioni dell’agente