chrisvnz commited on
Commit
5f9a0c8
·
1 Parent(s): d664ac9

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -0
app.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from gradio.inputs import File as InputFile
3
+ from gradio.outputs import File as OutputFile
4
+ from yahoo_fin import stock_info as si
5
+ import yfinance as yf
6
+ import pandas as pd
7
+ import pandas_ta as ta
8
+ import csv
9
+ import os
10
+
11
+ def detect_head_and_shoulders(hist):
12
+ local_max = hist['Close'][-60:][((hist['Close'][-60:].shift(1) < hist['Close'][-60:]) & (hist['Close'][-60:].shift(-1) < hist['Close'][-60:]))]
13
+ if len(local_max) < 3:
14
+ return False
15
+ peaks = local_max[-3:]
16
+ if peaks[0] < peaks[1] and peaks[2] < peaks[1] and abs(peaks[0] - peaks[2]) < peaks[1]*0.05:
17
+ return True
18
+ return False
19
+
20
+ def detect_inverted_head_and_shoulders(hist):
21
+ local_min = hist['Close'][-60:][((hist['Close'][-60:].shift(1) > hist['Close'][-60:]) & (hist['Close'][-60:].shift(-1) > hist['Close'][-60:]))]
22
+ if len(local_min) < 3:
23
+ return False
24
+ valleys = local_min[-3:]
25
+ if valleys[0] > valleys[1] and valleys[2] > valleys[1] and abs(valleys[0] - valleys[2]) < valleys[1]*0.05:
26
+ return True
27
+ return False
28
+
29
+ def process_csv(csv_file):
30
+ all_tickers = []
31
+ with open(csv_file.name, 'r') as file:
32
+ reader = csv.reader(file)
33
+ next(reader) # Skip the header
34
+ for row in reader:
35
+ all_tickers.append(row[0]) # Append the value in the first column
36
+
37
+ ttl_tickers = len(all_tickers)
38
+ filtered_tickers = []
39
+ for ticker in all_tickers:
40
+ try:
41
+ data = yf.Ticker(ticker)
42
+ hist = data.history(period="1y", actions=False)
43
+ if not hist.empty and hist['Volume'][-1] > 999999 and 9 <= hist['Close'][-1] <= 301:
44
+ hist.ta.ema(close='Close', length=20, append=True)
45
+ hist.ta.ema(close='Close', length=50, append=True)
46
+ hist.ta.ema(close='Close', length=100, append=True)
47
+ hist.ta.sma(close='Close', length=150, append=True)
48
+ stoch = hist.ta.stoch(high='High', low='Low', close='Close')
49
+ if all(hist['EMA_20'][-10:] > hist['EMA_50'][-10:]) and all(hist['EMA_50'][-10:] > hist['EMA_100'][-10:]) and all(hist['EMA_100'][-10:] > hist['SMA_150'][-10:]) and stoch['STOCHk_14_3_3'][-1] < 30:
50
+ filtered_tickers.append([ticker, hist['Close'][-1], hist['Volume'][-1], 'Bullish', 'Head and Shoulders' if detect_head_and_shoulders(hist) else '', 'Inverted Head and Shoulders' if detect_inverted_head_and_shoulders(hist) else ''])
51
+ elif all(hist['EMA_20'][-10:] < hist['EMA_50'][-10:]) and all(hist['EMA_50'][-10:] < hist['EMA_100'][-10:]) and all(hist['EMA_100'][-10:] < hist['SMA_150'][-10:]) and stoch['STOCHk_14_3_3'][-1] > 70:
52
+ filtered_tickers.append([ticker, hist['Close'][-1], hist['Volume'][-1], 'Bearish', 'Head and Shoulders' if detect_head_and_shoulders(hist) else '', 'Inverted Head and Shoulders' if detect_inverted_head_and_shoulders(hist) else ''])
53
+ except Exception as e:
54
+ print(f"An error occurred with ticker {ticker}: {e}")
55
+
56
+ df = pd.DataFrame(filtered_tickers, columns=['Ticker', 'Close', 'Volume', 'Trend', 'Head and Shoulders', 'Inverted Head and Shoulders'])
57
+ output_xlsx = 'ema_stacks_list.xlsx'
58
+ df.to_excel(output_xlsx, index=False)
59
+ output_txt = 'pyScreener.txt'
60
+ with open(output_txt, 'w') as f:
61
+ for ticker in df['Ticker']:
62
+ f.write(f"{ticker}\n")
63
+ return output_xlsx, output_txt
64
+
65
+ iface = gr.Interface(
66
+ fn=process_csv,
67
+ inputs=InputFile(label="Upload CSV"),
68
+ outputs=[
69
+ OutputFile(label="Download XLSX"),
70
+ OutputFile(label="Download TXT")
71
+ ],
72
+ title="Stock Shortlist",
73
+ description="Upload a CSV file with columns: Ticker | Description | Industry | Market Capitalization | Sector from TradingView and get shortlisted, stacked EMA trends in return."
74
+ )
75
+
76
+ iface.launch()