ValueError: Der Wahrheitswert einer Serie ist nicht eindeutig. Verwenden Sie a.empty, a.bool(), a.item(), a.any() oder a
Posted: 20 Jan 2025, 18:31
Das ist mein Code:
Und das ist der Fehler:Traceback (letzter Anruf zuletzt):
Ich weiß nicht, wie ich es lösen soll. Wenn mir jemand hilft, wäre ich dankbar.
Code: Select all
import yfinance as yf
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.models import load_model
import matplotlib.pyplot as plt
# Descargar datos del S&P 500
def download_data(ticker="^GSPC", start="1990-01-01", end="2020-01-01"):
data = yf.download(ticker, start, end)
data["Returns"] = data["Close"].pct_change()
data.dropna(inplace=True)
return data
# Generar etiquetas para comprar/vender
def generate_labels(data, threshold=0.005):
data["Signal"] = np.where(data["Returns"] > threshold, 1,
np.where(data["Returns"] < -threshold, -1, 0))
data.dropna(inplace=True)
return data
# Preprocesar datos
def preprocess_data(data):
features = ["Open", "High", "Low", "Close", "Volume"]
X = data[features]
y = data["Signal"]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Convertir -1 (vender) a 0 para clasificación binaria
y_binary = np.where(y == -1, 0, 1)
return X_scaled, y_binary, scaler
# Backtest para cerrar posición a diario o cuando se invierte la señal
def backtest(data, model, scaler, strategy='daily', initial_balance=100000, transaction_cost=0.001):
balance = initial_balance
position = 0 # Representa el dinero invertido en acciones, se usa como un valor escalar
trade_history = []
# Preprocesar los datos para las predicciones
X_scaled, _, _ = preprocess_data(data)
predictions = (model.predict(X_scaled) > 0.5).astype(int) # Predicciones del modelo
for i in range(1, len(data)):
signal = predictions[i] # Señal predicha por el modelo
price = data['Close'].iloc[i]
# Estrategia: Cerrar posición a diario
if strategy == 'daily':
if signal != 0: # Si hay señal de compra o venta
if position > 0: # Si hay posición comprada, se vende
balance += position * (price * (1 - transaction_cost))
position = 0 # Cerrar la posición
if signal == 1: # Si es señal de compra, se compra
position = balance / price
balance = 0 # Ahora no tenemos dinero en efectivo
# Estrategia: Cerrar cuando se invierte la señal
elif strategy == 'signal_reversal':
if signal == 1 and position == 0: # Comprar cuando la señal sea de compra
position = balance / price
balance = 0 # Ahora no tenemos dinero en efectivo
elif signal == -1 and position > 0: # Vender cuando la señal sea de venta
balance += position * price * (1 - transaction_cost)
position = 0 # Cerrar la posición
# Al final del periodo, si hay una posición abierta, se cierra
if i == len(data) - 1:
if position > 0:
balance += position * price * (1 - transaction_cost)
trade_history.append(balance + position * price) # Guardar el balance total en cada paso
return trade_history
# Evaluación de ambos enfoques
def evaluate_backtest():
data = download_data()
data = generate_labels(data)
# Cargar el modelo y el escalador previamente guardado
model = load_model("sp500_model.h5")
scaler_mean = np.load("scaler.npy")
scaler_scale = np.load("scaler_scale.npy")
scaler = StandardScaler()
scaler.mean_ = scaler_mean
scaler.scale_ = scaler_scale
# Backtest con dos enfoques
daily_results = backtest(data, model, scaler, strategy='daily')
signal_reversal_results = backtest(data, model, scaler, strategy='signal_reversal')
# Comparar resultados
daily_final_balance = daily_results[-1]
signal_reversal_final_balance = signal_reversal_results[-1]
print(f"Resultado final con cierre diario: {daily_final_balance:.2f}")
print(f"Resultado final con inversión por señal: {signal_reversal_final_balance:.2f}")
return daily_results, signal_reversal_results
# Ejecutar evaluación
if __name__ == "__main__":
daily_results, signal_reversal_results = evaluate_backtest()
# Convertir en DataFrame para graficar
results_df = pd.DataFrame({
"Daily": daily_results,
"Signal Reversal": signal_reversal_results
})
# Graficar resultados
results_df.plot(title="Comparación de estrategias de backtest", figsize=(12, 6))
plt.show()
Code: Select all
File "c:\Users\jmpgo\Desktop\Python\Precios Predict\backtest2.py", line 107, in
daily_results, signal_reversal_results = evaluate_backtest()
^^^^^^^^^^^^^^^^^^^
File "c:\Users\jmpgo\Desktop\Python\Precios Predict\backtest2.py", line 93, in evaluate_backtest
daily_results = backtest(data, model, scaler, strategy='daily')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\jmpgo\Desktop\Python\Precios Predict\backtest2.py", line 54, in backtest
if position > 0: # Si hay posición comprada, se vende
File "C:\Users\jmpgo\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\generic.py", line 1577, in __nonzero__
raise ValueError(
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().