import numpy as np
import pandas as pd
start = '2009-01-01'
end = '2018-12-31' # 回测结束时间
universe = DynamicUniverse('HS300') + DynamicUniverse('ZZ500')
benchmark = 'HS300' # 策略参考标准
freq = 'd' # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
refresh_rate = 20 # 调仓频率
accounts = {
'fantasy_account': AccountConfig(account_type='security', capital_base=10000000)
}
def initialize(context): # 初始化虚拟账户状态
context.signal_generator = SignalGenerator(Signal('ROE'), Signal('PE'), Signal('OperatingRevenueGrowRate'), Signal('PB'),Signal('NPParentCompanyGrowRate'),Signal('CurrentRatio'), Signal('CTOP'),Signal('REVS60'),Signal('REVS20'))
def handle_data(context): # 每个交易日的买入卖出指令
account = context.get_account('fantasy_account')
current_universe = context.get_universe(exclude_halt=True)
yesterday = context.previous_date.strftime('%Y-%m-%d')
signals = context.history(current_universe, ['PE', 'ROE', 'OperatingRevenueGrowRate', 'PB', 'NPParentCompanyGrowRate', 'CurrentRatio', 'CTOP', 'REVS60', 'REVS20'], 1, freq='1d', rtype='frame',style='tas')[yesterday]
signal1 = standardize((1.0 / winsorize(signals['PE'])).replace([np.inf, -np.inf], 0.0))
signal2 = standardize(winsorize(signals['ROE'].dropna()))
signal3 = standardize(winsorize(signals['OperatingRevenueGrowRate']))
signal4 = standardize((1.0 / winsorize(signals['PB'])).replace([np.inf, -np.inf], 0.0))
signal5 = standardize(winsorize(signals['NPParentCompanyGrowRate']))
signal6 = standardize(winsorize(signals['CurrentRatio'].dropna()))
signal7 = standardize(winsorize(signals['CTOP'].dropna()))
signal8 = -standardize(winsorize(signals['REVS60']))
signal9 = -standardize(winsorize(signals['REVS20']))
signal = (0.2178*signal1).add(0.2149*signal2, fill_value=0.0).add(0.1273*signal3, fill_value=0.0).add(0.1535*signal4, fill_value=0.0).add(0.0328*signal5, fill_value=0.0).add(0.0753*signal6, fill_value=0.0).add(0.1328*signal7, fill_value=0.0).add(0.0218*signal8, fill_value=0.0).add(0.0239*signal9, fill_value=0.0)
wts = long_only(signal.to_dict(), select_type=1, top_ratio=0.02, weight_type=1, target_date=yesterday)
# 交易部分
positions = account.get_positions()
sell_list = [stk for stk in positions if stk not in wts]
for stk in sell_list:
account.order_to(stk,0)
c = account.portfolio_value
change = {}
for stock, w in wts.iteritems():
p = context.current_price(stock)
if not np.isnan(p) and p > 0:
if stock in positions:
change[stock] = int(c * w / p) - positions[stock].amount
else:
change[stock] = int(c * w / p) - 0
for stock in sorted(change, key=change.get):
account.order(stock, change[stock])