qnloft-stock/fp/行情指数数据.py

251 lines
9.1 KiB
Python
Raw Permalink Normal View History

2023-11-24 06:42:22 +00:00
from datetime import timedelta
import numpy as np
import pandas
from utils.comm import *
class AllIndex:
# 中国的指数
ZH_INDEX = pd.DataFrame(
[["上证指数", "000001.SH"], ["深证成指", "399001.SZ"], ["创业板指", "399006.SZ"], ["中证100", "000903.SH"],
["中证100", "399903.SZ"]],
columns=['name', 'value'])
# 世界的指数
GLOBAL_INDEX = ['道琼斯', '标普500', '纳斯达克', '恒生指数', '日经225', '韩国KOSPI', '美元指数']
METAL_INDEX = pd.DataFrame(
[["黄金", "Au99.99"]
# , ["白银", "Ag99.99"]
], columns=['name', 'value'])
def __init__(self, trade_date):
self.trade_date = trade_date.strftime('%Y%m%d')
self.start_date = return_trading_day(trade_date, -29)
self.end_date = self.trade_date
def calendar_page_json(self):
"""
日历页面数据只要A股指数
获取1年内的全部数控生成一个json文件
:return:
"""
# 计算一年前的日期
start_date = datetime.strptime(self.end_date, '%Y%m%d') - timedelta(days=365)
start_date = start_date.strftime("%Y%m%d")
# 在首页显示 这三个的当日最新涨跌情况
index_page_display = ["000001.SH", "399001.SZ", "399006.SZ"]
res_pandas = pandas.DataFrame(columns=['title', 'start', 'textColor', 'backgroundColor'])
for stock in index_page_display:
for _ in range(5):
try:
# 获取单个指数日线行情
df = xcsc_pro.index_daily(
ts_code=stock,
start_date=start_date,
end_date=self.end_date,
fields="ts_code,trade_date,pct_chg")
break
except Exception as e:
print("获取单个指数日线行情 出现问题:", e)
time.sleep(1)
continue
else:
print("重试5次依然没有解决问题请重视~")
return None
# 获取对应的中文名称
name = self.ZH_INDEX.loc[self.ZH_INDEX['value'] == stock, 'name'].iloc[0]
df['pct_chg_format'] = (round(df['pct_chg'], 2)).astype("str") + "%"
df['title'] = name + " --> " + df['pct_chg_format']
# 将字符串转换为日期时间对象
df['trade_date'] = pd.to_datetime(df['trade_date'])
# 格式化日期时间列为 "YYYY-MM-DD" 形式
df['start'] = df['trade_date'].dt.strftime("%Y-%m-%d")
# 设置条件
conditions = [
(df['pct_chg'] > 1),
(df['pct_chg'] < -1),
((-1 <= df['pct_chg']) & (df['pct_chg'] < 0)),
((0 < df['pct_chg']) & (df['pct_chg'] <= 1))
]
# 字体颜色 当涨跌幅大于1的时候将字体颜色设置成白色 #e60000
text_colors = ['#ffffff', '#ffffff', '#5fcf57', '#e60000']
df['textColor'] = np.select(conditions, text_colors)
# 背景颜色
background_colors = ['#e60000', '#5fcf57', '#ffffff', '#ffffff']
df['backgroundColor'] = np.select(conditions, background_colors)
df = df[['title', 'start', 'textColor', 'backgroundColor']]
res_pandas = pd.concat([res_pandas, df], ignore_index=True)
return res_pandas
def html_page_data(self):
# A股指数
a_all_df, a_table_date, a_home_page_df = self.a_data()
# 全球部分指数
g_all_df, g_table_date, g_home_page_df = self.global_index()
# 贵金属行情
s_all_df, s_table_date, s_home_page_df = self.spot_hist_sge()
# 生成首页的徽章
badge = ""
badge += self.__create_badge(a_home_page_df)
badge += self.__create_badge(g_home_page_df)
badge += self.__create_badge(s_home_page_df)
# 生成 指数数据 页
card_deck_df = pd.concat([a_table_date, g_table_date], axis=0)
card_deck_df = pd.concat([card_deck_df, s_table_date], axis=0)
card_deck = self.__create_card_deck(card_deck_df)
return badge, card_deck
def __create_badge(self, df):
# 生成首页的徽章
badge = ""
for index, row in df.iterrows():
badge_color = "badge-success"
if row['pct_chg'] > 0:
badge_color = "badge-danger"
badge += f"<div class='col-md-auto'><span class='badge badge-pill {badge_color}'>{row['name']}{row['pct_chg']}</span></div>"
return badge
def __create_card_deck(self, df):
grouped = df.groupby('name')
card_deck = '<div class="card-deck">'
row = 1
for group_name, group_df in grouped:
card_deck_color = "border-success"
if group_df.head(1)["pct_chg"].values[0] > 0:
card_deck_color = "border-danger"
card_deck += f'<div class="card {card_deck_color} mb-3" style="max-width: 14rem;">' \
f'<div class="card-header">{group_name}</div>' \
f'<div class="card-body {"text-danger" if group_df.head(1)["pct_chg"].values[0] > 0 else "text-success"}">' \
f'<h4 class="card-title">{round(group_df.head(1)["close"].values[0], 2)}</h4>' \
f'<p class="card-text row">' \
f'<span class="{"text-danger" if group_df.head(2)["pct_chg"].values[1] > 0 else "text-success"} ml-3">' \
f'{round(group_df.head(2)["close"].values[1], 2)}' \
f'</span>' \
f'<span class="{"text-danger" if group_df.head(3)["pct_chg"].values[2] > 0 else "text-success"} ml-auto mr-3">' \
f'{round(group_df.head(3)["close"].values[2], 2)}' \
f'</span>' \
f'</p>' \
f'</div>' \
f'</div>'
if row % 5 == 0:
card_deck += '</div>'
print(f"{row - 1} -- >> {len(grouped)}")
if row != len(grouped):
card_deck += '<div class="card-deck">'
if row % 5 != 0 and row == len(grouped):
card_deck += '</div>'
row += 1
return card_deck
def a_data(self):
"""
A股指数数据
返回 1个月内31
:return:
"""
# 在首页显示 这三个的当日最新涨跌情况
index_page_display = ["000001.SH", "399001.SZ", "399006.SZ"]
all_df, home_page_df, table_df = pd.DataFrame(), pd.DataFrame(), pd.DataFrame()
for index, row in self.ZH_INDEX.iterrows():
print(self.start_date, " --- >>", self.end_date)
# 获取单个指数日线行情
for _ in range(5):
try:
df = xcsc_pro.index_daily(ts_code=row['value'], start_date=self.start_date,
end_date=self.end_date,
fields="ts_code,trade_date,pct_chg,close")
break
except Exception as e:
print("获取单个指数日线行情 出现问题:", e)
continue
else:
print("重试5次依然没有解决问题请重视~")
return None
df['pct_chg'] = df['pct_chg'].round(2)
df['name'] = self.ZH_INDEX.loc[self.ZH_INDEX['value'] == row['value'], 'name'].iloc[0]
# 一个月的数据
all_df = pd.concat([all_df, df], axis=0)
if index_page_display.count(row['value']):
print(df)
# 一日的数据
home_page_date = df.head(1)
home_page_df = pd.concat([home_page_df, home_page_date], axis=0)
# 三日的数据
table_df_date = df.head(3)
table_df = pd.concat([table_df, table_df_date], axis=0)
return all_df, table_df, home_page_df
def global_index(self):
"""
国外部分指数数据
3日内的涨跌幅
1个月内的折线图
:return:
"""
all_df, table_df, home_page_df = pd.DataFrame(), pd.DataFrame(), pd.DataFrame()
for i in self.GLOBAL_INDEX:
for _ in range(5):
try:
df = qs.get_data(i)
break
except Exception as e:
print(f"国外部分指数数据【{i}】拉取出现错误,", e)
continue
else:
print("重试5次依然没有解决问题请重视~")
return None
df['pct_chg'] = round(((df['close'] - df['open']) / df['open']) * 100, 2)
all_df_date, table_df_date, home_page_data = df.tail(30), df.tail(3), df.tail(1)
all_df = pd.concat([all_df, all_df_date], axis=0)
table_df = pd.concat([table_df, table_df_date], axis=0)
home_page_df = pd.concat([home_page_df, home_page_data], axis=0)
# pct_chg = global_df.groupby('name')['pct_chg'].apply(list).reset_index()
# print(pct_chg)
return all_df, table_df, home_page_df
def oil_index(self): # 油价
# 调价日期
energy_oil_hist_df = ak.energy_oil_hist()
print(energy_oil_hist_df)
formatted_date = energy_oil_hist_df['调整日期'].iloc[-3].strftime('%Y%m%d')
# 地区油价
energy_oil_detail_df = ak.energy_oil_detail(date=formatted_date)
energy_oil_detail_df = energy_oil_detail_df[energy_oil_detail_df['地区'] == '北京']
print(energy_oil_detail_df)
def spot_hist_sge(self):
all_df, table_df, home_page_df = pd.DataFrame(), pd.DataFrame(), pd.DataFrame()
for index, row in self.METAL_INDEX.iterrows():
for _ in range(5):
try:
df = ak.spot_hist_sge(symbol=row['value'])
break
except Exception as e:
print(f"上海黄金交易所-数据资讯-行情走势-历史数据,", e)
continue
else:
print("重试5次依然没有解决问题请重视~")
return None
df['name'] = self.METAL_INDEX.loc[self.METAL_INDEX['value'] == row['value'], 'name'].iloc[0]
df['pct_chg'] = round(((df['close'] - df['open']) / df['open']) * 100, 2)
all_df_date, table_df_date, home_page_data = df.tail(30), df.tail(3), df.tail(1)
all_df = pd.concat([all_df, all_df_date], axis=0)
table_df = pd.concat([table_df, table_df_date], axis=0)
home_page_df = pd.concat([home_page_df, home_page_data], axis=0)
return all_df, table_df, home_page_df
if __name__ == '__main__':
# current_date = datetime.now().strftime('%Y%m%d')
current_date = datetime.strptime('20230918', "%Y%m%d")
# if if_run(current_date):
index = AllIndex(trade_date=current_date)
# index.a_index()
badge, card_deck = index.html_page_data()
print(badge)