Spaces:
Sleeping
Sleeping
Upload 15 files
Browse files- .gitattributes +1 -0
- ChatBot.py +133 -0
- Data/Bitcoin_data.csv +0 -0
- Data/daily_bitcoin_price.csv +0 -0
- Data/modeldata.csv +1 -0
- Data/portfolio.json +7 -0
- Dockerfile +13 -0
- app.py +211 -0
- db/bitcoin_data.db +3 -0
- models/daily_stat.pkl +3 -0
- models/hourly_stat.pkl +3 -0
- models/input_scaler.pkl +3 -0
- models/lstm_model.onnx +3 -0
- models/ouput_scaler.pkl +3 -0
- requirements.txt +17 -0
- templates/index.html +344 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
db/bitcoin_data.db filter=lfs diff=lfs merge=lfs -text
|
ChatBot.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from langchain_community.utilities import SQLDatabase
|
| 2 |
+
from langchain_tavily import TavilySearch
|
| 3 |
+
from langgraph.prebuilt import create_react_agent
|
| 4 |
+
from langchain_community.agent_toolkits import SQLDatabaseToolkit
|
| 5 |
+
from langchain.chat_models import init_chat_model
|
| 6 |
+
from dotenv import load_dotenv
|
| 7 |
+
from langchain.prompts import ChatPromptTemplate
|
| 8 |
+
from langgraph.graph import StateGraph,START,END
|
| 9 |
+
from typing import TypedDict
|
| 10 |
+
from langchain import hub
|
| 11 |
+
import os
|
| 12 |
+
load_dotenv()
|
| 13 |
+
mistralapi=os.environ['MISTRAL']
|
| 14 |
+
taviliy=os.environ['TAVILY']
|
| 15 |
+
|
| 16 |
+
llm=init_chat_model("ministral-8b-latest",model_provider="mistralai",api_key=mistralapi)
|
| 17 |
+
|
| 18 |
+
db=SQLDatabase.from_uri("sqlite:///db/bitcoin_data.db")
|
| 19 |
+
toolkit=SQLDatabaseToolkit(db=db,llm=llm)
|
| 20 |
+
sqltools=toolkit.get_tools()
|
| 21 |
+
table_info=db.get_table_info()
|
| 22 |
+
sqlprompt=hub.pull("langchain-ai/sql-agent-system-prompt")
|
| 23 |
+
sqlprompt=sqlprompt.format(dialect="SQLite", top_k=5)
|
| 24 |
+
|
| 25 |
+
class GraphState(TypedDict):
|
| 26 |
+
userinput:str
|
| 27 |
+
movewhere:str
|
| 28 |
+
aimessages:list[str]
|
| 29 |
+
query:str
|
| 30 |
+
finalanswer:str
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def router(state:GraphState):
|
| 34 |
+
userinput=state["userinput"]
|
| 35 |
+
prompt=ChatPromptTemplate.from_messages([
|
| 36 |
+
("system","You are assistant who have to decide what user need right now reponsd with 'News' or 'Analysis' or 'Research' or 'all' 'none' dont use any puctuation, symbols or extra text in the reponse. Remember when you respond with analysis we run sql queries on a database with bitcoin high low volume and rsi mcad etc respond this only when the user asks about statistical analysis on the bitcoin data. When you select Research we search internet for any financial oredictions or articles. You must first understand prompt and check which option is best for better responses. Respond with 'all' when i the query of user is diverse like getting some financial advice or require some extra info other than seraching old database. If none of the options is required or question is not about bitcoin or related terms or personalities respond 'none'"),
|
| 37 |
+
("user",f"Here is the input from user '{userinput}'")
|
| 38 |
+
])
|
| 39 |
+
chain=prompt | llm
|
| 40 |
+
response=chain.invoke({'userinput':userinput})
|
| 41 |
+
print(response.content)
|
| 42 |
+
state['movewhere']=response.content.lower()
|
| 43 |
+
return state
|
| 44 |
+
|
| 45 |
+
def querygen(state:GraphState):
|
| 46 |
+
userinput=state['userinput']
|
| 47 |
+
prompt=ChatPromptTemplate.from_messages([
|
| 48 |
+
("system","You are a assistant who would generate questions for an agent which generates sql queries for data {datainfo}. Analyze the user input and generate the questions for that agent that gives maximum information that user need for better answer. You should ask only 5 statistical questions without heading just simple questions"),
|
| 49 |
+
("user","Here is a prompt from user '{userinput}'")
|
| 50 |
+
])
|
| 51 |
+
chain=prompt | llm
|
| 52 |
+
response=chain.invoke({"datainfo":table_info,'userinput':userinput})
|
| 53 |
+
state['query']=response.content
|
| 54 |
+
return state
|
| 55 |
+
|
| 56 |
+
def news(state:GraphState):
|
| 57 |
+
news_update=TavilySearch(
|
| 58 |
+
tavily_api_key=taviliy,
|
| 59 |
+
max_results=5,
|
| 60 |
+
topic="news"
|
| 61 |
+
)
|
| 62 |
+
userinput=state['userinput']
|
| 63 |
+
searchagent=create_react_agent(llm,tools=[news_update])
|
| 64 |
+
response=searchagent.invoke({"messages":[{"role":"user","content":userinput}]})
|
| 65 |
+
state['aimessages'].append(response['messages'][-1].content)
|
| 66 |
+
return state
|
| 67 |
+
|
| 68 |
+
def analysis(state:GraphState):
|
| 69 |
+
queries=state['query']
|
| 70 |
+
sqlagent=create_react_agent(llm,tools=sqltools,prompt=sqlprompt)
|
| 71 |
+
response=sqlagent.invoke({"messages":[{"role":"user","content":queries}]})
|
| 72 |
+
state['aimessages'].append(response['messages'][-1].content)
|
| 73 |
+
return state
|
| 74 |
+
|
| 75 |
+
def search(state:GraphState):
|
| 76 |
+
userinput=state['userinput']
|
| 77 |
+
finance_update=TavilySearch(
|
| 78 |
+
tavily_api_key=taviliy,
|
| 79 |
+
max_results=5,
|
| 80 |
+
topic="finance"
|
| 81 |
+
)
|
| 82 |
+
searchagent=create_react_agent(llm,tools=[finance_update])
|
| 83 |
+
response=searchagent.invoke({"messages":[{"role":"user","content":userinput}]})
|
| 84 |
+
state['aimessages'].append(response['messages'][-1].content)
|
| 85 |
+
return state
|
| 86 |
+
|
| 87 |
+
def finalnode(state:GraphState):
|
| 88 |
+
userinput=state['userinput']
|
| 89 |
+
aimessages=state['aimessages']
|
| 90 |
+
prompt=ChatPromptTemplate.from_messages([
|
| 91 |
+
("system","You are an agent who have to write final comprehensive answer based on user query and the provided docs given by different AI agents here are some docs that might help {aimessages}"),
|
| 92 |
+
("user","{userinput}")
|
| 93 |
+
])
|
| 94 |
+
chain=prompt | llm
|
| 95 |
+
response=chain.invoke({"aimessages":aimessages,"userinput":userinput})
|
| 96 |
+
state['finalanswer']=response.content
|
| 97 |
+
return state
|
| 98 |
+
|
| 99 |
+
def runall(state:GraphState):
|
| 100 |
+
return state
|
| 101 |
+
|
| 102 |
+
def random(state:GraphState):
|
| 103 |
+
response=llm.invoke(state['userinput'])
|
| 104 |
+
state['finalanswer']=response.content
|
| 105 |
+
return state
|
| 106 |
+
|
| 107 |
+
builder=StateGraph(GraphState)
|
| 108 |
+
builder.add_node("decide",router)
|
| 109 |
+
builder.add_node("random",random)
|
| 110 |
+
|
| 111 |
+
builder.add_edge(START,"decide")
|
| 112 |
+
builder.add_conditional_edges("decide",lambda state:state['movewhere'],
|
| 113 |
+
{
|
| 114 |
+
"news":"news",
|
| 115 |
+
"analysis":"querygen",
|
| 116 |
+
"research":"search",
|
| 117 |
+
"none":"random",
|
| 118 |
+
"all":"runall"
|
| 119 |
+
})
|
| 120 |
+
builder.add_sequence([
|
| 121 |
+
("runall",runall),
|
| 122 |
+
("queerygenall",querygen),
|
| 123 |
+
("analyzeall",analysis),
|
| 124 |
+
("newsall",news),
|
| 125 |
+
("searchall",search),
|
| 126 |
+
("finalnodeall",finalnode)
|
| 127 |
+
])
|
| 128 |
+
builder.add_sequence([("search",search),("finalsearch",finalnode)])
|
| 129 |
+
builder.add_sequence([("news",news),("finalnews",finalnode)])
|
| 130 |
+
builder.add_sequence([("querygen",querygen),("analyze",analysis),("finalanalyze",finalnode)])
|
| 131 |
+
builder.add_edge("random",END)
|
| 132 |
+
|
| 133 |
+
graph=builder.compile()
|
Data/Bitcoin_data.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Data/daily_bitcoin_price.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
Data/modeldata.csv
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
open_time,open,high,low,close,volume,close_time,quote_asset_volume, number_of_trades, taker_buy_base_asset_volume,taker_buy_quote_asset_volume
|
Data/portfolio.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"amount":1000000,
|
| 3 |
+
"trades":[],
|
| 4 |
+
"tradesDone":[],
|
| 5 |
+
"PNL":0,
|
| 6 |
+
"bitcoin_holdings":0
|
| 7 |
+
}
|
Dockerfile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.9
|
| 2 |
+
|
| 3 |
+
RUN useradd -m -u 1000 user
|
| 4 |
+
USER user
|
| 5 |
+
ENV PATH="/home/user/.local/bin:$PATH"
|
| 6 |
+
|
| 7 |
+
WORKDIR /app
|
| 8 |
+
|
| 9 |
+
COPY --chown=user ./requirements.txt requirements.txt
|
| 10 |
+
RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
| 11 |
+
|
| 12 |
+
COPY --chown=user . /app
|
| 13 |
+
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
|
app.py
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import onnxruntime as ort
|
| 2 |
+
import pickle
|
| 3 |
+
import joblib
|
| 4 |
+
import numpy as np
|
| 5 |
+
import json
|
| 6 |
+
import os
|
| 7 |
+
import requests
|
| 8 |
+
import pandas as pd
|
| 9 |
+
from flask import Flask,render_template,jsonify,request
|
| 10 |
+
import plotly.graph_objects as go
|
| 11 |
+
from livereload import Server
|
| 12 |
+
from dotenv import load_dotenv
|
| 13 |
+
from ta.momentum import RSIIndicator
|
| 14 |
+
from ta.trend import MACD, EMAIndicator
|
| 15 |
+
from ta.volatility import AverageTrueRange
|
| 16 |
+
import plotly.io as pio
|
| 17 |
+
import ChatBot as cb
|
| 18 |
+
|
| 19 |
+
load_dotenv()
|
| 20 |
+
api=os.environ['API_KEY']
|
| 21 |
+
head={
|
| 22 |
+
"x-cg-demo-api-key":api
|
| 23 |
+
}
|
| 24 |
+
params={
|
| 25 |
+
"vs_currency":"usd",
|
| 26 |
+
"days":1
|
| 27 |
+
}
|
| 28 |
+
lines=requests.get("https://api.coingecko.com/api/v3/coins/bitcoin/ohlc",params=params,headers=head).json()
|
| 29 |
+
|
| 30 |
+
def preprocess(lines):
|
| 31 |
+
cols=["open_time","open","high","low","close"]
|
| 32 |
+
data=pd.DataFrame(lines,columns=cols)
|
| 33 |
+
data['open_time']=pd.to_datetime(data['open_time'],unit='ms')
|
| 34 |
+
data['rsi']=RSIIndicator(close=data["close"],window=14,fillna=0).rsi()
|
| 35 |
+
macd=MACD(close=data["close"])
|
| 36 |
+
data["macd"]=macd.macd()
|
| 37 |
+
data['macd_signal']=macd.macd_signal()
|
| 38 |
+
data['ema_20']=EMAIndicator(close=data['close'],window=14,fillna=0).ema_indicator()
|
| 39 |
+
data['atr']=AverageTrueRange(high=data['high'],low=data['low'],close=data['close'],window=14).average_true_range()
|
| 40 |
+
data['weekday']=data['open_time'].dt.day_of_week
|
| 41 |
+
data['day_of_year']=data['open_time'].dt.day_of_year
|
| 42 |
+
data['hour']=data['open_time'].dt.hour
|
| 43 |
+
data['month_end']=data['open_time'].dt.is_month_end.astype(np.float32)
|
| 44 |
+
data['month_start']=data['open_time'].dt.is_month_start.astype(np.float32)
|
| 45 |
+
data['quarter_start']=data['open_time'].dt.is_quarter_start.astype(np.float32)
|
| 46 |
+
data["quarter_end"]=data['open_time'].dt.is_quarter_end.astype(np.float32)
|
| 47 |
+
data["year"]=data['open_time'].dt.year
|
| 48 |
+
data['month']=data['open_time'].dt.month
|
| 49 |
+
data['is_recent']=data['open_time'].dt.year>2023
|
| 50 |
+
data['is_recent']=data['is_recent'].astype(np.float64)
|
| 51 |
+
data=data[data["open_time"].dt.minute==0].reset_index(drop=True)
|
| 52 |
+
return data
|
| 53 |
+
data=preprocess(lines)
|
| 54 |
+
|
| 55 |
+
session=ort.InferenceSession("models/lstm_model.onnx")
|
| 56 |
+
|
| 57 |
+
with open("models/hourly_stat.pkl","rb") as f:
|
| 58 |
+
hourly_model=pickle.load(f)
|
| 59 |
+
|
| 60 |
+
with open("models/daily_stat.pkl","rb") as f:
|
| 61 |
+
daily_model=pickle.load(f)
|
| 62 |
+
|
| 63 |
+
input_scaler=joblib.load("models/input_scaler.pkl")
|
| 64 |
+
|
| 65 |
+
output_scaler=joblib.load("models/ouput_scaler.pkl")
|
| 66 |
+
|
| 67 |
+
with open("Data/news.json","r") as f:
|
| 68 |
+
news=json.load(f)
|
| 69 |
+
|
| 70 |
+
with open("Data/portfolio.json","r") as f:
|
| 71 |
+
portfolio=json.load(f)
|
| 72 |
+
|
| 73 |
+
def predict_onnx(data):
|
| 74 |
+
ourdata=data.drop(columns=['open_time'])
|
| 75 |
+
impfactor=np.linspace(0,1,15).reshape(15,1)
|
| 76 |
+
scaled=input_scaler.transform(ourdata)
|
| 77 |
+
X=np.append(scaled,impfactor,axis=1).reshape(1,15,20)
|
| 78 |
+
input_name = session.get_inputs()[0].name
|
| 79 |
+
output = session.run(None, {input_name: X.astype(np.float32)})
|
| 80 |
+
return pd.DataFrame({
|
| 81 |
+
"ds":data[-15:]['open_time']+pd.Timedelta(hours=1),
|
| 82 |
+
"x":output_scaler.inverse_transform(output[0][0].reshape(1,15)).reshape(15)
|
| 83 |
+
})
|
| 84 |
+
def precict_ml(data):
|
| 85 |
+
prediction=hourly_model.predict(data.rename(columns={"open_time":"ds","close":"previous_close"}).fillna(0))
|
| 86 |
+
return pd.DataFrame({
|
| 87 |
+
"ds":data['open_time']+pd.Timedelta(hours=1),
|
| 88 |
+
"y":prediction['yhat']
|
| 89 |
+
})
|
| 90 |
+
def plot_chart():
|
| 91 |
+
temp=pd.DataFrame()
|
| 92 |
+
batchsize=15
|
| 93 |
+
for i in range(0,len(data),batchsize):
|
| 94 |
+
input_data=data[len(data)-i-batchsize:len(data)-i].fillna(0)
|
| 95 |
+
if len(input_data)<batchsize:
|
| 96 |
+
prediction=predict_onnx(data[:15].fillna(0))[:-(batchsize-(len(data)-i))]
|
| 97 |
+
temp=pd.concat([prediction,temp])
|
| 98 |
+
break
|
| 99 |
+
prediction=predict_onnx(input_data)
|
| 100 |
+
temp=pd.concat([prediction,temp])
|
| 101 |
+
predicted=temp
|
| 102 |
+
mlprediction=precict_ml(data)
|
| 103 |
+
fig=go.Figure()
|
| 104 |
+
fig.add_trace(go.Candlestick(
|
| 105 |
+
x=data["open_time"],
|
| 106 |
+
open=data["open"],
|
| 107 |
+
high=data['high'],
|
| 108 |
+
low=data['low'],
|
| 109 |
+
close=data['close'],
|
| 110 |
+
name="liveprice"
|
| 111 |
+
))
|
| 112 |
+
fig.add_trace(go.Scatter(
|
| 113 |
+
x=predicted['ds'],
|
| 114 |
+
y=predicted['x'],
|
| 115 |
+
name="lstm_prediction"
|
| 116 |
+
))
|
| 117 |
+
fig.add_trace(go.Scatter(
|
| 118 |
+
x=mlprediction['ds'],
|
| 119 |
+
y=mlprediction['y'],
|
| 120 |
+
name="MlPrediction"
|
| 121 |
+
)
|
| 122 |
+
)
|
| 123 |
+
fig.update_layout(
|
| 124 |
+
xaxis=dict(
|
| 125 |
+
range=[data['open_time'].iloc[-15],data['open_time'].iloc[-1]],
|
| 126 |
+
rangeslider=dict(visible=False),
|
| 127 |
+
fixedrange=False
|
| 128 |
+
),
|
| 129 |
+
paper_bgcolor='rgba(113, 78, 161, 0.5)',
|
| 130 |
+
plot_bgcolor='rgba(113, 78, 161, 0.5)',
|
| 131 |
+
font_color="white",
|
| 132 |
+
dragmode="pan"
|
| 133 |
+
)
|
| 134 |
+
return fig
|
| 135 |
+
|
| 136 |
+
def Predict20Days():
|
| 137 |
+
today=pd.to_datetime("today").normalize()
|
| 138 |
+
timerange=pd.date_range(start=today,end=today+pd.Timedelta(days=20),freq="d")
|
| 139 |
+
input_data=pd.DataFrame(timerange,columns=['ds'])
|
| 140 |
+
pred=daily_model.predict(input_data)
|
| 141 |
+
return {
|
| 142 |
+
"ds":timerange,
|
| 143 |
+
"y":pred['yhat']
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
def make_20_days_chart():
|
| 147 |
+
df=Predict20Days()
|
| 148 |
+
fig=go.Figure()
|
| 149 |
+
fig.add_trace(go.Scatter(
|
| 150 |
+
x=df['ds'],
|
| 151 |
+
y=df['y']
|
| 152 |
+
))
|
| 153 |
+
fig.update_layout(
|
| 154 |
+
paper_bgcolor='rgba(113, 78, 161, 0.5)',
|
| 155 |
+
plot_bgcolor='rgba(113, 78, 161, 0.5)',
|
| 156 |
+
font_color="white",
|
| 157 |
+
dragmode="pan"
|
| 158 |
+
)
|
| 159 |
+
return fig
|
| 160 |
+
|
| 161 |
+
app=Flask(__name__)
|
| 162 |
+
app.config['TEMPLATES_AUTO_RELOAD'] = True
|
| 163 |
+
@app.route("/")
|
| 164 |
+
def front():
|
| 165 |
+
figure=plot_chart()
|
| 166 |
+
next20days=make_20_days_chart()
|
| 167 |
+
config={
|
| 168 |
+
"displayModeBar":False
|
| 169 |
+
}
|
| 170 |
+
plot=pio.to_html(figure,full_html=False,config=config)
|
| 171 |
+
plot2=pio.to_html(next20days,full_html=False,config=config)
|
| 172 |
+
return render_template("index.html",chart=plot,newsset=news,pred20=plot2)
|
| 173 |
+
|
| 174 |
+
@app.route("/update_chart")
|
| 175 |
+
def give_update():
|
| 176 |
+
global lines
|
| 177 |
+
global data
|
| 178 |
+
newlines=requests.get("https://api.coingecko.com/api/v3/coins/bitcoin/ohlc",params=params,headers=head).json()
|
| 179 |
+
lines.append(newlines)
|
| 180 |
+
data=preprocess(lines)
|
| 181 |
+
data=data.drop_duplicates()
|
| 182 |
+
predonnx=predict_onnx(data.iloc[-15:].fillna(0))
|
| 183 |
+
predml=precict_ml(data.iloc[[-1]])
|
| 184 |
+
return jsonify({
|
| 185 |
+
"x":[str(data['open_time'].iloc[-1]),str(predonnx['ds']),str(predml['ds'])],
|
| 186 |
+
"open":float(data['open'].iloc[-1]),
|
| 187 |
+
"high":float(data["high"].iloc[-1]),
|
| 188 |
+
"low":float(data['low'].iloc[-1]),
|
| 189 |
+
"close":float(data['close'].iloc[-1]),
|
| 190 |
+
"y":[float(predonnx['x']),float(predml['y'])]
|
| 191 |
+
})
|
| 192 |
+
|
| 193 |
+
@app.route("/get_response",methods=['POST'])
|
| 194 |
+
def chat():
|
| 195 |
+
res=request.get_json()
|
| 196 |
+
query=res['text']
|
| 197 |
+
inputinvoke={
|
| 198 |
+
"userinput":query,
|
| 199 |
+
"movewhere":"",
|
| 200 |
+
"aimessages":[],
|
| 201 |
+
"query":"",
|
| 202 |
+
"finalanswer":""
|
| 203 |
+
}
|
| 204 |
+
response=cb.graph.invoke(inputinvoke)
|
| 205 |
+
return jsonify(response=response['finalanswer'])
|
| 206 |
+
if __name__=="__main__":
|
| 207 |
+
server=Server(app.wsgi_app)
|
| 208 |
+
server.watch("templates/*.html")
|
| 209 |
+
server.serve(open_url_delay=True,port=8000)
|
| 210 |
+
|
| 211 |
+
|
db/bitcoin_data.db
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:46994e6de2be5be140de2d7391dfa5f955b26228954183b9c6138bb003e2eb10
|
| 3 |
+
size 10829824
|
models/daily_stat.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3830450ddbf7da2b6a487a63156d11524fb61fbbb3acc815c7da20a06a5a82a5
|
| 3 |
+
size 264600
|
models/hourly_stat.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0a4ac589ffced0ce751bc5fd9b70c0b9d95b2d99c9a5135d45ddaecbb1ab0277
|
| 3 |
+
size 11240526
|
models/input_scaler.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4609bf36aac5b361cd26ce883c87ec7890fcd90019c563159764e0bbf42ebcaf
|
| 3 |
+
size 1871
|
models/lstm_model.onnx
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:26160009c3b3db4579423a9bca33a517dc28e25848c4c4a006a7383fcedd8449
|
| 3 |
+
size 104079
|
models/ouput_scaler.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:fa3b69b83f876def26db98b9c9c3cc60d11839aca37bdd800fdbf3c6e7c74f0a
|
| 3 |
+
size 975
|
requirements.txt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
onnxruntime
|
| 2 |
+
pickle-mixin
|
| 3 |
+
joblib
|
| 4 |
+
numpy
|
| 5 |
+
jsonlib
|
| 6 |
+
requests
|
| 7 |
+
pandas
|
| 8 |
+
flask
|
| 9 |
+
plotly
|
| 10 |
+
livereload
|
| 11 |
+
python-dotenv
|
| 12 |
+
ta
|
| 13 |
+
langchain
|
| 14 |
+
langgraph
|
| 15 |
+
langchain_community
|
| 16 |
+
langchain_tavily
|
| 17 |
+
uvicorn
|
templates/index.html
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<script src="https://cdn.plot.ly/plotly-2.32.0.min.js"></script>
|
| 7 |
+
<title>Trading Analysis</title>
|
| 8 |
+
</head>
|
| 9 |
+
<style>
|
| 10 |
+
.page{
|
| 11 |
+
display: flex;
|
| 12 |
+
flex-direction: row;
|
| 13 |
+
}
|
| 14 |
+
.tab1{
|
| 15 |
+
flex: 0 0 70%;
|
| 16 |
+
height:100vh;
|
| 17 |
+
scrollbar-width: none;
|
| 18 |
+
overflow: auto;
|
| 19 |
+
}
|
| 20 |
+
.tab2{
|
| 21 |
+
flex: 0 0 30%;
|
| 22 |
+
height:100vh;
|
| 23 |
+
scrollbar-width: none;
|
| 24 |
+
border-left: 2px solid gray;
|
| 25 |
+
overflow: auto;
|
| 26 |
+
}
|
| 27 |
+
#news{
|
| 28 |
+
margin: 20px;
|
| 29 |
+
}
|
| 30 |
+
#header{
|
| 31 |
+
display: flex;
|
| 32 |
+
flex-direction: row;
|
| 33 |
+
justify-content: space-between;
|
| 34 |
+
}
|
| 35 |
+
#boticon{
|
| 36 |
+
position:relative;
|
| 37 |
+
border-radius: 20px;
|
| 38 |
+
width:100px;
|
| 39 |
+
height:40px;
|
| 40 |
+
top:2.5px;
|
| 41 |
+
border: none;
|
| 42 |
+
overflow: hidden;
|
| 43 |
+
z-index: 2;
|
| 44 |
+
font-weight: bolder;
|
| 45 |
+
background-color:white;
|
| 46 |
+
color:#1a1a1a;
|
| 47 |
+
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
|
| 48 |
+
}
|
| 49 |
+
#border{
|
| 50 |
+
position:absolute;
|
| 51 |
+
display: flex;
|
| 52 |
+
z-index: 0;
|
| 53 |
+
bottom: 5%;
|
| 54 |
+
right: 5%;
|
| 55 |
+
align-content: center;
|
| 56 |
+
justify-content: center;
|
| 57 |
+
border-radius: 20px;
|
| 58 |
+
width:105px;
|
| 59 |
+
height:45px;
|
| 60 |
+
background:linear-gradient(75deg,blue,red,greenyellow);
|
| 61 |
+
}
|
| 62 |
+
#boticon::before{
|
| 63 |
+
content:"";
|
| 64 |
+
position: absolute;
|
| 65 |
+
z-index:-1;
|
| 66 |
+
top:0;
|
| 67 |
+
left: -100%;
|
| 68 |
+
width:100px;
|
| 69 |
+
height:40px;
|
| 70 |
+
background:linear-gradient(75deg,blue,red,greenyellow);
|
| 71 |
+
transition: transform 1.5s ease;
|
| 72 |
+
transform: translateX(0);
|
| 73 |
+
}
|
| 74 |
+
#boticon:hover::before{
|
| 75 |
+
transform: translateX(100%);
|
| 76 |
+
}
|
| 77 |
+
#buy,#sell{
|
| 78 |
+
width:150px;
|
| 79 |
+
height:50px;
|
| 80 |
+
border-radius: 20px;
|
| 81 |
+
}
|
| 82 |
+
#buy{
|
| 83 |
+
background-color: rgb(21, 223, 21);
|
| 84 |
+
}
|
| 85 |
+
#sell{
|
| 86 |
+
background-color: red;
|
| 87 |
+
}
|
| 88 |
+
#buttons{
|
| 89 |
+
display: flex;
|
| 90 |
+
justify-content: space-around;
|
| 91 |
+
}
|
| 92 |
+
#menu{
|
| 93 |
+
display: flex;
|
| 94 |
+
align-items: center;
|
| 95 |
+
justify-content: center;
|
| 96 |
+
margin-bottom: 20px;
|
| 97 |
+
}
|
| 98 |
+
#buysell{
|
| 99 |
+
display: flex;
|
| 100 |
+
flex-direction: column;
|
| 101 |
+
justify-content: space-around;
|
| 102 |
+
align-items: center;
|
| 103 |
+
height: 300px;
|
| 104 |
+
margin:50px;
|
| 105 |
+
background-color: rgba(70, 57, 96, 0.8);
|
| 106 |
+
border-radius: 20px;
|
| 107 |
+
box-shadow: 0 0 20px rgba(113, 78, 161, 0.6);
|
| 108 |
+
}
|
| 109 |
+
body{
|
| 110 |
+
background-color: rgba(57, 57, 96, 0.9);
|
| 111 |
+
}
|
| 112 |
+
a{
|
| 113 |
+
color:#66ccff;
|
| 114 |
+
}
|
| 115 |
+
a:hover{
|
| 116 |
+
color:#ffffff;
|
| 117 |
+
}
|
| 118 |
+
h2{
|
| 119 |
+
color:#c4b5fd;
|
| 120 |
+
text-align: center;
|
| 121 |
+
}
|
| 122 |
+
#description{
|
| 123 |
+
color:#f0f0f0;
|
| 124 |
+
}
|
| 125 |
+
#qty{
|
| 126 |
+
border:none;
|
| 127 |
+
background-color: inherit;
|
| 128 |
+
outline: none;
|
| 129 |
+
border-bottom: 2px solid black ;
|
| 130 |
+
}
|
| 131 |
+
#news{
|
| 132 |
+
border-radius: 10px;
|
| 133 |
+
box-shadow: 0 0 20px rgba(113, 78, 161, 0.5);
|
| 134 |
+
padding: 20px;
|
| 135 |
+
}
|
| 136 |
+
#news:hover{
|
| 137 |
+
box-shadow: 0 0 20px rgba(113, 64, 180, 0.8);
|
| 138 |
+
}
|
| 139 |
+
.livechart{
|
| 140 |
+
border-radius: 20px;
|
| 141 |
+
overflow: hidden;
|
| 142 |
+
margin:10px;
|
| 143 |
+
}
|
| 144 |
+
h3{
|
| 145 |
+
color:#f0f0f0;
|
| 146 |
+
}
|
| 147 |
+
#chatbot{
|
| 148 |
+
display: none;
|
| 149 |
+
flex-direction: column;
|
| 150 |
+
bottom:20%;
|
| 151 |
+
top:20%;
|
| 152 |
+
left:20%;
|
| 153 |
+
right:20%;
|
| 154 |
+
flex-direction: column;
|
| 155 |
+
justify-content: center;
|
| 156 |
+
align-items: center;
|
| 157 |
+
position:fixed;
|
| 158 |
+
border-radius: 20px;
|
| 159 |
+
background-color: black;
|
| 160 |
+
color:greenyellow;
|
| 161 |
+
box-shadow: 0 0 20px rgb(240, 185, 252);
|
| 162 |
+
|
| 163 |
+
}
|
| 164 |
+
#X{
|
| 165 |
+
position: absolute;
|
| 166 |
+
top:0px;
|
| 167 |
+
right:20px;
|
| 168 |
+
}
|
| 169 |
+
#X:hover{
|
| 170 |
+
border: 1px solid white;
|
| 171 |
+
}
|
| 172 |
+
#chatheading{
|
| 173 |
+
position: absolute;
|
| 174 |
+
top:30px;
|
| 175 |
+
}
|
| 176 |
+
#textbox{
|
| 177 |
+
position: absolute;
|
| 178 |
+
bottom: 10px;
|
| 179 |
+
left: 10px;
|
| 180 |
+
right:0px;
|
| 181 |
+
}
|
| 182 |
+
#inp{
|
| 183 |
+
width: 82%;
|
| 184 |
+
height: 30px;
|
| 185 |
+
border-radius: 20px;
|
| 186 |
+
padding: 7px;
|
| 187 |
+
font-size: xx-large;
|
| 188 |
+
}
|
| 189 |
+
#send{
|
| 190 |
+
border: 20px;
|
| 191 |
+
background-color: rgb(34, 191, 26);
|
| 192 |
+
border: 2px solid rgb(47, 166, 43);
|
| 193 |
+
color: black;
|
| 194 |
+
font-size: xx-large;
|
| 195 |
+
border-radius: 20px;
|
| 196 |
+
}
|
| 197 |
+
#send:active{
|
| 198 |
+
background-color: rgb(158, 255, 149);
|
| 199 |
+
}
|
| 200 |
+
.question,.response{
|
| 201 |
+
border-radius: 20px;
|
| 202 |
+
background-color: navy;
|
| 203 |
+
padding:20px;
|
| 204 |
+
display: inline-block;
|
| 205 |
+
}
|
| 206 |
+
.question{
|
| 207 |
+
align-self: flex-start;
|
| 208 |
+
}
|
| 209 |
+
.response{
|
| 210 |
+
align-self: flex-end;
|
| 211 |
+
}
|
| 212 |
+
#qapair{
|
| 213 |
+
display: flex;
|
| 214 |
+
flex-direction: column;
|
| 215 |
+
gap: 10px;
|
| 216 |
+
width: 100%;
|
| 217 |
+
padding: 20px;
|
| 218 |
+
overflow-y: auto;
|
| 219 |
+
max-height: 50%;
|
| 220 |
+
box-sizing: border-box;
|
| 221 |
+
}
|
| 222 |
+
</style>
|
| 223 |
+
<body>
|
| 224 |
+
<div class="bottom_page">
|
| 225 |
+
<div class="page">
|
| 226 |
+
<div class="tab1">
|
| 227 |
+
<h2>Live Price</h2>
|
| 228 |
+
<div class="livechart" id="stock_hourly_price">{{chart | safe}}</div>
|
| 229 |
+
<h2>20 Days Predicion</h2>
|
| 230 |
+
<div class="livechart" id="next20days">{{pred20 | safe}}</div>
|
| 231 |
+
<div class="portfolio">
|
| 232 |
+
<div id="buysell">
|
| 233 |
+
<h2>Buy Sell</h2>
|
| 234 |
+
<h3>Balance:{{amount}}</h3>
|
| 235 |
+
<h3>Coins:{{qty}}</h3>
|
| 236 |
+
<input type="text" id="qty" placeholder="Amount" style="margin-bottom:10px;color:white;">
|
| 237 |
+
<div id="buttons">
|
| 238 |
+
<button id="buy">Buy</button>
|
| 239 |
+
<button id="sell">Sell</button>
|
| 240 |
+
</div>
|
| 241 |
+
</div>
|
| 242 |
+
</div>
|
| 243 |
+
</div>
|
| 244 |
+
<div class="tab2">
|
| 245 |
+
<h2>News</h2>
|
| 246 |
+
{% for news in newsset %}
|
| 247 |
+
<div id="news">
|
| 248 |
+
<a href="{{newsset[news]['url']}}">{{newsset[news]['title']}}</a>
|
| 249 |
+
<div id="description">{{newsset[news]['snippet']}}</div>
|
| 250 |
+
</div>
|
| 251 |
+
{% endfor %}
|
| 252 |
+
</div>
|
| 253 |
+
</div>
|
| 254 |
+
<div id="border">
|
| 255 |
+
<button id="boticon">Chat AI </button>
|
| 256 |
+
</div>
|
| 257 |
+
</div>
|
| 258 |
+
<div id="chatbot">
|
| 259 |
+
<h2 id="X">X</h2>
|
| 260 |
+
<h1 id="chatheading">Hey Chat</h1>
|
| 261 |
+
<div id="qapair">
|
| 262 |
+
</div>
|
| 263 |
+
<div id="textbox">
|
| 264 |
+
<div>
|
| 265 |
+
<input type="radio" name="chattype" value="doc">Document
|
| 266 |
+
<input type="radio" name="chattype" value="news">Search
|
| 267 |
+
</div>
|
| 268 |
+
<input type="text" placeholder="Chat..." id="inp" autocomplete="off">
|
| 269 |
+
<button id="send" onclick="sendchat()">>>></button>
|
| 270 |
+
</div>
|
| 271 |
+
</div>
|
| 272 |
+
|
| 273 |
+
<script>
|
| 274 |
+
function fetchnew(){
|
| 275 |
+
fetch("/update_chart")
|
| 276 |
+
.then(res=>res.json())
|
| 277 |
+
.then(data=>{
|
| 278 |
+
Plotly,expandTraces("stock_hourly_price",{
|
| 279 |
+
x:[data.x[0],data.x[1],data.x[2]],
|
| 280 |
+
open:data.open[0],
|
| 281 |
+
high:data.high[0],
|
| 282 |
+
low:data.low[0],
|
| 283 |
+
close:data.close[0],
|
| 284 |
+
y:[data.y[0],data.y[1]]
|
| 285 |
+
}
|
| 286 |
+
,{displayModeBar:false})
|
| 287 |
+
});
|
| 288 |
+
}
|
| 289 |
+
let icon=document.querySelector("#boticon")
|
| 290 |
+
|
| 291 |
+
let bottompage=document.querySelector(".bottom_page")
|
| 292 |
+
|
| 293 |
+
let bot=document.querySelector("#chatbot")
|
| 294 |
+
|
| 295 |
+
icon.addEventListener("click",()=>{
|
| 296 |
+
bottompage.style.opacity=0.2
|
| 297 |
+
chatbot.style.display="flex"
|
| 298 |
+
})
|
| 299 |
+
|
| 300 |
+
let cancel=document.querySelector("#X")
|
| 301 |
+
|
| 302 |
+
cancel.addEventListener("click",()=>{
|
| 303 |
+
bottompage.style.opacity=1
|
| 304 |
+
chatbot.style.display="none"
|
| 305 |
+
})
|
| 306 |
+
let inputfield=document.getElementById("inp")
|
| 307 |
+
let buton=document.getElementById("send")
|
| 308 |
+
buton.disabled=true;
|
| 309 |
+
buton.style.backgroundColor="grey"
|
| 310 |
+
inputfield.addEventListener('input',()=>{
|
| 311 |
+
if(inputfield.value.trim() !== ""){
|
| 312 |
+
buton.style.backgroundColor="rgb(34, 191, 26)"
|
| 313 |
+
buton.disabled=false
|
| 314 |
+
} else{
|
| 315 |
+
buton.style.backgroundColor="grey"
|
| 316 |
+
buton.disabled=true
|
| 317 |
+
}
|
| 318 |
+
})
|
| 319 |
+
|
| 320 |
+
function sendchat(){
|
| 321 |
+
let container=document.getElementById("qapair")
|
| 322 |
+
const qus=document.createElement("div")
|
| 323 |
+
const ans=document.createElement("div")
|
| 324 |
+
let text=inputfield.value
|
| 325 |
+
qus.className="question"
|
| 326 |
+
qus.innerHTML=text
|
| 327 |
+
container.appendChild(qus)
|
| 328 |
+
inputfield.value=""
|
| 329 |
+
fetch('/get_response',{
|
| 330 |
+
method:"POST",
|
| 331 |
+
headers: {
|
| 332 |
+
"Content-Type": "application/json"
|
| 333 |
+
},
|
| 334 |
+
body:JSON.stringify({text})
|
| 335 |
+
}).then(res=>res.json()).then(data=>{
|
| 336 |
+
ans.innerHTML=data.response
|
| 337 |
+
ans.className="response"
|
| 338 |
+
container.appendChild(ans)
|
| 339 |
+
})
|
| 340 |
+
}
|
| 341 |
+
setInterval(fetchnew,60*60*1000)
|
| 342 |
+
</script>
|
| 343 |
+
</body>
|
| 344 |
+
</html>
|