mirror of
https://github.com/shawnkim1997/All-in-one-Financial-Analysis.git
synced 2026-08-19 13:28:07 +00:00
Add asset-type aware market/overview flows, portfolio OCR reverse-engineering with exchange overrides, and interactive index heatmap features. Update README with recent updates and wire backend/frontend APIs for FX matrix, exchange options, and improved portfolio editing flows. Made-with: Cursor
48 lines
1.8 KiB
Python
48 lines
1.8 KiB
Python
"""Backtesting service for simple strategies."""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
async def run_backtest(
|
|
ticker: str,
|
|
strategy: str,
|
|
start_date: str,
|
|
end_date: str,
|
|
initial_capital: float = 10000.0,
|
|
) -> dict:
|
|
"""Run a basic backtest for selected strategy."""
|
|
import yfinance as yf
|
|
import ta
|
|
|
|
df = yf.Ticker(ticker.upper()).history(start=start_date, end=end_date)
|
|
if df is None or df.empty:
|
|
return {"error": "No price data"}
|
|
|
|
if strategy == "sma_crossover":
|
|
df["sma50"] = ta.trend.sma_indicator(df["Close"], 50)
|
|
df["sma200"] = ta.trend.sma_indicator(df["Close"], 200)
|
|
df["signal"] = (df["sma50"] > df["sma200"]).astype(int)
|
|
elif strategy == "rsi_oversold":
|
|
df["rsi"] = ta.momentum.rsi(df["Close"], 14)
|
|
df["signal"] = 0
|
|
df.loc[df["rsi"] < 30, "signal"] = 1
|
|
df.loc[df["rsi"] > 70, "signal"] = 0
|
|
else:
|
|
df["signal"] = 1
|
|
|
|
df["returns"] = df["Close"].pct_change().fillna(0)
|
|
df["strategy_returns"] = (df["returns"] * df["signal"].shift(1)).fillna(0)
|
|
cumulative = (1 + df["strategy_returns"]).cumprod()
|
|
benchmark = (1 + df["returns"]).cumprod()
|
|
|
|
return {
|
|
"total_return_pct": round((float(cumulative.iloc[-1]) - 1) * 100, 2),
|
|
"benchmark_return_pct": round((float(benchmark.iloc[-1]) - 1) * 100, 2),
|
|
"alpha": round((float(cumulative.iloc[-1]) - float(benchmark.iloc[-1])) * 100, 2),
|
|
"max_drawdown_pct": round(float(((cumulative / cumulative.cummax()) - 1).min()) * 100, 2),
|
|
"sharpe_ratio": round(float(df["strategy_returns"].mean() / (df["strategy_returns"].std() + 1e-10) * (252 ** 0.5)), 2),
|
|
"equity_curve": [float(x) for x in cumulative.tolist()],
|
|
"benchmark_curve": [float(x) for x in benchmark.tolist()],
|
|
"dates": df.index.strftime("%Y-%m-%d").tolist(),
|
|
}
|