Chaitanya01's picture
Upload 16 files
919ec8d
raw
history blame
69.7 kB
import requests
import json
from requests.api import delete, options
import streamlit as st
import time
import tweepy
import requests
from io import BytesIO
import base64
import matplotlib.pyplot as plt
import numpy as np
from plotly.subplots import make_subplots
from config import *
from dateutil.relativedelta import relativedelta
from patterns import patterns
# import talibsddsfs
from datetime import datetime, timedelta, tzinfo
from alpaca_trade_api.rest import REST
from streamlit_tags import st_tags_sidebar
# from streamlit_autorefresh import st_autorefresh
# import plotly.express as px
from coinbaskets import *
import plotly.graph_objects as go
from mapping import *
import pandas as pd
import threading
from bs4 import BeautifulSoup
from ETFs import *
from dateutil import tz
import os
# try:
# from streamlit.ReportThread import add_report_ctx
# except Exception:
# # Streamlit >= 0.65.0
# from streamlit.report_thread import add_report_ctx
# # from streamlit.scriptrunner import add_script_run_ctx
from streamlit.scriptrunner import add_script_run_ctx as add_report_ctx
def get_stocktwits_data(req,code,label):
r = requests.get(req)
trending_syms = pd.DataFrame(r.json()["stocks"]).T
trending_syms.index.name = "stock_id"
trending_syms.index = trending_syms.index.astype("int")
trending_score = pd.DataFrame(r.json()["table"][code])
trending_score.set_index("stock_id",inplace = True)
most_trending_syms = pd.merge(trending_syms,trending_score,on= "stock_id")
most_trending_syms.sort_values("val",ascending = False, inplace = True)
most_trending_syms.set_index("symbol",inplace = True)
most_trending_syms.columns = ["Name","Price","%Change",label]
return most_trending_syms
def get_cnbc_data(symbol):
ticker = symbol.replace(" ","")
if ticker == "NASDAQ":
ticker = "NDX"
elif ticker == "NIFTY50":
ticker = ".NSEI"
# Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
# df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={ticker}").json()["barData"]["priceBars"])
df_1D = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1D.json?symbol={ticker}").json()["barData"]["priceBars"])
# df["datetime"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
# df["close"] = df["close"].astype(float)
df_1D["close"] = df_1D["close"].astype(float)
# df.set_index("datetime",inplace = True)
# dma200 = df["close"].rolling(200).mean()
close = (df_1D["close"].iloc[-1])
return close
def vix_gradient(vix):
"""
Mapping is done as follows rsi<=20 --> -100, rsi>=80, 100, and then linear variation
"""
if vix<20:
return 100
elif vix<30:
return (-20*vix+500)
else:
return -100
def roro_comp_get(series,i,state, inverse = False):
current = series.iloc[-i]
current_idx = series.index[-i]
w_1_ago = current_idx - relativedelta(days=7)
w_2_ago = current_idx - relativedelta(days=14)
m_1_ago = current_idx - relativedelta(months=1)
if state == 0:
w_1_ret = (current - series.loc[w_1_ago:].iloc[0])*100/series.loc[w_1_ago:].iloc[0]
w_2_ret = (current - series.loc[w_2_ago:].iloc[0])*100/series.loc[w_2_ago:].iloc[0]
m_1_ret = (current - series.loc[m_1_ago:].iloc[0])*100/series.loc[m_1_ago:].iloc[0]
else:
w_1_ret = (current - series.iloc[-1-i])*100/series.iloc[-1-i]
w_2_ret = (current - series.iloc[-2-i])*100/series.iloc[-2-i]
m_1_ret = (current - series.iloc[-4-i])*100/series.iloc[-4-i]
sign_of = 1
if inverse == True:
sign_of = -1
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
return val
def get_roro(tf = "1Y"):
df_spx = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=.SPX").json()["barData"]["priceBars"])
df_spx["datetime"] = pd.to_datetime(df_spx['tradeTimeinMills'],unit='ms').dt.date
df_spx.set_index("datetime",inplace = True)
df_spx["close"] = df_spx["close"].astype(float)
df_vix = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=.VIX").json()["barData"]["priceBars"])
df_vix["close"] = df_vix["close"].astype(float)
df_AUDJPY = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=AUDJPY=").json()["barData"]["priceBars"])
df_AUDJPY["datetime"] = pd.to_datetime(df_AUDJPY['tradeTimeinMills'],unit='ms').dt.date
df_AUDJPY.set_index("datetime",inplace = True)
df_AUDJPY["close"] = df_AUDJPY["close"].astype(float)
df_gold = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=@GC.1").json()["barData"]["priceBars"])
df_gold["datetime"] = pd.to_datetime(df_gold['tradeTimeinMills'],unit='ms').dt.date
df_gold.set_index("datetime",inplace = True)
df_gold["close"] = df_gold["close"].astype(float)
df_silver = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=@SI.1").json()["barData"]["priceBars"])
df_silver["datetime"] = pd.to_datetime(df_silver['tradeTimeinMills'],unit='ms').dt.date
df_silver.set_index("datetime",inplace = True)
df_silver["close"] = df_silver["close"].astype(float)
gold_silver_ratio = df_gold["close"]/df_silver["close"]
df_bnd = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=BND").json()["barData"]["priceBars"])
df_bnd["datetime"] = pd.to_datetime(df_bnd['tradeTimeinMills'],unit='ms').dt.date
df_bnd.set_index("datetime",inplace = True)
df_bnd["close"] = df_bnd["close"].astype(float)
df_sphb = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SPHB").json()["barData"]["priceBars"])
df_sphb["datetime"] = pd.to_datetime(df_sphb['tradeTimeinMills'],unit='ms').dt.date
df_sphb.set_index("datetime",inplace = True)
df_sphb["close"] = df_sphb["close"].astype(float)
df_splv = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SPLV").json()["barData"]["priceBars"])
df_splv["datetime"] = pd.to_datetime(df_splv['tradeTimeinMills'],unit='ms').dt.date
df_splv.set_index("datetime",inplace = True)
df_splv["close"] = df_splv["close"].astype(float)
sphb_splv_ratio = df_sphb["close"]/df_splv["close"]
df_HYG = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=HYG").json()["barData"]["priceBars"])
df_HYG["datetime"] = pd.to_datetime(df_HYG['tradeTimeinMills'],unit='ms').dt.date
df_HYG.set_index("datetime",inplace = True)
df_HYG["close"] = df_HYG["close"].astype(float)
df_fnda = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=FNDA").json()["barData"]["priceBars"])
df_fnda["datetime"] = pd.to_datetime(df_fnda['tradeTimeinMills'],unit='ms').dt.date
df_fnda.set_index("datetime",inplace = True)
df_fnda["close"] = df_fnda["close"].astype(float)
df_schx = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=SCHX").json()["barData"]["priceBars"])
df_schx["datetime"] = pd.to_datetime(df_schx['tradeTimeinMills'],unit='ms').dt.date
df_schx.set_index("datetime",inplace = True)
df_schx["close"] = df_schx["close"].astype(float)
fnda_schx_ratio = df_fnda["close"]/df_schx["close"]
df_btc_usd = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{tf}.json?symbol=BTC.CB=").json()["barData"]["priceBars"])
df_btc_usd["datetime"] = pd.to_datetime(df_btc_usd['tradeTimeinMills'],unit='ms').dt.date
df_btc_usd.set_index("datetime",inplace = True)
df_btc_usd["close"] = df_btc_usd["close"].astype(float)
periods = 300
roro = []
if tf == "5Y":
state = 1
else:
state = 0
for i in range(periods,0,-1):
temp = dict(
date = (pd.to_datetime(df_spx.index).date)[-i],
spx = roro_comp_get(df_spx["close"],i,state),
audjpy = roro_comp_get(df_AUDJPY["close"],i,state),
gold_silver = roro_comp_get(gold_silver_ratio,i,state,inverse = True),
bnd = roro_comp_get(df_bnd["close"],i,state,inverse = True),
sphb_splv = roro_comp_get(sphb_splv_ratio,i,state),
hyg = roro_comp_get(df_HYG["close"],i,state),
fnda_schx = roro_comp_get(fnda_schx_ratio,i,state),
vix = vix_gradient(df_vix["close"].iloc[-i]),
btc_usd = roro_comp_get(df_btc_usd["close"],i,state)
)
roro.append(temp)
return roro
# Setting the page layout as wide
st.set_page_config(layout="wide")
def get_data_yields(symbol,lookback_period):
global response_yields
df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/{lookback_period}.json?symbol={symbol}").json()["barData"]["priceBars"])
df["datetime"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
df.set_index("datetime",inplace = True)
response_yields[symbol] = df["close"].astype(float)
def get_recommendation(symbol,rsi_val,drop_frm_ath,dist_from_5_yr_low):
global momentum_recommendations,cheap_recommendations
df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={symbol}").json()["barData"]["priceBars"])
df_all = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/ALL.json?symbol={symbol}").json()["barData"]["priceBars"])
df_all["high"] = df_all["high"].astype(float)
df_all["low"] = df_all["low"].astype(float)
df["tradeTimeinMills"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
df_all["tradeTimeinMills"] = pd.to_datetime(df_all['tradeTimeinMills'],unit='ms')
df["close"] = df["close"].astype(float)
df["open"] = df["open"].astype(float)
df.set_index("tradeTimeinMills",inplace = True)
df_all.set_index("tradeTimeinMills",inplace = True)
current_close = df["close"].iloc[-1]
df["50DMA"] = df["close"].rolling(50).mean()
df["100DMA"] = df["close"].rolling(100).mean()
df["Vol_mon_avg"] = 5*df["volume"].rolling(252).mean()
df["RSI"] = talib.RSI(df["close"])
cond1 = current_close>df["50DMA"].iloc[-1]
cond2 = current_close>df["100DMA"].iloc[-1]
cond3 = df["volume"].rolling(5).sum().iloc[-1]>1.5*df["Vol_mon_avg"].iloc[-1]
mom_score = int(cond1)+int(cond2)+int(cond3)
ath = df_all["high"].max()
distance_from_ath = round((ath-current_close)*100/ath,2)
yr_2_ago_dt = datetime.now() - relativedelta(years=2)
yr_2_low = df_all["low"].loc[yr_2_ago_dt:].min()
distance_frm_2yr_low = round((current_close - yr_2_low)*100/current_close,2)
rsi = round(df["RSI"].iloc[-1],2)
cond_1 = rsi<rsi_val
cond_2 = distance_from_ath>=drop_frm_ath
cond_3 = distance_frm_2yr_low<=dist_from_5_yr_low
cheap_score = int(cond_1)+int(cond_2)+int(cond_3)
if (cond1 or cond2) or cond3:
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"])}
if cond_1 or cond_2 or cond_3:
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"])}
def sparkline(data, figsize=(4,0.25),**kwags):
data = list(data)
fig,ax = plt.subplots(1,1,figsize=figsize,**kwags)
ax.plot(data)
for k,v in ax.spines.items():
v.set_visible(False)
ax.set_xticks([])
ax.set_yticks([])
plt.plot(len(data)-1, data[len(data)-1], 'r.')
ax.fill_between(range(len(data)), data, len(data)*[min(data)], alpha=0.1)
img = BytesIO()
plt.savefig(img, transparent=True, bbox_inches='tight')
img.seek(0)
# plt.show()
plt.close()
# return base64.b64encode(img.read()).decode("utf-8")
return '<img src="data:image/png;base64,{}"/>'.format(base64.b64encode(img.read()))
def highlight_rec_momentum(s):
arr = []
arr.append('background-color: white')
if s["50DMA"]<s["LTP"]:
arr.append('background-color: #90EE90')
else:
arr.append('background-color: #FF7F7F')
if s["100DMA"]<s["LTP"]:
arr.append('background-color: #90EE90')
else:
arr.append('background-color: #FF7F7F')
if s["Vol>1.5avg"]:
arr.append('background-color: #90EE90')
else:
arr.append('background-color: #FF7F7F')
arr.append('background-color: white')
arr.append('background-color: white')
return arr
def font_color(s):
return ["color: black"]*len(s)
def highlight_rec_cheap(s,rsi_val,drop_frm_ath,dist_from_5_yr_low):
arr = []
arr.append('background-color: white')
if s["RSI"]<rsi_val:
arr.append('background-color: #90EE90')
else:
arr.append('background-color: #FF7F7F')
if s[f"drop frm ATH"]>drop_frm_ath:
arr.append('background-color: #90EE90')
else:
arr.append('background-color: #FF7F7F')
if s[f"% away 2 yr low"]<dist_from_5_yr_low:
arr.append('background-color: #90EE90')
else:
arr.append('background-color: #FF7F7F')
arr.append('background-color: white')
arr.append('background-color: white')
return arr
def get_etf_rets(symbol):
global res_etf_ret, vol_etf_info,expense_ratios
df = pd.DataFrame(requests.get(f"https://ts-api.cnbc.com/harmony/app/charts/1Y.json?symbol={symbol}").json()["barData"]["priceBars"])
df["tradeTimeinMills"] = pd.to_datetime(df['tradeTimeinMills'],unit='ms')
df["close"] = df["close"].astype(float)
df["open"] = df["open"].astype(float)
df.set_index("tradeTimeinMills",inplace = True)
df_new = df.resample("W-Sun").agg({"close":"last","open":"first"})
price_1_yr_ago = df.loc[df_new.index[-1] - relativedelta(years = 1):].iloc[0]["open"]
price_1_mon_ago = df.loc[df.index[-1] - relativedelta(months=1):].iloc[0]["open"]
close = df.iloc[-1]["close"]
daily_ret = (close - df.iloc[-1]["open"].astype(float))*100/df.iloc[-1]["open"]
w_1_ret = round((close - df_new.iloc[-1]["open"])*100/df_new.iloc[-1]["open"],2)
w_2_ret = round((close - df_new.iloc[-2]["open"])*100/df_new.iloc[-2]["open"],2)
y_1_ret = round((close - price_1_yr_ago)*100/price_1_yr_ago,2)
m_1_ret = round((close - price_1_mon_ago)*100/price_1_mon_ago,2)
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)
res_etf_ret.append(temp)
iv = (df["close"].pct_change()*100).iloc[-30:].std()*np.sqrt(252)
vol_etf_info[symbol] = round(iv,2)
r = requests.get(f"https://etfdb.com/etf/{symbol}/#etf-ticker-profile")
soup = BeautifulSoup(r.content, 'html5lib')
expense_ratio = soup.find("div",{"class":"ticker-assets"}).find_all("div")[3].text.split("\n")[-2]
expense_ratios[symbol] = expense_ratio
return
def get_data(ticker, timeframe = 60*60 * 4):
# Function to get OHLC data for a symbol from FTX api
data = pd.DataFrame(json.loads(requests.get(f"https://ftx.com/api/markets/{ticker}/candles?resolution={timeframe}").text)["result"])
return data
def in_squeeze(symbol,bb_mul, kc_mul,num_days,plot = False, timeframe = 60*60*4):
# Function to check whether Keltner Channel and Bollinger bands squeeze is happening
# Get Data
data = get_data(symbol,timeframe)
# Calculate BB
data["20sma"] = data["close"].rolling(window = 20).mean()
data["stddev"] = data["close"].rolling(window = 20).std()
data["lowerband"] = data["20sma"] - bb_mul*data["stddev"]
data["upperband"] = data["20sma"] + bb_mul*data["stddev"]
# Calculate KC
data["TR"] = data["high"] - data["low"]
data["ATR"] = data["TR"].rolling(window = 20).mean()
data['upperKC'] = data["20sma"] + kc_mul*data["ATR"]
data['lowerKC'] = data["20sma"] - kc_mul*data["ATR"]
data["squeeze_on"] = np.where(
np.logical_and(data["lowerband"]>data["lowerKC"], data["upperband"]<data["upperKC"]),1,0)
# Now if "num_days" days earlier BB were in KC but now, its not then that's breakout
if data.iloc[-num_days]["squeeze_on"] and not data.iloc[-1]["squeeze_on"]:
# If user wants to plot the candlestick then pass the plot = True
if plot == True:
# Template for plotting KC and BB and candlesticks
candlestick = go.Candlestick(x=data["startTime"],open=data["open"],high=data["high"],low=data["low"],close=data["close"], name = symbol)
upperband = go.Scatter(x = data["startTime"], y = data["upperband"], name = "Upper BB", line = dict(color = "blue"))
lowerband = go.Scatter(x = data["startTime"], y = data["lowerband"], name = "Lower BB", line = dict(color = "blue"))
upperKC = go.Scatter(x = data["startTime"], y = data["upperKC"], name = "Upper KC", line = dict(color = "green"))
lowerKC = go.Scatter(x = data["startTime"], y = data["lowerKC"], name = "Upper KC", line = dict(color = "green"))
fig = go.Figure(data = [candlestick,upperband, lowerband, upperKC, lowerKC])
# Slider in Xaxes for 1month, 6month, YTD and 1Y
fig.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="1mon", step="month", stepmode="backward"),
dict(count=6, label="6mon", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(step="all")
])
))
fig.update_layout(yaxis=dict(autorange = True,fixedrange= False))
st.plotly_chart(fig,use_container_width=True)
else:
print(f"{symbol}")
def plot_candlestick(data):
# Function to plot candlestick out of a given OHLC dataframe
fig = go.Figure(data=[go.Candlestick(x=data.index,
open=data['open'],
high=data['high'],
low=data['low'],
close=data['close'])])
fig.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="1mon", step="month", stepmode="backward"),
dict(count=6, label="6mon", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(step="all")
])
))
return fig
def get_key(dict_given, val):
# Function to get the key of the required value from a dictionary
for key, value in dict_given.items():
if val == value:
return key
def get_crypto_data_daily(symbol):
data = get_data(symbol,timeframe = 60*60*24)
data.to_csv(f"crypto_data/{symbol.replace('/','_')}.csv")
def get_cnbc_yields(symbol):
# Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
URL = f"https://www.cnbc.com/quotes/US5Y"
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'}
page = requests.get(URL, headers = headers)
soup = BeautifulSoup(page.text, "html.parser")
yields = ["US 2Y","US 5Y", "US 10Y","US 30Y"]
if symbol in yields:
elements = soup.find('div',{'class':'QuoteStrip-lastPriceStripContainer'})
price = elements.find_all('span')[0].text.replace("%","")
return float(price.replace(",",""))
def get_yahoo_finance_quote(symbol):
# Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
URL = f"https://finance.yahoo.com/quote/{symbol}"
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'}
page = requests.get(URL, headers = headers)
soup = BeautifulSoup(page.text, "html.parser")
price = soup.find('div',{'class':'D(ib) Mend(20px)'}).find_all('fin-streamer')[0].text
return price.replace(",","")
def get_symbol_quote(ticker_tape, symbol,tck_tape, idx):
# Get the symbol quote from yahoo finance, we are using Beautiful Soup for scraping
URL = f"https://finance.yahoo.com/quote/{symbol}"
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'}
page = requests.get(URL, headers = headers)
soup = BeautifulSoup(page.text, "html.parser")
price = soup.find('div',{'class':'D(ib) Mend(20px)'}).find_all('span')[0].text
change = soup.find('div',{'class':'D(ib) Mend(20px)'}).find_all('span')[1].text
change = change.split(" ")[1]
change = change[1:-1]
if ticker_tape == "US 10Y":
# US 10Y treated differently because of some formating purposes
change = float(change.replace("(","").replace(")","").replace("%",""))
price_now = float(price)
change = round(price_now - price_now/(1+change/100),2)
change = str(change) + "%"
tck_tape[idx].metric(label = ticker_tape ,value = price,delta = change)
# Set the twitter client and set the access token which comes from config.py
auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET)
auth.set_access_token(TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET)
api = tweepy.API(auth)
if "trade_api" not in st.session_state:
# Now, if this api is not there in session_state then add it,
# we are doing this because we don't want to let the info go once site is refreshed
# And session_state is kind of memory used for caching required info
# Set the trade_api variable
st.session_state.trade_api = REST(API_KEY, SECRET_KEY, API_URL)
if "stocks" not in st.session_state:
# If stocks are not present then from companies.csv file add them
with open('datasets/companies.csv') as f:
companies = f.read().splitlines()
symbols = []
for company in companies:
symbols.append(company.split(",")[0])
st.session_state.stocks = symbols
if "login" not in st.session_state:
# If user has not logged in set login = False
# This is done because once logged in we want the program to remember that it logged in
# Hence setting the session_state
st.session_state.login = False
if st.session_state.login == False:
# If login is false then create a login window
st.sidebar.write("Login")
# Create sidebar login boxes
user = st.sidebar.text_input(label = "Username")
password = st.sidebar.text_input(label = "Password", type = "password")
login_btn = st.sidebar.button("Login")
if login_btn:
# This is the users list which will help in login and password for both is 123
if user in ["Chaitanya", "Sagar"] and password == "Wizards@123Trade#":
st.sidebar.success(f"Logged In as {user}")
st.session_state.login = True
# Now if clicked on login wait for 1 second then reload the page using experimental_rerun
time.sleep(1)
st.experimental_rerun()
else:
# If incorrect credentials then pose an error
st.sidebar.warning("Incorrect Username/Password")
else:
# Get the crypto data from FTX api
df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
# Get the LTP and 24H %change for BTCUSDT, ETHUSDT
st.session_state.index_btc = df[df["name"]=="BTC/USDT"]["last"].values[0]
st.session_state.index_btc_pct_change = round(df[df["name"]=="BTC/USDT"]["change24h"].values[0],2)
st.session_state.index_eth = df[df["name"]=="ETH/USDT"]["last"].values[0]
st.session_state.index_eth_pct_change = round(df[df["name"]=="ETH/USDT"]["change24h"].values[0],2)
st.session_state.roro = get_roro()
roro_df = pd.DataFrame(st.session_state.roro)
roro_df.set_index("date",inplace = True)
roro_df["sum"] = roro_df.sum(axis = 1) / len(roro_df.columns)
# Code below is for formatting purpose
cols_ticker_tape_cryp = st.columns([1,1])
cols_ticker_tape_cryp[0].metric(label = "BTC",value = st.session_state.index_btc, delta = f"{st.session_state.index_btc_pct_change}%")
cols_ticker_tape_cryp[1].metric(label = "ETH", value = st.session_state.index_eth, delta = f"{st.session_state.index_eth_pct_change}%")
fig = go.Figure(go.Indicator(
mode = "number+delta",
value = round(roro_df["sum"].iloc[-1]),
domain = {'x': [0, 0.2], 'y': [0, 0.2]},
delta = {'reference': round(roro_df["sum"].iloc[-2])},
gauge = {'axis': {'range': [-100, 100]}},
title = {'text': "RORO Indicator"}))
fig.add_trace(go.Scatter(y = roro_df["sum"].values,x = roro_df.index,mode = "lines",fill='tozeroy'))
st.plotly_chart(fig,use_container_width=True,use_container_height = True)
cols_ticker_tape = st.columns(5)
# Now, since fetching each symbol will take lots of time
# So, we are running all the process in threads parally multi-processing
thread_ticker = []
for i in range(len (symbol_mapping.keys())):
# Get the symbol_mapping and run it in thread and display each of them
ticker_tape = list(symbol_mapping.keys())[i]
t_ticker = threading.Thread(target = get_symbol_quote, args = (ticker_tape, symbol_mapping[ticker_tape],cols_ticker_tape,i,))
add_report_ctx(t_ticker)
t_ticker.start()
thread_ticker.append(t_ticker)
for x in thread_ticker:
# Wait for the threads to finish
x.join()
# This is a menu for various dashboard windows
option = st.sidebar.selectbox("Which Dashboard?",
("Watchlist","twitter","wallstreetbets","stocktwits","CryptoIndex","Chart","pattern", "MACRO",
"Technical Scanner", "coinBaskets", "Breakout","ETFs", "Commodities","Report","Recommendations","RORO Components"))
# If you want to momentarily hide your website from people then remove the below from commenting
# Or you could do one more thing, setup a pseudo id-password, which log in you to only limited features
# option = st.sidebar.selectbox("Which Dashboard?",
# ("twitter","coinBaskets"))
# Set the option value as header
st.header(option)
if option == "Watchlist":
# If watchlist is selected
st.subheader("Watchlist")
col1, col2 = st.columns([1,6.5])
df_watchlist = pd.read_csv('watchlist.csv')
with col1:
# Now, create a form which will help you add symbol name, comments, etc
with st.form(key = "symbol_add"):
# df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
# df = df[df["quoteCurrency"].isin(["USD","USDT"])]
# symbols = df.name.values
# asset_class = st.sidebar.selectbox("Asset Class",["Crypto","Fixed Income","Stocks","Index","Commodity"])
asset_class = st.sidebar.selectbox("Asset Class",["Fixed Income","Stocks","Index","Commodity"])
if asset_class == "Crypto":
symbol = st.selectbox("Symbol",symbols)
st.write("Currently working for crypto symbols from FTX")
elif asset_class == "Fixed Income":
symbol = st.selectbox("Symbol",["HYG","LQD","US 2Y","US 5Y","US 10Y","US 30Y"])
elif asset_class == "Index":
symbol = st.selectbox("Symbol",["SPX","NASDAQ","NIFTY50","VIX"])
st.write("If an alert got triggered, but you want to add another, first delete it, then add")
trigger = st.text_input("Trigger Price")
view_type = st.selectbox("View Type",["Above","Below"])
dma200 = st.selectbox("DMA alert",["Yes", "No"])
dma200_view_type = st.selectbox("DMA200 View Type",["Above","Below"])
alert_type = st.selectbox("Alert Type",["Macro","Individual"])
comments = st.text_area("Comments")
# Create buttons like add and delete symbols for use
add_symbol = st.form_submit_button("Add")
delete_symbol = st.form_submit_button("Remove")
# Empty watchlist button to clear whole watchlist
empty_checkbox = st.checkbox("Yes, I wish to empty the watchlist",value = False)
empty_watchlist = st.form_submit_button("Empty Watchlist")
with col2:
# If empty_watchlist button is clicked then, clear the watchlist
if empty_watchlist and empty_checkbox:
st.info("Watchlist cleared")
df_watchlist = pd.DataFrame(columns=["Symbol","Comments"])
df_watchlist.to_csv('watchlist.csv',index=False)
elif empty_watchlist:
st.error("Could not clear the watchlist, please select the checkbox")
elif add_symbol:
if symbol not in df_watchlist["Symbol"].values:
# If symbol is added then add it to csv file, then update the csv file
st.info("Symbol added")
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)
df_watchlist.to_csv('watchlist.csv',index=False)
else:
st.warning("Symbol Already Present, Please check")
elif delete_symbol:
if symbol not in df_watchlist["Symbol"].values:
st.warning("Symbol not present, please check...")
else:
# Delte symbol and update the csv file
st.info("Symbol Deleted")
df_watchlist = df_watchlist[df_watchlist["Symbol"]!= symbol]
df_watchlist.to_csv('watchlist.csv',index=False)
if len(df_watchlist)>0:
# If there's something in watchlist then for cryptos fetch the LTP from FTX api
# Getting LTP is currently for Crypto only due to free data unavailability for stocks/ETFs
df_watchlist.set_index("Symbol",inplace = True)
df_watchlist["LTP"] = 0
def get_data_symbol(symbol_name_for_quote):
global df_watchlist
try:
if symbol_name_for_quote in ["HYG","LQD","SPX","NASDAQ","NIFTY50","VIX","US 2Y","US 5Y", "US 10Y","US 30Y"]:
data_symbol = get_cnbc_data(symbol_name_for_quote)
else:
data_symbol = json.loads(requests.get(f"https://ftx.com/api/markets/{symbol_name_for_quote}").text)["result"]["price"]
df_watchlist.loc[symbol_name_for_quote,"LTP"] = data_symbol
except:
pass
threads_list = []
for i in range(len(df_watchlist)):
symbol_name_for_quote = df_watchlist.index[i]
x = threading.Thread(target = get_data_symbol,args = (symbol_name_for_quote,))
x.start()
add_report_ctx(x)
threads_list.append(x)
for thread in threads_list:
thread.join()
df_watchlist["pct_away"] = np.round(100*np.abs(df_watchlist["Trigger"] - df_watchlist["LTP"])/df_watchlist["LTP"])
# Show the watchlist
st.dataframe(df_watchlist)
elif option == "RORO Components":
lkbck_perd = st.sidebar.selectbox("Lookback Period",["1Y","5Y"])
st.sidebar.write("1Y will fetch daily data, 5Y --> weekly")
st.sidebar.write("Number of lookback periods is set as 300")
roro_run_btn = st.sidebar.button("Run")
if roro_run_btn:
roro_comp_df = pd.DataFrame(get_roro(lkbck_perd))
roro_comp_df.set_index("date",inplace = True)
roro_comp_df["roro"] = roro_comp_df.sum(axis = 1)/(len(roro_comp_df.columns))
fig = make_subplots(rows=len(roro_comp_df.columns), shared_xaxes=True,vertical_spacing=0.01,subplot_titles=(roro_comp_df.columns))
counter = 1
for key in roro_comp_df.columns:
if key!= "roro":
fig.add_scatter(x = roro_comp_df.index, y = roro_comp_df[key].values,mode = "lines",row = counter, col = 1, name = key)
else:
fig.add_scatter(y = roro_comp_df["roro"].values,x = roro_comp_df.index,mode = "lines",fill='tozeroy',row = counter,col =1,name = key)
counter+=1
fig['layout'].update(height=2500, width=600, title='Subplots of components')
st.plotly_chart(fig,use_container_width = True)
elif option == "Recommendations":
select_asset = st.sidebar.selectbox("Asset Class",["ETF"])
rsi_val = st.sidebar.number_input("RSI Thresh",value = 50)
drop_frm_ath = st.sidebar.number_input("Drop From ATH(%) Thresh",value = 50)
dist_from_5_yr_low = st.sidebar.number_input(f"%away from 2 yr Low Thresh",value = 20)
rec_run_btn = st.sidebar.button("Run")
st.sidebar.write("**Momentum Rising Screening Conditions**")
st.sidebar.write("LTP>50DMA")
st.sidebar.write("LTP>100DMA")
st.sidebar.write("5D Vol>1.5*(5D Vol. yearly_avg")
st.sidebar.write("**Cheap Stocks Screening Conditions**")
st.sidebar.write("RSI < RSI Thresh")
st.sidebar.write("Drop from ATH(%) > Drop from ATH(%) Thresh")
st.sidebar.write(f"% away from 2 yr Low < %away from 2 yr Low Thresh")
if rec_run_btn:
momentum_recommendations = {}
cheap_recommendations = {}
rec_threads = []
if select_asset == "ETF":
options_for_assets = all_etfs
for asset in options_for_assets:
x = threading.Thread(target=get_recommendation,args = (asset,rsi_val,drop_frm_ath,dist_from_5_yr_low,))
x.start()
rec_threads.append(x)
# get_recommendation(asset)
for rec in rec_threads:
rec.join()
# st.write(momentum_recommendations)
momentum_recommendations = pd.DataFrame(momentum_recommendations).T
momentum_recommendations.sort_values("score",ascending=False,inplace = True)
cheap_recommendations = pd.DataFrame(cheap_recommendations).T
cheap_recommendations.sort_values("score",ascending=False,inplace = True)
st.header("Momentum Rising")
st.dataframe(momentum_recommendations.style.apply(highlight_rec_momentum,axis = 1).apply(font_color))
st.header("Cheap Stocks")
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))
elif option == "MACRO":
select_timeframe = st.sidebar.selectbox("Which Timeframe (finviz only)?",["Daily","Weekly","Monthly"])
# select_lookback_period = st.sidebar.selectbox("LookbackPeriod for yields(yrs)",[1,2,3,4,5])
select_lookback_period = st.sidebar.selectbox("LookbackPeriod for yields",["1D","1M","3M","6M","1Y","5Y"])
timeframe_map = {"Daily":"d1","Weekly":"w1","Monthly":"mo"}
tf = timeframe_map[select_timeframe]
run_btn = st.sidebar.button("Run")
if run_btn:
col1, col2, col3 = st.columns([1,1,1])
with col1:
st.image(f"https://finviz.com/fut_image.ashx?es_{tf}_s.png")
with col2:
st.image(f"https://finviz.com/fut_image.ashx?vx_{tf}_s.png")
with col3:
st.image(f"https://finviz.com/fut_image.ashx?nq_{tf}_s.png")
response_yields = {}
thread_yields = []
for symbol in ["US1Y","US2Y","US5Y","US10Y","US30Y"]:
thread = threading.Thread(target = get_data_yields, args = (symbol,select_lookback_period,))
thread.start()
thread_yields.append(thread)
for x in thread_yields:
x.join()
df_yields = pd.concat(response_yields,axis = 1)
df_yields["2y/10y"] = df_yields["US10Y"]-df_yields["US2Y"]
df_yields["10y/30y"] = df_yields["US30Y"]-df_yields["US10Y"]
df_yields["2y/5y"] = df_yields["US5Y"]-df_yields["US2Y"]
df_yields["1y/2y"] = df_yields["US2Y"]-df_yields["US1Y"]
st.line_chart(df_yields[["US1Y","US2Y","US5Y","US10Y","US30Y"]])
col1, col2 = st.columns([1,1])
with col1:
st.line_chart(df_yields["1y/2y"])
st.line_chart(df_yields["2y/5y"])
with col2:
st.line_chart(df_yields["2y/10y"])
st.line_chart(df_yields["10y/30y"])
# today = datetime.now().strftime("%Y-%m-%d")
# past = (datetime.now() - timedelta(days=365*select_lookback_period)).strftime("%Y-%m-%d")
# # https://fred.stlouisfed.org/graph/?id=DGS10,DGS5,DGS30,DGS3MO,DGS1,DGS2,
# url = f"""https://fred.stlouisfed.org/graph/fredgraph.png?dwnld=0&hires=1&type=image/png&
# bgcolor=%23e1e9f0&chart_type=line&drp=0&fo=open%20sans&graph_bgcolor=%23ffffff&height=450&
# mode=fred&recession_bars=on&txtcolor=%23444444&ts=12&tts=12&width=1168&nt=0&thu=0&trc=0&
# show_legend=yes&show_axis_titles=yes&show_tooltip=yes&id=DGS10,DGS5,DGS30,DGS3MO,DGS1,DGS2&
# scale=left,left,left,left,left,left&cosd={past},{past},{past},{past},{past},{past}&
# coed={today},{today},{today},{today},{today},{today}&
# line_color=%234572a7,%23aa4643,%2389a54e,%2380699b,%233d96ae,%23db843d&
# link_values=false,false,false,false,false,false&line_style=solid,solid,solid,solid,solid,solid&
# mark_type=none,none,none,none,none,none&mw=3,3,3,3,3,3&lw=2,2,2,2,2,2&
# ost=-99999,-99999,-99999,-99999,-99999,-99999&oet=99999,99999,99999,99999,99999,99999&
# mma=0,0,0,0,0,0&fml=a,a,a,a,a,a&fq=Daily,Daily,Daily,Daily,Daily,Daily&
# fam=avg,avg,avg,avg,avg,avg&fgst=lin,lin,lin,lin,lin,lin&
# 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&
# transformation=lin,lin,lin,lin,lin,lin&
# vintage_date={today},{today},{today},{today},{today},{today}&
# revision_date={today},{today},{today},{today},{today},{today}&
# nd=1962-01-02,1962-01-02,1977-02-15,1981-09-01,1962-01-02,1976-06-01
# """
# url = url.replace("\n","")
# st.image(url,width = 800)
elif option == "twitter":
# If twitter is selected
today = datetime.today()
# Get the local timezone, this is important because then it works on a different timezone
to_zone = tz.tzlocal()
# Multibox for selecting multiple users
who = st.sidebar.multiselect("Choose person",tuple(TWITTER_USERNAMES))
twitter_run_btn = st.sidebar.button("Run")
if twitter_run_btn:
# if twitter run button is clicked then all those people selected are called
if "SELECT ALL" in who:
users_list = TWITTER_USERNAMES[1:]
else:
users_list = who
for username in users_list:
# For a given username fetch the tweets, its username, image
user = api.get_user(screen_name = username)
tweets = api.user_timeline(screen_name = username, count = 100, tweet_mode = "extended")
st.subheader(username)
st.image(user.profile_image_url)
for tweet in tweets:
# In all his tweets, bring those to local timezone
tweet_date = ((tweet.created_at).astimezone(to_zone)).replace(tzinfo = None)
#Now, we don't want tweets older than 3 days
delta = (today - tweet_date).days
if delta>3:
continue
# For the following user names certain modification is done to get the tweets
if username in ["@chartmojo","@MacroCharts"]:
if tweet.in_reply_to_screen_name== None:
st.subheader(tweet._json["created_at"])
st.write(tweet.full_text)
try:
for j in tweet.extended_entities["media"]:
st.image(j["media_url_https"], width=600)
except:
pass
else:
if tweet.in_reply_to_screen_name== None and len(tweet.entities["symbols"])>0:
symbols = []
for i in range(len(tweet.entities["symbols"])):
symbols.append(tweet.entities["symbols"][i]["text"])
st.subheader(" ".join(symbols))
st.subheader(tweet._json["created_at"])
st.subheader(tweet.full_text)
try:
for j in tweet.extended_entities["media"]:
st.image(j["media_url_https"], width = 600)
except:
pass
for symbol in symbols:
st.image(f"https://finviz.com/chart.ashx?t={symbol}&ta=1", width=600)
# elif option == "US Sectors":
# st.sidebar.write("Source - TradingView")
# select_sector = st.sidebar.selectbox("Select Sector", options = us_sectors)
# select_btn = st.sidebar.button("Run")
# url = "https://in.tradingview.com/markets/stocks-usa/sectorandindustry-sector/"
# r = requests.get(url)
# soup = BeautifulSoup(r.content, 'html5lib') # If this line causes an error, run 'pip install html5lib' or install html5lib
# req = soup.find_all('tr',attrs = {'class':'tv-data-table__row tv-data-table__stroke tv-screener-table__result-row'})
# sectors = []
# pct_change = []
# for i in req:
# arr = []
# for sector in i.find_all("td"):
# arr.append(sector.text)
# arr[0] = arr[0].split("\n")[3].split("\t")[0]
# sectors.append(arr[0])
# pct_change.append(float(arr[3][:-1]))
# fig = go.Figure([go.Bar(x=sectors, y=pct_change,
# marker = dict(color = ['rgba(63, 195, 128, 1)' if value>0 else 'rgba(219, 10, 91, 1)' for value in pct_change],
# line = dict(color='rgb(0,0,0)',width=1.5)))])
# st.plotly_chart(fig,use_container_width=True)
# if select_btn:
# val = "-".join(select_sector.lower().split(" "))
# url = f"https://in.tradingview.com/markets/stocks-usa/sectorandindustry-sector/{val}/"
# r = requests.get(url)
# soup = BeautifulSoup(r.content, 'html5lib') # If this line causes an error, run 'pip install html5lib' or install html5lib
# req = soup.find_all('tr',attrs = {'class':'tv-data-table__row tv-data-table__stroke tv-screener-table__result-row'})
# ticker = []
# pct_change_ticker = []
# company = []
# for i in req:
# arr = []
# for sector in i.find_all("td"):
# arr.append(sector.text)
# arr[0] = arr[0].split("\n")[4]
# # result.append(dict(ticker = arr[0],pct_change = float(arr[2][:-1]),vol = arr[5],mkt_cap = arr[6]))
# # ticker.append(arr[0])
# company.append(us_stocks_mapping[arr[0]])
# pct_change_ticker.append(float(arr[2][:-1]))
# layout = go.Layout(
# xaxis = go.XAxis(
# title = "Stocks",
# showticklabels = False
# )
# )
# fig = go.Figure([go.Bar(x=company, y=pct_change_ticker,
# marker = dict(color = ['rgba(63, 195, 128, 1)' if value>0 else 'rgba(219, 10, 91, 1)' for value in pct_change_ticker],
# line = dict(color='rgb(0,0,0)',width=1.5)))],layout = layout)
# st.write(len(company))
# st.plotly_chart(fig,use_container_width=True)
# st_autorefresh(interval=120000, limit=10000, key="US sectors refresh")
elif option == "Commodities":
select_timeframe = st.sidebar.selectbox("Which Timeframe?",["Daily","Weekly","Monthly"])
timeframe_map = {"Daily":"d1","Weekly":"w1","Monthly":"mo"}
tf = timeframe_map[select_timeframe]
col0,col1,col2 = st.columns([1,1,1])
count = 0
for key in commodity_mapping:
# https://finviz.com/futures_charts.ashx?t=YM&p=d1
# Get the mapping for commodities, which is there in config.py
keyword_comm = commodity_mapping[key]
num = count%3
if num ==0:
with col0:
st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png")
elif num == 1:
with col1:
st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png")
else:
with col2:
st.image(f"https://finviz.com/fut_image.ashx?{keyword_comm}_{tf}_s.png")
count = count+1
elif option == "CryptoIndex":
# If cryptoIndex tab is selected
# Select which crypto index, then timeframe and accordingly fetch the data
type_index = st.sidebar.selectbox("Which?",["Major","Minor","Shit"])
select_index_timeframe = st.sidebar.selectbox("Timeframe",["15s","1m","5m","15m","1h","4h","1d"])
if select_index_timeframe[-1] == "s":
timeframe = int(select_index_timeframe[:-1])
elif select_index_timeframe[-1] == "m":
timeframe = int(select_index_timeframe[:-1]) * 60
elif select_index_timeframe[-1] == "h":
timeframe = int(select_index_timeframe[:-1])*60*60
elif select_index_timeframe[-1] == "d":
timeframe = int(select_index_timeframe[:-1])* 60*60*24
if type_index == "Major":
# Our crypto index is of 0.5BTC + 0.5 ETH
st.write("0.5BTC + 0.5ETH")
# Fetch data and create crypto index in same proportion
data_btc = pd.DataFrame(json.loads(requests.get(f"https://ftx.com/api/markets/BTC/USDT/candles?resolution={timeframe}").text)["result"])
data_eth = pd.DataFrame(json.loads(requests.get(f"https://ftx.com/api/markets/ETH/USDT/candles?resolution={timeframe}").text)["result"])
data_btc.set_index("startTime",inplace = True)
data_eth.set_index("startTime",inplace = True)
# Note crypto index are normalized
data = (data_btc["close"]*0.5/data_btc["close"][0] + data_eth["close"]*0.5/data_eth["close"][0])*100
fig = go.Figure()
fig.add_trace(go.Scatter(x=data.index, y=data.values,
mode='lines',
name=type_index))
fig.update_xaxes(
rangeslider_visible=True,
nticks = 20,
spikemode = "toaxis",
rangeselector=dict(
buttons=list([
dict(count=1, label="1mon", step="month", stepmode="backward"),
dict(count=6, label="6mon", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(step="all")
])
)
)
fig.update_layout(
xaxis_tickformat = '%Y-%m-%d',
height = 600,
width = 900,
hovermode = "x"
)
st.plotly_chart(fig)
elif option == "Report":
df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
df = df[df["quoteCurrency"].isin(["USD","USDT"])]
symbols = df.name.values
to_analyze_symbol = st.sidebar.multiselect("Which symbol",symbols)
analysis_date = st.sidebar.selectbox("Which date for Analysis",["Current","Yesterday"])
if analysis_date == "Yesterday":
locn = -2
elif analysis_date == "Current":
locn = -1
fetch_data_btn = st.sidebar.button("Fetch Data")
if fetch_data_btn:
threads = []
for symbol in symbols:
t = threading.Thread(target = get_crypto_data_daily, args = (symbol,))
t.start()
add_report_ctx(t)
threads.append(t)
for x in threads:
x.join()
res = {}
for req_symbol in to_analyze_symbol:
req_symbol_file = req_symbol.replace("/","_")
df_req = pd.read_csv(f"crypto_data/{req_symbol_file}.csv",index_col = 0, parse_dates = True)
ans = {}
for period in [20,50,100,200]:
df_req[f"MA{period}"] = talib.SMA(df_req["close"],period)
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)
df_req["RSI14"] = talib.RSI(df_req["close"])
ans["RSI"] = round(df_req["RSI14"].iloc[locn],2)
ans["LTP"] = df_req["close"].iloc[-1]
res[req_symbol] = ans
result = pd.DataFrame(res).T
st.dataframe(result)
elif option == "Breakout":
# If breakout tab is selected
# Get the crypto symbols
#Create buttons and boxes for selecting timeframe, BB number, KC multiplier
df = pd.DataFrame(json.loads(requests.get("https://ftx.com/api/markets").text)["result"])
df = df[df["quoteCurrency"].isin(["USD","USDT"])]
symbols = df.name.values
select_consol_tf = st.sidebar.selectbox("Timeframe",["15s","1m","5m","15m","1h","4h","1d"])
if select_consol_tf[-1] == "s":
timeframe = int(select_consol_tf[:-1])
elif select_consol_tf[-1] == "m":
timeframe = int(select_consol_tf[:-1]) * 60
elif select_consol_tf[-1] == "h":
timeframe = int(select_consol_tf[:-1])*60*60
elif select_consol_tf[-1] == "d":
timeframe = int(select_consol_tf[:-1])* 60*60*24
select_BB_mul = st.sidebar.text_input("Bollinger Band multiplier",value = "2")
select_KC_mul = st.sidebar.text_input("KC multiplier", value = "1.5")
select_num_days = st.sidebar.text_input("Consolidating before how many periods?",3)
num_days = int(select_num_days)
bb_mul = float(select_BB_mul)
kc_mul = float(select_KC_mul)
consol_run_btn = st.sidebar.button("Run")
if consol_run_btn:
# If user clicks on run button
# Again running in threads.
threads = []
for symbol in symbols:
t = threading.Thread(target = in_squeeze, args = (symbol,bb_mul, kc_mul, num_days, True,60*60*24))
add_report_ctx(t)
t.start()
threads.append(t)
for x in threads:
x.join()
st.sidebar.write("Task Complete")
elif option == "ETFs":
# If ETFs are selected
# Button to select ETF
selectETF = st.sidebar.selectbox("Select ETF class",etf.keys())
today = datetime.now() - timedelta(days =80)
st.subheader(selectETF)
# Note Country ETFs are dealt differently as they have country names as well
if selectETF!= "Country":
# If ETF is not Country then its very easy just from ETF variable we can fetch it
etf_names = etf[selectETF].keys()
else:
# Select Markets, Country
selectMarket = st.sidebar.selectbox("Which Market?",etf[selectETF].keys())
country_list = list(etf[selectETF][selectMarket].keys())
etf_list = list(etf[selectETF][selectMarket].values())
etf_names = []
country_names = []
# In a for loop fetch all the ETFs for selected entries
for i in range(len(etf_list)):
if type(etf_list[i])==str:
etf_names.append(etf_list[i])
country_names.append(country_list[i])
else:
for sub_etf_name in etf_list[i]:
etf_names.append(sub_etf_name)
country_names.append(country_list[i])
select_timeframe = st.sidebar.selectbox("Which Timeframe?",["Daily","Weekly","Monthly"])
timeframe_map = {"Daily":"d","Weekly":"w","Monthly":"m"}
etf_run_btn = st.sidebar.button("Run")
if etf_run_btn:
tf = timeframe_map[select_timeframe]
# If After giving all the entries, run button is clicked get the charts for all the ETFs
count = 0
res_etf_ret = []
thread_det = []
vol_etf_info = {}
expense_ratios = {}
st.info("Loading..... Please Have Patience")
for n in etf_names:
thread = threading.Thread(target = get_etf_rets, args = (n,))
thread.start()
thread_det.append(thread)
for x in thread_det:
x.join()
st.success("Finished Loading")
etf_rets_df = pd.DataFrame(res_etf_ret)
etf_rets_df.set_index("symbol",inplace=True)
col1,col2,col3,col4,col5 = st.columns([1,1,1,1,1])
with col1:
# st.write("")
st.markdown("<h5 style='text-align: center; color: red;'>Daily Returns</h5>", unsafe_allow_html=True)
st.dataframe(etf_rets_df["day_ret"].sort_values(ascending=False))
with col2:
st.markdown("<h5 style='text-align: center; color: red;'>1 Week Returns</h5>", unsafe_allow_html=True)
st.dataframe(etf_rets_df["w1_ret"].sort_values(ascending=False))
with col3:
st.markdown("<h5 style='text-align: center; color: red;'>2 Week Returns</h5>", unsafe_allow_html=True)
st.dataframe(etf_rets_df["w2_ret"].sort_values(ascending=False))
with col4:
st.markdown("<h5 style='text-align: center; color: red;'>1 Month Returns</h5>", unsafe_allow_html=True)
st.dataframe(etf_rets_df["m1_ret"].sort_values(ascending=False))
with col5:
st.markdown("<h5 style='text-align: center; color: red;'>1 Year Returns</h5>", unsafe_allow_html=True)
st.dataframe(etf_rets_df["year_ret"].sort_values(ascending=False))
st.dataframe(etf_rets_df)
cols1,cols2 = st.columns([1,1])
if selectETF!= "Country":
for etf_name in etf_names:
num = count%2
if num == 0:
with cols1:
try:
st.write(f"{etf[selectETF][etf_name]}, IV = {vol_etf_info[etf_name]}, ER = {expense_ratios[etf_name]}")
except:
pass
if tf == "d":
st.image(f"https://finviz.com/chart.ashx?t={etf_name}&ta=1&p={tf}")
else:
st.image(f"https://finviz.com/chart.ashx?t={etf_name}&p={tf}")
else:
with cols2:
try:
st.write(f"{etf[selectETF][etf_name]}, IV = {vol_etf_info[etf_name]}, ER = {expense_ratios[etf_name]}")
except:
pass
if tf == "d":
st.image(f"https://finviz.com/chart.ashx?t={etf_name}&ta=1&p={tf}")
else:
st.image(f"https://finviz.com/chart.ashx?t={etf_name}&p={tf}")
count = count + 1
else:
for i in range(len(etf_names)):
try:
st.write(f"{country_names[i]}, IV = {vol_etf_info[etf_names[i]]}, ER = {expense_ratios[etf_names[i]]}")
except:
pass
if tf == "d":
st.image(f"https://finviz.com/chart.ashx?t={etf_names[i]}&ta=1&p={tf}")
else:
st.image(f"https://finviz.com/chart.ashx?t={etf_names[i]}&p={tf}")
elif option == "coinBaskets":
# If coinBaskets is selected
# Note, Mudrex was our reference here
baskets = st.sidebar.multiselect(label = "Baskets",options=names, default =names[0])
run_basket = st.sidebar.button("Run")
select_crypto_timeframe = st.sidebar.selectbox("Crypto Timeframe", options =
["1d","1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","3d","1w","1M"])
check_symbol = st.sidebar.text_input("Symbol check")
interval = select_crypto_timeframe
# Once all the inputs are given, and if any of the basket is chosen
if check_symbol != "":
for bkt in names:
# For each basket selected, get its components, fetch its price from Binance api
#Then plot all components in a single chart
#Here, you are giving in the symbol name and program is finding whether that symbol is there
# in any of the basket or not
if check_symbol in eval(bkt)["components"]:
fig_check = go.Figure()
st.write(bkt.upper())
cols = st.columns(len(eval(bkt)["components"]))
for i in eval(bkt)["components"]:
ticker = f'{i.upper()}USDT'
req_params = dict(symbol = ticker, interval = interval)
url = "https://api.binance.com/api/v3/klines"
data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text))
data = data.iloc[:,0:5]
data.columns = ['datetime', 'open','high','low', 'close']
data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime]
data["close"] = data["close"].astype(float)
df = (data["close"].pct_change() + 1).cumprod()
fig_check.add_trace(go.Scatter(x=df.index, y=df.values,
mode='lines',
name=i))
fig_check.update_xaxes(
rangeslider_visible=True,
nticks = 20,
spikemode = "toaxis",
rangeselector=dict(
buttons=list([
dict(count=1, label="1mon", step="month", stepmode="backward"),
dict(count=6, label="6mon", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(step="all")
])
)
)
fig_check.update_layout(
xaxis_tickformat = '%Y-%m-%d',
height = 600,
width = 900,
hovermode = "x"
)
fig_check.update_traces(
hovertemplate="<br>".join([
"Price: %{y}"
]))
st.plotly_chart(fig_check)
if run_basket:
for basket in baskets:
# Here, you are choosing the baskets and program is plotting the baskets
st.write(basket.upper())
st.table(eval(basket))
# Create traces
fig = go.Figure()
for i in eval(basket)["components"]:
ticker = f'{i.upper()}USDT'
interval = select_crypto_timeframe
req_params = dict(symbol = ticker, interval = interval)
url = "https://api.binance.com/api/v3/klines"
data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text))
data = data.iloc[:,0:5]
data.columns = ['datetime', 'open','high','low', 'close']
data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime]
data["close"] = data["close"].astype(float)
df = (data["close"].pct_change() + 1).cumprod()
fig.add_trace(go.Scatter(x=df.index, y=df.values,
mode='lines',
name=i))
fig.update_xaxes(
rangeslider_visible=True,
nticks = 20,
spikemode = "toaxis",
rangeselector=dict(
buttons=list([
dict(count=1, label="1mon", step="month", stepmode="backward"),
dict(count=6, label="6mon", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(step="all")
])
)
)
fig.update_layout(
xaxis_tickformat = '%Y-%m-%d',
height = 600,
width = 900,
hovermode = "x"
)
fig.update_traces(
hovertemplate="<br>".join([
"Price: %{y}"
]))
st.plotly_chart(fig)
elif option == "Chart":
# Charting platform
# Get user inputs
symbols = st_tags_sidebar(label = "Choose the tickers",
text = 'Press enter to add more', maxtags = 100)
select_stock_timeframe = st.sidebar.selectbox("Stock Timeframe",options=["1Min", "5Min", "15Min", "day"])
select_crypto_timeframe = st.sidebar.selectbox("Crypto Timeframe", options =
["1d","1m","3m","5m","15m","30m","1h","2h","4h","6h","8h","12h","3d","1w","1M"])
select_periods = st.sidebar.text_input("Number of Days(Stock)",value = "30")
today = datetime.now() - timedelta(int(select_periods))
if len(symbols)>0:
# If symbols are selected
for symbol in symbols:
# Run over all symbol in for loop and if they are crypto, treat them differently
#And if they are others, treat them differently
if f'{symbol.upper()}' in crypto_symbols:
# If crypto, get the data from Binance api
ticker = f'{symbol.upper()}USDT'
interval = select_crypto_timeframe
req_params = dict(symbol = ticker, interval = interval)
url = "https://api.binance.com/api/v3/klines"
st.subheader(ticker)
data = pd.DataFrame(json.loads(requests.get(url,params = req_params).text))
data = data.iloc[:,0:5]
data.columns = ['datetime', 'open','high','low', 'close']
data.index = [datetime.fromtimestamp(x/1000) for x in data.datetime]
data.drop("datetime",axis = 1, inplace = True)
else:
# If stocks then get it from trade_api
# Remember!!!--> trade_api was initiated in the session_state in the starting of code
data = st.session_state.trade_api.get_barset(symbol.upper(), select_stock_timeframe, start =today.strftime("%Y-%m-%d")).df
data = data[symbol.upper()]
st.subheader(symbol.upper())
fig = plot_candlestick(data)
st.plotly_chart(fig, use_container_width=False)
elif option == "stocktwits":
# If stocktwits is selected
# This is almost similar to Larry's video, so you can reference that as well
# Display Trending stocks based on watchlist count
st.header("Most Trending Symbols")
most_trending_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/ts",
code = "ts", label = "Trending Score")
st.dataframe(most_trending_syms)
st.header("Most messages in last 24 hrs")
most_active_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/m_day",
code = "m_day", label = "#messages")
st.dataframe(most_active_syms)
st.header("Top New Watchers added in last 24 hrs")
most_active_syms = get_stocktwits_data(req = "https://api.stocktwits.com/api/2/charts/wl_ct_day",
code = "wl_ct_day", label = "Count")
st.dataframe(most_active_syms)
# For a given symbol, use request module to hit the stocktwits api and get the required info
symbol = st.sidebar.text_input("Symbol", value = "AAPL", max_chars = 5)
r = requests.get(f"https://api.stocktwits.com/api/2/streams/symbol/{symbol}.json")
data = r.json()
for message in data["messages"]:
st.image(message["user"]["avatar_url"])
st.write(message['user']["username"])
st.write(message["created_at"])
st.write(message["body"])
st.sidebar.write("Update time for -->")
st.sidebar.write("Top Watchlist Counts : 5mins")
st.sidebar.write("Most Messages : 1hr")
elif option == "Technical Scanner":
# If technical scanner is selected
# Then choose the pattern, timeframe, etc
pattern = st.sidebar.selectbox("Which Pattern?", tuple(patterns.values()))
keywords = st_tags_sidebar(label = "Choose the tickers",
text = 'Press enter to add more', maxtags = 100)
select_timeframe = st.sidebar.selectbox("Timeframe",options=["1Min", "5Min", "15Min", "day"])
run_btn = st.sidebar.button("Run")
# Get the mapping for patterns from pattern.py file
pattern_code = get_key(patterns, pattern)
pattern_function = getattr(talib,pattern_code)
if run_btn:
# If clicked on run button
# Then for each symbol, check the output
keyword = [x.upper() for x in keywords]
data = st.session_state.trade_api.get_barset(keyword, select_timeframe, limit = 100).df
for symbol in keyword:
try:
# st.write(data)
result = pattern_function(data[symbol]["open"],data[symbol]["high"],data[symbol]["low"],data[symbol]["close"])
last = result.tail(1).values[0]
# For some of the indicators value <0 is Bearish and value>0 is Bullish
# But for others there would be a different logic, you shall handle it differently
if last>0:
st.write(f"Bullish {symbol}")
elif last<0:
st.write(f"Bearish {symbol}")
except:
pass