1.源码

from quantopian.pipeline import Pipeline
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import SimpleMovingAverage
from quantopian.pipeline.classifiers.morningstar import Sector
from quantopian.pipeline.data import morningstar as morningstar
from quantopian.pipeline.filters.morningstar import Q500US, Q1500US
from quantopian.pipeline.factors.morningstar import MarketCap
from quantopian.pipeline.data import Fundamentals
import quantopian.algorithm as algo


def make_pipeline():
q500 = Q500US()
mktcap = MarketCap()
sector = morningstar.asset_classification.morningstar_sector_code.latest
sectors_311 = sector.element_of([102, 311])
mkt_cap = morningstar.valuation.market_cap.latest
growth = Fundamentals.revenue_growth.latest
forward_pe_ratio = Fundamentals.forward_pe_ratio.latest
current_pe = Fundamentals.pe_ratio.latest

pipe = Pipeline()
attach_pipeline(pipe, 'pipeline_tutorial')
pipe.add(Sector(), 'Sector')
pipe.add(mktcap, 'mktcap')
pipe.add(growth, 'growth')
pipe.add(forward_pe_ratio, 'forward_pe_ratio')
pipe.add(current_pe, 'current_pe')

# log.info(current_pe / forward_pe_ratio)

pipe.set_screen(sectors_311 & q500)
# pipe.set_screen(q500)
return pipe


def initialize(context):
set_benchmark(symbol('QQQ'))

algo.schedule_function(
rebalance,
algo.date_rules.month_start(),
algo.time_rules.market_open(hours=1),
)

algo.attach_pipeline(make_pipeline(), 'pipeline')
#购买持仓数量
context.buy_stock_count = 10
#杠杆大小
context.leverage = 1.0
context.buy_stock_percent = float(context.leverage / context.buy_stock_count)
cash = context.portfolio.cash
context.purchase_value = cash / context.buy_stock_count
context.stocks_sold = []

def before_trading_start(context, data):
output = pipeline_output('pipeline_tutorial')
context.my_short_universe = output.sort('mktcap', ascending=True).iloc[0:context.buy_stock_count]
context.my_long_universe = output.sort('mktcap', ascending=False).iloc[0:context.buy_stock_count]




def rebalance(context, data):
"""
Execute orders according to our schedule_function() timing.
"""

if True:
# purchase_value = cash / left_buy_count
for stock in context.my_long_universe.index:
buy_stock_percent = context.my_long_universe["mktcap"][stock] / context.my_long_universe["mktcap"].sum()
if stock != symbol('QQQ'):
order_target_percent(stock, buy_stock_percent * context.leverage)
for stock in context.my_short_universe.index:
if stock != symbol('QQQ'):
order_target_percent(stock, -context.buy_stock_percent * 0)

for stock in context.portfolio.positions:
if stock != symbol('QQQ'):
if stock not in context.my_long_universe.index and stock not in context.my_long_universe.index:
order_target_value(stock, 0)
pass

2.回测结果:

Quantopian 大市值科技股市值加权回测_lua


比上​​《Quantopian 做多大市值科技和消费周期股,做空小市值和消费周期股回测》​​的要好些,特别是这2年。

上一篇的回测结果:

Quantopian 大市值科技股市值加权回测_lua_02

3.结论

我认为,市值加权是长期有效的策略,有点进化论的思想在里头。好的东西一定会变大。但是也需要定期重新寻找。所以如果你的组合跑不赢大盘,试着用点仓位以市值加权方式配置点指数前10大持仓。至少能跟得上指数。