def fund_nav_daily(code: str) -> pd.DataFrame: assert code[0] == 'f' code = code[1:] df = ak.fund_em_open_fund_info(code, indicator="单位净值走势") # print(df) df2 = ak.fund_em_open_fund_info(code, indicator="累计净值走势") df = pd.merge(df, df2, on='净值日期', how='outer') df2 = ak.fund_em_open_fund_info(code, indicator="同类排名百分比") # print(df2) df2 = df2.rename({'报告日期': '净值日期'}, axis=1) df = pd.merge(df, df2, on='净值日期', how='outer') df = df.rename( { '净值日期': '_id', '单位净值': 'nav', '日增长率': 'growth_rate', '累计净值': 'cum_nav', '同类型排名-每日近3月收益排名百分比': 'rank_3m' }, axis=1) if df.dtypes['nav'] != np.dtype('float64'): df['nav'] = df['nav'].apply(lambda x: None if x is None else float(x)) if df.dtypes['cum_nav'] != np.dtype('float64'): df['cum_nav'] = df['cum_nav'].apply(lambda x: None if x is None else float(x)) df['_id'] = pd.to_datetime(df['_id']) print(df) return df
def fund_list(tscode): ts_name = tscode df = ak.fund_em_open_fund_info(fund="%s" % ts_name, indicator="单位净值走势") df.to_sql("%s" % ts_name, con=ak_engine, if_exists="append", index=False) x = df['净值日期'] y = df['单位净值'] return x, y
def combine_data(self, start, end, mat: pd.DataFrame, batch=30): df_list = [] for ix, row in list(mat.iterrows()): sleep(1) fund_code = row['fund_code'] fund_name = row['fund_name'] try: # print('fund_code:', fund_code) fund_em_info_df = ak.fund_em_open_fund_info(fund=fund_code) except: logger.warning(f'获取 {fund_code}-{fund_name} 失败') continue # print(fund_em_info_df.head()) fund_em_info_df.rename(columns={'净值日期': 'Date', '单位净值': 'price', '日增长率': 'ret'}, inplace=True) fund_em_info_df.Date = pd.to_datetime(fund_em_info_df.Date) # print(fund_em_info_df.head()) fund_em_info_df.price = fund_em_info_df.price.astype(float) fund_em_info_df.set_index('Date', inplace=True) fund_em_info_df.rename(columns={'price': fund_name}, inplace=True) df_list.append(fund_em_info_df[[fund_name]]) total_df = pd.concat(df_list, axis=1) total_df = total_df.loc[start:end, :] total_df.fillna(method='ffill', inplace=True) return total_df
def fetch_fund_em_open_fund_info(code='163412', path='./data/bs'): file = '%s/%s.csv' % (path, code) if os.path.exists(file): logger.info('%s already exists' % file) return df = ak.fund_em_open_fund_info(code, '累计净值走势') df.columns = ['date_time', 'accumulated_value'] df.to_csv(file, encoding='utf_8')
def filled_fund_data_df(fund_code): ''' <class 'pandas.core.frame.DataFrame'> RangeIndex: 3770 entries, 0 to 3769 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 净值日期 3770 non-null object 1 累计净值 3770 non-null object ''' src_df = ak.fund_em_open_fund_info(fund_code, indicator="累计净值走势") df_date_index = src_df.set_index('净值日期') date_rng = pd.date_range(df_date_index.index[0], df_date_index.index[len(df_date_index) - 1], freq="D") return df_date_index.reindex(date_rng, method='ffill')
def max_drawdown(fCode, cPeriod=0, sDate='', eDate=''): """ 计算历史数据区间某基金的最大回撤 :param fCode: 基金代码 :param cPeriod: 区间长度(天) :param sDate: 开始日期(yyyy-mm-dd) :param eDate: 结束日期(yyyy-mm-dd) :return: 最大回撤(%) """ # 排除非法参数: 1) cPeriod与(sDate或eDate)同时出现 2) 有sDate无eDate 3) 有eDate无sDate if (cPeriod and (sDate or eDate)) or (sDate and not eDate) or (eDate and not sDate): raise ValueError("Illegal Argument") # 用akshare获取:开放式基金-历史数据 fInfo = ak.fund_em_open_fund_info(fund=fCode, indicator="单位净值走势") # 用cPeriod参数:选出历史数据区间 if cPeriod: fInfo = fInfo[-cPeriod:].reset_index(drop=True) # 用sDate和eDate参数:选出历史数据区间 elif sDate and eDate: sDate, eDate = datetime.strptime(sDate, "%Y-%m-%d").date(), datetime.strptime( eDate, "%Y-%m-%d").date() fInfo = fInfo.loc[(fInfo["净值日期"] >= sDate) & (fInfo["净值日期"] <= eDate)].reset_index(drop=True) # 舍弃无用的数据包 fInfo = fInfo["单位净值"] # 计算历史数据区间的最大回撤 maximumDrawdown = 0 for i in range(len(fInfo) - 1): for j in range(i + 1, len(fInfo)): drawdown = (fInfo["单位净值"][i] - fInfo["单位净值"][j]) / fInfo["单位净值"][i] if drawdown > maximumDrawdown: maximumDrawdown = drawdown return "{:.2%}".format(maximumDrawdown)
def test_load_fund_data(self): df = ak.fund_em_open_fund_info(fund="000217", indicator="单位净值走势") print(df.to_string())
df_spx['SPX'] = calc(df_spx['SPX']) df_spx.dropna(inplace=True) # For looking up other funds # df_funds = ak.fund_em_fund_name() # df_funds.query('基金代码=="096001"') funds_list = ['096001','161125','006075','050025','007722','007721'] # Putting the funds into one dataframe df_list = [] for fd in funds_list: df = ak.fund_em_open_fund_info(fund=fd, indicator="单位净值走势") df = df.drop(['equityReturn','unitMoney'],axis=1) df.rename(columns={'x':'date','y':fd},inplace=True) df[fd] = df[fd].astype(float) df.set_index('date',inplace=True) df_list.append(df) df_sum = pd.concat(df_list,axis=1,sort=True) df_sum.dropna(inplace=True) for fd in funds_list: df_sum[fd] = calc(df_sum[fd]) df_sum.index = pd.to_datetime(df_sum.index) df_spx.index = pd.to_datetime(df_spx.index)
df_rf = ak.rate_interbank(market="上海银行同业拆借市场", symbol="Shibor人民币", indicator="3月", need_page="1") print('无风险利率:' + str(df_rf['利率(%)'][0]) + '%\n') rf = np.power(1 + df_rf['利率(%)'][0] / 100, 1 / 360) - 1 # 转为日利率 # 随机抽取code_num只基金获取收益率数据并回归 codes = list(codes) random.shuffle(codes) print('基金代码' + '\t' + 'Alpha的T值') i = 0 while i < code_num and i < len(codes): code = codes[i] try: df_i = ak.fund_em_open_fund_info( fund=code, indicator="单位净值走势").rename(columns={'x': 'date'}) except: time.sleep(10) continue df_i = df_i[['净值日期', '日增长率']] if df_i['净值日期'].max().year - df_i['净值日期'].min().year < minYears: codes.pop(i) continue df_i['净值日期'] = df_i['净值日期'].apply(lambda date: time.strftime('%Y-%m-%d')) df_i['日增长率'] /= 100 df = pd.merge(df_M, df_i, how='inner', left_on='date', right_on='净值日期') y = df['日增长率'].apply(float).values - rf x = sm.add_constant(df['updown'].apply(float).values - rf) df['Ri'] = y df['Rm'] = df['updown'].apply(float).values - rf df.to_excel('./原始数据/' + code + '.xlsx')
def beat_benchmark_ratio(fCode, cPeriod=0, sDate='', eDate=''): # 排除非法参数: 1) cPeriod与(sDate或eDate)同时出现 2) 有sDate无eDate 3) 有eDate无sDate if (cPeriod and (sDate or eDate)) or (sDate and not eDate) or (eDate and not sDate): raise ValueError("Illegal Argument") # 用akshare获取:开放式基金-历史数据 fInfo = ak.fund_em_open_fund_info(fund=fCode, indicator="单位净值走势") # 舍弃无用的数据包 fInfo = fInfo[["净值日期", "单位净值"]] # 计算收益率为多少 rate = [(fInfo["单位净值"][i] - fInfo["单位净值"][i - 1]) / (fInfo["单位净值"][i - 1]) for i in range(1, len(fInfo))] fInfo = fInfo[1:] fInfo["rate"] = rate # 用cPeriod参数:选出历史数据区间 if cPeriod: fInfo = fInfo[-cPeriod:].reset_index(drop=True) # 用sDate和eDate参数:选出历史数据区间 elif sDate and eDate: f_sDate, f_eDate = datetime.strptime( sDate, "%Y-%m-%d").date(), datetime.strptime(eDate, "%Y-%m-%d").date() fInfo = fInfo.loc[(fInfo["净值日期"] >= f_sDate) & (fInfo["净值日期"] <= f_eDate)].reset_index(drop=True) # 舍弃无用的数据包 fInfo = fInfo["rate"] # 用akshare获取:沪深300-历史数据 benchmark = ak.stock_zh_index_daily(symbol="sh000300") # 把date转化为column而不是作为index,方便后面的历史数据区间的选中 benchmark = benchmark.reset_index().rename({'index': 'date'}, axis='columns') benchmark["date"] = benchmark["date"].apply( lambda x: x.to_pydatetime().date()) # 舍弃无用的数据包 benchmark = benchmark[["date", "close"]] # 计算收益率为多少 rate = [(benchmark["close"][i] - benchmark["close"][i - 1]) / (benchmark["close"][i - 1]) for i in range(1, len(benchmark))] benchmark = benchmark[1:] benchmark["rate"] = rate # 用cPeriod参数:选出历史数据区间 if cPeriod: benchmark = benchmark[-cPeriod:].reset_index(drop=True) # 用sDate和eDate参数:选出历史数据区间 elif sDate and eDate: b_sDate, b_eDate = datetime.strptime( sDate, "%Y-%m-%d").date(), datetime.strptime(eDate, "%Y-%m-%d").date() benchmark = benchmark.loc[(benchmark["date"] >= b_sDate) & ( benchmark["date"] <= b_eDate)].reset_index(drop=True) # 舍弃无用的数据包 benchmark = benchmark["rate"] # 计算区间内收益率击败沪深300的比例 benchmark = [ 1 if fInfo[i] > benchmark[i] else 0 for i in range(len(fInfo)) ] benchmark_ratio = Counter(benchmark)[1] / len(benchmark) return "{:.2%}".format(benchmark_ratio)
"HA-NSDK": "040046", "JS-XXCZ": "260108", "XQ-HR": "163406", "YFD-ZXP": "110011", "PH-HB": "000409", "PH-FL": "003547", "PH-FR": "000345", "PH-GM": "160644", "PH-KJ": "008811" } arr_fund_name = [] arr_fund_value = [] for fund_name, fund_code in fund_dict.items(): df_fund = ak.fund_em_open_fund_info(fund=fund_code, indicator="单位净值走势") df_fund = df_fund.set_index("净值日期") arr_fund_name.append(fund_name) arr_fund_value.append(df_fund["单位净值"][-1]) print(fund_name) time.sleep(1) for stock_name, stock_code in stock_dict.items(): df_stock = ak.stock_zh_a_daily(symbol=stock_code, start_date=e_date, end_date=e_date, adjust="qfq") arr_fund_name.append(stock_name) arr_fund_value.append(df_stock.loc[e_date, 'close']) print(stock_name) time.sleep(1)
#%% import akshare as ak #%% import akshare as ak fund_em_fund_name_df = ak.fund_em_fund_name() print(fund_em_fund_name_df) #%% fund_etf_hist_sina_df = ak.fund_etf_hist_sina( symbol="sz169103") print(fund_etf_hist_sina_df) #%% fund_em_info_df = ak.fund_em_open_fund_info( fund="163402", indicator="累计收益率走势") print(fund_em_info_df) #%% import akshare as ak js_news_df = ak.js_news(indicator='最新资讯') # js_news_df['content'] for i in range(len(js_news_df)): print(f"{js_news_df.iloc[i, 0]}") print(f"{js_news_df.iloc[i, 1]}") print() #%% import akshare as ak
import streamlit as st import akshare as ak import altair as alt my_fund = [{'code': '0001630', 'name': '天弘中证计算机主题ETF连接C'}] res = ak.fund_em_open_fund_info(fund="001630", indicator="单位净值走势") st.dataframe(res.iloc())
import akshare as ak # 沪深300 6% # fund_codes = '110020' # 上证50 fund_codes = '110003' fund_history = ak.fund_em_open_fund_info(fund_codes) print(fund_history) # 1 * (1 + x) ** 10 = 1.7974 # import math # # print(math.pow(2.4335, 1 / 15) - 1) # print((1 + 0.10) ** 10)
#!/usr/bin/python import akshare as ak import pandas as pd import matplotlib.pyplot as plt fund_num = '110003' #data="单位净值走势" data = "累计收益率走势" name_df = ak.fund_em_fund_name() fund_name = fund_num + name_df.loc[name_df['基金代码'] == fund_num]['基金简称'].item() df = ak.fund_em_open_fund_info(fund=fund_num, indicator=data) #df['日增长率']=df['日增长率'].astype('float') print(df) df.plot(x='净值日期', figsize=(20, 10), grid=True, title=fund_name).get_figure().savefig('fund.jpg') #df.plot(x='净值日期',figsize=(20,10),grid=True,title=fund_name,secondary_y=['日增长率']).get_figure().savefig('fund.jpg')