# ... (previous code remains the same) # Backtesting simulation loop for i in range(1, len(data)): today = data.index[i] price = float(data['Close'].iloc[i]) # Cast to float rsi_today = float(data['RSI'].iloc[i]) # Cast to float # Check for buy signal macd_today = float(data['MACD'].iloc[i]) signal_today = float(data['MACD_signal'].iloc[i]) macd_yesterday = float(data['MACD'].iloc[i-1]) signal_yesterday = float(data['MACD_signal'].iloc[i-1]) buy_condition = (macd_yesterday < signal_yesterday) and (macd_today > signal_today) and (rsi_today < 50) if buy_condition and (last_buy_date is None or (today - last_buy_date).days >= min_days_between_buys): allocation = cash * buy_fraction if allocation > 0: shares_bought = allocation / price cash -= allocation last_buy_date = today open_positions.append({ "entry_date": today, "entry_price": price, "allocated": allocation, "shares": shares_bought, "highest": price, # Ensure scalar "trailing_stop": price * (1 - trailing_stop_pct) }) data.at[today, 'Buy'] = True # Update positions and check sell conditions positions_to_remove = [] for idx, pos in enumerate(open_positions): current_highest = pos["highest"] if price > current_highest: pos["highest"] = price pos["trailing_stop"] = pos["highest"] * (1 - trailing_stop_pct) # Partial sell condition if price >= (pos["entry_price"] * target_multiplier) and rsi_today > 50: shares_to_sell = pos["shares"] * sell_fraction cash += shares_to_sell * price pos["shares"] -= shares_to_sell pos["allocated"] -= shares_to_sell * pos["entry_price"] data.at[today, 'Sell'] = True if pos["shares"] < 0.001: completed_trades.append({ "entry_date": pos["entry_date"], "exit_date": today, "entry_price": pos["entry_price"], "exit_price": price, "allocated": pos["allocated"] }) positions_to_remove.append(idx) continue # Trailing stop exit current_trailing_stop = pos["trailing_stop"] if price < current_trailing_stop: cash += pos["shares"] * price completed_trades.append({ "entry_date": pos["entry_date"], "exit_date": today, "entry_price": pos["entry_price"], "exit_price": price, "allocated": pos["allocated"] }) positions_to_remove.append(idx) for idx in reversed(positions_to_remove): del open_positions[idx] # Update equity curve position_value = sum(pos["shares"] * price for pos in open_positions) equity_curve.append(cash + position_value) # ... (remaining code remains the same)