|
| 1 | +import yfinance as yf |
| 2 | +import pandas as pd |
| 3 | +from ta.momentum import RSIIndicator |
| 4 | + |
| 5 | +# Download daily Nifty 50 data for the last decade |
| 6 | +data = yf.download('^NSEI', start='2015-07-13', end='2025-07-13') |
| 7 | +data = data[['Close']].dropna() |
| 8 | + |
| 9 | +# Calculate RSI for daily, weekly, and monthly |
| 10 | +data['RSI_D'] = RSIIndicator(data['Close'], window=14).rsi() |
| 11 | +data['Week'] = data.index.to_period('W') |
| 12 | +data['Month'] = data.index.to_period('M') |
| 13 | + |
| 14 | +# Weekly RSI |
| 15 | +weekly = data.groupby('Week')['Close'].last() |
| 16 | +weekly_rsi = RSIIndicator(weekly, window=14).rsi() |
| 17 | +data['RSI_W'] = data['Week'].map(weekly_rsi) |
| 18 | + |
| 19 | +# Monthly RSI |
| 20 | +monthly = data.groupby('Month')['Close'].last() |
| 21 | +monthly_rsi = RSIIndicator(monthly, window=14).rsi() |
| 22 | +data['RSI_M'] = data['Month'].map(monthly_rsi) |
| 23 | + |
| 24 | +# Generate signals |
| 25 | +data['Buy_Signal'] = ( |
| 26 | + (data['RSI_D'] > 40) & |
| 27 | + (data['RSI_D'].shift(1) <= 40) & # Daily RSI just crossed above 40 |
| 28 | + (data['RSI_W'] > 60) & |
| 29 | + (data['RSI_M'] > 60) |
| 30 | +) |
| 31 | + |
| 32 | +# Backtest: Buy at next day's open after signal, sell at next buy or end |
| 33 | +trades = [] |
| 34 | +entry_price = None |
| 35 | +for i in range(1, len(data)): |
| 36 | + if data['Buy_Signal'].iloc[i] and entry_price is None: |
| 37 | + entry_price = data['Close'].iloc[i] |
| 38 | + elif data['Buy_Signal'].iloc[i] and entry_price is not None: |
| 39 | + exit_price = data['Close'].iloc[i] |
| 40 | + trades.append(exit_price > entry_price) |
| 41 | + entry_price = data['Close'].iloc[i] |
| 42 | +# Close last trade if open |
| 43 | +if entry_price is not None and not data['Buy_Signal'].iloc[-1]: |
| 44 | + exit_price = data['Close'].iloc[-1] |
| 45 | + trades.append(exit_price > entry_price) |
| 46 | + |
| 47 | +# Results |
| 48 | +if trades: |
| 49 | + win_probability = sum(trades) / len(trades) |
| 50 | + print(f"Total trades: {len(trades)}") |
| 51 | + print(f"Winning trades: {sum(trades)}") |
| 52 | + print(f"Win probability: {win_probability:.2%}") |
| 53 | +else: |
| 54 | + print("No trades found with the given strategy.") |
0 commit comments