it be better

This commit is contained in:
zastian-dev
2026-02-13 13:12:22 +00:00
parent 80a8e7c346
commit 1ef03999b7
6 changed files with 250 additions and 223 deletions

View File

@@ -54,6 +54,8 @@ pub struct TradingBot {
new_positions_this_cycle: usize,
/// Rolling list of day trade dates for PDT tracking.
day_trades: Vec<NaiveDate>,
/// Current portfolio value (updated each cycle), used for PDT exemption check.
current_portfolio_value: f64,
}
impl TradingBot {
@@ -78,6 +80,7 @@ impl TradingBot {
cooldown_timers: HashMap::new(),
new_positions_this_cycle: 0,
day_trades: Vec::new(),
current_portfolio_value: 0.0,
};
// Load persisted state
@@ -273,7 +276,11 @@ impl TradingBot {
}
/// Check if a day trade is allowed (under PDT limit).
/// PDT rule only applies to accounts under $25,000.
fn can_day_trade(&self) -> bool {
if self.current_portfolio_value >= 25_000.0 {
return true;
}
self.day_trades_in_window() < PDT_MAX_DAY_TRADES
}
@@ -359,12 +366,17 @@ impl TradingBot {
if let Some(halt_start) = self.drawdown_halt_start {
if self.trading_cycle_count >= halt_start + DRAWDOWN_HALT_BARS {
tracing::info!(
"Drawdown halt expired after {} cycles. Resuming trading at {:.2}% drawdown.",
"Drawdown halt expired after {} cycles. Resuming trading. \
Peak reset from ${:.2} to ${:.2} (was {:.2}% drawdown).",
DRAWDOWN_HALT_BARS,
self.peak_portfolio_value,
portfolio_value,
drawdown_pct * 100.0
);
self.drawdown_halt = false;
self.drawdown_halt_start = None;
// Reset peak to current value to prevent cascading re-triggers.
self.peak_portfolio_value = portfolio_value;
}
}
}
@@ -409,13 +421,15 @@ impl TradingBot {
// ── Account helpers ──────────────────────────────────────────────
async fn log_account_info(&self) {
async fn log_account_info(&mut self) {
match self.client.get_account().await {
Ok(account) => {
let portfolio_value: f64 = account.portfolio_value.parse().unwrap_or(0.0);
let buying_power: f64 = account.buying_power.parse().unwrap_or(0.0);
let cash: f64 = account.cash.parse().unwrap_or(0.0);
self.current_portfolio_value = portfolio_value;
tracing::info!("Account Status: {}", account.status);
tracing::info!("Buying Power: ${:.2}", buying_power);
tracing::info!("Portfolio Value: ${:.2}", portfolio_value);
@@ -738,12 +752,17 @@ impl TradingBot {
self.prune_old_day_trades();
tracing::info!("{}", "=".repeat(60));
tracing::info!("Starting trading cycle #{}...", self.trading_cycle_count);
tracing::info!(
"PDT status: {}/{} day trades in rolling 5-business-day window",
self.day_trades_in_window(),
PDT_MAX_DAY_TRADES
);
self.log_account_info().await;
if self.current_portfolio_value >= 25_000.0 {
tracing::info!("PDT status: EXEMPT (portfolio ${:.2} >= $25,000)", self.current_portfolio_value);
} else {
tracing::info!(
"PDT status: {}/{} day trades in rolling 5-business-day window (portfolio ${:.2} < $25,000)",
self.day_trades_in_window(),
PDT_MAX_DAY_TRADES,
self.current_portfolio_value,
);
}
// Increment bars_held once per trading cycle (matches backtester's per-bar increment)
for meta in self.position_meta.values_mut() {