Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Trading Contest BMMZ

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.filters.morningstar import Q1500US
from quantopian.pipeline.data import Fundamentals
from quantopian.pipeline.factors import CustomFactor, Returns, Latest
from quantopian.pipeline.classifiers import Classifier

def initialize(context):
## комиссию не прописываем, берем базовую
## Назначаем время переформирования портфеля (в начале каждого месяца)
schedule_function(my_rebalance,
date_rules.month_start(),
time_rules.market_open(hours=1))

# Запись данных в конце каждого дня  
schedule_function(my_record_vars,  
                  date_rules.every_day(),  
                  time_rules.market_close())

# Создаем pipeline  
my_pipe = make_pipeline()  
attach_pipeline(my_pipe, 'my_pipeline')

def make_pipeline():

# Используем данные по капитализации и B/M по топ-1500 компаний в США Q1500US.  
base_universe = Q1500US()  
market_cap = Latest([Fundamentals.market_cap])  
book_to_price = 1/Latest([Fundamentals.pb_ratio])

# Из 1500 акций берем 500 с наименьшей капитализацией  
market_cap_rank = market_cap.rank(mask=Q1500US())  
book_to_price_rank = book_to_price.rank(mask=market_cap_rank.bottom(500))

# Из этих 500 берем 40 с наибольшей B/M - их и покупаем на данный месяц  
longs = book_to_price_rank.top(40)  
securities_to_trade = (longs)

return Pipeline(  
    columns={  
        'longs': longs,  
    },  
    screen=(securities_to_trade),  
 )

# Рассчитываем веса - каждую акцию покупаем на 2,5% портфеля, то есть равномерно распределяем портфель по 40 акциям
def my_compute_weights(context):
long_weight = 1.0 / len(context.longs)
return long_weight

def before_trading_start(context, data):
# Применяем pipeline каждый день
context.output = pipeline_output('my_pipeline')

# Обновляем список акций для портфеля  
context.longs = context.output[context.output['longs']].index.tolist()  
context.long_weight = my_compute_weights(context)

Создаем функцию ребаланса, которая продает лишние и докупает нужные акции до приведения портфеля в соответствии с желаемым портфелем

def my_rebalance(context, data):

for security in context.portfolio.positions:  
    if security not in context.longs and data.can_trade(security):  
        order_target_percent(security, 0)

for security in context.longs:  
    if data.can_trade(security):  
        order_target_percent(security, context.long_weight)

# Записываем значения переменных  

def my_record_vars(context, data):

longs = shorts = 0  
for position in context.portfolio.positions.itervalues():  
    if position.amount > 0:  
        longs += 1  
    elif position.amount < 0:  
        shorts += 1

record(leverage=context.account.leverage, long_count=longs, short_count=shorts)