发布时间:2024-02-02 15:30
为北交所构造一个股票指数,【北证50】,包含50个成分股。
文章目录
前言
一、股指构建流程
二、Python实现
1.引入库
2.绘制K线图函数
3.从含有多个股票数据的面板中抽取出某个股票的数据函数
4.判断调整股本系数函数
5.成分股筛选函数
6.股指计算函数(加权计算公式)
7.调用函数实现功能
总结
北交所目前没有一个成熟的指数,咱给他编一个。
一、基期和基点的确定:
基期:20211231
大部分股指是以某一固定日为基日。基于北交所的情况,选取其开市当年的年尾作为基日
基点:1000
基点参考沪深300指数
二、样本股的确定:
考虑到北交所上市不到180天,上市公司不到一百家,故根据日均成交金额剔除排名后25%的股票,再根据日均总市值对剩余股票进行排名,选取前50只股票作为样本股。
三、计算公式的确定
代码如下(示例):
import pandas as pd
import mplfinance as mpf
from datetime import datetime,timedelta
base_index = 1000 #基期的基点数确定为1000
def draw_candlepic(data, filename):
# 设置marketcolors
mc = mpf.make_marketcolors(
up=\'red\',
down=\'green\',
edge=\'i\',
wick=\'i\',
volume=\'in\',
inherit=True)
# 设置图形风格
s = mpf.make_mpf_style(
gridaxis=\'both\',
gridstyle=\'-.\',
y_on_right=False,
marketcolors=mc)
kwargs = dict(
type=\'candle\',
mav=(5, 10),
volume=True,
title=\"BJ stock exchange stock index\",
ylabel=\'Stock Index\',
ylabel_lower=\'Traded Volume\',
# figratio=(15, 10),
# figscale=5
)
pic = mpf.plot(data,
**kwargs,
style=s,
show_nontrading=False,
savefig=filename
)
return pic
def pro_daily_stock(code_val,data,start_val ,end_val):
\"\"\"
从含有多个股票数据的面板中抽取出某个股票的数据。
Parameters:
code_val - 要抽取的股票带代码
data - 含有股指成分股票的open、close、high、low、volume、流通股本、总股本数据的dataframe
start_val - 开始的时间
end_val - 结束的时间
Returns:
股指的open、close、high、low、volume、equity_all 、equity_mkt,dataframe。
Raises:
KeyError - raises an exception
\"\"\"
df = data.loc[data[\'Code\'] == code_val]
df = df[(df[\'Date\'] < end_val) & (df[\'Date\'] > start_val)]
#返回
return df
def adjusted_pro(proposition_all):
#print(proposition_all)
result = []
for proposition in proposition_all:
if(proposition <= 0.1):
result.append(proposition)
elif(proposition > 0.1 and proposition <= 0.2):
result.append(0.2)
elif(proposition > 0.2 and proposition <= 0.3):
result.append(0.3)
elif(proposition > 0.3 and proposition <= 0.4):
result.append(0.4)
elif(proposition > 0.4 and proposition <= 0.5):
result.append(0.5)
elif(proposition > 0.5 and proposition <= 0.6):
result.append(0.6)
elif(proposition > 0.6 and proposition <= 0.7):
result.append(0.7)
elif(proposition > 0.7 and proposition <= 0.8):
result.append(0.8)
elif(proposition > 0.8):
result.append(1.0)
#print(result)
return result
def component_select( stock_list , volum , value):
\"\"\"
对选入北交所股指的成分股进行筛选.
Parameters:
stock_list - 所有股票的代码列表
volum - 用于筛选的成交量列表
value - 用于筛选的市值列表
Returns:
被筛选进入股指的股票代码列表
Raises:
KeyError - raises an exception
\"\"\"
table = []
for stock, vol, val in zip(stock_list , volum , value):
table.append([stock, vol, val])
table.sort(key=lambda x : x[1],reverse=True)
table = table[0:int(3*(len(table)/4))]
table.sort(key=lambda x : x[2],reverse=True)
table = table[0:20]
return [i[0] for i in table]
#股指计算函数(加权计算公式)
def stockindex_cal(list_code, data , start_val, end_val):
\"\"\"
计算股指的open、close、high、low、volume数值,并返回dataframe。
Parameters:
list_code - 所有股票的代码列表
data - 含有股指成分股票的open、close、high、low、volume、流通股本、总股本数据的dataframe
start_val - 开始的时间
end_val - 结束的时间
Returns:
股指的open、close、high、low、volume,dataframe。
Raises:
KeyError - raises an exception
\"\"\"
dfopen_list = pd.DataFrame()
dfclose_list = pd.DataFrame()
dfhigh_list = pd.DataFrame()
dflow_list = pd.DataFrame()
dfvolumn_list = pd.DataFrame()
dfequity_adjusted_list = pd.DataFrame()
dfdatetime_list = pd.DataFrame()
i = 0
j = []
stock_dati = pro_daily_stock(list_code[0],data, start_val, end_val)
dfdatetime_list = stock_dati[\'Date\']
for code in list_code:
print(i,\"股票代码:\",code)
stock_dati = pro_daily_stock(code,data, start_val, end_val)
#dfdatetime_list[i] = stock_dati[\'Date\']
#stock_dati.info()
##更新数值,叠加序列
proposition_all = []
for a,b in zip(stock_dati[\'equity_mkt\'] , stock_dati[\'equity_all\']):
proposition_all.append(a/b)
dfequity_adjusted_list[i] = (np.multiply(np.array(stock_dati[\'equity_all\']),np.array(adjusted_pro(proposition_all)))).tolist()
dfopen_list[i] = (np.multiply(np.array(stock_dati[\'Open\']),np.array(dfequity_adjusted_list[i]))).tolist()
dfclose_list[i] = (np.multiply(np.array(stock_dati[\'Close\']),np.array(dfequity_adjusted_list[i]))).tolist()
dfhigh_list[i] = (np.multiply(np.array(stock_dati[\'High\']),np.array(dfequity_adjusted_list[i]))).tolist()
dflow_list[i] = (np.multiply(np.array(stock_dati[\'Low\']),np.array(dfequity_adjusted_list[i]))).tolist()
dfvolumn_list[i] = stock_dati[\'Volume\'].tolist()
j.append(dfequity_adjusted_list[i])
i = i + 1
new_j = []
for column in range(len(j[0])):
total = 0
# print(\"column = \",column)
for i in range(len(j)):
total += j[i][column]
new_j.append(total)
df_new_j = pd.DataFrame(new_j)
#
print(pd.concat([dfopen_list,df_new_j],axis=1,ignore_index=True).index)
stockindex = pd.DataFrame()
stockindex[\'Open\'] = pd.concat([dfopen_list,df_new_j],axis=1,ignore_index=True).apply(lambda x: x[0:len(x)-2].sum()/x[len(x)-1], axis=1)
stockindex[\'Close\'] = pd.concat([dfclose_list,df_new_j],axis=1,ignore_index=True).apply(lambda x: x[0:len(x)-2].sum()/x[len(x)-1], axis=1)
stockindex[\'High\'] = pd.concat([dfhigh_list,df_new_j],axis=1,ignore_index=True).apply(lambda x: x[0:len(x)-2].sum()/x[len(x)-1], axis=1)
stockindex[\'Low\'] = pd.concat([dflow_list,df_new_j],axis=1,ignore_index=True).apply(lambda x: x[0:len(x)-2].sum()/x[len(x)-1], axis=1)
stockindex[\'Volume\'] = dfvolumn_list.apply(lambda x: x.sum(), axis=1)
coefficient = 1000 / stockindex[\'Open\'][0]
stockindex[\'Open\'] = stockindex[\'Open\'] *coefficient
stockindex[\'Close\'] = stockindex[\'Close\'] *coefficient
stockindex[\'High\'] = stockindex[\'High\'] *coefficient
stockindex[\'Low\'] = stockindex[\'Low\'] *coefficient
stockindex.index = dfdatetime_list
return stockindex
#获取数据
filepath = r\'\'#北交所股票数据文件位置
df_data = pd.read_excel(filepath)
df_data=df_data[~df_data.isin([\'--\'])]
df_data=df_data[~df_data.isin([\'#VALUE!\'])]
df_data[\'Date\'] = pd.to_datetime(df_data[\'Date\'])
df_data.dropna(inplace = True)
name = [\'Code\',\'Date\']
for (columnName, columnData) in df_data.iteritems():
if(columnName not in name):
df_data[columnName] = df_data[columnName].astype(\'float\')
benchemarkday = \'2021-12-31\'
df_data_benchemarkday = df_data[df_data[\'Date\'] == benchemarkday]
#print(df_data_benchemarkday)
#对应代码 选取市值前十的编制指数
list_code = component_select(list(df_data_benchemarkday[\'Code\']),list(df_data_benchemarkday[\'Volume\']),list(df_data_benchemarkday[\'Value\']))
#print(list_code)
BJstockindex = stockindex_cal(list_code,df_data,datetime(2021,12,31), datetime(2022,4,29))
print(BJstockindex)
BJstockindex.info()
BJstockindex.to_excel(r\'\')#股指行情数据存储位置
#绘制版块K线图
filename = r\'\'#k线图存储位置
pic = draw_candlepic(BJstockindex, filename)
mpf.plot(BJstockindex)
print(\"成分股包括\",len(list_code),\"个:\",list_code)
结果
北交所【北证50】行情数据:
Date | Open | Close | High | Low | Volume |
2022-01-04 00:00:00 | 1000 | 986.5408 | 1022.178 | 953.5873 | 80598800 |
2022-01-05 00:00:00 | 989.2613 | 954.2665 | 1006.629 | 936.4114 | 1.03E+08 |
2022-01-06 00:00:00 | 946.8143 | 945.2824 | 969.7085 | 911.8832 | 77924100 |
2022-01-07 00:00:00 | 942.4053 | 915.9837 | 958.7197 | 911.758 | 60408800 |
2022-01-10 00:00:00 | 912.706 | 929.5972 | 946.6833 | 901.8682 | 52655000 |
2022-01-11 00:00:00 | 938.3407 | 934.82 | 960.3012 | 922.3229 | 55217800 |
2022-01-12 00:00:00 | 942.1217 | 939.1366 | 951.3516 | 916.4603 | 45396100 |
2022-01-13 00:00:00 | 939.2697 | 927.4674 | 963.4592 | 905.494 | 83014200 |
2022-01-14 00:00:00 | 914.5249 | 927.7141 | 943.0316 | 899.8858 | 60246600 |
2022-01-17 00:00:00 | 925.4504 | 955.1867 | 977.8098 | 912.5262 | 75765800 |
2022-01-18 00:00:00 | 960.5596 | 940.2313 | 980.2006 | 921.9308 | 76349300 |
2022-01-19 00:00:00 | 944.1635 | 935.6306 | 971.2086 | 911.5943 | 61660000 |
2022-01-20 00:00:00 | 934.9683 | 938.9257 | 978.9594 | 908.132 | 95134700 |
2022-01-21 00:00:00 | 1028.6 | 1023.601 | 1050.957 | 1001.908 | 72205400 |
2022-01-24 00:00:00 | 1010.445 | 1024.021 | 1051.696 | 981.6646 | 54250600 |
2022-01-25 00:00:00 | 1019.272 | 981.6793 | 1036.821 | 974.0316 | 51871600 |
2022-01-26 00:00:00 | 983.0435 | 988.1808 | 1014.898 | 965.7074 | 50068600 |
2022-01-27 00:00:00 | 992.7041 | 974.8998 | 1011.379 | 963.4773 | 46187500 |
2022-01-28 00:00:00 | 977.2909 | 987.1041 | 1005.311 | 949.9261 | 40265700 |
2022-02-07 00:00:00 | 999.698 | 994.0131 | 1014.872 | 983.5998 | 32720800 |
2022-02-08 00:00:00 | 990.8865 | 987.0471 | 1002.264 | 960.0484 | 29712700 |
2022-02-09 00:00:00 | 1450.09 | 1466.217 | 1483.445 | 1423.855 | 37139700 |
2022-02-10 00:00:00 | 1428.835 | 1378.052 | 1442.228 | 1373.028 | 33087300 |
2022-02-11 00:00:00 | 1368.167 | 1286.253 | 1385.1 | 1262.891 | 40672700 |
2022-02-14 00:00:00 | 1295.337 | 1247.96 | 1323.363 | 1212.197 | 44993000 |
2022-02-15 00:00:00 | 1250.372 | 1273.998 | 1299.66 | 1225.309 | 39029600 |
2022-02-16 00:00:00 | 1276.899 | 1263.539 | 1307.824 | 1241.128 | 29390200 |
2022-02-17 00:00:00 | 1268.484 | 1305.274 | 1367.227 | 1249.467 | 38378700 |
2022-02-18 00:00:00 | 1300.815 | 1304.83 | 1336.585 | 1266.32 | 34889700 |
2022-02-21 00:00:00 | 1351.581 | 1323.68 | 1366.376 | 1291.069 | 46562100 |
2022-02-22 00:00:00 | 1294.972 | 1284.721 | 1333.129 | 1272.243 | 40648000 |
2022-02-23 00:00:00 | 1274.881 | 1329.058 | 1345.19 | 1271.517 | 31787500 |
2022-02-24 00:00:00 | 1313.74 | 1278.999 | 1341.771 | 1249.304 | 47591400 |
2022-02-25 00:00:00 | 1295.946 | 1299.368 | 1330.629 | 1280.885 | 28000000 |
2022-02-28 00:00:00 | 1283.309 | 1294.169 | 1314.167 | 1267.874 | 26582000 |
2022-03-01 00:00:00 | 1312.017 | 1332.495 | 1354.694 | 1289.717 | 23780100 |
2022-03-02 00:00:00 | 1340.972 | 1340.7 | 1353.752 | 1300.461 | 23910000 |
2022-03-03 00:00:00 | 1352.794 | 1329.664 | 1385.332 | 1310.594 | 42113000 |
2022-03-04 00:00:00 | 1306.006 | 1279.347 | 1321.759 | 1266.478 | 30435200 |
2022-03-07 00:00:00 | 1283.316 | 1223.638 | 1292.16 | 1204.202 | 24980100 |
2022-03-08 00:00:00 | 1220.691 | 1145.845 | 1229.332 | 1138.984 | 30382200 |
2022-03-09 00:00:00 | 1167.263 | 1143.331 | 1178.242 | 1085.955 | 27911700 |
2022-03-10 00:00:00 | 1194.332 | 1178.875 | 1205.584 | 1158.722 | 25295200 |
2022-03-11 00:00:00 | 1148.767 | 1186.108 | 1198.658 | 1128.707 | 32567800 |
2022-03-14 00:00:00 | 1175.973 | 1145.295 | 1191.162 | 1125.298 | 30073600 |
2022-03-15 00:00:00 | 1119.607 | 1101.183 | 1148.451 | 1083.695 | 29185900 |
2022-03-16 00:00:00 | 1125.492 | 1142.168 | 1159.565 | 1070.374 | 40329000 |
2022-03-17 00:00:00 | 1170.873 | 1201.55 | 1272.452 | 1151.441 | 64867900 |
2022-03-18 00:00:00 | 1190.577 | 1226.283 | 1249.543 | 1167.585 | 39864200 |
2022-03-21 00:00:00 | 1226.993 | 1242.745 | 1261.102 | 1209.557 | 34461500 |
2022-03-22 00:00:00 | 1239.708 | 1253.67 | 1277.65 | 1188.961 | 35634000 |
2022-03-23 00:00:00 | 1245.819 | 1229.006 | 1292.028 | 1217.96 | 33735700 |
2022-03-24 00:00:00 | 1219.059 | 1231.971 | 1252.869 | 1194.718 | 41297500 |
2022-03-25 00:00:00 | 1232.595 | 1165.315 | 1243.135 | 1156.427 | 33959000 |
2022-03-28 00:00:00 | 1162.159 | 1136.051 | 1178.955 | 1114.905 | 24276300 |
2022-03-29 00:00:00 | 1146.782 | 1139.965 | 1170.548 | 1123.653 | 18767600 |
2022-03-30 00:00:00 | 1125.18 | 1176.721 | 1193.722 | 1116.72 | 18174700 |
2022-03-31 00:00:00 | 1184.614 | 1159.233 | 1202.292 | 1138.03 | 26247300 |
2022-04-01 00:00:00 | 1150.849 | 1148.865 | 1175.49 | 1129.803 | 31485500 |
2022-04-06 00:00:00 | 1152.652 | 1142.254 | 1168.794 | 1134.1 | 18058400 |
2022-04-07 00:00:00 | 1143.542 | 1109.45 | 1148.069 | 1098.292 | 27544100 |
2022-04-08 00:00:00 | 1104.86 | 1091.087 | 1116.109 | 1067.896 | 16668200 |
2022-04-11 00:00:00 | 1087.215 | 1038.793 | 1088.858 | 1020.6 | 16673700 |
2022-04-12 00:00:00 | 1032.911 | 1049.588 | 1060.75 | 1026.167 | 16275600 |
2022-04-13 00:00:00 | 1035.516 | 1022.78 | 1048.966 | 1010.46 | 13224300 |
2022-04-14 00:00:00 | 1035.141 | 998.5331 | 1046.152 | 987.6233 | 19209800 |
2022-04-15 00:00:00 | 992.672 | 960.7639 | 999.4594 | 953.5972 | 18066900 |
2022-04-18 00:00:00 | 965.4588 | 1036.804 | 1051.604 | 945.1813 | 16440500 |
2022-04-19 00:00:00 | 1028.708 | 1011.64 | 1045.359 | 1000.62 | 14490700 |
2022-04-20 00:00:00 | 1013.811 | 989.1011 | 1019.696 | 973.8115 | 15203200 |
2022-04-21 00:00:00 | 988.0004 | 953.9597 | 996.0003 | 944.6672 | 17631900 |
2022-04-22 00:00:00 | 941.2076 | 953.4744 | 972.9929 | 925.416 | 16280500 |
2022-04-25 00:00:00 | 945.9288 | 899.1527 | 955.1544 | 883.6141 | 20358500 |
2022-04-26 00:00:00 | 914.9489 | 862.8075 | 928.0836 | 851.0499 | 18024600 |
2022-04-27 00:00:00 | 844.578 | 920.8308 | 932.3685 | 823.7524 | 21012500 |
2022-04-28 00:00:00 | 913.7189 | 899.2154 | 935.7863 | 885.6944 | 17545400 |
数据点我主页查找