"""
This is a template algorithm on Quantopian for you to adapt and fill in.
"""
import quantopian.algorithm as algo
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.filters import QTradableStocksUS
import math
from quantopian.pipeline import CustomFactor, Pipeline
import talib
import pandas as pd
from quantopian.pipeline.filters.morningstar import Q1500US, Q500US
from quantopian.algorithm import attach_pipeline, pipeline_output
def initialize(context):
context.securities = [
sid(24),
]
# Rebalance every day, 1 hour after market open.
algo.schedule_function(
rebalance,
algo.date_rules.every_day(),
algo.time_rules.market_open(hours=1),
)
context.trade_percent = 0.01
context.atrlength = 20
context.portfolio_size = context.portfolio.cash + context.portfolio.positions_value
my_pipe = make_pipeline()
attach_pipeline(my_pipe, 'my_pipeline')
class Cal_unit(CustomFactor):
def compute(self, today, assets, out, portfolio_value, trade_percent, ATR):
out[:] = math.floor(portfolio_value * trade_percent/ATR)
def make_pipeline():
base_universe = Q500US()
return Pipeline(
columns={
},screen=(base_universe)
)
def before_trading_start(context, data):
pipe_results = algo.pipeline_output('my_pipeline')
record(leverage=context.account.leverage)
def rebalance(context, data):
global recordme
hist = data.history(context.securities, ['high', 'low', 'close'], 200, '1d')
account_size = context.portfolio_size
recordme = pd.DataFrame({'symbol':[],'add_time':[],'last_buy_price':[]})
for sec in context.securities:
#close = data.history(sec,'close',200,'1d')
#high = data.history(sec,'high',200,'1d')
#low = data.history(sec,'low',200,'1d')
ATR = talib.ATR(hist['high'][sec],
hist['low'][sec],
hist['close'][sec], timeperiod=context.atrlength)[-1]
cur_price = data.current(sec, 'price')
position = context.portfolio.positions[sec].amount
#log.info(position)
if len(recordme)!=0:
recordme= recordme[recordme['symbol']!=sec]
unit = account_size*0.01 / ATR
#unit = Cal_unit(inputs = [account_size, 0.01, ATR], window_length = 1)
if cur_price > hist['high'][sec][-20:-1].max() and position is 0:
order(sec, unit)
recordme = recordme.append(pd.DataFrame({'symbol':[sec],'add_time':[1],'last_buy_price':[cur_price]}))
continue
elif sec in context.portfolio.positions: #buy 1 unit if sec price up 0.5N
last_price =(recordme[recordme['symbol'] == sec]['last_buy_price']).astype(float)
add_price =(last_price + 0.5 * ATR).astype(float)
add_unit = (recordme[recordme['symbol'] == sec]['add_time']).astype(float)
if cur_price > add_price and add_unit < 4: #4 - limit unit
unit = account_size*0.01 / ATR
order(sec,unit)
#update sec info into recordme
recordme.loc[recordme['symbol']== sec,'add_time']=recordme[recordme['symbol']== sec]['add_time']+1
recordme.loc[recordme['symbol']== sec,'last_buy_price']=cur_price
elif cur_price< hist['low'][sec][-int(20/2):-1].min() or cur_price < (last_price - 2*ATR):
order_target_percent(sec,0)
#After sell the stock, empty recordme
recordme = recordme[recordme['symbol']!=sec]
Its the Turtal Trading strategy that it will add 0.5N when price go up, but add no more than 4 times