Spaces:
Running
Running
File size: 7,828 Bytes
bdb7320 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
import streamlit as st
import yfinance as yf
import pandas as pd
from langchain.agents import create_pandas_dataframe_agent
import re
import sqlite3
from htmlTemplates import css, user_template, bot_template
from typing import Optional, List, Mapping, Any
from langchain.llms.base import LLM
import g4f
class FinLLM(LLM):
@property
def _llm_type(self) -> str:
return "custom"
def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
out = g4f.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.5, # You can adjust parameters as needed
max_tokens=350 # Adjust the token limit as needed
) #
if stop:
stop_indexes = (out.find(s) for s in stop if s in out)
min_stop = min(stop_indexes, default=-1)
if min_stop > -1:
out = out[:min_stop]
return out
llm = FinLLM()
def create_users_db():
with sqlite3.connect('MASTER.db') as conn:
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS Users (
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT UNIQUE,
password TEXT
)
""")
def add_user_to_db(email, password):
with sqlite3.connect('MASTER.db') as conn:
cursor = conn.cursor()
try:
insert_query = "INSERT INTO Users (email, password) VALUES (?, ?)"
cursor.execute(insert_query, (email, password))
except sqlite3.IntegrityError as e:
# Handle specific error if the email already exists
print(f"Error: {e}")
return False
return True
def authenticate_user(email, password):
with sqlite3.connect('MASTER.db') as conn:
cursor = conn.cursor()
select_query = "SELECT * FROM Users WHERE email = ? AND password = ?"
cursor.execute(select_query, (email, password))
user = cursor.fetchone()
return user is not None
def init_ses_states():
st.session_state.setdefault('chat_history', [])
st.session_state.setdefault('user_authenticated', False)
def relative_returns(df):
rel = df.pct_change()
cumret = ((1 + rel).cumprod() - 1).fillna(0)
return cumret
def display_convo():
with st.container():
for i, message in enumerate(reversed(st.session_state.chat_history)):
if i % 2 == 0:
st.markdown(bot_template.replace("{{MSG}}", message), unsafe_allow_html=True)
else:
st.markdown(user_template.replace("{{MSG}}", message), unsafe_allow_html=True)
def approve_password(password):
if len(password) >= 8 and re.search(r"(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[_@$#!?&*%])", password):
return True
return False
def approve_email(email):
email_regex = '^[a-zA-Z0-9]+[\._]?[a-zA-Z0-9]+[@]\w+[.]\w{2,3}$'
if re.search(email_regex, email):
return True
else:
return False
def user_authentication_tab():
with st.expander("User Authentication", expanded=True):
login_tab, create_account_tab = st.tabs(["Login", "Create Account"])
with login_tab:
email = st.text_input("Email:")
password = st.text_input("Password:", type='password')
if st.button("Login"):
if authenticate_user(email=email,password=password):
st.session_state.user_authenticated = True
else:
st.caption('Incorrect Username or Password.')
if st.session_state.user_authenticated:
st.caption("User Authenticated")
with create_account_tab:
new_email = st.text_input("New Email:")
new_password = st.text_input("New Password:", type='password')
confirm_password = st.text_input("Confirm Password:", type='password')
if st.button("Create Account"):
if not approve_email(new_email):
st.caption("Invalid Email")
return
if not approve_password(new_password):
st.caption("Invalid Password")
return
if new_password != confirm_password:
st.caption("Passwords do not match")
return
add_user_to_db(email=new_email, password=new_password)
st.caption(f"{new_email} Successfully Added")
def main():
st.set_page_config(page_title="Stock Price AI Bot", page_icon=":chart:")
st.write(css, unsafe_allow_html=True)
create_users_db()
init_ses_states()
st.title("Stock Price AI Bot")
st.caption("Visualizations and OpenAI Chatbot for Multiple Stocks Over A Specified Period")
with st.sidebar:
user_authentication_tab()
if st.session_state.user_authenticated:
with st.sidebar:
with st.expander("Settings",expanded=True):
asset_tickers = sorted(['DOW','NVDA','TSL','GOOGL','AMZN','AI','NIO','LCID','F','LYFY','AAPL', 'MSFT', 'BTC-USD', 'ETH-USD'])
asset_dropdown = st.multiselect('Pick Assets:', asset_tickers)
metric_tickers = ['Adj. Close', 'Relative Returns']
metric_dropdown = st.selectbox("Metric", metric_tickers)
viz_tickers = ['Line Chart', 'Area Chart']
viz_dropdown = st.multiselect("Pick Charts:", viz_tickers)
start = st.date_input('Start', value=pd.to_datetime('2023-01-01'))
end = st.date_input('End', value=pd.to_datetime('today'))
chatbot_temp = st.slider("Chat Bot Temperature",0.0,1.0,0.5)
# Only when a stock is selected
if len(asset_dropdown) > 0:
df = yf.download(asset_dropdown,start,end)['Adj Close']
if metric_dropdown == 'Relative Returns':
df = relative_returns(df)
if len(viz_dropdown) > 0:
with st.expander("Data Visualizations for {} of {}".format(metric_dropdown,asset_dropdown), expanded=True):
if "Line Chart" in viz_dropdown:
st.subheader("Line Chart")
st.line_chart(df)
if "Area Chart" in viz_dropdown:
st.subheader("Area Chart")
st.area_chart(df)
st.header("Chat with your Data")
query = st.text_input("Enter a query:")
chat_prompt = f'''
You are an AI ChatBot intended to help with user stock data.
\nYou have access to a pandas dataframe with the following specifications
\nDATA MODE: {metric_dropdown}
\nSTOCKS: {asset_dropdown}
\nTIME PERIOD: {start} to {end}
\nCHAT HISTORY: {st.session_state.chat_history}
\nUSER MESSAGE: {query}
\nAI RESPONSE HERE:
'''
if st.button("Execute") and query:
with st.spinner('Generating response...'):
try:
agent = create_pandas_dataframe_agent(
llm,
pd.DataFrame(df),
verbose=True
)
answer = agent.run(chat_prompt)
st.session_state.chat_history.append(f"USER: {query}\n")
st.session_state.chat_history.append(f"AI: {answer}\n")
display_convo()
except Exception as e:
st.error(f"An error occurred: {str(e)}")
if __name__ == '__main__':
main()
|