Chaitanya01 commited on
Commit
919ec8d
1 Parent(s): 34665c9

Upload 16 files

Browse files
Files changed (16) hide show
  1. .gitattributes +1 -8
  2. ETFs.py +78 -0
  3. Procfile +1 -0
  4. README.md +4 -4
  5. alerts.py +85 -0
  6. app.py +1297 -0
  7. coinbaskets.py +21 -0
  8. config.py +391 -0
  9. googleNewsSlackAlerts.py +47 -0
  10. mapping.py +0 -0
  11. notifier.py +40 -0
  12. patterns.py +64 -0
  13. requirements.txt +13 -0
  14. setup.sh +13 -0
  15. tempCodeRunnerFile.py +2 -0
  16. watchlist.csv +2 -0
.gitattributes CHANGED
@@ -2,27 +2,20 @@
2
  *.arrow filter=lfs diff=lfs merge=lfs -text
3
  *.bin filter=lfs diff=lfs merge=lfs -text
4
  *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
  *.ftz filter=lfs diff=lfs merge=lfs -text
7
  *.gz filter=lfs diff=lfs merge=lfs -text
8
  *.h5 filter=lfs diff=lfs merge=lfs -text
9
  *.joblib filter=lfs diff=lfs merge=lfs -text
10
  *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
  *.model filter=lfs diff=lfs merge=lfs -text
13
  *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
  *.onnx filter=lfs diff=lfs merge=lfs -text
17
  *.ot filter=lfs diff=lfs merge=lfs -text
18
  *.parquet filter=lfs diff=lfs merge=lfs -text
19
  *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
  *.pt filter=lfs diff=lfs merge=lfs -text
23
  *.pth filter=lfs diff=lfs merge=lfs -text
24
  *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
  saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
  *.tar.* filter=lfs diff=lfs merge=lfs -text
28
  *.tflite filter=lfs diff=lfs merge=lfs -text
@@ -30,5 +23,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
30
  *.wasm filter=lfs diff=lfs merge=lfs -text
31
  *.xz filter=lfs diff=lfs merge=lfs -text
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
- *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
2
  *.arrow filter=lfs diff=lfs merge=lfs -text
3
  *.bin filter=lfs diff=lfs merge=lfs -text
4
  *.bz2 filter=lfs diff=lfs merge=lfs -text
 
5
  *.ftz filter=lfs diff=lfs merge=lfs -text
6
  *.gz filter=lfs diff=lfs merge=lfs -text
7
  *.h5 filter=lfs diff=lfs merge=lfs -text
8
  *.joblib filter=lfs diff=lfs merge=lfs -text
9
  *.lfs.* filter=lfs diff=lfs merge=lfs -text
 
10
  *.model filter=lfs diff=lfs merge=lfs -text
11
  *.msgpack filter=lfs diff=lfs merge=lfs -text
 
 
12
  *.onnx filter=lfs diff=lfs merge=lfs -text
13
  *.ot filter=lfs diff=lfs merge=lfs -text
14
  *.parquet filter=lfs diff=lfs merge=lfs -text
15
  *.pb filter=lfs diff=lfs merge=lfs -text
 
 
16
  *.pt filter=lfs diff=lfs merge=lfs -text
17
  *.pth filter=lfs diff=lfs merge=lfs -text
18
  *.rar filter=lfs diff=lfs merge=lfs -text
 
19
  saved_model/**/* filter=lfs diff=lfs merge=lfs -text
20
  *.tar.* filter=lfs diff=lfs merge=lfs -text
21
  *.tflite filter=lfs diff=lfs merge=lfs -text
 
23
  *.wasm filter=lfs diff=lfs merge=lfs -text
24
  *.xz filter=lfs diff=lfs merge=lfs -text
25
  *.zip filter=lfs diff=lfs merge=lfs -text
26
+ *.zstandard filter=lfs diff=lfs merge=lfs -text
27
  *tfevents* filter=lfs diff=lfs merge=lfs -text
ETFs.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # List of ETFs
2
+ etf = {
3
+ "ARK":
4
+ {
5
+ "ARKK":"ARK Innovation ETF",
6
+ "ARKW":"ARK Next Generation Internet ETF",
7
+ "ARKG":"ARK Genomic Revolution ETF",
8
+ "ARKQ":"ARK Autonomous Technology & Robotics ETF",
9
+ "ARKF":"Ark Fintech Innovation ETF",
10
+ "ARKX":"ARK Space Exploration & Innovation ETF",
11
+ "PRNT":"3D Printing ETF",
12
+ "IZRL":"Ark Israel Innovative Technology ETF"},
13
+ "US Sector":
14
+ {
15
+ "XLE":"Energy Select Sector SPDR Fund",
16
+ "XLF":"Financial Select Sector SPDR Fund",
17
+ "XLU":"Utilities Select Sector SPDR Fund",
18
+ "XLI":"Industrial Select Sector SPDR Fund",
19
+ "GDX":"VanEck Gold Miners ETF",
20
+ "XLK":"Technology Select Sector SPDR Fund",
21
+ "XLV":"Health Care Select Sector SPDR Fund",
22
+ "XLY":"Consumer Discretionary Select Sector SPDR Fund",
23
+ "XLP":"Consumer Staples Select Sector SPDR Fund",
24
+ "XLB":"Materials Select Sector SPDR Fund",
25
+ "XOP":"SPDR S&P Oil & Gas Exploration & Production ETF",
26
+ "IYR":"iShares US Real Estate ETF",
27
+ "XHB":"SPDR S&P Homebuilders ETF",
28
+ "ITB":"iShares U.S. Home Construction ETF",
29
+ "VNQ":"Vanguard Real Estate Index Fund ETF",
30
+ "GDXJ":"VanEck Junior Gold Miners ETF",
31
+ "IYE":"iShares US Energy ETF",
32
+ "OIH":"VanEck Oil Services ETF",
33
+ "XME":"SPDR S&P Metals & Mining ETF",
34
+ "XRT":"SPDR S&P Retail ETF",
35
+ "SMH":"VanEck Vectors Semiconductor ETF",
36
+ "IBB":"iShares Biotechnology ETF",
37
+ "KBE":"SPDR S&P Bank ETF",
38
+ "KRE":"SPDR S&P Regional Banking ETF",
39
+ "XTL":" SPDR® S&P® Telecom ETF"
40
+ },
41
+ "Others":
42
+ {
43
+ "ICLN":"iShares Global Clean Energy ETF",
44
+ "TAN":"Invesco Solar ETF",
45
+ "BOTZ":"Global X Robotics and Artificial Intelligence ETF",
46
+ "ROBO":"Global Robotics and Automation Index ETF",
47
+ "INFL":"Horizon Kinetics Inflation Beneficiaries ETF",
48
+ "DRIV":"Global X Autonomous & Electric Vehicles ETF",
49
+ "UFO":"Procure Space ETF",
50
+ "NERD":"The Roundhill BITKRAFT Esports & Digital Entertainment ETF",
51
+ "EDUT":"The Global X Education ETF"},
52
+ "Country":
53
+ {
54
+ "Developed Markets":
55
+ {
56
+ "Australia":"EWA", "Austria": "EWO", "Belgium": "EWK",
57
+ "Canada":"EWC", "Denmark":"EDEN", "Finland":"EFNL",
58
+ "France":"EWQ", "Germany":["EWG","EWGS"], "Hong Kong":"EWH",
59
+ "Ireland":"EIRL","Israel":"EIS","Italy":"EWI",
60
+ "Japan":["EWJ","EWJE","EWJV","JPXN","JPMV","SCJ"],
61
+ "Netherlands":"EWN","New Zealand":"ENZL","Norway":"ENOR",
62
+ "Singapore":"EWS","Spain":"EWP", "Sweden":"EWD","Switzerland":"EWL",
63
+ "UK":["EWU","EWUS"]
64
+ },
65
+ "Emerging Markets":
66
+ {
67
+ "Argentina":"AGT","Brazil":["EWZ","EWZS"],"Chile":"ECH",
68
+ "China":["FXI","MCHI","CNYA","ECNS"], "Colombia":"ICOL",
69
+ "India":["INDA","INDY","SMIN"], "Indonesia":"EIDO","Kuwait":"KWT",
70
+ "Malaysia":"EWM", "Mexico":"EWW","Peru":"EPU", "Philippines":"EPHE",
71
+ "Poland":"EPOL","Qatar":"QAT","Russia":"ERUS","Saudi Arabia":"KSA",
72
+ "South Africa":"EZA","South Korea":"EWY", "Taiwan":"EWT","Thailand":"THD",
73
+ "Turkey":"TUR","UAE":"UAE"
74
+
75
+ }
76
+ }
77
+ }
78
+ all_etfs = ['ARKK', 'ARKW', 'ARKG', 'ARKQ', 'ARKF', 'ARKX', 'PRNT', 'IZRL', 'XLE', 'XLF', 'XLU', 'XLI', 'GDX', 'XLK', 'XLV', 'XLY', 'XLP', 'XLB', 'XOP', 'IYR', 'XHB', 'ITB', 'VNQ', 'GDXJ', 'IYE', 'OIH', 'XME', 'XRT', 'SMH', 'IBB', 'KBE', 'KRE', 'XTL', 'ICLN', 'TAN', 'BOTZ', 'ROBO', 'INFL', 'DRIV', 'UFO', 'NERD', 'EDUT', 'EWA', 'EWO', 'EWK', 'EWC', 'EDEN', 'EFNL', 'EWQ', 'EWG', 'EWGS', 'EWH', 'EIRL', 'EIS', 'EWI', 'EWJ', 'EWJE', 'EWJV', 'JPXN', 'JPMV', 'SCJ', 'EWN', 'ENZL', 'ENOR', 'EWS', 'EWP', 'EWD', 'EWL', 'EWU', 'EWUS', 'AGT', 'EWZ', 'EWZS', 'ECH', 'FXI', 'MCHI', 'CNYA', 'ECNS', 'ICOL', 'INDA', 'INDY', 'SMIN', 'EIDO', 'KWT', 'EWM', 'EWW', 'EPU', 'EPHE', 'EPOL', 'QAT', 'ERUS', 'KSA', 'EZA', 'EWY', 'EWT', 'THD', 'TUR', 'UAE']
Procfile ADDED
@@ -0,0 +1 @@
 
 
1
+ web: sh setup.sh && streamlit run app.py && python notifier.py
README.md CHANGED
@@ -1,10 +1,10 @@
1
  ---
2
- title: InvestingPlatform
3
- emoji: 📈
4
- colorFrom: green
5
  colorTo: yellow
6
  sdk: streamlit
7
- sdk_version: 1.21.0
8
  app_file: app.py
9
  pinned: false
10
  ---
 
1
  ---
2
+ title: Wizards Streamlit App
3
+ emoji: 👀
4
+ colorFrom: indigo
5
  colorTo: yellow
6
  sdk: streamlit
7
+ sdk_version: 1.10.0
8
  app_file: app.py
9
  pinned: false
10
  ---
alerts.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from distutils.command.sdist import sdist
2
+ from numpy import tri
3
+ import pandas as pd
4
+ import json, requests
5
+ import slack, time
6
+ from datetime import datetime
7
+ # from bs4 import BeautifulSoup
8
+ from config import *
9
+ def get_yahoo_finance_quote(symbol):
10
+ # Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
11
+ URL = f"https://finance.yahoo.com/quote/{symbol}"
12
+ headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}
13
+ page = requests.get(URL, headers = headers)
14
+ soup = BeautifulSoup(page.text, "html.parser")
15
+ price = soup.find('div',{'class':'D(ib) Mend(20px)'}).find_all('fin-streamer')[0].text
16
+ return float(price.replace(",",""))
17
+ def get_cnbc_data(symbol):
18
+ ticker = symbol.replace(" ","")
19
+ if ticker == "NASDAQ":
20
+ ticker = "NDX"
21
+ elif ticker == "NIFTY50":
22
+ ticker = ".NSEI"
23
+ # Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
24
+ df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={ticker}").json()["barData"]["priceBars"])
25
+ # df_1D = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1D.json?symbol={ticker}").json()["barData"]["priceBars"])
26
+ df["datetime"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
27
+ df["close"] = df["close"].astype(float)
28
+ # df_1D["close"] = df_1D["close"].astype(float)
29
+ df.set_index("datetime",inplace = True)
30
+ dma200 = (df["close"].rolling(200).mean()).iloc[-1]
31
+ close = (df["close"].iloc[-1])
32
+ return dma200, close
33
+
34
+ client = slack.WebClient(token = SLACK_TOKEN)
35
+
36
+ while True:
37
+ df = pd.read_csv('watchlist.csv')
38
+ df.set_index("Symbol",inplace = True)
39
+ # df_crypto = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
40
+ # df_crypto = df_crypto[df_crypto["quoteCurrency"].isin(["USD","USDT"])]
41
+ # df_crypto.set_index("name",inplace = True)
42
+
43
+ if len(df)>0:
44
+ req_df_price = df[df["status"] == "Pending"]
45
+ req_df_dma = df[df["dma_status"] == "Pending"]
46
+ for symbol in req_df_price.index:
47
+ if symbol in ["SPX","US 2Y","US 5Y","US 10Y","US 30Y","HYG","LQD","NASDAQ","VIX","NIFTY50"]:
48
+ dma200, ltp= get_cnbc_data(symbol)
49
+ # else:
50
+ # ltp = df_crypto.loc[symbol]["last"]
51
+ trigger_level = req_df_price.loc[symbol]["Trigger"]
52
+ triggered = 0
53
+
54
+ if req_df_price.loc[symbol]["view_type"] == "Above":
55
+ if trigger_level<=ltp:
56
+ triggered = 1
57
+ elif req_df_price.loc[symbol]["view_type"] == "Below":
58
+ if trigger_level>=ltp:
59
+ triggered = 1
60
+
61
+ if triggered == 1:
62
+ df.at[symbol,"status"] = "Triggered"
63
+ client.chat_postMessage(channel = f"#{df.loc[symbol]['alert_type'].lower()}_signal",
64
+ text = f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} {symbol} is {df.loc[symbol]['view_type']} {trigger_level} at {ltp}")
65
+ for symbol in req_df_dma.index:
66
+ dma_check = req_df_dma.loc[symbol]["dma200"]
67
+ if dma_check == False:
68
+ continue
69
+ triggered_dma200 = 0
70
+ dma200, ltp= get_cnbc_data(symbol)
71
+ print(dma200)
72
+ if req_df_dma.loc[symbol]["dma200_view_type"] == "Above":
73
+ if dma200<=ltp:
74
+ triggered_dma200 = 1
75
+ elif req_df_dma.loc[symbol]["dma200_view_type"] == "Below":
76
+ if dma200>=ltp:
77
+ triggered_dma200 = 1
78
+
79
+ if triggered_dma200 == 1:
80
+ df.at[symbol,"dma_status"] = "Triggered"
81
+ client.chat_postMessage(channel = f"#{df.loc[symbol]['alert_type'].lower()}_signal",
82
+ text = f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} {symbol} is {df.loc[symbol]['dma200_view_type']} DMA200 at {ltp}")
83
+ df.to_csv("watchlist.csv")
84
+ # Recheck again after 60 minutes
85
+ time.sleep(60*60)
app.py ADDED
@@ -0,0 +1,1297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+ from requests.api import delete, options
4
+ import streamlit as st
5
+ import time
6
+ import tweepy
7
+ import requests
8
+ from io import BytesIO
9
+ import base64
10
+ import matplotlib.pyplot as plt
11
+ import numpy as np
12
+ from plotly.subplots import make_subplots
13
+ from config import *
14
+ from dateutil.relativedelta import relativedelta
15
+ from patterns import patterns
16
+ # import talibsddsfs
17
+ from datetime import datetime, timedelta, tzinfo
18
+ from alpaca_trade_api.rest import REST
19
+ from streamlit_tags import st_tags_sidebar
20
+ # from streamlit_autorefresh import st_autorefresh
21
+ # import plotly.express as px
22
+ from coinbaskets import *
23
+ import plotly.graph_objects as go
24
+ from mapping import *
25
+ import pandas as pd
26
+ import threading
27
+ from bs4 import BeautifulSoup
28
+ from ETFs import *
29
+ from dateutil import tz
30
+ import os
31
+ # try:
32
+ # from streamlit.ReportThread import add_report_ctx
33
+ # except Exception:
34
+ # # Streamlit >= 0.65.0
35
+ # from streamlit.report_thread import add_report_ctx
36
+ # # from streamlit.scriptrunner import add_script_run_ctx
37
+ from streamlit.scriptrunner import add_script_run_ctx as add_report_ctx
38
+ def get_stocktwits_data(req,code,label):
39
+
40
+ r = requests.get(req)
41
+ trending_syms = pd.DataFrame(r.json()["stocks"]).T
42
+ trending_syms.index.name = "stock_id"
43
+ trending_syms.index = trending_syms.index.astype("int")
44
+ trending_score = pd.DataFrame(r.json()["table"][code])
45
+ trending_score.set_index("stock_id",inplace = True)
46
+ most_trending_syms = pd.merge(trending_syms,trending_score,on= "stock_id")
47
+ most_trending_syms.sort_values("val",ascending = False, inplace = True)
48
+ most_trending_syms.set_index("symbol",inplace = True)
49
+ most_trending_syms.columns = ["Name","Price","%Change",label]
50
+ return most_trending_syms
51
+
52
+ def get_cnbc_data(symbol):
53
+ ticker = symbol.replace(" ","")
54
+ if ticker == "NASDAQ":
55
+ ticker = "NDX"
56
+ elif ticker == "NIFTY50":
57
+ ticker = ".NSEI"
58
+ # Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
59
+ # df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={ticker}").json()["barData"]["priceBars"])
60
+ df_1D = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1D.json?symbol={ticker}").json()["barData"]["priceBars"])
61
+ # df["datetime"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
62
+ # df["close"] = df["close"].astype(float)
63
+ df_1D["close"] = df_1D["close"].astype(float)
64
+ # df.set_index("datetime",inplace = True)
65
+ # dma200 = df["close"].rolling(200).mean()
66
+ close = (df_1D["close"].iloc[-1])
67
+ return close
68
+ def vix_gradient(vix):
69
+ """
70
+ Mapping is done as follows rsi<=20 --> -100, rsi>=80, 100, and then linear variation
71
+ """
72
+ if vix<20:
73
+ return 100
74
+ elif vix<30:
75
+ return (-20*vix+500)
76
+ else:
77
+ return -100
78
+ def roro_comp_get(series,i,state, inverse = False):
79
+
80
+ current = series.iloc[-i]
81
+ current_idx = series.index[-i]
82
+
83
+ w_1_ago = current_idx - relativedelta(days=7)
84
+ w_2_ago = current_idx - relativedelta(days=14)
85
+ m_1_ago = current_idx - relativedelta(months=1)
86
+
87
+ if state == 0:
88
+ w_1_ret = (current - series.loc[w_1_ago:].iloc[0])*100/series.loc[w_1_ago:].iloc[0]
89
+ w_2_ret = (current - series.loc[w_2_ago:].iloc[0])*100/series.loc[w_2_ago:].iloc[0]
90
+ m_1_ret = (current - series.loc[m_1_ago:].iloc[0])*100/series.loc[m_1_ago:].iloc[0]
91
+ else:
92
+ w_1_ret = (current - series.iloc[-1-i])*100/series.iloc[-1-i]
93
+ w_2_ret = (current - series.iloc[-2-i])*100/series.iloc[-2-i]
94
+ m_1_ret = (current - series.iloc[-4-i])*100/series.iloc[-4-i]
95
+ sign_of = 1
96
+ if inverse == True:
97
+ sign_of = -1
98
+ val = 100*(3*(2*(sign_of*w_1_ret>0) - 1) + 2*(2*(sign_of*w_2_ret>0) - 1) + 2*(sign_of*m_1_ret>0) - 1)/6
99
+
100
+ return val
101
+ def get_roro(tf = "1Y"):
102
+
103
+ df_spx = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=.SPX").json()["barData"]["priceBars"])
104
+ df_spx["datetime"] = pd.to_datetime(df_spx['tradeTimeinMills'],unit='ms').dt.date
105
+ df_spx.set_index("datetime",inplace = True)
106
+ df_spx["close"] = df_spx["close"].astype(float)
107
+
108
+ df_vix = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=.VIX").json()["barData"]["priceBars"])
109
+ df_vix["close"] = df_vix["close"].astype(float)
110
+
111
+ df_AUDJPY = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=AUDJPY=").json()["barData"]["priceBars"])
112
+ df_AUDJPY["datetime"] = pd.to_datetime(df_AUDJPY['tradeTimeinMills'],unit='ms').dt.date
113
+ df_AUDJPY.set_index("datetime",inplace = True)
114
+ df_AUDJPY["close"] = df_AUDJPY["close"].astype(float)
115
+
116
+
117
+ df_gold = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=@GC.1").json()["barData"]["priceBars"])
118
+ df_gold["datetime"] = pd.to_datetime(df_gold['tradeTimeinMills'],unit='ms').dt.date
119
+ df_gold.set_index("datetime",inplace = True)
120
+ df_gold["close"] = df_gold["close"].astype(float)
121
+
122
+ df_silver = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=@SI.1").json()["barData"]["priceBars"])
123
+ df_silver["datetime"] = pd.to_datetime(df_silver['tradeTimeinMills'],unit='ms').dt.date
124
+ df_silver.set_index("datetime",inplace = True)
125
+ df_silver["close"] = df_silver["close"].astype(float)
126
+
127
+ gold_silver_ratio = df_gold["close"]/df_silver["close"]
128
+
129
+ df_bnd = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=BND").json()["barData"]["priceBars"])
130
+ df_bnd["datetime"] = pd.to_datetime(df_bnd['tradeTimeinMills'],unit='ms').dt.date
131
+ df_bnd.set_index("datetime",inplace = True)
132
+ df_bnd["close"] = df_bnd["close"].astype(float)
133
+
134
+ df_sphb = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SPHB").json()["barData"]["priceBars"])
135
+ df_sphb["datetime"] = pd.to_datetime(df_sphb['tradeTimeinMills'],unit='ms').dt.date
136
+ df_sphb.set_index("datetime",inplace = True)
137
+ df_sphb["close"] = df_sphb["close"].astype(float)
138
+
139
+ df_splv = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SPLV").json()["barData"]["priceBars"])
140
+ df_splv["datetime"] = pd.to_datetime(df_splv['tradeTimeinMills'],unit='ms').dt.date
141
+ df_splv.set_index("datetime",inplace = True)
142
+ df_splv["close"] = df_splv["close"].astype(float)
143
+
144
+ sphb_splv_ratio = df_sphb["close"]/df_splv["close"]
145
+
146
+ df_HYG = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=HYG").json()["barData"]["priceBars"])
147
+ df_HYG["datetime"] = pd.to_datetime(df_HYG['tradeTimeinMills'],unit='ms').dt.date
148
+ df_HYG.set_index("datetime",inplace = True)
149
+ df_HYG["close"] = df_HYG["close"].astype(float)
150
+
151
+ df_fnda = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=FNDA").json()["barData"]["priceBars"])
152
+ df_fnda["datetime"] = pd.to_datetime(df_fnda['tradeTimeinMills'],unit='ms').dt.date
153
+ df_fnda.set_index("datetime",inplace = True)
154
+ df_fnda["close"] = df_fnda["close"].astype(float)
155
+
156
+ df_schx = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SCHX").json()["barData"]["priceBars"])
157
+ df_schx["datetime"] = pd.to_datetime(df_schx['tradeTimeinMills'],unit='ms').dt.date
158
+ df_schx.set_index("datetime",inplace = True)
159
+ df_schx["close"] = df_schx["close"].astype(float)
160
+
161
+ fnda_schx_ratio = df_fnda["close"]/df_schx["close"]
162
+
163
+ df_btc_usd = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=BTC.CB=").json()["barData"]["priceBars"])
164
+ df_btc_usd["datetime"] = pd.to_datetime(df_btc_usd['tradeTimeinMills'],unit='ms').dt.date
165
+ df_btc_usd.set_index("datetime",inplace = True)
166
+ df_btc_usd["close"] = df_btc_usd["close"].astype(float)
167
+ periods = 300
168
+ roro = []
169
+ if tf == "5Y":
170
+ state = 1
171
+ else:
172
+ state = 0
173
+ for i in range(periods,0,-1):
174
+ temp = dict(
175
+ date = (pd.to_datetime(df_spx.index).date)[-i],
176
+ spx = roro_comp_get(df_spx["close"],i,state),
177
+ audjpy = roro_comp_get(df_AUDJPY["close"],i,state),
178
+ gold_silver = roro_comp_get(gold_silver_ratio,i,state,inverse = True),
179
+ bnd = roro_comp_get(df_bnd["close"],i,state,inverse = True),
180
+ sphb_splv = roro_comp_get(sphb_splv_ratio,i,state),
181
+ hyg = roro_comp_get(df_HYG["close"],i,state),
182
+ fnda_schx = roro_comp_get(fnda_schx_ratio,i,state),
183
+ vix = vix_gradient(df_vix["close"].iloc[-i]),
184
+ btc_usd = roro_comp_get(df_btc_usd["close"],i,state)
185
+ )
186
+ roro.append(temp)
187
+
188
+ return roro
189
+ # Setting the page layout as wide
190
+ st.set_page_config(layout="wide")
191
+ def get_data_yields(symbol,lookback_period):
192
+ global response_yields
193
+ df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{lookback_period}.json?symbol={symbol}").json()["barData"]["priceBars"])
194
+ df["datetime"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
195
+ df.set_index("datetime",inplace = True)
196
+ response_yields[symbol] = df["close"].astype(float)
197
+ def get_recommendation(symbol,rsi_val,drop_frm_ath,dist_from_5_yr_low):
198
+ global momentum_recommendations,cheap_recommendations
199
+ df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={symbol}").json()["barData"]["priceBars"])
200
+ df_all = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/ALL.json?symbol={symbol}").json()["barData"]["priceBars"])
201
+ df_all["high"] = df_all["high"].astype(float)
202
+ df_all["low"] = df_all["low"].astype(float)
203
+ df["tradeTimeinMills"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
204
+ df_all["tradeTimeinMills"] = pd.to_datetime(df_all['tradeTimeinMills'],unit='ms')
205
+ df["close"] = df["close"].astype(float)
206
+ df["open"] = df["open"].astype(float)
207
+ df.set_index("tradeTimeinMills",inplace = True)
208
+ df_all.set_index("tradeTimeinMills",inplace = True)
209
+
210
+ current_close = df["close"].iloc[-1]
211
+
212
+ df["50DMA"] = df["close"].rolling(50).mean()
213
+ df["100DMA"] = df["close"].rolling(100).mean()
214
+ df["Vol_mon_avg"] = 5*df["volume"].rolling(252).mean()
215
+ df["RSI"] = talib.RSI(df["close"])
216
+ cond1 = current_close>df["50DMA"].iloc[-1]
217
+ cond2 = current_close>df["100DMA"].iloc[-1]
218
+ cond3 = df["volume"].rolling(5).sum().iloc[-1]>1.5*df["Vol_mon_avg"].iloc[-1]
219
+ mom_score = int(cond1)+int(cond2)+int(cond3)
220
+
221
+ ath = df_all["high"].max()
222
+ distance_from_ath = round((ath-current_close)*100/ath,2)
223
+ yr_2_ago_dt = datetime.now() - relativedelta(years=2)
224
+ yr_2_low = df_all["low"].loc[yr_2_ago_dt:].min()
225
+ distance_frm_2yr_low = round((current_close - yr_2_low)*100/current_close,2)
226
+ rsi = round(df["RSI"].iloc[-1],2)
227
+ cond_1 = rsi<rsi_val
228
+ cond_2 = distance_from_ath>=drop_frm_ath
229
+ cond_3 = distance_frm_2yr_low<=dist_from_5_yr_low
230
+ cheap_score = int(cond_1)+int(cond_2)+int(cond_3)
231
+
232
+ if (cond1 or cond2) or cond3:
233
+ momentum_recommendations[symbol] = {"LTP":current_close,"50DMA":df["50DMA"].iloc[-1],"100DMA":df["100DMA"].iloc[-1],"Vol>1.5avg":cond3,"score":mom_score,"sparkline": sparkline(data=df["close"])}
234
+ if cond_1 or cond_2 or cond_3:
235
+ cheap_recommendations[symbol] = {"LTP":current_close,"RSI":rsi,f'drop frm ATH':distance_from_ath,f"% away 2 yr low":distance_frm_2yr_low,"score":cheap_score,"sparkline": sparkline(data=df["close"])}
236
+ def sparkline(data, figsize=(4,0.25),**kwags):
237
+ data = list(data)
238
+ fig,ax = plt.subplots(1,1,figsize=figsize,**kwags)
239
+ ax.plot(data)
240
+
241
+ for k,v in ax.spines.items():
242
+ v.set_visible(False)
243
+
244
+ ax.set_xticks([])
245
+ ax.set_yticks([])
246
+
247
+ plt.plot(len(data)-1, data[len(data)-1], 'r.')
248
+
249
+ ax.fill_between(range(len(data)), data, len(data)*[min(data)], alpha=0.1)
250
+
251
+ img = BytesIO()
252
+ plt.savefig(img, transparent=True, bbox_inches='tight')
253
+ img.seek(0)
254
+ # plt.show()
255
+ plt.close()
256
+
257
+ # return base64.b64encode(img.read()).decode("utf-8")
258
+ return '<img src="data:image/png;base64,{}"/>'.format(base64.b64encode(img.read()))
259
+ def highlight_rec_momentum(s):
260
+ arr = []
261
+ arr.append('background-color: white')
262
+ if s["50DMA"]<s["LTP"]:
263
+ arr.append('background-color: #90EE90')
264
+ else:
265
+ arr.append('background-color: #FF7F7F')
266
+ if s["100DMA"]<s["LTP"]:
267
+ arr.append('background-color: #90EE90')
268
+ else:
269
+ arr.append('background-color: #FF7F7F')
270
+ if s["Vol>1.5avg"]:
271
+ arr.append('background-color: #90EE90')
272
+ else:
273
+ arr.append('background-color: #FF7F7F')
274
+ arr.append('background-color: white')
275
+ arr.append('background-color: white')
276
+ return arr
277
+ def font_color(s):
278
+ return ["color: black"]*len(s)
279
+ def highlight_rec_cheap(s,rsi_val,drop_frm_ath,dist_from_5_yr_low):
280
+ arr = []
281
+ arr.append('background-color: white')
282
+ if s["RSI"]<rsi_val:
283
+ arr.append('background-color: #90EE90')
284
+ else:
285
+ arr.append('background-color: #FF7F7F')
286
+ if s[f"drop frm ATH"]>drop_frm_ath:
287
+ arr.append('background-color: #90EE90')
288
+ else:
289
+ arr.append('background-color: #FF7F7F')
290
+ if s[f"% away 2 yr low"]<dist_from_5_yr_low:
291
+ arr.append('background-color: #90EE90')
292
+ else:
293
+ arr.append('background-color: #FF7F7F')
294
+ arr.append('background-color: white')
295
+ arr.append('background-color: white')
296
+
297
+ return arr
298
+ def get_etf_rets(symbol):
299
+ global res_etf_ret, vol_etf_info,expense_ratios
300
+ df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={symbol}").json()["barData"]["priceBars"])
301
+ df["tradeTimeinMills"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
302
+ df["close"] = df["close"].astype(float)
303
+ df["open"] = df["open"].astype(float)
304
+ df.set_index("tradeTimeinMills",inplace = True)
305
+ df_new = df.resample("W-Sun").agg({"close":"last","open":"first"})
306
+ price_1_yr_ago = df.loc[df_new.index[-1] - relativedelta(years = 1):].iloc[0]["open"]
307
+ price_1_mon_ago = df.loc[df.index[-1] - relativedelta(months=1):].iloc[0]["open"]
308
+ close = df.iloc[-1]["close"]
309
+ daily_ret = (close - df.iloc[-1]["open"].astype(float))*100/df.iloc[-1]["open"]
310
+ w_1_ret = round((close - df_new.iloc[-1]["open"])*100/df_new.iloc[-1]["open"],2)
311
+ w_2_ret = round((close - df_new.iloc[-2]["open"])*100/df_new.iloc[-2]["open"],2)
312
+ y_1_ret = round((close - price_1_yr_ago)*100/price_1_yr_ago,2)
313
+ m_1_ret = round((close - price_1_mon_ago)*100/price_1_mon_ago,2)
314
+ temp = dict(symbol = symbol,day_ret = daily_ret, w1_ret = w_1_ret, w2_ret = w_2_ret, year_ret = y_1_ret,m1_ret = m_1_ret)
315
+ res_etf_ret.append(temp)
316
+ iv = (df["close"].pct_change()*100).iloc[-30:].std()*np.sqrt(252)
317
+ vol_etf_info[symbol] = round(iv,2)
318
+
319
+ r = requests.get(f"https://etfdb.com/etf/{symbol}/#etf-ticker-profile")
320
+ soup = BeautifulSoup(r.content, 'html5lib')
321
+ expense_ratio = soup.find("div",{"class":"ticker-assets"}).find_all("div")[3].text.split("\n")[-2]
322
+ expense_ratios[symbol] = expense_ratio
323
+ return
324
+ def get_data(ticker, timeframe = 60*60 * 4):
325
+ # Function to get OHLC data for a symbol from FTX api
326
+ data = pd.DataFrame(json.loads(requests.get(f"https://ftx.com/api/markets/{ticker}/candles?resolution={timeframe}").text)["result"])
327
+ return data
328
+ def in_squeeze(symbol,bb_mul, kc_mul,num_days,plot = False, timeframe = 60*60*4):
329
+ # Function to check whether Keltner Channel and Bollinger bands squeeze is happening
330
+ # Get Data
331
+ data = get_data(symbol,timeframe)
332
+ # Calculate BB
333
+ data["20sma"] = data["close"].rolling(window = 20).mean()
334
+ data["stddev"] = data["close"].rolling(window = 20).std()
335
+ data["lowerband"] = data["20sma"] - bb_mul*data["stddev"]
336
+ data["upperband"] = data["20sma"] + bb_mul*data["stddev"]
337
+
338
+ # Calculate KC
339
+ data["TR"] = data["high"] - data["low"]
340
+ data["ATR"] = data["TR"].rolling(window = 20).mean()
341
+ data['upperKC'] = data["20sma"] + kc_mul*data["ATR"]
342
+ data['lowerKC'] = data["20sma"] - kc_mul*data["ATR"]
343
+ data["squeeze_on"] = np.where(
344
+ np.logical_and(data["lowerband"]>data["lowerKC"], data["upperband"]<data["upperKC"]),1,0)
345
+ # Now if "num_days" days earlier BB were in KC but now, its not then that's breakout
346
+ if data.iloc[-num_days]["squeeze_on"] and not data.iloc[-1]["squeeze_on"]:
347
+ # If user wants to plot the candlestick then pass the plot = True
348
+ if plot == True:
349
+ # Template for plotting KC and BB and candlesticks
350
+ candlestick = go.Candlestick(x=data["startTime"],open=data["open"],high=data["high"],low=data["low"],close=data["close"], name = symbol)
351
+ upperband = go.Scatter(x = data["startTime"], y = data["upperband"], name = "Upper BB", line = dict(color = "blue"))
352
+ lowerband = go.Scatter(x = data["startTime"], y = data["lowerband"], name = "Lower BB", line = dict(color = "blue"))
353
+ upperKC = go.Scatter(x = data["startTime"], y = data["upperKC"], name = "Upper KC", line = dict(color = "green"))
354
+ lowerKC = go.Scatter(x = data["startTime"], y = data["lowerKC"], name = "Upper KC", line = dict(color = "green"))
355
+
356
+ fig = go.Figure(data = [candlestick,upperband, lowerband, upperKC, lowerKC])
357
+ # Slider in Xaxes for 1month, 6month, YTD and 1Y
358
+ fig.update_xaxes(
359
+ rangeslider_visible=True,
360
+ rangeselector=dict(
361
+ buttons=list([
362
+ dict(count=1, label="1mon", step="month", stepmode="backward"),
363
+ dict(count=6, label="6mon", step="month", stepmode="backward"),
364
+ dict(count=1, label="YTD", step="year", stepmode="todate"),
365
+ dict(count=1, label="1y", step="year", stepmode="backward"),
366
+ dict(step="all")
367
+ ])
368
+ ))
369
+ fig.update_layout(yaxis=dict(autorange = True,fixedrange= False))
370
+ st.plotly_chart(fig,use_container_width=True)
371
+ else:
372
+ print(f"{symbol}")
373
+
374
+ def plot_candlestick(data):
375
+ # Function to plot candlestick out of a given OHLC dataframe
376
+ fig = go.Figure(data=[go.Candlestick(x=data.index,
377
+ open=data['open'],
378
+ high=data['high'],
379
+ low=data['low'],
380
+ close=data['close'])])
381
+ fig.update_xaxes(
382
+ rangeslider_visible=True,
383
+ rangeselector=dict(
384
+ buttons=list([
385
+ dict(count=1, label="1mon", step="month", stepmode="backward"),
386
+ dict(count=6, label="6mon", step="month", stepmode="backward"),
387
+ dict(count=1, label="YTD", step="year", stepmode="todate"),
388
+ dict(count=1, label="1y", step="year", stepmode="backward"),
389
+ dict(step="all")
390
+ ])
391
+ ))
392
+ return fig
393
+
394
+ def get_key(dict_given, val):
395
+ # Function to get the key of the required value from a dictionary
396
+ for key, value in dict_given.items():
397
+ if val == value:
398
+ return key
399
+ def get_crypto_data_daily(symbol):
400
+ data = get_data(symbol,timeframe = 60*60*24)
401
+ data.to_csv(f"crypto_data/{symbol.replace('/','_')}.csv")
402
+ def get_cnbc_yields(symbol):
403
+ # Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
404
+
405
+ URL = f"https://www.cnbc.com/quotes/US5Y"
406
+ headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}
407
+ page = requests.get(URL, headers = headers)
408
+ soup = BeautifulSoup(page.text, "html.parser")
409
+ yields = ["US 2Y","US 5Y", "US 10Y","US 30Y"]
410
+ if symbol in yields:
411
+ elements = soup.find('div',{'class':'QuoteStrip-lastPriceStripContainer'})
412
+ price = elements.find_all('span')[0].text.replace("%","")
413
+ return float(price.replace(",",""))
414
+ def get_yahoo_finance_quote(symbol):
415
+ # Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
416
+ URL = f"https://finance.yahoo.com/quote/{symbol}"
417
+ headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}
418
+ page = requests.get(URL, headers = headers)
419
+ soup = BeautifulSoup(page.text, "html.parser")
420
+ price = soup.find('div',{'class':'D(ib) Mend(20px)'}).find_all('fin-streamer')[0].text
421
+ return price.replace(",","")
422
+ def get_symbol_quote(ticker_tape, symbol,tck_tape, idx):
423
+ # Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
424
+ URL = f"https://finance.yahoo.com/quote/{symbol}"
425
+ headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}
426
+ page = requests.get(URL, headers = headers)
427
+ soup = BeautifulSoup(page.text, "html.parser")
428
+ price = soup.find('div',{'class':'D(ib) Mend(20px)'}).find_all('span')[0].text
429
+ change = soup.find('div',{'class':'D(ib) Mend(20px)'}).find_all('span')[1].text
430
+ change = change.split(" ")[1]
431
+ change = change[1:-1]
432
+ if ticker_tape == "US 10Y":
433
+ # US 10Y treated differently because of some formating purposes
434
+ change = float(change.replace("(","").replace(")","").replace("%",""))
435
+ price_now = float(price)
436
+ change = round(price_now - price_now/(1+change/100),2)
437
+ change = str(change) + "%"
438
+ tck_tape[idx].metric(label = ticker_tape ,value = price,delta = change)
439
+
440
+ # Set the twitter client and set the access token which comes from config.py
441
+ auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET)
442
+ auth.set_access_token(TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET)
443
+
444
+ api = tweepy.API(auth)
445
+
446
+ if "trade_api" not in st.session_state:
447
+ # Now, if this api is not there in session_state then add it,
448
+ # we are doing this because we don't want to let the info go once site is refreshed
449
+ # And session_state is kind of memory used for caching required info
450
+ # Set the trade_api variable
451
+ st.session_state.trade_api = REST(API_KEY, SECRET_KEY, API_URL)
452
+ if "stocks" not in st.session_state:
453
+ # If stocks are not present then from companies.csv file add them
454
+ with open('datasets/companies.csv') as f:
455
+ companies = f.read().splitlines()
456
+ symbols = []
457
+ for company in companies:
458
+ symbols.append(company.split(",")[0])
459
+ st.session_state.stocks = symbols
460
+ if "login" not in st.session_state:
461
+ # If user has not logged in set login = False
462
+ # This is done because once logged in we want the program to remember that it logged in
463
+ # Hence setting the session_state
464
+ st.session_state.login = False
465
+
466
+ if st.session_state.login == False:
467
+ # If login is false then create a login window
468
+ st.sidebar.write("Login")
469
+
470
+ # Create sidebar login boxes
471
+ user = st.sidebar.text_input(label = "Username")
472
+ password = st.sidebar.text_input(label = "Password", type = "password")
473
+ login_btn = st.sidebar.button("Login")
474
+ if login_btn:
475
+ # This is the users list which will help in login and password for both is 123
476
+ if user in ["Chaitanya", "Sagar"] and password == "Wizards@123Trade#":
477
+ st.sidebar.success(f"Logged In as {user}")
478
+ st.session_state.login = True
479
+ # Now if clicked on login wait for 1 second then reload the page using experimental_rerun
480
+ time.sleep(1)
481
+ st.experimental_rerun()
482
+ else:
483
+ # If incorrect credentials then pose an error
484
+ st.sidebar.warning("Incorrect Username/Password")
485
+ else:
486
+ # Get the crypto data from FTX api
487
+ df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
488
+ # Get the LTP and 24H %change for BTCUSDT, ETHUSDT
489
+ st.session_state.index_btc = df[df["name"]=="BTC/USDT"]["last"].values[0]
490
+ st.session_state.index_btc_pct_change = round(df[df["name"]=="BTC/USDT"]["change24h"].values[0],2)
491
+ st.session_state.index_eth = df[df["name"]=="ETH/USDT"]["last"].values[0]
492
+ st.session_state.index_eth_pct_change = round(df[df["name"]=="ETH/USDT"]["change24h"].values[0],2)
493
+ st.session_state.roro = get_roro()
494
+ roro_df = pd.DataFrame(st.session_state.roro)
495
+ roro_df.set_index("date",inplace = True)
496
+ roro_df["sum"] = roro_df.sum(axis = 1) / len(roro_df.columns)
497
+ # Code below is for formatting purpose
498
+ cols_ticker_tape_cryp = st.columns([1,1])
499
+ cols_ticker_tape_cryp[0].metric(label = "BTC",value = st.session_state.index_btc, delta = f"{st.session_state.index_btc_pct_change}%")
500
+ cols_ticker_tape_cryp[1].metric(label = "ETH", value = st.session_state.index_eth, delta = f"{st.session_state.index_eth_pct_change}%")
501
+ fig = go.Figure(go.Indicator(
502
+ mode = "number+delta",
503
+ value = round(roro_df["sum"].iloc[-1]),
504
+ domain = {'x': [0, 0.2], 'y': [0, 0.2]},
505
+ delta = {'reference': round(roro_df["sum"].iloc[-2])},
506
+ gauge = {'axis': {'range': [-100, 100]}},
507
+ title = {'text': "RORO Indicator"}))
508
+ fig.add_trace(go.Scatter(y = roro_df["sum"].values,x = roro_df.index,mode = "lines",fill='tozeroy'))
509
+ st.plotly_chart(fig,use_container_width=True,use_container_height = True)
510
+ cols_ticker_tape = st.columns(5)
511
+ # Now, since fetching each symbol will take lots of time
512
+ # So, we are running all the process in threads parally multi-processing
513
+ thread_ticker = []
514
+ for i in range(len (symbol_mapping.keys())):
515
+ # Get the symbol_mapping and run it in thread and display each of them
516
+ ticker_tape = list(symbol_mapping.keys())[i]
517
+ t_ticker = threading.Thread(target = get_symbol_quote, args = (ticker_tape, symbol_mapping[ticker_tape],cols_ticker_tape,i,))
518
+ add_report_ctx(t_ticker)
519
+ t_ticker.start()
520
+ thread_ticker.append(t_ticker)
521
+ for x in thread_ticker:
522
+ # Wait for the threads to finish
523
+ x.join()
524
+ # This is a menu for various dashboard windows
525
+ option = st.sidebar.selectbox("Which Dashboard?",
526
+ ("Watchlist","twitter","wallstreetbets","stocktwits","CryptoIndex","Chart","pattern", "MACRO",
527
+ "Technical Scanner", "coinBaskets", "Breakout","ETFs", "Commodities","Report","Recommendations","RORO Components"))
528
+ # If you want to momentarily hide your website from people then remove the below from commenting
529
+ # Or you could do one more thing, setup a pseudo id-password, which log in you to only limited features
530
+ # option = st.sidebar.selectbox("Which Dashboard?",
531
+ # ("twitter","coinBaskets"))
532
+ # Set the option value as header
533
+ st.header(option)
534
+ if option == "Watchlist":
535
+ # If watchlist is selected
536
+ st.subheader("Watchlist")
537
+ col1, col2 = st.columns([1,6.5])
538
+ df_watchlist = pd.read_csv('watchlist.csv')
539
+ with col1:
540
+ # Now, create a form which will help you add symbol name, comments, etc
541
+ with st.form(key = "symbol_add"):
542
+ # df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
543
+ # df = df[df["quoteCurrency"].isin(["USD","USDT"])]
544
+ # symbols = df.name.values
545
+ # asset_class = st.sidebar.selectbox("Asset Class",["Crypto","Fixed Income","Stocks","Index","Commodity"])
546
+ asset_class = st.sidebar.selectbox("Asset Class",["Fixed Income","Stocks","Index","Commodity"])
547
+
548
+ if asset_class == "Crypto":
549
+ symbol = st.selectbox("Symbol",symbols)
550
+ st.write("Currently working for crypto symbols from FTX")
551
+ elif asset_class == "Fixed Income":
552
+ symbol = st.selectbox("Symbol",["HYG","LQD","US 2Y","US 5Y","US 10Y","US 30Y"])
553
+ elif asset_class == "Index":
554
+ symbol = st.selectbox("Symbol",["SPX","NASDAQ","NIFTY50","VIX"])
555
+ st.write("If an alert got triggered, but you want to add another, first delete it, then add")
556
+ trigger = st.text_input("Trigger Price")
557
+ view_type = st.selectbox("View Type",["Above","Below"])
558
+ dma200 = st.selectbox("DMA alert",["Yes", "No"])
559
+ dma200_view_type = st.selectbox("DMA200 View Type",["Above","Below"])
560
+ alert_type = st.selectbox("Alert Type",["Macro","Individual"])
561
+ comments = st.text_area("Comments")
562
+ # Create buttons like add and delete symbols for use
563
+ add_symbol = st.form_submit_button("Add")
564
+ delete_symbol = st.form_submit_button("Remove")
565
+ # Empty watchlist button to clear whole watchlist
566
+ empty_checkbox = st.checkbox("Yes, I wish to empty the watchlist",value = False)
567
+ empty_watchlist = st.form_submit_button("Empty Watchlist")
568
+ with col2:
569
+ # If empty_watchlist button is clicked then, clear the watchlist
570
+ if empty_watchlist and empty_checkbox:
571
+ st.info("Watchlist cleared")
572
+ df_watchlist = pd.DataFrame(columns=["Symbol","Comments"])
573
+ df_watchlist.to_csv('watchlist.csv',index=False)
574
+ elif empty_watchlist:
575
+ st.error("Could not clear the watchlist, please select the checkbox")
576
+ elif add_symbol:
577
+ if symbol not in df_watchlist["Symbol"].values:
578
+ # If symbol is added then add it to csv file, then update the csv file
579
+ st.info("Symbol added")
580
+ df_watchlist = df_watchlist.append(dict(Symbol = symbol, Trigger = float(trigger), alert_type = alert_type, view_type = view_type, status = "Pending",dma200 = dma200, dma200_view_type = dma200_view_type,dma_status = "Pending",Comments = comments), ignore_index=True)
581
+ df_watchlist.to_csv('watchlist.csv',index=False)
582
+ else:
583
+ st.warning("Symbol Already Present, Please check")
584
+ elif delete_symbol:
585
+ if symbol not in df_watchlist["Symbol"].values:
586
+ st.warning("Symbol not present, please check...")
587
+ else:
588
+ # Delte symbol and update the csv file
589
+ st.info("Symbol Deleted")
590
+ df_watchlist = df_watchlist[df_watchlist["Symbol"]!= symbol]
591
+ df_watchlist.to_csv('watchlist.csv',index=False)
592
+ if len(df_watchlist)>0:
593
+ # If there's something in watchlist then for cryptos fetch the LTP from FTX api
594
+ # Getting LTP is currently for Crypto only due to free data unavailability for stocks/ETFs
595
+ df_watchlist.set_index("Symbol",inplace = True)
596
+ df_watchlist["LTP"] = 0
597
+ def get_data_symbol(symbol_name_for_quote):
598
+ global df_watchlist
599
+ try:
600
+ if symbol_name_for_quote in ["HYG","LQD","SPX","NASDAQ","NIFTY50","VIX","US 2Y","US 5Y", "US 10Y","US 30Y"]:
601
+ data_symbol = get_cnbc_data(symbol_name_for_quote)
602
+ else:
603
+ data_symbol = json.loads(requests.get(f"https://ftx.com/api/markets/{symbol_name_for_quote}").text)["result"]["price"]
604
+ df_watchlist.loc[symbol_name_for_quote,"LTP"] = data_symbol
605
+ except:
606
+ pass
607
+ threads_list = []
608
+ for i in range(len(df_watchlist)):
609
+ symbol_name_for_quote = df_watchlist.index[i]
610
+ x = threading.Thread(target = get_data_symbol,args = (symbol_name_for_quote,))
611
+ x.start()
612
+ add_report_ctx(x)
613
+ threads_list.append(x)
614
+ for thread in threads_list:
615
+ thread.join()
616
+ df_watchlist["pct_away"] = np.round(100*np.abs(df_watchlist["Trigger"] - df_watchlist["LTP"])/df_watchlist["LTP"])
617
+ # Show the watchlist
618
+ st.dataframe(df_watchlist)
619
+ elif option == "RORO Components":
620
+ lkbck_perd = st.sidebar.selectbox("Lookback Period",["1Y","5Y"])
621
+ st.sidebar.write("1Y will fetch daily data, 5Y --> weekly")
622
+ st.sidebar.write("Number of lookback periods is set as 300")
623
+ roro_run_btn = st.sidebar.button("Run")
624
+ if roro_run_btn:
625
+ roro_comp_df = pd.DataFrame(get_roro(lkbck_perd))
626
+ roro_comp_df.set_index("date",inplace = True)
627
+ roro_comp_df["roro"] = roro_comp_df.sum(axis = 1)/(len(roro_comp_df.columns))
628
+ fig = make_subplots(rows=len(roro_comp_df.columns), shared_xaxes=True,vertical_spacing=0.01,subplot_titles=(roro_comp_df.columns))
629
+ counter = 1
630
+ for key in roro_comp_df.columns:
631
+ if key!= "roro":
632
+ fig.add_scatter(x = roro_comp_df.index, y = roro_comp_df[key].values,mode = "lines",row = counter, col = 1, name = key)
633
+ else:
634
+ fig.add_scatter(y = roro_comp_df["roro"].values,x = roro_comp_df.index,mode = "lines",fill='tozeroy',row = counter,col =1,name = key)
635
+ counter+=1
636
+ fig['layout'].update(height=2500, width=600, title='Subplots of components')
637
+ st.plotly_chart(fig,use_container_width = True)
638
+ elif option == "Recommendations":
639
+ select_asset = st.sidebar.selectbox("Asset Class",["ETF"])
640
+ rsi_val = st.sidebar.number_input("RSI Thresh",value = 50)
641
+ drop_frm_ath = st.sidebar.number_input("Drop From ATH(%) Thresh",value = 50)
642
+ dist_from_5_yr_low = st.sidebar.number_input(f"%away from 2 yr Low Thresh",value = 20)
643
+ rec_run_btn = st.sidebar.button("Run")
644
+ st.sidebar.write("**Momentum Rising Screening Conditions**")
645
+ st.sidebar.write("LTP>50DMA")
646
+ st.sidebar.write("LTP>100DMA")
647
+ st.sidebar.write("5D Vol>1.5*(5D Vol. yearly_avg")
648
+ st.sidebar.write("**Cheap Stocks Screening Conditions**")
649
+ st.sidebar.write("RSI < RSI Thresh")
650
+ st.sidebar.write("Drop from ATH(%) > Drop from ATH(%) Thresh")
651
+ st.sidebar.write(f"% away from 2 yr Low < %away from 2 yr Low Thresh")
652
+ if rec_run_btn:
653
+ momentum_recommendations = {}
654
+ cheap_recommendations = {}
655
+ rec_threads = []
656
+ if select_asset == "ETF":
657
+ options_for_assets = all_etfs
658
+ for asset in options_for_assets:
659
+ x = threading.Thread(target=get_recommendation,args = (asset,rsi_val,drop_frm_ath,dist_from_5_yr_low,))
660
+ x.start()
661
+ rec_threads.append(x)
662
+ # get_recommendation(asset)
663
+ for rec in rec_threads:
664
+ rec.join()
665
+ # st.write(momentum_recommendations)
666
+ momentum_recommendations = pd.DataFrame(momentum_recommendations).T
667
+
668
+ momentum_recommendations.sort_values("score",ascending=False,inplace = True)
669
+ cheap_recommendations = pd.DataFrame(cheap_recommendations).T
670
+ cheap_recommendations.sort_values("score",ascending=False,inplace = True)
671
+
672
+ st.header("Momentum Rising")
673
+ st.dataframe(momentum_recommendations.style.apply(highlight_rec_momentum,axis = 1).apply(font_color))
674
+ st.header("Cheap Stocks")
675
+ st.dataframe(cheap_recommendations.style.apply(highlight_rec_cheap,args = (rsi_val,drop_frm_ath,dist_from_5_yr_low),axis = 1).apply(font_color))
676
+ elif option == "MACRO":
677
+ select_timeframe = st.sidebar.selectbox("Which Timeframe (finviz only)?",["Daily","Weekly","Monthly"])
678
+ # select_lookback_period = st.sidebar.selectbox("LookbackPeriod for yields(yrs)",[1,2,3,4,5])
679
+ select_lookback_period = st.sidebar.selectbox("LookbackPeriod for yields",["1D","1M","3M","6M","1Y","5Y"])
680
+ timeframe_map = {"Daily":"d1","Weekly":"w1","Monthly":"mo"}
681
+ tf = timeframe_map[select_timeframe]
682
+ run_btn = st.sidebar.button("Run")
683
+ if run_btn:
684
+ col1, col2, col3 = st.columns([1,1,1])
685
+ with col1:
686
+ st.image(f"https://finviz.com/fut_image.ashx?es_{tf}_s.png")
687
+ with col2:
688
+ st.image(f"https://finviz.com/fut_image.ashx?vx_{tf}_s.png")
689
+ with col3:
690
+ st.image(f"https://finviz.com/fut_image.ashx?nq_{tf}_s.png")
691
+ response_yields = {}
692
+ thread_yields = []
693
+ for symbol in ["US1Y","US2Y","US5Y","US10Y","US30Y"]:
694
+ thread = threading.Thread(target = get_data_yields, args = (symbol,select_lookback_period,))
695
+ thread.start()
696
+ thread_yields.append(thread)
697
+ for x in thread_yields:
698
+ x.join()
699
+ df_yields = pd.concat(response_yields,axis = 1)
700
+ df_yields["2y/10y"] = df_yields["US10Y"]-df_yields["US2Y"]
701
+ df_yields["10y/30y"] = df_yields["US30Y"]-df_yields["US10Y"]
702
+
703
+ df_yields["2y/5y"] = df_yields["US5Y"]-df_yields["US2Y"]
704
+ df_yields["1y/2y"] = df_yields["US2Y"]-df_yields["US1Y"]
705
+
706
+
707
+ st.line_chart(df_yields[["US1Y","US2Y","US5Y","US10Y","US30Y"]])
708
+ col1, col2 = st.columns([1,1])
709
+ with col1:
710
+ st.line_chart(df_yields["1y/2y"])
711
+ st.line_chart(df_yields["2y/5y"])
712
+ with col2:
713
+ st.line_chart(df_yields["2y/10y"])
714
+ st.line_chart(df_yields["10y/30y"])
715
+ # today = datetime.now().strftime("%Y-%m-%d")
716
+ # past = (datetime.now() - timedelta(days=365*select_lookback_period)).strftime("%Y-%m-%d")
717
+ # # https://fred.stlouisfed.org/graph/?id=DGS10,DGS5,DGS30,DGS3MO,DGS1,DGS2,
718
+ # url = f"""https://fred.stlouisfed.org/graph/fredgraph.png?dwnld=0&hires=1&type=image/png&
719
+ # bgcolor=%23e1e9f0&chart_type=line&drp=0&fo=open%20sans&graph_bgcolor=%23ffffff&height=450&
720
+ # mode=fred&recession_bars=on&txtcolor=%23444444&ts=12&tts=12&width=1168&nt=0&thu=0&trc=0&
721
+ # show_legend=yes&show_axis_titles=yes&show_tooltip=yes&id=DGS10,DGS5,DGS30,DGS3MO,DGS1,DGS2&
722
+ # scale=left,left,left,left,left,left&cosd={past},{past},{past},{past},{past},{past}&
723
+ # coed={today},{today},{today},{today},{today},{today}&
724
+ # line_color=%234572a7,%23aa4643,%2389a54e,%2380699b,%233d96ae,%23db843d&
725
+ # link_values=false,false,false,false,false,false&line_style=solid,solid,solid,solid,solid,solid&
726
+ # mark_type=none,none,none,none,none,none&mw=3,3,3,3,3,3&lw=2,2,2,2,2,2&
727
+ # ost=-99999,-99999,-99999,-99999,-99999,-99999&oet=99999,99999,99999,99999,99999,99999&
728
+ # mma=0,0,0,0,0,0&fml=a,a,a,a,a,a&fq=Daily,Daily,Daily,Daily,Daily,Daily&
729
+ # fam=avg,avg,avg,avg,avg,avg&fgst=lin,lin,lin,lin,lin,lin&
730
+ # fgsnd=2020-02-01,2020-02-01,2020-02-01,2020-02-01,2020-02-01,2020-02-01&line_index=1,2,3,4,5,6&
731
+ # transformation=lin,lin,lin,lin,lin,lin&
732
+ # vintage_date={today},{today},{today},{today},{today},{today}&
733
+ # revision_date={today},{today},{today},{today},{today},{today}&
734
+ # nd=1962-01-02,1962-01-02,1977-02-15,1981-09-01,1962-01-02,1976-06-01
735
+ # """
736
+ # url = url.replace("\n","")
737
+ # st.image(url,width = 800)
738
+
739
+
740
+ elif option == "twitter":
741
+ # If twitter is selected
742
+ today = datetime.today()
743
+ # Get the local timezone, this is important because then it works on a different timezone
744
+ to_zone = tz.tzlocal()
745
+ # Multibox for selecting multiple users
746
+ who = st.sidebar.multiselect("Choose person",tuple(TWITTER_USERNAMES))
747
+ twitter_run_btn = st.sidebar.button("Run")
748
+ if twitter_run_btn:
749
+ # if twitter run button is clicked then all those people selected are called
750
+ if "SELECT ALL" in who:
751
+ users_list = TWITTER_USERNAMES[1:]
752
+ else:
753
+ users_list = who
754
+
755
+ for username in users_list:
756
+ # For a given username fetch the tweets, its username, image
757
+ user = api.get_user(screen_name = username)
758
+ tweets = api.user_timeline(screen_name = username, count = 100, tweet_mode = "extended")
759
+ st.subheader(username)
760
+ st.image(user.profile_image_url)
761
+ for tweet in tweets:
762
+ # In all his tweets, bring those to local timezone
763
+ tweet_date = ((tweet.created_at).astimezone(to_zone)).replace(tzinfo = None)
764
+ #Now, we don't want tweets older than 3 days
765
+ delta = (today - tweet_date).days
766
+ if delta>3:
767
+ continue
768
+ # For the following user names certain modification is done to get the tweets
769
+ if username in ["@chartmojo","@MacroCharts"]:
770
+ if tweet.in_reply_to_screen_name== None:
771
+ st.subheader(tweet._json["created_at"])
772
+ st.write(tweet.full_text)
773
+ try:
774
+ for j in tweet.extended_entities["media"]:
775
+ st.image(j["media_url_https"], width=600)
776
+ except:
777
+ pass
778
+ else:
779
+ if tweet.in_reply_to_screen_name== None and len(tweet.entities["symbols"])>0:
780
+ symbols = []
781
+ for i in range(len(tweet.entities["symbols"])):
782
+ symbols.append(tweet.entities["symbols"][i]["text"])
783
+ st.subheader(" ".join(symbols))
784
+ st.subheader(tweet._json["created_at"])
785
+ st.subheader(tweet.full_text)
786
+ try:
787
+ for j in tweet.extended_entities["media"]:
788
+ st.image(j["media_url_https"], width = 600)
789
+ except:
790
+ pass
791
+ for symbol in symbols:
792
+ st.image(f"https://finviz.com/chart.ashx?t={symbol}&ta=1", width=600)
793
+ # elif option == "US Sectors":
794
+ # st.sidebar.write("Source - TradingView")
795
+ # select_sector = st.sidebar.selectbox("Select Sector", options = us_sectors)
796
+ # select_btn = st.sidebar.button("Run")
797
+ # url = "https://in.tradingview.com/markets/stocks-usa/sectorandindustry-sector/"
798
+ # r = requests.get(url)
799
+ # soup = BeautifulSoup(r.content, 'html5lib') # If this line causes an error, run 'pip install html5lib' or install html5lib
800
+ # req = soup.find_all('tr',attrs = {'class':'tv-data-table__row tv-data-table__stroke tv-screener-table__result-row'})
801
+ # sectors = []
802
+ # pct_change = []
803
+ # for i in req:
804
+ # arr = []
805
+ # for sector in i.find_all("td"):
806
+ # arr.append(sector.text)
807
+ # arr[0] = arr[0].split("\n")[3].split("\t")[0]
808
+ # sectors.append(arr[0])
809
+ # pct_change.append(float(arr[3][:-1]))
810
+ # fig = go.Figure([go.Bar(x=sectors, y=pct_change,
811
+ # marker = dict(color = ['rgba(63, 195, 128, 1)' if value>0 else 'rgba(219, 10, 91, 1)' for value in pct_change],
812
+ # line = dict(color='rgb(0,0,0)',width=1.5)))])
813
+ # st.plotly_chart(fig,use_container_width=True)
814
+ # if select_btn:
815
+ # val = "-".join(select_sector.lower().split(" "))
816
+ # url = f"https://in.tradingview.com/markets/stocks-usa/sectorandindustry-sector/{val}/"
817
+ # r = requests.get(url)
818
+ # soup = BeautifulSoup(r.content, 'html5lib') # If this line causes an error, run 'pip install html5lib' or install html5lib
819
+ # req = soup.find_all('tr',attrs = {'class':'tv-data-table__row tv-data-table__stroke tv-screener-table__result-row'})
820
+ # ticker = []
821
+ # pct_change_ticker = []
822
+ # company = []
823
+ # for i in req:
824
+ # arr = []
825
+ # for sector in i.find_all("td"):
826
+ # arr.append(sector.text)
827
+ # arr[0] = arr[0].split("\n")[4]
828
+ # # result.append(dict(ticker = arr[0],pct_change = float(arr[2][:-1]),vol = arr[5],mkt_cap = arr[6]))
829
+ # # ticker.append(arr[0])
830
+ # company.append(us_stocks_mapping[arr[0]])
831
+ # pct_change_ticker.append(float(arr[2][:-1]))
832
+ # layout = go.Layout(
833
+ # xaxis = go.XAxis(
834
+ # title = "Stocks",
835
+ # showticklabels = False
836
+ # )
837
+ # )
838
+ # fig = go.Figure([go.Bar(x=company, y=pct_change_ticker,
839
+ # marker = dict(color = ['rgba(63, 195, 128, 1)' if value>0 else 'rgba(219, 10, 91, 1)' for value in pct_change_ticker],
840
+ # line = dict(color='rgb(0,0,0)',width=1.5)))],layout = layout)
841
+ # st.write(len(company))
842
+ # st.plotly_chart(fig,use_container_width=True)
843
+
844
+ # st_autorefresh(interval=120000, limit=10000, key="US sectors refresh")
845
+ elif option == "Commodities":
846
+ select_timeframe = st.sidebar.selectbox("Which Timeframe?",["Daily","Weekly","Monthly"])
847
+ timeframe_map = {"Daily":"d1","Weekly":"w1","Monthly":"mo"}
848
+ tf = timeframe_map[select_timeframe]
849
+ col0,col1,col2 = st.columns([1,1,1])
850
+ count = 0
851
+ for key in commodity_mapping:
852
+ # https://finviz.com/futures_charts.ashx?t=YM&p=d1
853
+ # Get the mapping for commodities, which is there in config.py
854
+ keyword_comm = commodity_mapping[key]
855
+ num = count%3
856
+ if num ==0:
857
+ with col0:
858
+ st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png")
859
+ elif num == 1:
860
+ with col1:
861
+ st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png")
862
+ else:
863
+ with col2:
864
+ st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png")
865
+ count = count+1
866
+ elif option == "CryptoIndex":
867
+ # If cryptoIndex tab is selected
868
+ # Select which crypto index, then timeframe and accordingly fetch the data
869
+ type_index = st.sidebar.selectbox("Which?",["Major","Minor","Shit"])
870
+ select_index_timeframe = st.sidebar.selectbox("Timeframe",["15s","1m","5m","15m","1h","4h","1d"])
871
+ if select_index_timeframe[-1] == "s":
872
+ timeframe = int(select_index_timeframe[:-1])
873
+ elif select_index_timeframe[-1] == "m":
874
+ timeframe = int(select_index_timeframe[:-1]) * 60
875
+ elif select_index_timeframe[-1] == "h":
876
+ timeframe = int(select_index_timeframe[:-1])*60*60
877
+ elif select_index_timeframe[-1] == "d":
878
+ timeframe = int(select_index_timeframe[:-1])* 60*60*24
879
+ if type_index == "Major":
880
+ # Our crypto index is of 0.5BTC + 0.5 ETH
881
+ st.write("0.5BTC + 0.5ETH")
882
+ # Fetch data and create crypto index in same proportion
883
+ data_btc = pd.DataFrame(json.loads(requests.get(f"https://ftx.com/api/markets/BTC/USDT/candles?resolution={timeframe}").text)["result"])
884
+ data_eth = pd.DataFrame(json.loads(requests.get(f"https://ftx.com/api/markets/ETH/USDT/candles?resolution={timeframe}").text)["result"])
885
+ data_btc.set_index("startTime",inplace = True)
886
+ data_eth.set_index("startTime",inplace = True)
887
+ # Note crypto index are normalized
888
+ data = (data_btc["close"]*0.5/data_btc["close"][0] + data_eth["close"]*0.5/data_eth["close"][0])*100
889
+ fig = go.Figure()
890
+ fig.add_trace(go.Scatter(x=data.index, y=data.values,
891
+ mode='lines',
892
+ name=type_index))
893
+ fig.update_xaxes(
894
+ rangeslider_visible=True,
895
+ nticks = 20,
896
+ spikemode = "toaxis",
897
+ rangeselector=dict(
898
+ buttons=list([
899
+ dict(count=1, label="1mon", step="month", stepmode="backward"),
900
+ dict(count=6, label="6mon", step="month", stepmode="backward"),
901
+ dict(count=1, label="YTD", step="year", stepmode="todate"),
902
+ dict(count=1, label="1y", step="year", stepmode="backward"),
903
+ dict(step="all")
904
+ ])
905
+ )
906
+ )
907
+ fig.update_layout(
908
+ xaxis_tickformat = '%Y-%m-%d',
909
+ height = 600,
910
+ width = 900,
911
+ hovermode = "x"
912
+ )
913
+ st.plotly_chart(fig)
914
+
915
+ elif option == "Report":
916
+
917
+ df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
918
+ df = df[df["quoteCurrency"].isin(["USD","USDT"])]
919
+ symbols = df.name.values
920
+
921
+ to_analyze_symbol = st.sidebar.multiselect("Which symbol",symbols)
922
+ analysis_date = st.sidebar.selectbox("Which date for Analysis",["Current","Yesterday"])
923
+ if analysis_date == "Yesterday":
924
+ locn = -2
925
+ elif analysis_date == "Current":
926
+ locn = -1
927
+ fetch_data_btn = st.sidebar.button("Fetch Data")
928
+
929
+ if fetch_data_btn:
930
+ threads = []
931
+ for symbol in symbols:
932
+ t = threading.Thread(target = get_crypto_data_daily, args = (symbol,))
933
+ t.start()
934
+ add_report_ctx(t)
935
+
936
+ threads.append(t)
937
+ for x in threads:
938
+ x.join()
939
+ res = {}
940
+ for req_symbol in to_analyze_symbol:
941
+ req_symbol_file = req_symbol.replace("/","_")
942
+ df_req = pd.read_csv(f"crypto_data/{req_symbol_file}.csv",index_col = 0, parse_dates = True)
943
+ ans = {}
944
+ for period in [20,50,100,200]:
945
+ df_req[f"MA{period}"] = talib.SMA(df_req["close"],period)
946
+ ans[f"% from MA{period}"] = round((df_req["close"].iloc[locn] - df_req[f"MA{period}"].iloc[locn])*100/df_req[f"MA{period}"].iloc[locn],2)
947
+ df_req["RSI14"] = talib.RSI(df_req["close"])
948
+ ans["RSI"] = round(df_req["RSI14"].iloc[locn],2)
949
+ ans["LTP"] = df_req["close"].iloc[-1]
950
+ res[req_symbol] = ans
951
+ result = pd.DataFrame(res).T
952
+ st.dataframe(result)
953
+
954
+ elif option == "Breakout":
955
+ # If breakout tab is selected
956
+ # Get the crypto symbols
957
+ #Create buttons and boxes for selecting timeframe, BB number, KC multiplier
958
+ df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
959
+ df = df[df["quoteCurrency"].isin(["USD","USDT"])]
960
+ symbols = df.name.values
961
+ select_consol_tf = st.sidebar.selectbox("Timeframe",["15s","1m","5m","15m","1h","4h","1d"])
962
+ if select_consol_tf[-1] == "s":
963
+ timeframe = int(select_consol_tf[:-1])
964
+ elif select_consol_tf[-1] == "m":
965
+ timeframe = int(select_consol_tf[:-1]) * 60
966
+ elif select_consol_tf[-1] == "h":
967
+ timeframe = int(select_consol_tf[:-1])*60*60
968
+ elif select_consol_tf[-1] == "d":
969
+ timeframe = int(select_consol_tf[:-1])* 60*60*24
970
+ select_BB_mul = st.sidebar.text_input("Bollinger Band multiplier",value = "2")
971
+ select_KC_mul = st.sidebar.text_input("KC multiplier", value = "1.5")
972
+ select_num_days = st.sidebar.text_input("Consolidating before how many periods?",3)
973
+ num_days = int(select_num_days)
974
+ bb_mul = float(select_BB_mul)
975
+ kc_mul = float(select_KC_mul)
976
+ consol_run_btn = st.sidebar.button("Run")
977
+ if consol_run_btn:
978
+ # If user clicks on run button
979
+ # Again running in threads.
980
+ threads = []
981
+ for symbol in symbols:
982
+ t = threading.Thread(target = in_squeeze, args = (symbol,bb_mul, kc_mul, num_days, True,60*60*24))
983
+ add_report_ctx(t)
984
+ t.start()
985
+ threads.append(t)
986
+ for x in threads:
987
+ x.join()
988
+ st.sidebar.write("Task Complete")
989
+ elif option == "ETFs":
990
+ # If ETFs are selected
991
+ # Button to select ETF
992
+ selectETF = st.sidebar.selectbox("Select ETF class",etf.keys())
993
+ today = datetime.now() - timedelta(days =80)
994
+ st.subheader(selectETF)
995
+ # Note Country ETFs are dealt differently as they have country names as well
996
+ if selectETF!= "Country":
997
+ # If ETF is not Country then its very easy just from ETF variable we can fetch it
998
+ etf_names = etf[selectETF].keys()
999
+ else:
1000
+ # Select Markets, Country
1001
+ selectMarket = st.sidebar.selectbox("Which Market?",etf[selectETF].keys())
1002
+ country_list = list(etf[selectETF][selectMarket].keys())
1003
+ etf_list = list(etf[selectETF][selectMarket].values())
1004
+ etf_names = []
1005
+ country_names = []
1006
+ # In a for loop fetch all the ETFs for selected entries
1007
+ for i in range(len(etf_list)):
1008
+ if type(etf_list[i])==str:
1009
+ etf_names.append(etf_list[i])
1010
+ country_names.append(country_list[i])
1011
+ else:
1012
+ for sub_etf_name in etf_list[i]:
1013
+ etf_names.append(sub_etf_name)
1014
+ country_names.append(country_list[i])
1015
+ select_timeframe = st.sidebar.selectbox("Which Timeframe?",["Daily","Weekly","Monthly"])
1016
+ timeframe_map = {"Daily":"d","Weekly":"w","Monthly":"m"}
1017
+ etf_run_btn = st.sidebar.button("Run")
1018
+ if etf_run_btn:
1019
+ tf = timeframe_map[select_timeframe]
1020
+ # If After giving all the entries, run button is clicked get the charts for all the ETFs
1021
+ count = 0
1022
+ res_etf_ret = []
1023
+ thread_det = []
1024
+ vol_etf_info = {}
1025
+ expense_ratios = {}
1026
+ st.info("Loading..... Please Have Patience")
1027
+ for n in etf_names:
1028
+ thread = threading.Thread(target = get_etf_rets, args = (n,))
1029
+ thread.start()
1030
+ thread_det.append(thread)
1031
+ for x in thread_det:
1032
+ x.join()
1033
+ st.success("Finished Loading")
1034
+
1035
+ etf_rets_df = pd.DataFrame(res_etf_ret)
1036
+ etf_rets_df.set_index("symbol",inplace=True)
1037
+ col1,col2,col3,col4,col5 = st.columns([1,1,1,1,1])
1038
+ with col1:
1039
+ # st.write("")
1040
+ st.markdown("<h5 style='text-align: center; color: red;'>Daily Returns</h5>", unsafe_allow_html=True)
1041
+ st.dataframe(etf_rets_df["day_ret"].sort_values(ascending=False))
1042
+ with col2:
1043
+ st.markdown("<h5 style='text-align: center; color: red;'>1 Week Returns</h5>", unsafe_allow_html=True)
1044
+
1045
+ st.dataframe(etf_rets_df["w1_ret"].sort_values(ascending=False))
1046
+ with col3:
1047
+ st.markdown("<h5 style='text-align: center; color: red;'>2 Week Returns</h5>", unsafe_allow_html=True)
1048
+ st.dataframe(etf_rets_df["w2_ret"].sort_values(ascending=False))
1049
+ with col4:
1050
+ st.markdown("<h5 style='text-align: center; color: red;'>1 Month Returns</h5>", unsafe_allow_html=True)
1051
+ st.dataframe(etf_rets_df["m1_ret"].sort_values(ascending=False))
1052
+ with col5:
1053
+ st.markdown("<h5 style='text-align: center; color: red;'>1 Year Returns</h5>", unsafe_allow_html=True)
1054
+ st.dataframe(etf_rets_df["year_ret"].sort_values(ascending=False))
1055
+
1056
+ st.dataframe(etf_rets_df)
1057
+ cols1,cols2 = st.columns([1,1])
1058
+ if selectETF!= "Country":
1059
+ for etf_name in etf_names:
1060
+ num = count%2
1061
+ if num == 0:
1062
+ with cols1:
1063
+ try:
1064
+ st.write(f"{etf[selectETF][etf_name]}, IV = {vol_etf_info[etf_name]}, ER = {expense_ratios[etf_name]}")
1065
+ except:
1066
+ pass
1067
+ if tf == "d":
1068
+ st.image(f"https://finviz.com/chart.ashx?t={etf_name}&ta=1&p={tf}")
1069
+ else:
1070
+ st.image(f"https://finviz.com/chart.ashx?t={etf_name}&p={tf}")
1071
+ else:
1072
+ with cols2:
1073
+ try:
1074
+ st.write(f"{etf[selectETF][etf_name]}, IV = {vol_etf_info[etf_name]}, ER = {expense_ratios[etf_name]}")
1075
+ except:
1076
+ pass
1077
+ if tf == "d":
1078
+ st.image(f"https://finviz.com/chart.ashx?t={etf_name}&ta=1&p={tf}")
1079
+ else:
1080
+ st.image(f"https://finviz.com/chart.ashx?t={etf_name}&p={tf}")
1081
+ count = count + 1
1082
+ else:
1083
+ for i in range(len(etf_names)):
1084
+ try:
1085
+ st.write(f"{country_names[i]}, IV = {vol_etf_info[etf_names[i]]}, ER = {expense_ratios[etf_names[i]]}")
1086
+ except:
1087
+ pass
1088
+ if tf == "d":
1089
+ st.image(f"https://finviz.com/chart.ashx?t={etf_names[i]}&ta=1&p={tf}")
1090
+ else:
1091
+ st.image(f"https://finviz.com/chart.ashx?t={etf_names[i]}&p={tf}")
1092
+ elif option == "coinBaskets":
1093
+ # If coinBaskets is selected
1094
+ # Note, Mudrex was our reference here
1095
+ baskets = st.sidebar.multiselect(label = "Baskets",options=names, default =names[0])
1096
+ run_basket = st.sidebar.button("Run")
1097
+ select_crypto_timeframe = st.sidebar.selectbox("Crypto Timeframe", options =
1098
+ ["1d","1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","3d","1w","1M"])
1099
+ check_symbol = st.sidebar.text_input("Symbol check")
1100
+ interval = select_crypto_timeframe
1101
+ # Once all the inputs are given, and if any of the basket is chosen
1102
+ if check_symbol != "":
1103
+ for bkt in names:
1104
+ # For each basket selected, get its components, fetch its price from Binance api
1105
+ #Then plot all components in a single chart
1106
+ #Here, you are giving in the symbol name and program is finding whether that symbol is there
1107
+ # in any of the basket or not
1108
+ if check_symbol in eval(bkt)["components"]:
1109
+ fig_check = go.Figure()
1110
+ st.write(bkt.upper())
1111
+ cols = st.columns(len(eval(bkt)["components"]))
1112
+ for i in eval(bkt)["components"]:
1113
+ ticker = f'{i.upper()}USDT'
1114
+ req_params = dict(symbol = ticker, interval = interval)
1115
+ url = "https://api.binance.com/api/v3/klines"
1116
+ data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text))
1117
+ data = data.iloc[:,0:5]
1118
+ data.columns = ['datetime', 'open','high','low', 'close']
1119
+ data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime]
1120
+ data["close"] = data["close"].astype(float)
1121
+ df = (data["close"].pct_change() + 1).cumprod()
1122
+ fig_check.add_trace(go.Scatter(x=df.index, y=df.values,
1123
+ mode='lines',
1124
+ name=i))
1125
+ fig_check.update_xaxes(
1126
+ rangeslider_visible=True,
1127
+ nticks = 20,
1128
+ spikemode = "toaxis",
1129
+ rangeselector=dict(
1130
+ buttons=list([
1131
+ dict(count=1, label="1mon", step="month", stepmode="backward"),
1132
+ dict(count=6, label="6mon", step="month", stepmode="backward"),
1133
+ dict(count=1, label="YTD", step="year", stepmode="todate"),
1134
+ dict(count=1, label="1y", step="year", stepmode="backward"),
1135
+ dict(step="all")
1136
+ ])
1137
+ )
1138
+ )
1139
+ fig_check.update_layout(
1140
+ xaxis_tickformat = '%Y-%m-%d',
1141
+ height = 600,
1142
+ width = 900,
1143
+ hovermode = "x"
1144
+ )
1145
+ fig_check.update_traces(
1146
+ hovertemplate="<br>".join([
1147
+ "Price: %{y}"
1148
+ ]))
1149
+ st.plotly_chart(fig_check)
1150
+ if run_basket:
1151
+ for basket in baskets:
1152
+ # Here, you are choosing the baskets and program is plotting the baskets
1153
+ st.write(basket.upper())
1154
+ st.table(eval(basket))
1155
+ # Create traces
1156
+ fig = go.Figure()
1157
+ for i in eval(basket)["components"]:
1158
+ ticker = f'{i.upper()}USDT'
1159
+ interval = select_crypto_timeframe
1160
+ req_params = dict(symbol = ticker, interval = interval)
1161
+ url = "https://api.binance.com/api/v3/klines"
1162
+ data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text))
1163
+ data = data.iloc[:,0:5]
1164
+ data.columns = ['datetime', 'open','high','low', 'close']
1165
+ data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime]
1166
+ data["close"] = data["close"].astype(float)
1167
+ df = (data["close"].pct_change() + 1).cumprod()
1168
+ fig.add_trace(go.Scatter(x=df.index, y=df.values,
1169
+ mode='lines',
1170
+ name=i))
1171
+ fig.update_xaxes(
1172
+ rangeslider_visible=True,
1173
+ nticks = 20,
1174
+ spikemode = "toaxis",
1175
+ rangeselector=dict(
1176
+ buttons=list([
1177
+ dict(count=1, label="1mon", step="month", stepmode="backward"),
1178
+ dict(count=6, label="6mon", step="month", stepmode="backward"),
1179
+ dict(count=1, label="YTD", step="year", stepmode="todate"),
1180
+ dict(count=1, label="1y", step="year", stepmode="backward"),
1181
+ dict(step="all")
1182
+ ])
1183
+ )
1184
+ )
1185
+ fig.update_layout(
1186
+ xaxis_tickformat = '%Y-%m-%d',
1187
+ height = 600,
1188
+ width = 900,
1189
+ hovermode = "x"
1190
+ )
1191
+ fig.update_traces(
1192
+ hovertemplate="<br>".join([
1193
+ "Price: %{y}"
1194
+ ]))
1195
+ st.plotly_chart(fig)
1196
+ elif option == "Chart":
1197
+ # Charting platform
1198
+ # Get user inputs
1199
+ symbols = st_tags_sidebar(label = "Choose the tickers",
1200
+ text = 'Press enter to add more', maxtags = 100)
1201
+ select_stock_timeframe = st.sidebar.selectbox("Stock Timeframe",options=["1Min", "5Min", "15Min", "day"])
1202
+ select_crypto_timeframe = st.sidebar.selectbox("Crypto Timeframe", options =
1203
+ ["1d","1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","3d","1w","1M"])
1204
+ select_periods = st.sidebar.text_input("Number of Days(Stock)",value = "30")
1205
+ today = datetime.now() - timedelta(int(select_periods))
1206
+ if len(symbols)>0:
1207
+ # If symbols are selected
1208
+ for symbol in symbols:
1209
+ # Run over all symbol in for loop and if they are crypto, treat them differently
1210
+ #And if they are others, treat them differently
1211
+ if f'{symbol.upper()}' in crypto_symbols:
1212
+ # If crypto, get the data from Binance api
1213
+ ticker = f'{symbol.upper()}USDT'
1214
+ interval = select_crypto_timeframe
1215
+ req_params = dict(symbol = ticker, interval = interval)
1216
+ url = "https://api.binance.com/api/v3/klines"
1217
+ st.subheader(ticker)
1218
+ data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text))
1219
+ data = data.iloc[:,0:5]
1220
+ data.columns = ['datetime', 'open','high','low', 'close']
1221
+ data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime]
1222
+ data.drop("datetime",axis = 1, inplace = True)
1223
+ else:
1224
+ # If stocks then get it from trade_api
1225
+ # Remember!!!--> trade_api was initiated in the session_state in the starting of code
1226
+ data = st.session_state.trade_api.get_barset(symbol.upper(), select_stock_timeframe, start =today.strftime("%Y-%m-%d")).df
1227
+ data = data[symbol.upper()]
1228
+ st.subheader(symbol.upper())
1229
+ fig = plot_candlestick(data)
1230
+ st.plotly_chart(fig, use_container_width=False)
1231
+
1232
+ elif option == "stocktwits":
1233
+ # If stocktwits is selected
1234
+ # This is almost similar to Larry's video, so you can reference that as well
1235
+
1236
+ # Display Trending stocks based on watchlist count
1237
+ st.header("Most Trending Symbols")
1238
+ most_trending_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/ts",
1239
+ code = "ts", label = "Trending Score")
1240
+ st.dataframe(most_trending_syms)
1241
+
1242
+ st.header("Most messages in last 24 hrs")
1243
+ most_active_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/m_day",
1244
+ code = "m_day", label = "#messages")
1245
+ st.dataframe(most_active_syms)
1246
+
1247
+ st.header("Top New Watchers added in last 24 hrs")
1248
+ most_active_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/wl_ct_day",
1249
+ code = "wl_ct_day", label = "Count")
1250
+ st.dataframe(most_active_syms)
1251
+
1252
+ # For a given symbol, use request module to hit the stocktwits api and get the required info
1253
+
1254
+
1255
+
1256
+ symbol = st.sidebar.text_input("Symbol", value = "AAPL", max_chars = 5)
1257
+ r = requests.get(f"https://api.stocktwits.com/api/2/streams/symbol/{symbol}.json")
1258
+ data = r.json()
1259
+ for message in data["messages"]:
1260
+ st.image(message["user"]["avatar_url"])
1261
+ st.write(message['user']["username"])
1262
+ st.write(message["created_at"])
1263
+ st.write(message["body"])
1264
+
1265
+ st.sidebar.write("Update time for -->")
1266
+ st.sidebar.write("Top Watchlist Counts : 5mins")
1267
+ st.sidebar.write("Most Messages : 1hr")
1268
+
1269
+ elif option == "Technical Scanner":
1270
+ # If technical scanner is selected
1271
+ # Then choose the pattern, timeframe, etc
1272
+ pattern = st.sidebar.selectbox("Which Pattern?", tuple(patterns.values()))
1273
+ keywords = st_tags_sidebar(label = "Choose the tickers",
1274
+ text = 'Press enter to add more', maxtags = 100)
1275
+ select_timeframe = st.sidebar.selectbox("Timeframe",options=["1Min", "5Min", "15Min", "day"])
1276
+ run_btn = st.sidebar.button("Run")
1277
+ # Get the mapping for patterns from pattern.py file
1278
+ pattern_code = get_key(patterns, pattern)
1279
+ pattern_function = getattr(talib,pattern_code)
1280
+ if run_btn:
1281
+ # If clicked on run button
1282
+ # Then for each symbol, check the output
1283
+ keyword = [x.upper() for x in keywords]
1284
+ data = st.session_state.trade_api.get_barset(keyword, select_timeframe, limit = 100).df
1285
+ for symbol in keyword:
1286
+ try:
1287
+ # st.write(data)
1288
+ result = pattern_function(data[symbol]["open"],data[symbol]["high"],data[symbol]["low"],data[symbol]["close"])
1289
+ last = result.tail(1).values[0]
1290
+ # For some of the indicators value <0 is Bearish and value>0 is Bullish
1291
+ # But for others there would be a different logic, you shall handle it differently
1292
+ if last>0:
1293
+ st.write(f"Bullish {symbol}")
1294
+ elif last<0:
1295
+ st.write(f"Bearish {symbol}")
1296
+ except:
1297
+ pass
coinbaskets.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # These are the list of coin baskets
2
+ names = ["blue_chip","new_crypto_stars","defi_10",
3
+ "smart_contract_pf","web_3","best_exchange","nft","raging_bulls","vc_6"]
4
+ blue_chip = dict(components = ["btc","eth","bnb","ada","xrp"],
5
+ weights = [50, 33.68, 6.32,5,5])
6
+ new_crypto_stars = dict(components = ["doge","dot","uni","bch","link","ltc","sol","matic","theta","vet"],
7
+ weights = [23.39,15.28,11.09,9.08,8.55,8.47,8.2,5.94,5,5])
8
+ defi_10 = dict(components = ["uni","luna","aave","cake","mkr","comp","rune","yfi","snx","sushi"],
9
+ weights = [34.21,12.66,11.04,8.89,7.54,5.66,5,5,5,5])
10
+ smart_contract_pf = dict(components = ["eth","ada","dot","sol","etc","vet","icp"],
11
+ weights =[50,17.28,6.36,11.36,5,5,5])
12
+ web_3 = dict(components = ["link","fil","grt","stx","hnt","sc"],
13
+ weights = [45.38,22.67,13.75,7.74,5.46,5])
14
+ best_exchange = dict(components = ["bnb","ftt","uni","cake","rune","sushi"],
15
+ weights = [25,25,12.5,12.5,12.5,12.5])
16
+ nft = dict(components = ["theta","axs","chz","enj","mana","sand"],
17
+ weights = [16.67,16.67,16.67,16.67,16.66,16.66])
18
+ raging_bulls = dict(components = ["axs","sand","qnt","luna","flow","stx","snx","ankr","ftt","lsk"],
19
+ weights = [10,10,10,10,10,10,10,10,10,2.])
20
+ vc_6 = dict(components = ["dot","luna","near","rose","sol","keep"],
21
+ weights = [16.67,16.67,16.67,16.67,16.66,16.66])
config.py ADDED
@@ -0,0 +1,391 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # These are the tokens for twitter
2
+ TWITTER_CONSUMER_KEY = 'sw0F5LFCMaHtvlMvIiR7pc6WU'
3
+ TWITTER_CONSUMER_SECRET = 'DNb7V3NhPRjQN4GLwmEa4bcAwETmYQ3E9mHovV5sIDBY7G2vAb'
4
+ TWITTER_ACCESS_TOKEN = '1130160902358093825-e8xKgzIqhQG7BnJ1iJg6CES3rMFoKa'
5
+ TWITTER_ACCESS_TOKEN_SECRET = 'HUEG6XKDE7u9ZjUGucTkkzCI8TOl2hRHPCzulQj8XDK3P'
6
+ API_KEY = "PKK8K9OAF1WGCQ9JTK0Z"
7
+ SECRET_KEY = "d1uqIKPKq6iAVsvzYBNwFA4qe5WC2XuIpPFwN745"
8
+ API_URL = "https://paper-api.alpaca.markets/"
9
+ CRYPTO_API_URL = "https://data.alpaca.markets/v1beta1/crypto"
10
+ SLACK_TOKEN = "xoxb-2557354538181-2570404709172-oNr1bsP5hQoFyOL1HqgqF8lv"
11
+ TWITTER_USERNAMES = ["SELECT ALL",
12
+ '@saxena_puru',
13
+ '@chartmojo',
14
+ '@MacroCharts',
15
+ '@hiddensmallcaps',
16
+ '@jonahlupton',
17
+ '@cperruna',
18
+ '@cryptokaleo',
19
+ '@markminervini',
20
+ '@trendspider_j',
21
+ '@100trillionUSD',
22
+ '@fundstrat',
23
+ '@TKPTrader',
24
+ '@sunchartist',
25
+ '@ThePupOfWallSt'
26
+ ]
27
+ # This mapping is required to get live prices from yahoo finance
28
+ symbol_mapping = {"SPX":"%5EGSPC","NASDAQ":"%5ENDX","gold":"GC%3DF","NIFTY50":"%5ENSEI","NIFTYBANK":"%5ENSEBANK",
29
+ "crude oil":"CL%3DF","silver":"SI%3DF","EURUSD":"EURUSD%3DX",
30
+ "HYG":"HYG","LQD":"LQD","VIX":"%5EVIX",
31
+ "US 30Y":"US 30Y","US 10Y":"US 10Y","US 2Y":"US 2Y","US 5Y":"US 5Y"
32
+ }
33
+ us_sectors = ["Commercial Services", "Communications", "Consumer Durables","Consumer Non-Durables",
34
+ "Consumer Services", "Distribution Services", "Electronic Technology","Energy Minerals",
35
+ "Finance","Health Services","Health Technology","Industrial Services","Miscellaneous",
36
+ "Non-Energy Minerals","Process Industries","Producer Manufacturing","Retail Trade",
37
+ "Technology Services","Transportation","Utilities"]
38
+ commodity_mapping = {"Gold":"gc","Silver":"si", "Platinum":"pl","Copper":"hg","Palladium":"pa", "Brent crude oil":"QA"}
39
+
40
+ crypto_symbols = ['YFI',
41
+ 'ETH',
42
+ 'USDC',
43
+ 'EGLD',
44
+ 'XLM',
45
+ 'STPT',
46
+ 'JST',
47
+ 'AAVE',
48
+ 'MBL',
49
+ 'XEM',
50
+ 'DOT',
51
+ 'KLAY',
52
+ 'SUPER',
53
+ 'ALICE',
54
+ 'MATIC',
55
+ 'XMR',
56
+ 'LTCUP',
57
+ 'LTCDOWN',
58
+ 'GXS',
59
+ 'SUSHIUP',
60
+ 'DOGE',
61
+ 'BCHABC',
62
+ 'MANA',
63
+ 'FET',
64
+ 'DASH',
65
+ 'KEY',
66
+ 'WIN',
67
+ 'ETHUP',
68
+ 'COCOS',
69
+ 'HBAR',
70
+ 'FTT',
71
+ 'UNFI',
72
+ 'GHST',
73
+ 'XRPDOWN',
74
+ 'GYEN',
75
+ 'NMR',
76
+ 'SC',
77
+ 'UAH',
78
+ 'UMA',
79
+ 'MASK',
80
+ 'XLMDOWN',
81
+ 'BUSD',
82
+ 'HNT',
83
+ 'VITE',
84
+ 'SYS',
85
+ 'BTC',
86
+ 'RAMP',
87
+ 'SAND',
88
+ 'DEXE',
89
+ 'POND',
90
+ 'LINA',
91
+ 'BRY',
92
+ 'NBS',
93
+ 'GRT',
94
+ 'SUSHIDOWN',
95
+ 'BEAM',
96
+ 'CTXC',
97
+ 'GBP',
98
+ 'BTCST',
99
+ 'XRPUP',
100
+ 'STMX',
101
+ 'DODO',
102
+ 'BAR',
103
+ 'USDS',
104
+ 'AION',
105
+ 'WRX',
106
+ 'SXPDOWN',
107
+ 'BCHDOWN',
108
+ 'BOND',
109
+ 'AGLD',
110
+ 'EOSBEAR',
111
+ 'BKRW',
112
+ 'NGN',
113
+ 'BNBDOWN',
114
+ 'ALGO',
115
+ 'BURGER',
116
+ 'AKRO',
117
+ 'DCR',
118
+ 'ERN',
119
+ 'ENJ',
120
+ 'LUNA',
121
+ 'QTUM',
122
+ 'XEC',
123
+ 'MDX',
124
+ 'BTT',
125
+ 'LINKDOWN',
126
+ 'NEAR',
127
+ 'FIDA',
128
+ 'DOCK',
129
+ 'MITH',
130
+ 'TVK',
131
+ 'FIRO',
132
+ 'ETHBEAR',
133
+ 'TRX',
134
+ 'LINK',
135
+ 'ZEC',
136
+ 'TRXUP',
137
+ 'BNBUP',
138
+ 'NPXS',
139
+ 'DAI',
140
+ 'CVP',
141
+ 'MBOX',
142
+ 'IDEX',
143
+ 'DIA',
144
+ 'STRAT',
145
+ 'ZEN',
146
+ 'CELO',
147
+ 'ALPHA',
148
+ 'BADGER',
149
+ 'TORN',
150
+ 'IOTA',
151
+ 'REEF',
152
+ 'STORJ',
153
+ 'AXS',
154
+ 'RVN',
155
+ '1INCHDOWN',
156
+ 'WAN',
157
+ 'TKO',
158
+ 'USDSB',
159
+ 'BVND',
160
+ 'KSM',
161
+ 'REP',
162
+ 'ZRX',
163
+ 'FILUP',
164
+ 'ILV',
165
+ 'TRXDOWN',
166
+ 'BAND',
167
+ 'BULL',
168
+ 'NANO',
169
+ 'LINKUP',
170
+ 'OGN',
171
+ 'CAKE',
172
+ 'XRPBULL',
173
+ 'DEGO',
174
+ 'PERP',
175
+ 'QNT',
176
+ 'AR',
177
+ 'XVS',
178
+ 'DOTDOWN',
179
+ 'LIT',
180
+ 'STX',
181
+ 'KMD',
182
+ 'MINA',
183
+ 'LTO',
184
+ 'TRY',
185
+ 'BTS',
186
+ 'AVAX',
187
+ 'TRU',
188
+ 'BCH',
189
+ 'DNT',
190
+ 'XRPBEAR',
191
+ 'TWT',
192
+ 'TRIBE',
193
+ 'BZRX',
194
+ 'YFIDOWN',
195
+ 'SXPUP',
196
+ 'BNT',
197
+ 'GALA',
198
+ 'LRC',
199
+ 'UNIUP',
200
+ 'DAI',
201
+ 'SRM',
202
+ 'TOMO',
203
+ 'OM',
204
+ 'TRB',
205
+ 'AUTO',
206
+ 'LEND',
207
+ 'BEAR',
208
+ 'GTC',
209
+ 'WAXP',
210
+ 'PUNDIX',
211
+ 'OCEAN',
212
+ 'SUN',
213
+ 'ARPA',
214
+ 'DATA',
215
+ 'ORN',
216
+ 'CVC',
217
+ 'YFII',
218
+ 'KEEP',
219
+ 'ATOM',
220
+ 'YFIUP',
221
+ 'RUB',
222
+ 'NULS',
223
+ 'PAXG',
224
+ 'NEO',
225
+ 'VIDT',
226
+ 'PNT',
227
+ 'TUSD',
228
+ 'FORTH',
229
+ 'CELR',
230
+ 'PSG',
231
+ 'MFT',
232
+ 'MKR',
233
+ 'ETHBULL',
234
+ 'RSR',
235
+ 'POLS',
236
+ 'FILDOWN',
237
+ 'ASR',
238
+ 'RUNE',
239
+ 'SUSHI',
240
+ 'EOS',
241
+ 'SNX',
242
+ 'GNO',
243
+ 'SUSD',
244
+ 'CTK',
245
+ 'TLM',
246
+ 'ALPACA',
247
+ 'FOR',
248
+ 'RLC',
249
+ 'IOST',
250
+ '1INCH',
251
+ 'KNC',
252
+ 'COTI',
253
+ 'UNIDOWN',
254
+ 'SXP',
255
+ 'ANT',
256
+ 'HIVE',
257
+ 'FLOW',
258
+ 'FUN',
259
+ 'WAVES',
260
+ 'DYDX',
261
+ 'ACM',
262
+ 'BNBBEAR',
263
+ 'CRV',
264
+ 'TFUEL',
265
+ 'STRAX',
266
+ 'SHIB',
267
+ 'WTC',
268
+ 'BLZ',
269
+ 'ICP',
270
+ 'FIS',
271
+ 'XTZ',
272
+ 'ETHDOWN',
273
+ 'ONG',
274
+ 'BCHUP',
275
+ 'ADADOWN',
276
+ 'EOSDOWN',
277
+ 'IDRT',
278
+ 'ERD',
279
+ 'TCT',
280
+ 'HARD',
281
+ 'XVG',
282
+ 'ROSE',
283
+ 'IRIS',
284
+ 'RAY',
285
+ 'YGG',
286
+ 'COMP',
287
+ 'VET',
288
+ 'OMG',
289
+ 'WNXM',
290
+ 'AUDIO',
291
+ 'DUSK',
292
+ 'MIR',
293
+ 'GTO',
294
+ 'NKN',
295
+ 'FIO',
296
+ 'XTZDOWN',
297
+ 'NU',
298
+ 'LSK',
299
+ 'ZAR',
300
+ 'FIL',
301
+ 'OG',
302
+ 'FARM',
303
+ 'ARDR',
304
+ 'WING',
305
+ 'LTC',
306
+ 'HOT',
307
+ 'DGB',
308
+ 'RIF',
309
+ 'CHZ',
310
+ 'BNBBULL',
311
+ 'MTL',
312
+ 'HC',
313
+ 'BRL',
314
+ 'VEN',
315
+ 'JUV',
316
+ 'CHR',
317
+ 'EPS',
318
+ 'ATA',
319
+ 'OXT',
320
+ 'REN',
321
+ 'XRP',
322
+ 'VTHO',
323
+ 'BTCUP',
324
+ 'XZC',
325
+ 'MDT',
326
+ 'THETA',
327
+ 'AAVEUP',
328
+ 'PHA',
329
+ 'COS',
330
+ 'SKL',
331
+ 'DOTUP',
332
+ 'DENT',
333
+ 'SOL',
334
+ 'AAVEDOWN',
335
+ 'CKB',
336
+ 'MLN',
337
+ 'AUD',
338
+ 'BIDR',
339
+ 'ELF',
340
+ 'TROY',
341
+ 'IOTX',
342
+ 'MCO',
343
+ 'UNI',
344
+ 'ANKR',
345
+ 'FTM',
346
+ 'XLMUP',
347
+ 'EUR',
348
+ 'EOSUP',
349
+ 'BEL',
350
+ 'ZIL',
351
+ 'BTG',
352
+ 'KAVA',
353
+ 'SLP',
354
+ 'DREP',
355
+ 'BAKE',
356
+ 'CFX',
357
+ 'ATM',
358
+ 'FLM',
359
+ 'INJ',
360
+ 'CTSI',
361
+ 'STORM',
362
+ '1INCHUP',
363
+ 'FRONT',
364
+ 'DF',
365
+ 'ADAUP',
366
+ 'ONE',
367
+ 'C98',
368
+ 'BCC',
369
+ 'BCHSV',
370
+ 'QUICK',
371
+ 'BAL',
372
+ 'BAT',
373
+ 'POLY',
374
+ 'ETC',
375
+ 'AVA',
376
+ 'EOSBULL',
377
+ 'XTZUP',
378
+ 'USDP',
379
+ 'UTK',
380
+ 'PAX',
381
+ 'PERL',
382
+ 'ADA',
383
+ 'BKRW',
384
+ 'ONT',
385
+ 'SFP',
386
+ 'BNB',
387
+ 'LPT',
388
+ 'ICX',
389
+ 'CLV',
390
+ 'REQ',
391
+ 'BTCDOWN']
googleNewsSlackAlerts.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from GoogleNews import GoogleNews
2
+ import pandas as pd
3
+ import numpy as np
4
+ import slack
5
+ import time
6
+ from datetime import datetime
7
+
8
+ # Slack token
9
+ SLACK_TOKEN = "xoxb-2557354538181-2570404709172-oNr1bsP5hQoFyOL1HqgqF8lv"
10
+ # Initialize the slack client
11
+ client = slack.WebClient(token = SLACK_TOKEN)
12
+ # Google News Api
13
+ googlenews = GoogleNews()
14
+ googlenews = GoogleNews(lang='en', region='US')
15
+ googlenews = GoogleNews(period='1h')
16
+
17
+ googlenews.set_encode('utf-8')
18
+
19
+ arr = []
20
+ while True:
21
+ # Run this in for loop and is to be run continously
22
+ today = datetime.now()
23
+ # If its midnight reset the array
24
+ if today.hour + today.minute == 0 and today.second<2:
25
+ arr = []
26
+ # Search for the word crypto in googlenews
27
+ googlenews.search("crypto")
28
+ # Sort the results
29
+ result = googlenews.results(sort=True)
30
+ for i in result:
31
+ # Now if a news has already been scraped, ignore it
32
+ if i["title"] in arr:
33
+ continue
34
+ if "min" in i["date"]:
35
+ # If the time for the news is in minute then only fetch it
36
+ if "$" in i["desc"] or "$" in i["title"]:
37
+ # If the title or decription contains dollar symbol, then go ahead
38
+ if "million" in i["desc"].lower() or "raised" in i["desc"].lower():
39
+ # If million or raised keywords are present then go ahead
40
+ arr.append(i["title"])
41
+ # Post the news on slack bot
42
+ client.chat_postMessage(channel = "#bot_alerts",
43
+ text = f'{i["datetime"]} {i["date"]} {i["title"]} {i["link"]} {i["desc"]}')
44
+ # Clear the google news
45
+ googlenews.clear()
46
+ # Wait for 30seconds for next query
47
+ time.sleep(30)
mapping.py ADDED
The diff for this file is too large to render. See raw diff
 
notifier.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import threading
2
+ from config import *
3
+ import requests
4
+ import slack
5
+ import json
6
+ from datetime import datetime
7
+ import time
8
+ arr = []
9
+ def symbol_info(req_params, i):
10
+ global arr
11
+ url = "https://api.binance.com/api/v3/ticker/24hr"
12
+ val = requests.get(url,params = req_params)
13
+ try:
14
+ data = json.loads(val.text)
15
+
16
+ x = arr[i]
17
+ try:
18
+ if float(data["priceChangePercent"])>=x:
19
+ client = slack.WebClient(token = SLACK_TOKEN)
20
+ client.chat_postMessage(channel = "#bot_alerts",
21
+ text = f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} {data['symbol']} 24Hchange={float(data['priceChangePercent'])}% new benchmark {x+5}%")
22
+ arr[i] = arr[i] + 5
23
+ except:
24
+ pass
25
+ except:
26
+ print("Could not connect")
27
+
28
+ for i in range(len(crypto_symbols)):
29
+ arr.append(20)
30
+
31
+ while True:
32
+ for i in range(len(crypto_symbols)):
33
+ today = datetime.now()
34
+ if today.hour + today.minute + today.second == 0:
35
+ for i in range(len(crypto_symbols)):
36
+ arr[i] = 20
37
+ req_params = dict(symbol = crypto_symbols[i] + "USDT")
38
+ thread = threading.Thread(target = symbol_info, args = (req_params,i,))
39
+ thread.start()
40
+ time.sleep(15)
patterns.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Candlestick patterns mapping
2
+ patterns = {
3
+ 'CDL2CROWS':'Two Crows',
4
+ 'CDL3BLACKCROWS':'Three Black Crows',
5
+ 'CDL3INSIDE':'Three Inside Up/Down',
6
+ 'CDL3LINESTRIKE':'Three-Line Strike',
7
+ 'CDL3OUTSIDE':'Three Outside Up/Down',
8
+ 'CDL3STARSINSOUTH':'Three Stars In The South',
9
+ 'CDL3WHITESOLDIERS':'Three Advancing White Soldiers',
10
+ 'CDLABANDONEDBABY':'Abandoned Baby',
11
+ 'CDLADVANCEBLOCK':'Advance Block',
12
+ 'CDLBELTHOLD':'Belt-hold',
13
+ 'CDLBREAKAWAY':'Breakaway',
14
+ 'CDLCLOSINGMARUBOZU':'Closing Marubozu',
15
+ 'CDLCONCEALBABYSWALL':'Concealing Baby Swallow',
16
+ 'CDLCOUNTERATTACK':'Counterattack',
17
+ 'CDLDARKCLOUDCOVER':'Dark Cloud Cover',
18
+ 'CDLDOJI':'Doji',
19
+ 'CDLDOJISTAR':'Doji Star',
20
+ 'CDLDRAGONFLYDOJI':'Dragonfly Doji',
21
+ 'CDLENGULFING':'Engulfing Pattern',
22
+ 'CDLEVENINGDOJISTAR':'Evening Doji Star',
23
+ 'CDLEVENINGSTAR':'Evening Star',
24
+ 'CDLGAPSIDESIDEWHITE':'Up/Down-gap side-by-side white lines',
25
+ 'CDLGRAVESTONEDOJI':'Gravestone Doji',
26
+ 'CDLHAMMER':'Hammer',
27
+ 'CDLHANGINGMAN':'Hanging Man',
28
+ 'CDLHARAMI':'Harami Pattern',
29
+ 'CDLHARAMICROSS':'Harami Cross Pattern',
30
+ 'CDLHIGHWAVE':'High-Wave Candle',
31
+ 'CDLHIKKAKE':'Hikkake Pattern',
32
+ 'CDLHIKKAKEMOD':'Modified Hikkake Pattern',
33
+ 'CDLHOMINGPIGEON':'Homing Pigeon',
34
+ 'CDLIDENTICAL3CROWS':'Identical Three Crows',
35
+ 'CDLINNECK':'In-Neck Pattern',
36
+ 'CDLINVERTEDHAMMER':'Inverted Hammer',
37
+ 'CDLKICKING':'Kicking',
38
+ 'CDLKICKINGBYLENGTH':'Kicking - bull/bear determined by the longer marubozu',
39
+ 'CDLLADDERBOTTOM':'Ladder Bottom',
40
+ 'CDLLONGLEGGEDDOJI':'Long Legged Doji',
41
+ 'CDLLONGLINE':'Long Line Candle',
42
+ 'CDLMARUBOZU':'Marubozu',
43
+ 'CDLMATCHINGLOW':'Matching Low',
44
+ 'CDLMATHOLD':'Mat Hold',
45
+ 'CDLMORNINGDOJISTAR':'Morning Doji Star',
46
+ 'CDLMORNINGSTAR':'Morning Star',
47
+ 'CDLONNECK':'On-Neck Pattern',
48
+ 'CDLPIERCING':'Piercing Pattern',
49
+ 'CDLRICKSHAWMAN':'Rickshaw Man',
50
+ 'CDLRISEFALL3METHODS':'Rising/Falling Three Methods',
51
+ 'CDLSEPARATINGLINES':'Separating Lines',
52
+ 'CDLSHOOTINGSTAR':'Shooting Star',
53
+ 'CDLSHORTLINE':'Short Line Candle',
54
+ 'CDLSPINNINGTOP':'Spinning Top',
55
+ 'CDLSTALLEDPATTERN':'Stalled Pattern',
56
+ 'CDLSTICKSANDWICH':'Stick Sandwich',
57
+ 'CDLTAKURI':'Takuri (Dragonfly Doji with very long lower shadow)',
58
+ 'CDLTASUKIGAP':'Tasuki Gap',
59
+ 'CDLTHRUSTING':'Thrusting Pattern',
60
+ 'CDLTRISTAR':'Tristar Pattern',
61
+ 'CDLUNIQUE3RIVER':'Unique 3 River',
62
+ 'CDLUPSIDEGAP2CROWS':'Upside Gap Two Crows',
63
+ 'CDLXSIDEGAP3METHODS':'Upside/Downside Gap Three Methods'
64
+ }
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ streamlit_tags==1.2.8
2
+ alpaca_trade_api==1.4.0
3
+ matplotlib==3.5.1
4
+ requests==2.24.0
5
+ numpy==1.21.5
6
+ tweepy==4.0.1
7
+ pandas==1.4.0
8
+ streamlit
9
+ plotly==5.5.0
10
+ beautifulsoup4==4.11.1
11
+ GoogleNews==1.6.4
12
+ python_dateutil==2.8.2
13
+ slackclient==2.9.4
setup.sh ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ mkdir -p ~/.streamlit/
2
+
3
+ echo "\
4
+ [general]\n\
5
+ email = \"your-email@domain.com\"\n\
6
+ " > ~/.streamlit/credentials.toml
7
+
8
+ echo "\
9
+ [server]\n\
10
+ headless = true\n\
11
+ enableCORS=false\n\
12
+ port = $PORT\n\
13
+ " > ~/.streamlit/config.toml
tempCodeRunnerFile.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # client.chat_postMessage(channel = f"#{df.loc[symbol]['alert_type'].lower()}_signal",
2
+
watchlist.csv ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Symbol,Comments,Trigger,alert_type,dma200,dma200_view_type,dma_status,status,view_type
2
+ US 2Y,,0.5,Macro,Yes,Above,Triggered,Pending,Below