a-ge commited on
Commit
25232b5
·
verified ·
1 Parent(s): 670609b

Initial Commit

Browse files
Files changed (1) hide show
  1. app.py +167 -0
app.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from tradingview_ta import TA_Handler
3
+ from config import SCREENER, interval_options
4
+ import quantstats as qs
5
+ from io import BytesIO
6
+ from PIL import Image
7
+
8
+ qs.extend_pandas()
9
+
10
+
11
+ def get_technical_analysis(
12
+ symbol: str, exchange: str, screener: str, interval: str
13
+ ) -> dict[str:any]:
14
+ """Get the technical analysis for the given symbol.
15
+
16
+ Args:
17
+ symbol(str): Ticker symbol which is to be analyzed (e.g., "AAPL","MSFT","VOD").
18
+ exchange(str): Exchange at which the tikcer is traded (e.g., "NASDAQ", "NSE", "LSE").
19
+ screener(str): The exchange's country as the screener (e.g., "america", "india", "uk").The possible values are listed in the config.py file
20
+ interval(str): The time interval for the analysis (e.g., "1d", "1h", "15m").The possible values are listed in the config.py file
21
+
22
+ Returns:
23
+ dict: Technical analysis for the symbol/ticker for the given period. Returns a dict containing the analysis.
24
+ """
25
+ try:
26
+ screener = list(SCREENER.keys())[screener]
27
+ handler = TA_Handler(
28
+ symbol=symbol,
29
+ screener=screener,
30
+ exchange=exchange,
31
+ interval=interval,
32
+ )
33
+ analysis = handler.get_analysis()
34
+ analysis_dict = {
35
+ "Symbol": analysis.symbol,
36
+ "Exchange": analysis.exchange,
37
+ "Screener": analysis.screener,
38
+ "Interval": analysis.interval,
39
+ "Time": analysis.time.strftime("%Y-%m-%d %H:%M:%S"),
40
+ "Summary": analysis.summary,
41
+ "Oscillators": analysis.oscillators,
42
+ "Moving Averages": analysis.moving_averages,
43
+ "Indicators": analysis.indicators,
44
+ }
45
+ return analysis_dict
46
+ except Exception as e:
47
+ return {"Error": str(e)}
48
+
49
+
50
+ def get_comparison_details_and_generate_report(symbol: str, benchmark: str):
51
+ """Get the symbol performance against provided benchmark and return plots and HTML report content.
52
+
53
+ Args:
54
+ symbol (str): Ticker symbol to be analyzed (e.g., "AAPL", "TSLA").
55
+ benchmark (str): Benchmark symbol (e.g., "^DJI", "SPY").
56
+ """
57
+
58
+ data = qs.utils.download_returns(symbol)
59
+
60
+ # Snapshot plot to in-memory image
61
+ snapshot_buf = BytesIO()
62
+ qs.plots.snapshot(data, title="Performance", savefig=snapshot_buf)
63
+ snapshot_buf.seek(0)
64
+ snapshot_img = Image.open(snapshot_buf)
65
+
66
+ # Yearly returns plot to in-memory image
67
+ returns_buf = BytesIO()
68
+ qs.plots.yearly_returns(data, benchmark=benchmark, savefig=returns_buf)
69
+ returns_buf.seek(0)
70
+ returns_img = Image.open(returns_buf)
71
+
72
+ # Generate and read HTML report
73
+ report_path = "performance_report.html"
74
+ qs.reports.html(
75
+ data,
76
+ benchmark=benchmark,
77
+ output=report_path,
78
+ strategy_title=symbol,
79
+ title="Detailed Comparison",
80
+ )
81
+ with open(report_path, "r", encoding="utf-8") as file:
82
+ report_content = file.read()
83
+
84
+ return snapshot_img, returns_img, report_content, report_path
85
+
86
+
87
+ def gradio_interface(symbol: str, benchmark: str):
88
+ """Gradio interface function to generate and display the report and plots."""
89
+ snapshot_img, returns_img, report_content, report_path = (
90
+ get_comparison_details_and_generate_report(symbol, benchmark)
91
+ )
92
+ return snapshot_img, report_content, report_path, returns_img
93
+
94
+
95
+ with gr.Blocks() as demo:
96
+ gr.Markdown("# Trade-lens🔎")
97
+ gr.Markdown("Get Analyst ratings and technical indicator details")
98
+
99
+ with gr.Tab("Technical Analysis"):
100
+ symbol_input = gr.Textbox(
101
+ label="Ticker/Symbol (e.g., AAPL,MSFT,GOOGL)",
102
+ )
103
+ exchange_input = gr.Textbox(label="Exchange (e.g., NASDAQ, NSE, LSE)")
104
+ screener_input = gr.Dropdown(
105
+ choices=SCREENER.values(),
106
+ label="Screener (for stocks, enter the exchange's country as the screener)",
107
+ type="index",
108
+ )
109
+ interval_input = gr.Dropdown(interval_options, label="Select Interval:")
110
+ submit_button = gr.Button("Generate Analysis", variant="primary")
111
+ output_json = gr.JSON(label="Output")
112
+
113
+ submit_button.click(
114
+ fn=get_technical_analysis,
115
+ inputs=[symbol_input, exchange_input, screener_input, interval_input],
116
+ outputs=output_json,
117
+ )
118
+
119
+ with gr.Tab("Performance Comparison"):
120
+ with gr.Blocks() as interface:
121
+ gr.Markdown("# Stock Performance Analyzer")
122
+ gr.Markdown(
123
+ "Enter a stock symbol and a benchmark to generate a performance report and snapshot."
124
+ )
125
+
126
+ with gr.Row():
127
+ with gr.Column():
128
+ symbol_input = gr.Textbox(
129
+ label="Stock Symbol (e.g., TSLA,MSFT,AAPL)",
130
+ placeholder="Enter stock symbol",
131
+ info="Some symbols may require a dot(.)suffix of corresponding exchange as TCS.NS",
132
+ )
133
+ benchmark_input = gr.Textbox(
134
+ label="Benchmark Symbol (e.g., ^DJI,^NSEI,^UKX,SPY)",
135
+ placeholder="Enter benchmark symbol",
136
+ info="For index use (^) as that is the accepted format. It can also be other valid stocks/symbols too.",
137
+ )
138
+
139
+ generate_button = gr.Button("Generate Report", variant="primary")
140
+ returns_output = gr.Image(label="Yearly Returns")
141
+
142
+ with gr.Column():
143
+ download_button = gr.File(label="Download Report")
144
+ snapshot_output = gr.Image(label="Performance Snapshot")
145
+
146
+ with gr.Row():
147
+ report_output = gr.HTML(label="Performance Report")
148
+
149
+ def generate_report(symbol, benchmark):
150
+ snapshot_img, report_html, report_path, returns_img = gradio_interface(
151
+ symbol, benchmark
152
+ )
153
+ return snapshot_img, report_html, report_path, returns_img
154
+
155
+ generate_button.click(
156
+ generate_report,
157
+ inputs=[symbol_input, benchmark_input],
158
+ outputs=[
159
+ snapshot_output,
160
+ report_output,
161
+ download_button,
162
+ returns_output,
163
+ ],
164
+ )
165
+
166
+
167
+ demo.launch(mcp_server=True)