Alisa,
thanks for your answer. Below my code. I use the API in the method "rebalance". Any help is very welcome.
I attach the backtest with the leverage plotted. I do not believe that it can be above 1.1 in other backtests.
Hans
from quantopian.algorithm import attach_pipeline, pipeline_output, order_optimal_portfolio
from quantopian.pipeline import Pipeline
from quantopian.pipeline.factors import CustomFactor, SimpleMovingAverage, AverageDollarVolume, RollingLinearRegressionOfReturns
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.filters.morningstar import IsPrimaryShare
from quantopian.pipeline.classifiers.morningstar import Sector
import numpy as np
import pandas as pd
import quantopian.optimize as opt
Constraint Parameters
MAX_GROSS_EXPOSURE = 0.1
NUM_LONG_POSITIONS = 25
NUM_SHORT_POSITIONS = 25
MAX_SHORT_POSITION_SIZE = 2*1.0/(NUM_LONG_POSITIONS + NUM_SHORT_POSITIONS)
MAX_LONG_POSITION_SIZE = 2*1.0/(NUM_LONG_POSITIONS + NUM_SHORT_POSITIONS)
Risk Exposures
MAX_SECTOR_EXPOSURE = 0.10
MAX_BETA_EXPOSURE = 0.20
good lengt 30, number pos = 30
def make_pipeline():
dollar_volume = AverageDollarVolume(window_length=200)#
universe = dollar_volume.percentile_between(10, 40) # 40:182
slope_long = Dev(mask=universe, inputs=[USEquityPricing().close], window_length=23)
combined_rank = slope_long.rank(mask=universe)
longs = combined_rank.top(NUM_LONG_POSITIONS)
shorts = combined_rank.bottom(NUM_SHORT_POSITIONS)
long_short_screen = (longs | shorts)
# Create pipeline
pipe = Pipeline(columns = {
'longs':longs,
'shorts':shorts,
'combined_rank':combined_rank
},
screen = long_short_screen)
return pipe
def initialize(context):
set_commission(commission.PerShare(cost=0.0, min_trade_cost=0))
set_slippage(slippage.VolumeShareSlippage(volume_limit=1, price_impact=0))
context.spy = sid(8554)
attach_pipeline(make_pipeline(), 'long_short_equity_template')
# Schedule my rebalance function
schedule_function(func=rebalance,
date_rule=date_rules.every_day(),
time_rule=time_rules.market_open(hours=0,minutes=30),
half_days=True)
# record my portfolio variables at the end of day
schedule_function(func=recording_statements,
date_rule=date_rules.every_day(),
time_rule=time_rules.market_close(),
half_days=True)
def before_trading_start(context, data):
context.pipeline_data = pipeline_output('long_short_equity_template')
def recording_statements(context, data):
#record(num_positions=len(context.portfolio.positions))
record(leverage=context.account.leverage)
def rebalance(context, data):
pipeline_data = context.pipeline_data
objective = opt.MaximizeAlpha(pipeline_data.combined_rank)
constraints = []
# Constrain our maximum gross leverage
constraints.append(opt.MaxGrossExposure(MAX_GROSS_EXPOSURE))
constraints.append(opt.DollarNeutral())
constraints.append(
opt.PositionConcentration.with_equal_bounds(
min=-MAX_SHORT_POSITION_SIZE,
max=MAX_LONG_POSITION_SIZE
))
order_optimal_portfolio(
objective=objective,
constraints=constraints,
)
class Dev(CustomFactor):
def compute(self, today, asset_ids, out, values):
# Calculates the column-wise standard deviation, ignoring NaNs
x = []
nDays = values.shape[0]
nShares = values.shape[1]
for iShare in range(0, nShares):
mean = 0
for iDay in range(0, nDays):
mean = mean + values[iDay][iShare]
mean = mean / nDays
for iDay in range(0, nDays):
values[iDay][iShare] = values[iDay][iShare] / mean
out[:] = values[nDays-1,:]