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.
 
 
 
 
 
 
alpha_tools/wq101alphas/alpha101_code/06-有效因子回测

68 lines
3.6 KiB

from WindPy import *
from datetime import *
from WindAlgo import *
from scipy.stats import rankdata
import numpy as np
import pandas as pd
from datetime import datetime
import scipy.stats as stats
import numpy.linalg as la
w.start()
alpha_data = alpha_m
def initialize(context):
context.capital = 10000000 # 回测的初始资金
context.securities = w.wset("sectorconstituent", "date=20140101;windcode=000906.SH").Data[1]
context.start_date = "20140104" # 回测开始时间
context.end_date = "20190530" # 回测结束时间
context.commission = 0.0003 # 手续费
context.alpha_data = alpha_data
context.benchmark = '000906.SH' # 设置回测基准
def handle_data(bar_datetime, context, bar_data):
pass
def my_schedule1(bar_datetime, context, bar_data):
bar_datetime_str = bar_datetime.strftime('%Y-%m-%d')
stock800 = w.wset("sectorconstituent", "date="+bar_datetime_str+";windcode=000906.SH").Data[1]
stocks = get_stocks(bar_datetime_str,stock800) # 获取筛选后的股票池
## 提取因子数据法
data = context.alpha_data.loc[bar_datetime_str].reset_index().set_index(['codes']).drop(columns = ['date']) #提取因子数据并调整结构
stock_v = list(set(stocks) & set(data.index))
data = data.loc[stock_v].dropna(axis=0) # 筛选出有效股票池对应数据
profit = w.wss(stock_v, "fa_oigr_ttm,pe_ttm", tradeDate=bar_datetime_str, usedf=True)[1] # 加入财务因子
profit.index = data.index
data['1/PEG'] = profit['FA_OIGR_TTM']/profit['PE_TTM']
data = data_process(data,bar_datetime_str) # 数据预处理
weight = [] # 因子加权权重
data = factor_sum(data,weight) # 因子打分
## 回测中计算法
# start_time = w.tdaysoffset(-5, bar_datetime_str,usedf=True).Data[0][0].strftime('%Y-%m-%d')
# close = w.wsd(stocks,'close',start_time,bar_datetime_str,usedf = True)[1].reset_index().drop(columns = ['index'])
# vwap = w.wsd(stocks,'vwap',start_time,bar_datetime_str,usedf = True)[1].reset_index().drop(columns = ['index'])
# alpha = {'alpha':alpha42(vwap,close).iloc[-1]}
# data = pd.DataFrame(alpha,index=stocks)
data = data.sort_values([data.columns.values[-1]],ascending=False) # 按打分大小排序
code_list = list(data[:round(len(stocks)/5)].index) # 选出top组股票
wa.change_securities(code_list) # 改变证券池
context.securities = code_list
list_sell = list(wa.query_position().get_field('code')) # 获取当前仓位股票池
for code in list_sell:
if code not in code_list:
volumn = wa.query_position()[code]['volume'] # 找到每个股票的持仓量
res = wa.order(code,volumn,'sell',price='close', volume_check=False)
def my_schedule2(bar_datetime, context,bar_data):
buy_code_list=list(set(context.securities)-(set(context.securities)-set(list(bar_data.get_field('code')))))
list_now = list(wa.query_position().get_field('code')) # 获取当前仓位股票池
for code in buy_code_list:
if code not in list_now:
res = wa.order_percent(code,1/len(buy_code_list),'buy',price='close', volume_check=False) # 等权买入
wa = BackTest(init_func = initialize, handle_data_func=handle_data) # 实例化回测对象
wa.schedule(my_schedule1, "w", 0) # w表示在每周执行一次策略,0表示偏移,表示月初第一个交易日往后0天
wa.schedule(my_schedule2, "w", 0)
res = wa.run(show_progress=True) # 调用run()函数开始回测,show_progress可用于指定是否显示回测净值曲线图
nav_df = wa.summary('nav') # 获取回测结果,回测周期内每一天的组合净值