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 做多大市值科技和消費週期股,做空小市值和消費週期股回測》的要好些,特別是這2年。
上一篇的回測結果:
3.結論
我認爲,市值加權是長期有效的策略,有點進化論的思想在裏頭。好的東西一定會變大。但是也需要定期重新尋找。所以如果你的組合跑不贏大盤,試着用點倉位以市值加權方式配置點指數前10大持倉。至少能跟得上指數。