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.
68 lines
3.6 KiB
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') # 获取回测结果,回测周期内每一天的组合净值
|
|
|