|
from openai import OpenAI |
|
from langchain.agents import AgentExecutor, create_openai_tools_agent |
|
from langchain_core.messages import BaseMessage, HumanMessage |
|
from langchain_openai import ChatOpenAI |
|
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder |
|
from typing import Annotated |
|
import operator |
|
from typing import Sequence, TypedDict |
|
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder |
|
import numpy as np |
|
import pandas as pd |
|
from dotenv import load_dotenv |
|
import os |
|
from typing import Annotated |
|
import operator |
|
from typing import Sequence, TypedDict |
|
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder |
|
import matplotlib.pyplot as plt |
|
from langchain.schema.output_parser import StrOutputParser |
|
from tools import data_analyst |
|
from tools import crypto_sentiment_analysis_util |
|
import app_crypto_rf_model as rf |
|
import app_crypto_scrape as sa |
|
import app_crypto_arima_model as arima |
|
import streamlit as st |
|
|
|
from datetime import date |
|
today = date.today() |
|
|
|
st.set_page_config(page_title="LangChain Agent", layout="wide") |
|
load_dotenv() |
|
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] |
|
|
|
llm = ChatOpenAI(model="gpt-3.5-turbo") |
|
|
|
|
|
|
|
class AgentState(TypedDict): |
|
|
|
|
|
messages: Annotated[Sequence[BaseMessage], operator.add] |
|
|
|
next: str |
|
|
|
tool=data_analyst.data_analyst_tools() |
|
|
|
from langchain_core.runnables import RunnableConfig |
|
st.title("💬 Krypto") |
|
|
|
|
|
|
|
|
|
|
|
if "chat_history" not in st.session_state: |
|
st.session_state["messages"] = [{"role":"system", "content":""" |
|
How can I help you? |
|
"""}] |
|
|
|
|
|
|
|
|
|
st.image('crypto_image.png') |
|
|
|
|
|
sideb = st.sidebar |
|
|
|
with st.sidebar: |
|
|
|
|
|
|
|
title = st.text_input("Start by entering the currency name:") |
|
|
|
check1 = sideb.button(f"analyze {title}") |
|
results=[] |
|
|
|
if check1: |
|
st.write(f"I am now producing analysis for {title}") |
|
|
|
model = ChatOpenAI(temperature=0.7, api_key=OPENAI_API_KEY) |
|
chain= model | StrOutputParser() |
|
result=chain.invoke(f"You are a cryptocurrency data analyst.\ |
|
Provide correct cryptocurrency ticker from Coingecko website for cryptocurrency: {title}.\ |
|
Expected output: ticker.\ |
|
Provide it in the following format: >>cryptocurrencyticker>> \ |
|
for example: >>BTC>>") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(result) |
|
print('ticker',str(result).split(">>")[0]) |
|
if len(str(result).split(">>")[1])<10: |
|
cryptocurrencyticker=(str(result).split(">>")[1]) |
|
else: |
|
cryptocurrencyticker=(str(result).split(">>")[0]) |
|
cryptocurrency=title |
|
|
|
print(cryptocurrency,cryptocurrencyticker) |
|
print('here') |
|
|
|
|
|
df=sa.scrape_crypto(cryptocurrency,cryptocurrencyticker) |
|
if len(df)>0: |
|
print("Running forecasting models on historical prices") |
|
df_with_forecast_rf, accuracy_rf, result_rf=rf.model_run(df) |
|
|
|
df_with_forecast_arima, accuracy_arima, result_arima=arima.model_run(df) |
|
|
|
|
|
if accuracy_rf<accuracy_arima: |
|
forecasted_price=(np.round(np.array(df_with_forecast_arima['prices'])[-1]),2) |
|
prompt = f"You are an investment recommendation expert for crypto currency {cryptocurrency}.You are selecting the predicted price from the ARIMA model because its accuracy (R2 measure:{(np.round(accuracy_arima,2))}) is higher than the accuracy (R2:{(np.round(accuracy_rf,2))}) for random forest model.Compare current price to the predicted price. If current price exceeds predicted price, recommend selling the stock, otherwise recommend buying. Tell the user what the current price, predicted price and accuracy values are. You know that the predicted price for tomorrow using random forest model is {(np.round(np.array(df_with_forecast_rf['prices'])[-1],2))}. The prediction accuracy for the random forest model is {(np.round(accuracy_rf,2))}. The current price of {cryptocurrency} is: {(np.round(df['prices'][-1],2))}. " |
|
|
|
|
|
else: |
|
forecasted_price=(np.round(np.array(df_with_forecast_rf['prices'])[-1],2)) |
|
prompt = f"You are an investment recommendation expert for crypto currency {cryptocurrency}. You are selecting the predicted price from the random forest model because its accuracy (R2 measure:{(np.round(accuracy_rf,2))}) is higher than the accuracy (R2:{(np.round(accuracy_arima,2))}) for arima model. Compare current price to the predicted price. If current price exceeds predicted price, recommend selling the stock, otherwise recommend buying. Tell the user what the current price, predicted price and accuracy values are. You know that the predicted price for tomorrow using random forest model is {(np.round(np.array(df_with_forecast_arima['prices'])[-1]),2)}. The prediction accuracy for the random forest model is {(np.round(accuracy_arima,2))}. The current price of {cryptocurrency} is: {(np.round(df['prices'][-1],2))}. " |
|
current_forecast=pd.read_csv('current_forecast.csv',index_col='date',parse_dates=True,infer_datetime_format=True) |
|
today=pd.to_datetime(today).strftime('%Y-%m-%d') |
|
print([(np.array(df_with_forecast_arima['prices'])[-1]),np.array(df_with_forecast_rf['prices'])[-1],today]) |
|
|
|
if today not in (current_forecast.index): |
|
prices_arima=np.append(current_forecast['prices_arima'],(np.array(df_with_forecast_arima['prices'])[-1])) |
|
prices_rf=np.append(current_forecast['prices_rf'],(np.array(df_with_forecast_rf['prices'])[-1])) |
|
dates=np.append(current_forecast.index[0].strftime('%Y-%m-%d'),today) |
|
current_forecast=pd.DataFrame({'date':dates, 'prices_rf':prices_rf,'prices_arima':prices_arima}) |
|
current_forecast.to_csv('current_forecast.csv') |
|
|
|
|
|
inputs_reccommend = {"messages": [HumanMessage(content=prompt)]} |
|
|
|
model = ChatOpenAI(temperature=0.7, api_key=OPENAI_API_KEY) |
|
response=model.invoke(prompt) |
|
response_content=response.content |
|
st.chat_message("assistant").markdown((response_content)) |
|
st.session_state.messages.append({"role": "assistant", "content": prompt}) |
|
|
|
fig, ax = plt.subplots(1,2, figsize=(10, 3)) |
|
ax[0].plot(result_arima['prediction'], color='blue', marker='o') |
|
ax[0].plot(result_arima['data'], color='orange', marker='o') |
|
ax[0].set_title('ARIMA') |
|
ax[1].plot(result_rf['prediction'], color='blue', marker='o') |
|
ax[1].plot(result_rf['data'], color='orange', marker='o') |
|
ax[1].set_title('RF') |
|
fig.suptitle('Prediction vs Actuals') |
|
plt.legend(['prediction','actuals']) |
|
st.pyplot(fig) |
|
|
|
|
|
|
|
|
|
|
|
news_articles = crypto_sentiment_analysis_util.fetch_news(cryptocurrency) |
|
reddit_news_articles=crypto_sentiment_analysis_util.fetch_reddit_news(cryptocurrency) |
|
|
|
|
|
|
|
|
|
analysis_results = [] |
|
|
|
|
|
for article in news_articles: |
|
if cryptocurrency[0:6] in article['News_Article'].lower(): |
|
sentiment_analysis_result = crypto_sentiment_analysis_util.analyze_sentiment(article['News_Article']) |
|
|
|
|
|
|
|
|
|
result = { |
|
'News_Article': sentiment_analysis_result["News_Article"], |
|
'Sentiment': sentiment_analysis_result["Sentiment"][0]['label'], |
|
'Index': sentiment_analysis_result["Sentiment"][0]['score'] |
|
} |
|
|
|
analysis_results.append(result) |
|
|
|
for article in reddit_news_articles: |
|
if cryptocurrency[0:6] in article.lower(): |
|
sentiment_analysis_result_reddit = crypto_sentiment_analysis_util.analyze_sentiment(article) |
|
|
|
|
|
|
|
|
|
result = { |
|
'News_Article': sentiment_analysis_result_reddit["News_Article"], |
|
'Index':np.round(sentiment_analysis_result_reddit["Sentiment"][0]['score'],2) |
|
} |
|
analysis_results.append(result) |
|
|
|
|
|
summary = crypto_sentiment_analysis_util.generate_summary_of_sentiment(analysis_results) |
|
st.chat_message("assistant").write(str(summary)) |
|
st.session_state.messages.append({"role": "assistant", "content": summary}) |
|
|
|
|
|
|
|
client = OpenAI(api_key=OPENAI_API_KEY) |
|
|
|
|
|
if "openai_model" not in st.session_state: |
|
st.session_state["openai_model"] = "gpt-3.5-turbo" |
|
|
|
|
|
if prompt := st.chat_input("Some other questions?"): |
|
|
|
st.session_state.messages.append({"role": "user", "content": prompt}) |
|
|
|
with st.chat_message("user"): |
|
st.markdown(prompt) |
|
|
|
with st.chat_message("assistant"): |
|
stream = client.chat.completions.create( |
|
model=st.session_state["openai_model"], |
|
messages=[ |
|
{"role": m["role"], "content": m["content"]} |
|
for m in st.session_state.messages |
|
], |
|
stream=True, |
|
) |
|
response = st.write_stream(stream) |
|
st.session_state.messages.append({"role": "assistant", "content": response}) |
|
|