can another suggest a way to do simply quantile regression in backtest? Statsmodle is not able to use here. For sklearn do I need to use GradientBoostingRegressor for the only option?
can another suggest a way to do simply quantile regression in backtest? Statsmodle is not able to use here. For sklearn do I need to use GradientBoostingRegressor for the only option?
https://phillipmfeldman.org/Python/quantile_regression_demo.py
I am trying to use this algorithm to do the quantile regression, but when I use the pipeline it's always some error.
import quantopian.algorithm as algo
import numpy as np
from quantopian.pipeline import Pipeline
from quantopian.pipeline.factors import(
SimpleMovingAverage,
DailyReturns,
CustomFactor,
Returns,
RSI,
DailyReturns,
SimpleBeta,
AverageDollarVolume
)
from quantopian.pipeline.filters import QTradableStocksUS
from quantopian.pipeline.experimental import Momentum, ShortTermReversal, Size, Value, Volatility
from quantopian.pipeline.data import Fundamentals
from numpy import array, pi
from numpy.polynomial.polynomial import polyval
from scipy.optimize import fmin
rho = 0.05
# Define number of polynomial coefficients. (The degree of the model is one
# more than the number of coefficients).
N_coefficients= 3
fractions= [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
rsi = RSI()
daily_returns_10d = Returns(window_length = 10)
# Constraint Parameters
MAX_GROSS_LEVERAGE = 1.0
TOTAL_POSITIONS = 600
MAX_SHORT_POSITION_SIZE = 1.0 / TOTAL_POSITIONS
MAX_LONG_POSITION_SIZE = 1.0 / TOTAL_POSITIONS
def initialize(context):
pipe = Pipeline()
pipe.add(Size(), 'size')
pipe.add(ShortTermReversal(), 'shor')
pipe.add(Momentum(), 'mome')
algo.attach_pipeline(pipe, 'factor_pipeline')
# Schedule our rebalance function
algo.schedule_function(func=rebalance,
date_rule=algo.date_rules.week_start(),
time_rule=algo.time_rules.market_open(hours=0,
minutes=30),
half_days=True)
# Record our portfolio variables at the end of day
algo.schedule_function(func=record_vars,
date_rule=algo.date_rules.every_day(),
time_rule=algo.time_rules.market_close(),
half_days=True)
def make_pipeline():
universe = QTradableStocksUS()
# The factors we create here are based on fundamentals data and a moving
value = Fundamentals.ebit.latest / Fundamentals.enterprise_value.latest
quality = Fundamentals.roe.latest
# 筛选
value_winsorized = value.winsorize(min_percentile=0.05, max_percentile=0.95)
quality_winsorized = quality.winsorize(min_percentile=0.05, max_percentile=0.95)
combined_factor = (
value_winsorized.zscore() +
quality_winsorized.zscore()
)
longs = combined_factor.top(TOTAL_POSITIONS//2, mask=universe)
shorts = combined_factor.bottom(TOTAL_POSITIONS//2, mask=universe)
# The final output of our pipeline should only include
# the top/bottom 300 stocks by our criteria
long_short_screen = (longs | shorts)
beta_to_spy = SimpleBeta(target=symbols('SPY'),
regression_length=252,
allowed_missing_percentage=0.05)
daily_returns = DailyReturns()
returns_1w = Returns(window_length=6)
# Create pipeline
pipe = Pipeline(
columns={
'longs': longs,
'shorts': shorts,
'combined_factor': combined_factor,
'daily_returns': daily_returns,
'returns_1w': returns_1w,
'beta_to_spy': beta_to_spy,
},
screen=long_short_screen
)
return pipe
def before_trading_start(context, data):
context.pipeline_data = algo.pipeline_output('factor_pipeline')
x = context.pipeline_data.mome
y = Returns(window_length=2)
# Section 1: Define tilted absolute value function.
def tilted_abs(rho, x):
"""
OVERVIEW
The tilted absolute value function is used in quantile regression.
INPUTS
rho: This parameter is a probability, and thus takes values between 0 and 1.
x: This parameter represents a value of the independent variable, and in
general takes any real value (float) or NumPy array of floats.
"""
return x * (rho - (x < 0))
def model(x, beta):
"""
This example defines the model as a polynomial, where the coefficients of the polynomial are passed via `beta`.
"""
return polyval(x, beta)
def objective(beta, rho):
"""
The objective function to be minimized is the sum of the tilted absolute values of the differences between the observations and the model.
"""
return tilted_abs(rho, y - model(x, beta)).sum()
# Section 2: Estimate quantiles via direct optimization.
# Define starting point for optimization:
beta_0= np.zeros(N_coefficients)
if N_coefficients >= 2:
beta_0[1]= 1.0
# `beta_hat[i]` will store the parameter estimates for the quantile
# corresponding to `fractions[i]`:
beta_hat= []
for i, fraction in enumerate(fractions):
beta_hat.append( fmin(objective, x0=beta_0, args=(fraction,),
xtol=1e-8,disp=True, maxiter=3000) )
def record_vars(context, data):
# Plot the number of positions over time.
algo.record(num_positions=len(context.portfolio.positions))
def rebalance(context, data):
pipeline_data = context.pipeline_data
algo.order_percent(asset, ...)
e.g.
x = Momentum()
y = Returns(window_length=2)