You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
8.9 KiB
277 lines
8.9 KiB
5 months ago
|
# import pandas as pd
|
||
|
# import pandas_profiling
|
||
|
# import streamlit as st
|
||
|
# # from pydantic_settings import BaseSettings
|
||
|
#
|
||
|
# from streamlit_pandas_profiling import st_profile_report
|
||
|
#
|
||
|
# df = pd.read_csv("https://storage.googleapis.com/tf-datasets/titanic/train.csv")
|
||
|
# pr = df.profile_report()
|
||
|
#
|
||
|
# st_profile_report(pr)
|
||
|
import os
|
||
|
|
||
|
import django
|
||
|
from django.conf import settings
|
||
|
|
||
|
os.chdir('D:/python/djangoProject/test_Bootstrap')
|
||
|
# 设置 Django 环境变量
|
||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_Bootstrap.settings')
|
||
|
print('开始初始化')
|
||
|
# 强制初始化 Django
|
||
|
django.setup()
|
||
|
print("Django configured.")
|
||
|
|
||
|
print("Starting Streamlit...")
|
||
|
import streamlit as st
|
||
|
from streamlit_vertical_slider import vertical_slider
|
||
|
from st_pages import Page, Section, show_pages, add_page_title, add_indentation
|
||
|
add_page_title()
|
||
|
add_indentation()
|
||
|
|
||
|
import streamlit as st
|
||
|
import streamlit as st
|
||
|
|
||
|
# 定义点击回调函数
|
||
|
def reset_weights():
|
||
|
st.session_state.slider_values = [32, 12, 43, 12, 12]
|
||
|
st.session_state.reset_trigger += 1
|
||
|
|
||
|
# 初始化 session state 中的键
|
||
|
if 'slider_values' not in st.session_state:
|
||
|
st.session_state.slider_values = [32, 12, 43, 12, 12]
|
||
|
if 'reset_trigger' not in st.session_state:
|
||
|
st.session_state.reset_trigger = 0
|
||
|
if 'fund_code' not in st.session_state:
|
||
|
st.session_state['fund_code'] = ''
|
||
|
col1, col2 = st.columns([0.8, 0.2])
|
||
|
|
||
|
with col1:
|
||
|
# 使用 HTML 和内联CSS来增加字体大小
|
||
|
st.markdown("""
|
||
|
<div style='font-size: 34px; font-weight: bold;'>
|
||
|
数据加权
|
||
|
</div>
|
||
|
""", unsafe_allow_html=True)
|
||
|
|
||
|
with col2:
|
||
|
st.button("使用默认权重", key="hidden_button", on_click=reset_weights)
|
||
|
col1, col2 = st.columns([0.8, 0.2])
|
||
|
with col1:
|
||
|
st.markdown('######')
|
||
|
# 创建滑块
|
||
|
columns = st.columns(5)
|
||
|
labels = [
|
||
|
"国家流感中心周报数据",
|
||
|
"北京疾控中心数据",
|
||
|
"百度流感指数数据",
|
||
|
"药品相关股票数据",
|
||
|
"流感相关基金数据"
|
||
|
]
|
||
|
descriptions = [
|
||
|
"详细数据来自国家流感中心的周报。",
|
||
|
"来自北京市疾控中心的相关数据。",
|
||
|
"基于百度搜索指数的流感数据。",
|
||
|
"涉及流感药品的股票数据。",
|
||
|
"投资于流感相关领域的基金数据。"
|
||
|
]
|
||
|
|
||
|
# 使用循环生成滑块
|
||
|
for i, col in enumerate(columns):
|
||
|
with col:
|
||
|
st.markdown(f"##### {labels[i]}")
|
||
|
st.markdown(descriptions[i]) # 使用 Markdown 来提供一致的文本框高度
|
||
|
st.slider(
|
||
|
label="b", # 使用空标签,因为标题和描述已包含足够信息
|
||
|
min_value=0,
|
||
|
max_value=100,
|
||
|
value=st.session_state.slider_values[i],
|
||
|
step=1,
|
||
|
key=f"slider_{i}_{st.session_state.reset_trigger}"
|
||
|
)
|
||
|
|
||
|
# 定义点击回调函数
|
||
|
def reset_model_weights():
|
||
|
st.session_state.model_slider_values = [2, 12, 43, 12, 12]
|
||
|
st.session_state.reset_trigger += 1
|
||
|
|
||
|
# 初始化 session state 中的键
|
||
|
if 'model_slider_values' not in st.session_state:
|
||
|
st.session_state.model_slider_values = [2, 12, 43, 12, 12]
|
||
|
if 'reset_trigger' not in st.session_state:
|
||
|
st.session_state.reset_trigger = 0
|
||
|
|
||
|
col1, col2 = st.columns([0.8, 0.2])
|
||
|
|
||
|
with col1:
|
||
|
# 使用 HTML 和内联CSS来增加字体大小
|
||
|
st.markdown("""
|
||
|
<div style='font-size: 34px; font-weight: bold;'>
|
||
|
模型加权
|
||
|
</div>
|
||
|
""", unsafe_allow_html=True)
|
||
|
|
||
|
with col2:
|
||
|
st.button("使用默认权重", key="hidden_button2", on_click=reset_model_weights)
|
||
|
col1, col2 = st.columns([0.8, 0.2])
|
||
|
with col1:
|
||
|
st.markdown('######')
|
||
|
# 创建滑块
|
||
|
columns = st.columns(5)
|
||
|
labels = [
|
||
|
"ARIMA",
|
||
|
"随机森林",
|
||
|
"VAR",
|
||
|
"SARIMA",
|
||
|
"LSTM"
|
||
|
]
|
||
|
descriptions = [
|
||
|
"自回归积分滑动平均模型。",
|
||
|
"适用于高维特征空间的预测问题。",
|
||
|
"向量自回归模型,适用多元数据。",
|
||
|
"季节性自回归积分滑动平均模型。",
|
||
|
"长期记忆网络模型。"
|
||
|
]
|
||
|
|
||
|
# 使用循环生成滑块
|
||
|
for i, col in enumerate(columns):
|
||
|
with col:
|
||
|
st.markdown(f"##### {labels[i]}")
|
||
|
st.markdown(descriptions[i]) # 使用 Markdown 来提供一致的文本框高度
|
||
|
value = st.slider(
|
||
|
label="none", # 使用空标签,因为标题和描述已包含足够信息
|
||
|
min_value=0,
|
||
|
max_value=100,
|
||
|
value=st.session_state.model_slider_values[i],
|
||
|
step=1,
|
||
|
key=f"model_slider_{i}_{st.session_state.reset_trigger}",
|
||
|
label_visibility = 'collapsed' # 隐藏标签
|
||
|
)
|
||
|
st.session_state.model_slider_values[i] = value
|
||
|
#从滑块获取模型权重
|
||
|
model_values_list = st.session_state.model_slider_values
|
||
|
# st.write('滑块数值:',model_values_list)
|
||
|
# print(model_values_list)
|
||
|
|
||
|
#基金预测函数
|
||
|
# 添加项目根目录到sys.path
|
||
|
import os
|
||
|
import sys
|
||
|
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), r'D:\python\djangoProject\\test_Bootstrap'))
|
||
|
sys.path.append(project_root)
|
||
|
from app_test.add_fund_data import add_fund_data
|
||
|
from app_test.VAR import VAR_run
|
||
|
from app_test.RF import RF_run
|
||
|
from app_test.ARIMA import ARIMA_run
|
||
|
import pandas as pd
|
||
|
import json
|
||
|
from pyecharts import options as opts
|
||
|
import streamlit.components.v1 as components
|
||
|
def fund_predect():
|
||
|
fund_code = st.session_state.fund_code
|
||
|
print(f'开始预测')
|
||
|
data = add_fund_data(fund_code)
|
||
|
VAR_result = VAR_run(data,'fund_data','')
|
||
|
power_var = model_values_list[2]/(model_values_list[1]+model_values_list[2])
|
||
|
power_rf = model_values_list[1] / (model_values_list[1] + model_values_list[2])
|
||
|
VAR_result = VAR_result.to_frame(name='fund_data')
|
||
|
print(VAR_result,type(VAR_result))
|
||
|
RF_result = RF_run(data,'fund_data',['liugan_index','infection_number_x', 'infection_number_y', 'jijin_data', 'shoupan'])
|
||
|
# print(ARIMA_run(data,'fund_data',['liugan_index','infection_number_x', 'infection_number_y', 'jijin_data', 'shoupan']))
|
||
|
print(RF_result,type(RF_result))
|
||
|
VAR = [item[0] for item in VAR_result.values.tolist()]
|
||
|
RF = [item[0] for item in RF_result.values.tolist()]
|
||
|
pre = [VAR[i]*power_var+RF[i]*power_rf for i in range(len(VAR))]
|
||
|
# 找到列表中的最小值和最大值
|
||
|
min_val = min(pre)
|
||
|
max_val = max(pre)
|
||
|
|
||
|
# 计算每个值相对于最小值的差异比例
|
||
|
pre = [(x - min_val) / (max_val - min_val) for x in pre]
|
||
|
|
||
|
# 将差异比例放大
|
||
|
pre= [x * 100 for x in pre]
|
||
|
print("放大差异后的列表:", pre)
|
||
|
print(pre,type(pre))
|
||
|
date_column = VAR_result.iloc[:, 0]
|
||
|
date = date_column.index.tolist()
|
||
|
date = [str(i)[:10] for i in date]
|
||
|
print('这是预测结果')
|
||
|
result = pd.DataFrame({
|
||
|
'date': date,
|
||
|
'prediction': pre
|
||
|
})
|
||
|
print(result,type(result))
|
||
|
#可视化预测结果
|
||
|
date_js = json.dumps(date)
|
||
|
data_js = json.dumps(pre)
|
||
|
print('预测结果可视化')
|
||
|
col = columns = st.columns(1)[0]
|
||
|
with col:
|
||
|
st.markdown(f"##### ")
|
||
|
st.markdown("基金编号:") # 使用 Markdown 来提供一致的文本框高度
|
||
|
# st.markdown()
|
||
|
result_visualization(date_js, data_js)
|
||
|
print('结束')
|
||
|
# 基金代码输入框和反馈信息
|
||
|
col1, col2 = st.columns([4, 1])
|
||
|
with col1:
|
||
|
# 使用 HTML 和 CSS 来定制标题样式
|
||
|
st.markdown("""
|
||
|
<style>
|
||
|
.big-bold {
|
||
|
font-size: 34px; /* 设置字体大小 */
|
||
|
font-weight: bold; /* 字体加粗 */
|
||
|
}
|
||
|
</style>
|
||
|
<p class='big-bold'>基金预测</p>
|
||
|
""", unsafe_allow_html=True)
|
||
|
# 创建一个输入框,使用 placeholder 参数设置提示语
|
||
|
fund_code = st.text_input('基金代码', placeholder='请输入基金代码', key='fund_code', on_change=fund_predect,
|
||
|
label_visibility='collapsed')
|
||
|
print(fund_code)
|
||
|
|
||
|
def result_visualization(date_js, data_js):
|
||
|
html_content = f"""
|
||
|
<style>
|
||
|
#echarts-container {{
|
||
|
position: fixed;
|
||
|
bottom: 0;
|
||
|
left: 50%;
|
||
|
transform: translateX(-50%);
|
||
|
width: 700px;
|
||
|
height: 300px;
|
||
|
background: #f5f5f5;
|
||
|
z-index: 100;
|
||
|
}}
|
||
|
</style>
|
||
|
<div id="echarts-container"></div>
|
||
|
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||
|
<script>
|
||
|
var main = echarts.init(document.getElementById("echarts-container"));
|
||
|
|
||
|
option = {{
|
||
|
backgroundColor: '#f5f5f5', // 设置背景颜色为浅灰色
|
||
|
legend: {{
|
||
|
data: ['基金预测结果']
|
||
|
}},
|
||
|
xAxis: {{
|
||
|
type: 'category',
|
||
|
data: {date_js}
|
||
|
}},
|
||
|
yAxis: {{
|
||
|
type: 'value'
|
||
|
}},
|
||
|
series: [{{
|
||
|
name: '国家流感中心周报数据',
|
||
|
data: {data_js},
|
||
|
type: 'line'
|
||
|
}}]
|
||
|
}};
|
||
|
main.setOption(option);
|
||
|
</script>
|
||
|
"""
|
||
|
|
||
|
# 使用 Streamlit 的 HTML 函数将 HTML 内容嵌入页面中
|
||
|
components.html(html_content, height=350)
|