diff --git a/src/backtester.rs b/src/backtester.rs index fdba270..2dc3bfb 100644 --- a/src/backtester.rs +++ b/src/backtester.rs @@ -199,12 +199,12 @@ impl Backtester { let shares = self.strategy .calculate_position_size(price, portfolio_value, available_cash, signal); - if shares == 0 { + if shares <= 0.0 { return false; } let fill_price = Self::apply_slippage(price, "buy"); - let cost = shares as f64 * fill_price; + let cost = shares * fill_price; if cost > self.cash { return false; } @@ -214,7 +214,7 @@ impl Backtester { symbol.to_string(), BacktestPosition { symbol: symbol.to_string(), - shares: shares as f64, + shares: shares, entry_price: fill_price, entry_time: timestamp, entry_atr: signal.atr, @@ -229,7 +229,7 @@ impl Backtester { self.trades.push(Trade { symbol: symbol.to_string(), side: "BUY".to_string(), - shares: shares as f64, + shares: shares, price: fill_price, timestamp, pnl: 0.0, diff --git a/src/bot.rs b/src/bot.rs index ee9c0cd..d549f3a 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -452,12 +452,12 @@ impl TradingBot { // ── Volatility-adjusted position sizing ────────────────────────── - async fn calculate_position_size(&self, signal: &TradeSignal) -> u64 { + async fn calculate_position_size(&self, signal: &TradeSignal) -> f64 { let account = match self.client.get_account().await { Ok(a) => a, Err(e) => { tracing::error!("Failed to get account: {}", e); - return 0; + return 0.0; } }; @@ -557,14 +557,14 @@ impl TradingBot { } let shares = self.calculate_position_size(signal).await; - if shares == 0 { + if shares <= 0.0 { tracing::info!("{}: Insufficient funds for purchase", symbol); return false; } match self .client - .submit_market_order(symbol, shares as f64, "buy") + .submit_market_order(symbol, shares, "buy") .await { Ok(order) => { diff --git a/src/strategy.rs b/src/strategy.rs index 6df6dce..d0a485a 100644 --- a/src/strategy.rs +++ b/src/strategy.rs @@ -33,9 +33,9 @@ impl Strategy { portfolio_value: f64, available_cash: f64, signal: &TradeSignal, - ) -> u64 { + ) -> f64 { if available_cash <= 0.0 { - return 0; + return 0.0; } let position_value = if signal.atr_pct > MIN_ATR_PCT { @@ -51,7 +51,9 @@ impl Strategy { }; let position_value = position_value.min(available_cash); - (position_value / price).floor() as u64 + // Use fractional shares — Alpaca supports them for paper trading. + // Truncate to 4 decimal places to avoid floating point dust. + ((position_value / price) * 10000.0).floor() / 10000.0 } /// Check if stop-loss, trailing stop, or time exit should trigger.