File size: 4,825 Bytes
05e03e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import gradio as gr
import yfinance as yf
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime

# Ensure visualization styles are set for the plots
sns.set(style="whitegrid")
plt.rcParams['figure.figsize'] = [10, 5]

def backtest_ema_strategy(asset_symbol, short_ema, long_ema, timeframe='1d'):
    # Fetching financial data with dynamic timeframe and date range
    start_date = '2020-01-01'
    end_date = '2024-01-01'
    asset_data = yf.download(asset_symbol, start=start_date, end=end_date, interval=timeframe)
    
    # Check if data is empty (can happen with incorrect symbols or network issues)
    if asset_data.empty:
        return None, "Failed to fetch data. Please check the asset symbol and date range.", 0, 0

    # Calculate the short-term and long-term EMAs
    asset_data[f'EMA{short_ema}'] = asset_data['Close'].ewm(span=short_ema, adjust=False).mean()
    asset_data[f'EMA{long_ema}'] = asset_data['Close'].ewm(span=long_ema, adjust=False).mean()

    # Generate signals
    asset_data['Signal'] = np.where(asset_data[f'EMA{short_ema}'] > asset_data[f'EMA{long_ema}'], 1, 0)
    asset_data['Position'] = asset_data['Signal'].diff()

    # Plotting
    plt.figure(figsize=(14, 7))
    plt.plot(asset_data['Close'], label=f'{asset_symbol} Close', alpha=0.5)
    plt.plot(asset_data[f'EMA{short_ema}'], label=f'{short_ema}-day EMA', alpha=0.75)
    plt.plot(asset_data[f'EMA{long_ema}'], label=f'{long_ema}-day EMA', alpha=0.75)
    plt.plot(asset_data[asset_data['Position'] == 1].index, asset_data[f'EMA{short_ema}'][asset_data['Position'] == 1], '^', markersize=10, color='g', lw=0, label='Buy Signal')
    plt.plot(asset_data[asset_data['Position'] == -1].index, asset_data[f'EMA{short_ema}'][asset_data['Position'] == -1], 'v', markersize=10, color='r', lw=0, label='Sell Signal')
    plt.title(f'{asset_symbol} EMA Crossover Trading Strategy')
    plt.legend()
    plt_path = f"{asset_symbol}_EMA_Strategy.png"
    plt.savefig(plt_path)
    plt.close()

    # Calculating total and annual returns
    initial_price = asset_data['Close'].iloc[0]
    final_price = asset_data['Close'].iloc[-1]
    total_returns = ((final_price - initial_price) / initial_price) * 100
    years_diff = (datetime.strptime(end_date, "%Y-%m-%d") - datetime.strptime(start_date, "%Y-%m-%d")).days / 365.25
    annual_returns = ((final_price / initial_price) ** (1 / years_diff) - 1) * 100

    # Returning path of the saved plot, total and annual returns
    return plt_path, "Backtest completed message", total_returns, annual_returns


def create_gradio_interface(asset_symbol, short_ema, long_ema, timeframe):
    # Convert string inputs for EMAs to integers and pass all new parameters to the backtest strategy
    short_ema = int(short_ema)
    long_ema = int(long_ema)
    
    plot_path, message,total_returns, annual_returns = backtest_ema_strategy(asset_symbol, short_ema, long_ema, timeframe)
    
    # Prepare and return the results
    result_text = [
        [message], # f"Backtest completed for {asset_symbol} from {start_date} to {end_date} using {timeframe} data.",
        [f"Total Returns: {total_returns:.2f}%"],
        [f"Annual Returns: {annual_returns:.2f}%"]
    ]
    
    return plot_path, result_text


# Expanded list of major assets to include Indian indices and major stocks
major_assets = [
    # Global and Cryptocurrencies
    "AAPL",  # Apple
    "GOOGL",  # Alphabet
    "MSFT",  # Microsoft
    "AMZN",  # Amazon
    "FB",  # Facebook
    "TSLA",  # Tesla
    "BTC-USD",  # Bitcoin
    "ETH-USD",  # Ethereum
    # # Indian Indices and Major Stocks
    # "NIFTY50.NS",  # Nifty 50 Index
    # "RELIANCE.NS",  # Reliance Industries Limited
    # "TCS.NS",  # Tata Consultancy Services
    # "HDFCBANK.NS",  # HDFC Bank
    # "INFY.NS",  # Infosys
    # "HINDUNILVR.NS",  # Hindustan Unilever
    # "ITC.NS",  # ITC Limited
    # "SBIN.NS",  # State Bank of India
    # "ICICIBANK.NS",  # ICICI Bank
    # "BHARTIARTL.NS",  # Bharti Airtel
]

# Define the Gradio app with updated inputs
iface = gr.Interface(
    fn=create_gradio_interface,
    inputs=[
        gr.Dropdown(choices=major_assets, label="Asset Symbol (Select or type, e.g., NIFTY50.NS)"),
        gr.Textbox(label="Short EMA Period"),
        gr.Textbox(label="Long EMA Period"),
        gr.Dropdown(choices=['1d', '1wk', '1mo'], label="Timeframe (1d = daily, 1wk = weekly, 1mo = monthly)"),
        
    ],
    outputs=[
        gr.Image(label="Trading Strategy Chart"),
        gr.List(label="Results")
    ],
    title="EMA Crossover Trading Strategy Backtest",
    description="Enter the asset symbol, EMA periods, timeframe, and date range to backtest the EMA Crossover Trading Strategy."
)



# Launch the app
if __name__ == "__main__":
    iface.launch(share=True)