中证300、500、800成分股调整时间

本文介绍了一个Python函数,用于生成沪深300、500和800指数成分股的调整日期,以及如何从这些日期中随机选择一个区间进行分析。函数首先获取每年的交易日,然后确定每年六月和十二月的调整日期。

 

 

'''
函数get_rng(start_year=None,end_year=None)得到的是每次指数成分股改变时的开始日期
在函数get_interval(start_year,end_year)中得到一个完整的周期
'''

from datetime import datetime
def get_rng(start_year=None,end_year=None):
    '''
    输入起始结束年份,得到300,500,800指数成分股调整日期。
    
    '''
    y = pd.date_range(start_year,end_year,freq='Y')
    start_rng = pd.Series(index=pd.date_range(start_year,end_year,freq='WOM-2FRI'))
    rng = list()
    
    def june(i):
        June = '6-'+str(i.year)
        start_date = start_rng.loc[June].index[0]
        date = pd.to_datetime(jd.get_trade_days(start_date=str(i.year)+'-06-01', end_date=str(i.year)+'-06-30'))
        
        d = date[date > start_date]
        return d[0]
    
    def dec(i):
        Dec = '12-'+str(i.year)
        start_date = start_rng.loc[Dec].index[0]
        date = pd.to_datetime(jd.get_trade_days(start_date=str(i.year)+'-12-01', end_date=str(i.year)+'-12-30'))
        
        d = date[date > start_date]
        return d[0]
    
    for i in y:
        if datetime.now() > june(i):
            rng.append(june(i))
            
        if datetime.now() > dec(i):  
            rng.append(dec(i))
        
    return rng

rng = get_rng(start_year='2010',end_year='2021')

import numpy.random as npr
def get_interval(start_year,end_year):
    
    rng = get_rng(start_year=start_year,end_year=end_year)
    #生成随机数,随机选取一个区间
    ind = npr.randint(0,len(rng))
    start_date = rng[ind].strftime('%Y-%m-%d')
    #适当处理得到结束日期
    end_date = jd.get_trade_days(end_date=rng[ind+1],count=2)[0]

    return (start_date,end_date)

start_date,end_date = get_interval(start_year='2010',end_year='2021')

要根据您的需求构建一个基于Fama-French三因子模型扩展的五因子选股模型,并进行量化策略回测,我们可以将整个过程分为以下几个步骤: 1. **获取数据**:从金融数据库(如Wind、Tushare等)下载中800指数成分股的历史价格、财务指标等相关数据。 2. **计算特征值**: - 市场超额收益率 (Market Return Premium); - 市销率 (P/S Ratio, Price-to-Sales); - 流通市值 (Circulating Market Capitalization); - 利润总额同比增长率 (Growth Rate of Total Profit); - 流动比率 (Current Ratio). 3. **执行回归分析**:使用线性回归拟合每个股票在这五个因子上的暴露系数,得到每只股票的因子权重。 4. **组合优化**:依据回归结果构造投资组合并分配权重。 5. **模拟交易**:设定每月调仓规则,在给定日期范围内运行策略。 下面是完整的 Python 实现代码示例。为了简化演示逻辑,这里假设您已经安装了 `tqdm` 和 `statsmodels` 库用于进度条显示和统计建模任务;同时假设有可用的数据源接口供查询所需字段信息。 ```python import numpy as np import pandas as pd from datetime import datetime, timedelta from statsmodels.api import OLS # 参数设置 index_code = "000906.SH" # 中800指数代号 start_date = '2022-09-01' end_date = '2023-08-01' holding_stocks_num = 20 rebalance_freq_days = 30 def fetch_data(index_code, start_dt, end_dt): """ 模拟函数: 获取指定时间范围内的所有标的及其基本面/行情数据 """ symbols_df = get_index_members(index_code=index_code, from_date=start_dt, to_date=end_dt) symbol_list = list(set(symbols_df['symbol'])) data_dict = {} for ticker in tqdm(symbol_list): daily_price = get_stock_prices(ticker=ticker, interval='daily', start_time=start_dt, end_time=end_dt) financials = get_financial_ratios(ticker=ticker, ratios=['ps_ratio', 'circulating_mcap', 'profit_growth_rate', 'current_ratio'], period_type="quarterly", fiscal_year_end_month=12) merged_data = merge_datasets(daily_returns=daily_price.pct_change(), fundamentals=financials).dropna() if not merged_data.empty: data_dict[ticker] = merged_data return data_dict class StrategyBacktester(object): def __init__(self, stock_universe, factor_names): self.stock_universe = stock_universe self.factor_names = factor_names def run(self): portfolio_weights_history = [] current_portfolio = [] rebalance_dates = generate_rebalancing_schedule(start=self.start_date, stop=self.end_date, freq=rebalance_freq_days) for i, date in enumerate(rebalance_dates[:-1]): next_date = rebalance_dates[i + 1] print(f"\nRebalancing on {date}") universe_subset = filter_universe_by_trading_period(universe=self.stock_universe, start=date.strftime('%Y-%m-%d'), end=next_date.strftime('%Y-%m-%d')) X_matrix, y_vector = prepare_regression_inputs(dataframes=list(universe_subset.values()), factors_of_interest=self.factor_names) weights = estimate_factor_loadings(X=X_matrix, Y=y_vector) selected_tickers = rank_and_select_top_n(weights=weights.flatten(), n=holding_stocks_num) updated_portfolo = adjust_positions(current=current_portfolio, target_selection=selected_tickers, weight_allocation_method=lambda _: equal_weighting()) portfolio_weights_history.append(updated_portfolo.copy()) current_portfolio = updated_portfolo @staticmethod def evaluate_performance(portfolio_records): pass # TODO Implement performance metrics calculation. if __name__ == "__main__": raw_dataset = fetch_data(index_code=index_code, start_dt=datetime.strptime(start_date,'%Y-%m-%d').isoformat(), end_dt=(datetime.today() - timedelta(days=1)).strftime("%Y-%m-%d")) strategy = StrategyBacktester(stock_universe=raw_dataset, factor_names=["MKT_RF", "PS_RATIO", "CMCAP", "PROFIT_GROWTH", "CURRENT_RATIO"]) results = strategy.run() ``` ### 解释 这段脚本实现了以下功能: 1. 定义了一个名为 `fetch_data()` 的辅助函数用来抓取目标指数所覆盖的所有个股的相关资料。 2. 创建了主类 `StrategyBacktester`, 其职责包括管理周期性的再平衡操作以及生成相应的资产配置方案。 3. 在每次迭代期间完成如下动作: * 过滤出符合当前时段内有效的券列表; * 构造输入矩阵 \(X\) 包含各影响因素,输出向量\(y\) 表达期望收益; * 计算每种产品的负载情况并通过评分挑选最优者集合; * 根据最新选择重新校正持仓比例直至结束循环。 请注意此版本省略了一些细节实现例如实际连接API请求具体数值填充等内容留待自行补充完善即可满足实战用途。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值