├── algorithms ├── peterfabakker │ └── peterfabakker.txt ├── 1nad │ ├── LICENSE │ ├── Cloned from _New Feature - Record and Plot Variables_.py │ ├── Cloned from _Reply to_ Rebalance using a percentage hurdle_.py │ ├── Example_MA_crossover.py │ └── Cloned from _Reply to_ The Pipeline API, Dividends and Splits - What You Need to Know_.py ├── common │ └── LICENSE ├── FrankPSch │ ├── LICENSE │ ├── _My first Algorithm on Quantopian_.py │ ├── Hello World Algorithm.py │ ├── Cloned from _Can't fill a single order of the most liquid future contract__.py │ ├── zR1750 S1 DD54 4 fixed stocks _Stocks missing split adjustment_.py │ ├── R892 S1.3 DD31 _Problems observed in algo trading equities on futures data._.py │ ├── talib ADX Indicator _Apply APX and crossover between +DI and -DI_.py │ ├── R604 S1.2 DD23 _Exploiting ETF Decay_.py │ ├── Cloned from _Reply to_ Best performing algorithms_.py │ ├── zR10000 S1.15 DD60 _Simple Moving Average Crossover Strategy 15_50_.py │ ├── R-725 S-0.23 DD-700 _this strategy gave more than 100% return_.py │ ├── xx R0015 S0.17 DD42 talib _Systematic trading strategies - ADX and WVF_.py │ ├── Rnnn Sn.n DDnn _Google Search Terms predict market movements_.py │ ├── _Reply to_ Hurst Exponent_.py │ ├── E46 TALib Coke Pepsi _Reply to_ Cointegration, RSI signals, Long Only_.py │ ├── R201 S0.72 DD26 _'Gaming' the contest._.py │ ├── Sample Fetcher 1.py │ ├── R189 S0.80 DD32 _ETF Rotation Strategy from LazyTrader_.py │ ├── xx R0440 S0.84 DD32 _Momentum Strategy_ zscore_sine wave_.py │ ├── Cloned from _Reply to_ Google Search Terms predict market movements_.py │ ├── xxx R- S- DD- _Google Search Terms predict market movements_.py │ ├── R178 S0.82 DD22 _Going live on IB with this algo.. any advice__.py │ ├── Template Algorithm.py │ ├── zR6252 S1.26 DD53 _QuantCon 2016_ Peculiarities of Volatility by Dr. Ernest Chan_.py │ ├── D-37 S-0.7 DD40 _Cash Return Algorithm_.py │ ├── R197 S0.54 DD34 _DJIA with Momentum for Mr. Shibanov_.py │ ├── _Second Attempt at ML - Stochastic Gradient Descent Method Using Hinge Loss Function_.py │ ├── R305 S1.21 DD13 _Combining Strategic and Tactical Asset Allocation_.py │ ├── Cloned from _Reply to_ Portfolio Optimization with the Minimax algorithm [help needed]_.py │ ├── xxx R0028 S1.5 DD3 _Ernie Chan's EWA_EWC pair trade with Kalman filter_.py │ ├── R326 S0.58 DD60 _The Q500US and Q1500US_.py │ ├── nil _Pair trading using $10,00,000 equity_.py │ ├── xx R0114 S0.47 DD40 cls_opn_crs() _Holding Spy Overnight_.py │ ├── R290 S0.62 DD50 _Trading strategy for team_.py │ ├── E data _Accern Alphaone Long Short_.py │ ├── Cloned from _New Strategy - Presenting the “Quality Companies in an Uptrend” Model_.py │ ├── xx R0750 S1.04 DD34 B-0.04 _Gap Up strategy_.py │ ├── R43x S1.31 DD-50 _Another Another Volatility Trading Strategy_.py │ ├── zR6178 S1.43 DD48 _Another Volatility Trading Strategy_.py │ ├── Cloned from _Reply to_ Getting Yesterdays Close Price_.py │ ├── R195 S1.19 DD13.15 Lever1 _Classic RSI2 Mean-Reversion Strategy (SPY_TLT)_.py │ ├── R220 S0.56 DD56 _Investment management._.py │ ├── zR2099 S1.2 DD50 AAPL IBM _Fundamental data for particular stocks_.py │ ├── E70 _Reply to_ Forex data __.py │ ├── R143 S0.68 DD29 _QuantCon 2016_ Dual Momentum Strategy_.py │ ├── R043 S0.96 DD20 _Pipeline Trading Universe - Best Practice_.py │ ├── Try Again _MACD signal_.py │ ├── E _MACD signal_.py │ ├── Sentdex Long-Short Equity 1.py │ ├── R029 S0.22 DD61 _BM Size_.py │ ├── Cloned from _GARCH Volatility (RV(t+1) - IV) Revisited_.py │ ├── R083 S1.51 D5 _Free Cashflow Yield_.py │ ├── R769 S1.57 DD16 _William's Volatility Fix - help_.py │ ├── E75 _Trading VIX - Quandl Data Now In Pipeline For Backtesting And Live Trading_.py │ ├── Cloned from _New Strategy — “In & Out”_.py │ ├── Peter Bakker live from _Reply to_ The SPY who loved WVF (or Just another Volatility SPY strategy)_.py │ ├── E62 _XIV Shotgun - Trading Inverse VIX with WVF_.py │ ├── _Computing the Fama-French Factors with Pipeline_.py │ ├── R101 S0.78 DD21 V02 Luke _Beta Zero-Targeting - Automatic - Never worry about Beta again_.py │ ├── R150 S0.57 DD53 _[Investment Management course] Smart Momentum Strategy_.py │ ├── xx R0065 S0.58 DD15 _Algo with Support Vector Machine in Pipeline_.py │ ├── hivebot _Mean Reversion and Momentum Switching Model_.py │ └── xxx R639 S0.65 DD80 _Trading strategy_.py └── ajjcoppola │ └── LICENSE ├── README.md └── .gitignore /algorithms/peterfabakker/peterfabakker.txt: -------------------------------------------------------------------------------- 1 | https://github.com/peterfabakker -------------------------------------------------------------------------------- /algorithms/1nad/LICENSE: -------------------------------------------------------------------------------- 1 | The inclusion of this license file certifies that the user accepts the license terms 2 | in the top directory of this Repo contained in the file LICENSE. -------------------------------------------------------------------------------- /algorithms/common/LICENSE: -------------------------------------------------------------------------------- 1 | The inclusion of this license file certifies that the user accepts the license terms 2 | in the top directory of this Repo contained in the file LICENSE. -------------------------------------------------------------------------------- /algorithms/FrankPSch/LICENSE: -------------------------------------------------------------------------------- 1 | The inclusion of this license file certifies that FrankPSch accepts the license terms 2 | in the top directory of this Repo contained in the file LICENSE. -------------------------------------------------------------------------------- /algorithms/ajjcoppola/LICENSE: -------------------------------------------------------------------------------- 1 | The inclusion of this license file certifies that USER:ajjcoppola accepts the license terms 2 | in the top directory of this Repo contained in the file LICENSE. -------------------------------------------------------------------------------- /algorithms/FrankPSch/_My first Algorithm on Quantopian_.py: -------------------------------------------------------------------------------- 1 | def initialize(context): 2 | context.fcau = sid(47888) 3 | schedule_function(open_positions, date_rules.week_start(), time_rules.market_open()) 4 | schedule_function(close_positions, date_rules.week_end(), time_rules.market_close(minutes=30)) 5 | 6 | def open_positions(context, data): 7 | order_target_percent(context.fcau, 0.50) 8 | 9 | def close_positions(context, data): 10 | order_target_percent(context.fcau, 0) -------------------------------------------------------------------------------- /algorithms/1nad/Cloned from _New Feature - Record and Plot Variables_.py: -------------------------------------------------------------------------------- 1 | def initialize(context): 2 | context.sid = sid(26578) 3 | context.invested = False 4 | 5 | def handle_data(context, data): 6 | context.price = data[context.sid].price 7 | short = data[context.sid].mavg(20) 8 | long = data[context.sid].mavg(60) 9 | 10 | if (short > long) and not context.invested: 11 | order(context.sid, 500) 12 | context.invested = True 13 | elif (short < long) and context.invested: 14 | order(context.sid, -500) 15 | context.invested = False 16 | 17 | record(short_mavg = short, 18 | long_mavg = long, 19 | goog_price = context.price) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Hello World Algorithm.py: -------------------------------------------------------------------------------- 1 | # Called once at the start of the simulation. 2 | def initialize(context): 3 | # Reference to the AAPL security. 4 | context.aapl = sid(24) 5 | 6 | # Rebalance every day, one hour and a half after market open. 7 | schedule_function(my_rebalance, 8 | date_rules.every_day(), 9 | time_rules.market_open(hours=1, minutes=30)) 10 | 11 | # This function was scheduled to run once per day at 11AM ET. 12 | def my_rebalance(context, data): 13 | 14 | # Take a 100% long position in AAPL. Readjusts each day to 15 | # account for price fluctuations. 16 | if data.can_trade(context.aapl): 17 | order_target_percent(context.aapl, 1.00) 18 | -------------------------------------------------------------------------------- /algorithms/FrankPSch/Cloned from _Can't fill a single order of the most liquid future contract__.py: -------------------------------------------------------------------------------- 1 | from zipline.api import continuous_future, schedule_function 2 | from zipline.api import time_rules, date_rules, record 3 | #from zipline.algorithm import log 4 | #from zipline.assets.continuous_futures import ContinuousFuture 5 | from zipline.api import order_target_value, order_target_percent 6 | from zipline.utils.calendars import get_calendar 7 | import numpy as np 8 | import scipy as sp 9 | import pandas as pd 10 | 11 | 12 | def initialize(context): 13 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(hours=1)) 14 | 15 | def my_rebalance(context, data): 16 | f = continuous_future("SY", offset=0, roll='volume', adjustment='mul') 17 | contract = data.current_chain(f)[0] 18 | log.info(contract) 19 | order(contract, 1) -------------------------------------------------------------------------------- /algorithms/FrankPSch/zR1750 S1 DD54 4 fixed stocks _Stocks missing split adjustment_.py: -------------------------------------------------------------------------------- 1 | def initialize(context): 2 | context.my_equities = [ 3 | sid(26401), 4 | sid(5213), 5 | sid(23709), 6 | sid(21382), 7 | ] 8 | 9 | schedule_function( 10 | buy_and_hold, 11 | date_rules.every_day(), 12 | time_rules.market_open() 13 | ) 14 | 15 | context.bought = False 16 | 17 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 18 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 19 | 20 | 21 | def buy_and_hold(context, data): 22 | if not context.bought: 23 | for equity in context.my_equities: 24 | order_target_percent(equity, 1.0/len(context.my_equities)) 25 | 26 | context.bought = True 27 | 28 | else: 29 | pass -------------------------------------------------------------------------------- /algorithms/FrankPSch/R892 S1.3 DD31 _Problems observed in algo trading equities on futures data._.py: -------------------------------------------------------------------------------- 1 | # Short Bear 2 | # https://www.quantopian.com/posts/problems-observed-in-algo-trading-equities-on-futures-data 3 | 4 | def initialize(context): 5 | schedule_function(trade, date_rules.every_day(), time_rules.market_open(minutes = 65)) 6 | 7 | def trade(context, data): 8 | # ------------------------------------------------------ 9 | bear = symbol('VXX') 10 | future_vx = continuous_future('VX') 11 | LB = 0.950 12 | # ------------------------------------------------------ 13 | vx_chain = data.current_chain(future_vx) 14 | front_contract = vx_chain[0] 15 | secondary_contract = vx_chain[1] 16 | 17 | ratio = data.current(front_contract, 'price')/data.current(secondary_contract, 'price') 18 | wt_bear = -1.0 if ratio < LB else 0.0 19 | 20 | if get_open_orders(): return 21 | order_target_percent(bear, wt_bear) 22 | 23 | record(ratio = ratio, LB = LB) -------------------------------------------------------------------------------- /algorithms/FrankPSch/talib ADX Indicator _Apply APX and crossover between +DI and -DI_.py: -------------------------------------------------------------------------------- 1 | # talib ADX Indicator 2 | 3 | import talib 4 | 5 | def initialize(context): 6 | schedule_function(record_ADX, date_rules.every_day(), time_rules.market_close(hours = 1)) 7 | context.aapl = sid(24) 8 | 9 | def record_ADX(context, data): 10 | 11 | period = 14 12 | 13 | H = data.history(context.aapl,'high', 2*period, '1d').dropna() 14 | L = data.history(context.aapl,'low', 2*period, '1d').dropna() 15 | C = data.history(context.aapl,'price', 2*period, '1d').dropna() 16 | 17 | 18 | ta_ADX = talib.ADX(H, L, C, period) 19 | ta_nDI = talib.MINUS_DI(H, L, C, period) 20 | ta_pDI = talib.PLUS_DI(H, L, C, period) 21 | 22 | ADX = ta_ADX[-1] 23 | nDI = ta_nDI[-1] 24 | pDI = ta_pDI[-1] 25 | 26 | record( ADX = ADX, nDI = nDI, pDI = pDI) 27 | record(close_price = data.current(context.aapl,'close')) 28 | 29 | 30 | if nDI < pDI and ADX > 20 and data.can_trade(context.aapl): 31 | order_target_percent(context.aapl, 1) 32 | elif nDI > pDI and ADX > 20 and data.can_trade(context.aapl): 33 | order_target_percent(context.aapl, -1) 34 | 35 | 36 | 37 | 38 | 39 | print context.portfolio.positions[context.aapl].amount -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Quantopian_Algos 2 | This repository consists of several python based Algos for algorythmic trading formerly on the Quantopian platform. 3 | 4 | As Quantopian is shutting down its Quantopian community platform, Quantopian are allowing to download code (algorithms and notebooks) to continue on a local machine more easily. This repository consists of several algos which Quantopian has allowed to download. 5 | 6 | ## Algo Results in the header 7 | You will find that some of these algos have a funny stat of their name. Theses are the results from backtesting them including slippage and commisssion over a larger timeframe. 8 | 9 | Result header: 10 | * R = Return, eg R195 = 195% 11 | * S = Sharpe, eg S1.19 = Sharpe of 1.19 12 | * DD = Drawdown, eg DD13.15 = -13.5% 13 | 14 | Slippage / Commission used: 15 | * set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) 16 | * set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) 17 | 18 | ## Other contributions 19 | Downloadable forum discussion and notebooks 20 | * https://quantopian-archive.netlify.app/ 21 | * https://archive.org/details/quantopian-archive 22 | * https://archive.org/download/quantopian-archive 23 | 24 | ## Next Steps 25 | * Please contact me if you would like to get in touch to share and exchange trading ideas! 26 | -------------------------------------------------------------------------------- /algorithms/FrankPSch/R604 S1.2 DD23 _Exploiting ETF Decay_.py: -------------------------------------------------------------------------------- 1 | import quantopian.optimize as opt 2 | import quantopian.algorithm as algo 3 | 4 | def initialize(context): 5 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 6 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 7 | 8 | context.leveragedetfs= [sid(38532), sid(38292)] 9 | 10 | schedule_function(my_rebalance, 11 | date_rules.month_end(), 12 | time_rules.market_open(hours=1)) 13 | 14 | def my_rebalance(context,data): 15 | stock_dict = {} 16 | today = get_datetime() 17 | if today.month == 1 or today.month == 4 or today.month == 7 or today.month == 10: 18 | for stock in context.leveragedetfs: 19 | stock_dict[stock] = -1.0 / len(context.leveragedetfs) 20 | 21 | try: 22 | objective = opt.TargetWeights(stock_dict) 23 | constraints=[opt.MaxGrossExposure(1.0)] 24 | algo.order_optimal_portfolio(objective, constraints) 25 | except Exception as e: 26 | log.info('@@@@@@@@@@@@@@@@@@@ EXCEPTION: Trade @@@@@@@@@@@@@@@@@@@@@') 27 | log.info('Exception is %s' %e) 28 | return 29 | 30 | def handle_data(context,data): 31 | pass -------------------------------------------------------------------------------- /algorithms/FrankPSch/Cloned from _Reply to_ Best performing algorithms_.py: -------------------------------------------------------------------------------- 1 | def initialize(context): 2 | context.symbols = {symbol("TQQQ"):0.50, symbol("TMF"):0.25, symbol("EDZ"):0.25} 3 | #TQQQ - 3x performance of the Nasdaq-100 Index® 4 | #TMF - 3x performance of the ICE U.S. Treasury 20+ Year Bond Index 5 | #EDZ - 3x inverse performance of the MSCI Emerging Markets Index 6 | schedule_function(trade, date_rules.every_day(), time_rules.market_open(minutes = 33)) 7 | #0.5, 0.25, 0.25: r3049 a0.29 b0.58 s1.55 dd-26.49 8 | 9 | def trade(context, data): 10 | wt = {} 11 | for tick, weigh in context.symbols.items(): 12 | prices = data.history(tick,'open', 21,'1d') 13 | pricesl = data.history(tick,'open', 252,'1d') 14 | wt_sh = 1.0/(prices.pct_change()[-14:-1].std()**2) 15 | if (tick == symbol("TQQQ") or tick == symbol("TMF")): 16 | wt[tick] = max(0, weigh*(pricesl.max()/prices[-1])*wt_sh) # bull 17 | else: 18 | wt[tick] = max(0, weigh*(prices[-1]/pricesl.min())*wt_sh) # bear 19 | total_wt = sum([wt[x] for x in wt]) 20 | 21 | round_pct = 5.0 # rounding to reduce slippage and comission 22 | for tick, weigh in wt.items(): 23 | target_pct = 0.0 24 | try: 25 | target_pct = round(wt[tick]/total_wt/round_pct, 2)*round_pct 26 | except: 27 | pass 28 | order_target_percent(tick, target_pct) -------------------------------------------------------------------------------- /algorithms/FrankPSch/zR10000 S1.15 DD60 _Simple Moving Average Crossover Strategy 15_50_.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a template algorithm on Quantopian for you to adapt and fill in. 3 | """ 4 | from quantopian.algorithm import attach_pipeline, pipeline_output 5 | from quantopian.pipeline import Pipeline 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.factors import AverageDollarVolume 8 | from quantopian.pipeline.filters import Q1500US 9 | 10 | # ----------------------------------------------------------------------- 11 | stock, bond, ma_f, ma_s, lev = symbol('AAPL'), symbol('TLT'), 55, 56, 1.0 12 | # ----------------------------------------------------------------------- 13 | 14 | def initialize(context): 15 | set_benchmark(stock) 16 | schedule_function(trade,date_rules.every_day(),time_rules.market_open(minutes = 1)) 17 | 18 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 19 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 20 | 21 | 22 | def trade(context,data): 23 | if get_open_orders(): return 24 | mavg_f = data.history(stock,'price',ma_f,'1d').mean() 25 | mavg_s = data.history(stock,'price',ma_s,'1d').mean() 26 | 27 | if all(data.can_trade([stock, bond])): 28 | if mavg_f > mavg_s: 29 | order_target_percent(stock, lev*1.9) 30 | order_target_percent(bond, 0.0) 31 | elif mavg_f < mavg_s: 32 | order_target_percent(stock, 0.7) 33 | order_target_percent(bond, lev*0.3) 34 | 35 | 36 | 37 | def before_trading_start(context, data): 38 | record(Leverage = context.account.leverage) -------------------------------------------------------------------------------- /algorithms/FrankPSch/R-725 S-0.23 DD-700 _this strategy gave more than 100% return_.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a template algorithm on Quantopian for you to adapt and fill in. 3 | """ 4 | from quantopian.algorithm import attach_pipeline, pipeline_output 5 | from quantopian.pipeline import Pipeline 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.factors import AverageDollarVolume 8 | from quantopian.pipeline.filters import Q1500US 9 | def initialize(context): 10 | """ 11 | Called once at the start of the algorithm. 12 | """ 13 | context.security = symbol('SPY') 14 | 15 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 16 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 17 | 18 | 19 | def handle_data(context,data): 20 | """ 21 | Called every minute. 22 | """ 23 | print(data) 24 | MA1 = data[context.security].mavg(8) 25 | MA2 = data[context.security].mavg(33) 26 | 27 | current_price = data[context.security].price 28 | current_positions = context.portfolio.positions[symbol('SPY')].amount 29 | cash = context.portfolio.cash 30 | 31 | if(MA1 > MA2) and current_positions == 0: 32 | number_of_shares = int(cash/current_price) 33 | order(context.security, number_of_shares) 34 | log.info('buying shares') 35 | 36 | 37 | elif (MA1 < MA2) and current_positions != 0: 38 | order(context.security, -current_positions) 39 | order_target(context.security, 0) 40 | log.info('selling shares') 41 | 42 | record(MA1 = MA1, MA2 = MA2, price = current_price) -------------------------------------------------------------------------------- /algorithms/FrankPSch/xx R0015 S0.17 DD42 talib _Systematic trading strategies - ADX and WVF_.py: -------------------------------------------------------------------------------- 1 | from quantopian.algorithm import attach_pipeline, pipeline_output 2 | from quantopian.pipeline import Pipeline 3 | from quantopian.pipeline.data.builtin import USEquityPricing 4 | from quantopian.pipeline.factors import AverageDollarVolume 5 | from quantopian.pipeline.filters import Q1500US 6 | import talib 7 | import numpy 8 | import math 9 | import pandas 10 | 11 | def initialize(context): 12 | context.stock = sid(698) #Boeing 13 | context.market = sid(8554) # market still SPY 14 | set_benchmark(context.stock) #set the stock as benchmark 15 | schedule_function(record_ADX, date_rules.every_day(), time_rules.market_close()) 16 | 17 | def record_ADX(context, data): 18 | prices = data.history(context.stock, 'price', 252, '1d') 19 | market = data.history(context.market, 'price', 252, '1d') 20 | period = 14 21 | 22 | H = data.history(context.stock,'high', 2*period, '1d').dropna() 23 | L = data.history(context.stock,'low', 2*period, '1d').dropna() 24 | C = data.history(context.stock,'price', 2*period, '1d').dropna() 25 | 26 | ta_ADX = talib.ADX(H, L, C, period) 27 | ta_nDI = talib.MINUS_DI(H, L, C, period) 28 | ta_pDI = talib.PLUS_DI(H, L, C, period) 29 | 30 | ADX = ta_ADX[-1] 31 | nDI = ta_nDI[-1] 32 | pDI = ta_pDI[-1] 33 | 34 | beta = talib.BETA(prices, market, timeperiod=21)[-1:] 35 | 36 | if (ADX > 25) and (nDI > pDI): 37 | order_target_percent(context.stock, -1) and order_target_percent(context.market, beta) 38 | elif (ADX > 25) and (nDI < pDI): 39 | order_target_percent(context.stock, 1) and order_target_percent(context.market, -beta) 40 | 41 | record( ADX = ADX, nDI = nDI, pDI = pDI) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Rnnn Sn.n DDnn _Google Search Terms predict market movements_.py: -------------------------------------------------------------------------------- 1 | # https://www.quantopian.com/posts/google-search-terms-predict-market-movements 2 | import numpy as np 3 | import datetime 4 | from collections import deque as window 5 | 6 | delta_t = 6 7 | 8 | def initialize(context): 9 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 10 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 11 | 12 | context.query = 'terrorism' 13 | fetch_csv('https://gist.githubusercontent.com/gordondavidf/ee6bd0998ac727b1dbe2/raw/1f564dcb60200cb16860ad18e9698006c5b0dd8f/Terrorism', 14 | date_format='%d/%m/%Y', 15 | symbol='terrorism', 16 | ) 17 | context.order_size = 50 18 | context.security = symbol('GLD') # Gold Stocks 19 | context.window = window(maxlen=delta_t) 20 | set_slippage(slippage.FixedSlippage(spread=0.0)) 21 | 22 | def handle_data(context, data): 23 | c = context 24 | 25 | 26 | if (data[c.security].datetime.weekday()) == 0 and (len(c.window) == delta_t): # Monday and window full 27 | # Compute average over weeks in range [t-delta_t-1, t[ 28 | mean_indicator = np.mean(c.window) 29 | if mean_indicator is None: 30 | return 31 | 32 | # Exit previous positions 33 | order_target(c.security, 0) 34 | 35 | # Long or short depending on whether debt search 36 | # frequency went down or up, respectively. 37 | if data[c.query][c.query] > mean_indicator: 38 | order(c.security, -c.order_size*(c.query in data[c.query])) 39 | else: 40 | order(c.security, c.order_size) 41 | 42 | if c.query in data[c.query]: 43 | c.window.append(data[c.query][c.query]) 44 | record(terrorism_avg=np.mean(c.window)) -------------------------------------------------------------------------------- /algorithms/FrankPSch/_Reply to_ Hurst Exponent_.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Hurst Exponent implemented from Ernie Chan's 'Algorithmic Trading: winning strategies 3 | and their rationale'. One of several tools to test whether a strategy is mean-reverting 4 | ''' 5 | import numpy 6 | 7 | def initialize(context): 8 | context.past_prices = [] 9 | context.spy = sid(8554) 10 | 11 | def handle_data(context, data): 12 | hurst_val = hurst(context,data,context.spy) 13 | log.info(hurst_val) 14 | record(Hurst = hurst_val) 15 | 16 | ''' 17 | Adjusts a list of past prices to the number of periods you want 18 | So if you want the nummber of prices in the last forty days, set period = 40 19 | ''' 20 | def gather_prices(context, data, sid, period): 21 | context.past_prices = data.history(sid, fields="price", bar_count=period, frequency="1d") 22 | if len(context.past_prices) > period: 23 | context.past_prices.pop(0) 24 | return 25 | 26 | ''' 27 | Hurst exponent helps test whether the time series is: 28 | (1) A Random Walk (H ~ 0.5) 29 | (2) Trending (H > 0.5) 30 | (3) Mean reverting (H < 0.5) 31 | ''' 32 | def hurst(context, data, sid): 33 | # Gathers all the prices that you need 34 | gather_prices(context, data, sid, 128) 35 | 36 | tau, lagvec = [], [] 37 | # Step through the different lags 38 | for lag in range(2,25): 39 | # Produce price different with lag 40 | pp = numpy.subtract(context.past_prices[lag:],context.past_prices[:-lag]) 41 | # Write the different lags into a vector 42 | lagvec.append(lag) 43 | # Calculate the variance of the difference 44 | tau.append(numpy.sqrt(numpy.std(pp))) 45 | # Linear fit to a double-log graph to get power 46 | m = numpy.polyfit(numpy.log10(lagvec),numpy.log10(tau),1) 47 | # Calculate hurst 48 | hurst = m[0]*2 49 | 50 | return hurst -------------------------------------------------------------------------------- /algorithms/FrankPSch/E46 TALib Coke Pepsi _Reply to_ Cointegration, RSI signals, Long Only_.py: -------------------------------------------------------------------------------- 1 | import math 2 | import numpy 3 | import talib 4 | from collections import deque 5 | 6 | # Put any initialization logic here. The context object will be passed to 7 | # the other methods in your algorithm. 8 | def initialize(context): 9 | set_long_only() # Raise exception on short (negative share) attempt 10 | 11 | context.A = sid(4283) #Coke 12 | context.Z = sid(5885) #Pepsi 13 | context.stocks = [context.A, context.Z] 14 | context.threshold_buy = 30.0 15 | context.threshold_sell = 90.0 16 | context.allocation_limit = .5 17 | 18 | context.price_history = {} 19 | for stock in context.stocks: 20 | context.price_history[stock] = deque(maxlen=20) 21 | 22 | 23 | def handle_data(context, data): 24 | for stock in context.stocks: 25 | context.price_history[stock].append(data[stock].price) 26 | # https://www.quantopian.com/quantopian2/migration#data-current 27 | # new: context.price_history[stock].append(data.current.price) 28 | if len(context.price_history[stock]) < 15: 29 | continue 30 | 31 | stock_rsi = math.floor(talib.RSI(numpy.array(context.price_history[stock]), timeperiod=14)[-1]) 32 | log.info(stock_rsi) 33 | 34 | prices = numpy.array(context.price_history[stock]) 35 | 36 | willR = talib.WILLR(prices, prices, prices, timeperiod=14)[-1] 37 | 38 | willR = 100 - abs(willR) 39 | 40 | record(willR=willR,stock_rsi=stock_rsi) 41 | 42 | if(stock_rsi > context.threshold_sell or willR > 95): 43 | order_target(stock, 0) 44 | elif(stock_rsi < context.threshold_buy and willR < 10): 45 | # buy up to the percentage allocation limit 46 | order_target_percent(stock, context.allocation_limit) -------------------------------------------------------------------------------- /algorithms/FrankPSch/R201 S0.72 DD26 _'Gaming' the contest._.py: -------------------------------------------------------------------------------- 1 | import talib 2 | 3 | def initialize(context): 4 | 5 | schedule_function(setAlerts, date_rules.every_day(), time_rules.market_close()) 6 | schedule_function(rebalance, date_rules.every_day(), time_rules.market_open()) 7 | set_commission(commission.PerTrade(cost=5.00)) 8 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 9 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 10 | set_benchmark(symbol('SPY')) 11 | 12 | context.asset = symbol('SPY') 13 | 14 | context.rsi_period = 2 15 | context.OB = 50 16 | context.OS = 30 17 | context.pct_alloc = 1.00 18 | context.leverage = 1.00 19 | 20 | #Alert to buy or sell next day. 21 | context.buyAssetAlert = False 22 | context.sellAssetAlert = False 23 | 24 | def setAlerts(context, data): 25 | 26 | asset_price = data.history(context.asset, 'price', 3, '1d') 27 | 28 | rsi = talib.RSI(asset_price, context.rsi_period) 29 | 30 | if rsi[-1] < context.OS and data.can_trade(context.asset): 31 | #order_target_percent(asset, context.pct_alloc * leverage) 32 | context.buyAssetAlert = True 33 | elif rsi[-1] > context.OB and data.can_trade(context.asset): 34 | #order_target_percent(asset, 0.00 * leverage) 35 | context.sellAssetAlert = True 36 | 37 | record(leverage = context.account.leverage) 38 | 39 | def rebalance(context, data): 40 | 41 | if context.buyAssetAlert and data.can_trade(context.asset) and context.portfolio.positions[context.asset].amount == 0: 42 | order_target_percent(context.asset, context.pct_alloc * context.leverage) 43 | context.buyAssetAlert = False 44 | if context.sellAssetAlert and data.can_trade(context.asset): 45 | order_target_percent(context.asset, 0.00 * context.leverage) 46 | context.sellAssetAlert = False -------------------------------------------------------------------------------- /algorithms/FrankPSch/Sample Fetcher 1.py: -------------------------------------------------------------------------------- 1 | import pandas 2 | 3 | def rename_col(df): 4 | df = df.rename(columns={'New York 15:00': 'price'}) 5 | df = df.rename(columns={'Value': 'price'}) 6 | df = df.fillna(method='ffill') 7 | df = df[['price', 'sid']] 8 | # Correct look-ahead bias in mapping data to times 9 | df = df.tshift(1, freq='b') 10 | log.info(' \n %s ' % df.head()) 11 | return df 12 | 13 | def preview(df): 14 | log.info(' \n %s ' % df.head()) 15 | return df 16 | 17 | def initialize(context): 18 | # import the external data 19 | fetch_csv('https://www.quandl.com/api/v1/datasets/JOHNMATT/PALL.csv?trim_start=2012-01-01', 20 | date_column='Date', 21 | symbol='palladium', 22 | pre_func = preview, 23 | post_func=rename_col, 24 | date_format='%Y-%m-%d') 25 | 26 | fetch_csv('https://www.quandl.com/api/v1/datasets/BUNDESBANK/BBK01_WT5511.csv?trim_start=2012-01-01', 27 | date_column='Date', 28 | symbol='gold', 29 | pre_func = preview, 30 | post_func=rename_col, 31 | date_format='%Y-%m-%d') 32 | 33 | # Tiffany 34 | context.stock = sid(7447) 35 | 36 | schedule_function(rebalance, date_rules.every_day(), time_rules.market_open()) 37 | 38 | 39 | 40 | def rebalance(context, data): 41 | # Invest 100% of the portfolio in Tiffany stock when the price of gold is low. 42 | # Decrease the Tiffany position to 50% of portfolio when the price of gold is high. 43 | current_gold_price = data.current('gold', 'price') 44 | if (current_gold_price < 1600): 45 | order_target_percent(context.stock, 1.00) 46 | if (current_gold_price > 1750): 47 | order_target_percent(context.stock, 0.50) 48 | 49 | # Current prices of palladium (from .csv file) and TIF 50 | current_pd_price = data.current('palladium', 'price') 51 | current_tif_price = data.current(context.stock, 'price') 52 | 53 | # Record the variables 54 | record(palladium=current_pd_price, gold=current_gold_price, tif=current_tif_price) 55 | -------------------------------------------------------------------------------- /algorithms/FrankPSch/R189 S0.80 DD32 _ETF Rotation Strategy from LazyTrader_.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def initialize(context): 4 | """ 5 | Called once at the start of the algorithm. 6 | """ 7 | context.universe = [sid(8554), sid(22972), sid(22446), sid(23870), sid(26807)] 8 | schedule_function(my_rebalance, date_rules.month_end(), time_rules.market_close(hours=1)) 9 | 10 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 11 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 12 | 13 | 14 | def my_rebalance(context,data): 15 | closings = data.history(context.universe, fields = "price", bar_count = 61, frequency = "1d") 16 | return_20days = closings.ix[-2] / closings.ix[-21] - 1 17 | return_60days = closings.ix[-2] / closings.ix[-61] - 1 18 | return_daily = closings.pct_change(1) 19 | roll_vol_20days = return_daily.ix[-21:-1].std(axis = 0) 20 | rank_20days_ret = return_20days.rank(ascending=False) 21 | rank_60days_ret = return_60days.rank(ascending=False) 22 | rank_20days_roll_vol = roll_vol_20days.rank(ascending=True) 23 | # 20 days x 0.3, 60 days x 0.4, and 20 days vol x 0.3 24 | weighted_rank = rank_20days_ret * 0.3 + rank_60days_ret * 0.4 + rank_20days_roll_vol * 0.3 25 | context.to_buy = weighted_rank.sort_values(ascending = True).index[:2].tolist() 26 | print(context.to_buy) 27 | for security in context.universe: 28 | if (security not in context.to_buy) & (data.can_trade(security)): 29 | order_target_percent(security,0) 30 | elif (security in context.to_buy) & (data.can_trade(security)): 31 | order_target_percent(security, 0.5) 32 | 33 | #record("Leverage", context.account.leverage) 34 | #record("SPY", data.current(context.universe[0],"price")) 35 | #record("EFA", data.current(context.universe[1],"price")) 36 | #record("ICF", data.current(context.universe[2],"price")) 37 | #record("IEF", data.current(context.universe[3],"price")) 38 | #record("GLD", data.current(context.universe[4],"price")) -------------------------------------------------------------------------------- /algorithms/1nad/Cloned from _Reply to_ Rebalance using a percentage hurdle_.py: -------------------------------------------------------------------------------- 1 | PercentEquities = 70.0 2 | 3 | def initialize(context): 4 | set_symbol_lookup_date('2015-01-01') 5 | context.Equities = symbols("JKL","FAB","FVD","FTA","EZY","EPS","DEF","PRF","PWV","FDL","IWD") 6 | context.FixedIncome = symbols("TLO","VGSH","SCHO","PLW","EDV","GOVT","IEI","SHY","IEF","TLT") 7 | schedule_function(Rebalance, date_rule=date_rules.month_start()) 8 | 9 | def handle_data(context, data): 10 | record(Leverage = context.account.leverage) 11 | record(AccountValue = context.portfolio.positions_value + context.portfolio.cash) 12 | 13 | def Rebalance(context, data): 14 | accountValue = context.portfolio.positions_value + context.portfolio.cash 15 | 16 | pctEquities = PercentEquities / 100.0 17 | pctFixedInc = 1.0 - pctEquities 18 | 19 | # 20 | # Equities rebalance 21 | # 22 | eligible = [] 23 | accruedValue = 0.0 24 | for stock in context.Equities: 25 | if (stock in data): 26 | eligible.append(stock) 27 | accruedValue += context.portfolio.positions[stock].amount * data[stock].close_price 28 | 29 | eligibleCount = float(len(eligible)) 30 | for stock in eligible: 31 | order_target_percent(stock, pctEquities / eligibleCount) 32 | 33 | pctOfAccount = accruedValue / accountValue * 100.0 34 | record(EquityPct = pctOfAccount) 35 | print("Equities % of account {0:>5.2f}".format(pctOfAccount)) 36 | 37 | # 38 | # Fixed Income rebalance 39 | # 40 | eligible = [] 41 | accruedValue = 0.0 42 | for stock in context.FixedIncome: 43 | if (stock in data): 44 | eligible.append(stock) 45 | accruedValue += context.portfolio.positions[stock].amount * data[stock].close_price 46 | 47 | eligibleCount = float(len(eligible)) 48 | for stock in eligible: 49 | order_target_percent(stock, pctFixedInc / eligibleCount) 50 | 51 | pctOfAccount = accruedValue / accountValue * 100.0 52 | record(FixedIncomePct = pctOfAccount) 53 | print("FixedInc % of account {0:>5.2f}".format(pctOfAccount)) 54 | -------------------------------------------------------------------------------- /algorithms/FrankPSch/xx R0440 S0.84 DD32 _Momentum Strategy_ zscore_sine wave_.py: -------------------------------------------------------------------------------- 1 | import math 2 | from pytz import timezone 3 | 4 | trading_freq = 1 # of days 5 | n = 150 # sample size 6 | 7 | def initialize(context): 8 | 9 | context.secs = sid(8554) 10 | 11 | context.day_count = -1 12 | 13 | set_commission(commission.PerShare(cost=.005, min_trade_cost=1)) 14 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.25, price_impact=0.1)) 15 | 16 | def handle_data(context, data): 17 | 18 | lev = context.account.leverage 19 | 20 | # Trade according to freq rule 21 | loc_dt = get_datetime().astimezone(timezone('US/Eastern')) 22 | if loc_dt.hour == 11 and loc_dt.minute ==0: 23 | context.day_count += 1 24 | pass 25 | else: 26 | return 27 | 28 | if context.day_count % trading_freq != 0.0: 29 | return 30 | 31 | #################################### 32 | #mean = data[context.secs].mavg(n) 33 | price_hist = data.history(context.secs, 'price', n, '1d') 34 | mean = price_hist.mean() 35 | 36 | #sigma = data[context.secs].stddev(n) 37 | stddev_hist = data.history(context.secs, 'price', n, '1d')[:-1] 38 | sigma = stddev_hist.std() 39 | 40 | #price = data[context.secs].price 41 | price = data.current(context.secs, 'price') 42 | 43 | z = (price - mean) / sigma 44 | 45 | #target = math.sin(z)+1 # adding 1 to the sin wave to prevent shorting 46 | #target = 0.5*(math.sin(z)+1) # Long without leverage 47 | 48 | #target = 1.0/(1+math.exp(-1.2*z)) # Pure momentum 49 | target = 2.0/(1+math.exp(-1.2*z)) # Pure momentum with leverage 50 | 51 | target = round(target*10.0,0)/10.0 52 | 53 | # condition required to enter a trade. 54 | if -4 <= z <= 4 and lev <=2.5: 55 | order_target_percent(context.secs, target) 56 | order_target_percent(symbol('TLT'), 2-target) 57 | else: 58 | target = 0 59 | order_target_percent(symbol('TLT'), 1) 60 | order_target_percent(context.secs, 0) 61 | 62 | record(Treasury = (1-target)*100) 63 | record(SPY = target*100) 64 | #record(target = target) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Cloned from _Reply to_ Google Search Terms predict market movements_.py: -------------------------------------------------------------------------------- 1 | # This algorithm recreates the algorithm presented in 2 | # "Quantifying Trading Behavior in Financial Markets Using Google Trends" 3 | # Preis, Moat & Stanley (2013), Scientific Reports 4 | # (c) 2013 Thomas Wiecki, Quantopian Inc. 5 | 6 | import numpy as np 7 | import datetime 8 | # Average over 5 weeks, free parameter. 9 | delta_t = 5 10 | 11 | def initialize(context): 12 | # This is the search query we are using, this is tied to the csv file. 13 | context.query = 'flu' 14 | # User fetcher to get data. I uploaded this csv file manually, feel free to use. 15 | # Note that this data is already weekly averages. 16 | fetch_csv('https://raw.githubusercontent.com/timgood12/flu-data/master/data', 17 | date_format='%Y-%m-%d', 18 | symbol='flu', 19 | ) 20 | context.order_size = 10000 21 | context.sec_id = 5923 22 | context.security = sid(5923) #merck 23 | 24 | def handle_data(context, data): 25 | c = context 26 | 27 | if c.query not in data[c.query]: 28 | return 29 | 30 | # Extract weekly average of search query. 31 | indicator = data[c.query][c.query] 32 | 33 | # Buy and hold strategy that enters on the first day of the week 34 | # and exits after one week. 35 | if data[c.security].dt.weekday() == 0: # Monday 36 | # Compute average over weeks in range [t-delta_t-1, t[ 37 | mean_indicator = mean_past_queries(data, c.query) 38 | if mean_indicator is None: 39 | return 40 | 41 | # Exit positions 42 | amount = c.portfolio['positions'][c.sec_id].amount 43 | order(c.security, -amount) 44 | 45 | # Long or short depending on whether debt search frequency 46 | # went down or up, respectively. 47 | if indicator > mean_indicator: 48 | order(c.security, c.order_size) 49 | else: 50 | order(c.security, -c.order_size) 51 | 52 | # If we want the average over 5 weeks, we'll have to use a 6 53 | # week window as the newest element will be the current event. 54 | @batch_transform(window_length=delta_t+1, refresh_period=0) 55 | def mean_past_queries(data, query): 56 | # Compute mean over all events except most current one. 57 | return data[query][query][:-1].mean() 58 | 59 | 60 | -------------------------------------------------------------------------------- /algorithms/FrankPSch/xxx R- S- DD- _Google Search Terms predict market movements_.py: -------------------------------------------------------------------------------- 1 | # This algorithm recreates the algorithm presented in 2 | # "Quantifying Trading Behavior in Financial Markets Using Google Trends" 3 | # Preis, Moat & Stanley (2013), Scientific Reports 4 | # (c) 2014 Thomas Wiecki, Quantopian Inc. 5 | 6 | import numpy as np 7 | import datetime 8 | from collections import deque as window 9 | # Average over 5 weeks, free parameter. 10 | delta_t = 5 11 | 12 | def initialize(context): 13 | # This is the search query we are using, this is tied to the csv file. 14 | context.query = 'debt' 15 | # User fetcher to get data. I uploaded this csv file manually, feel free to use. 16 | # Note that this data is already weekly averages. 17 | #'https://gist.github.com/twiecki/5629198/raw/6247da04bacebcd6334a4b91ed21f14483c6d4d0/debt_google_trend' 18 | fetch_csv('https://gist.githubusercontent.com/anonymous/9778928/raw/92b9a8eafce50a2d184d72d7601c67a0223f77b8/preis_data.csv', 19 | date_format='%Y-%m-%d', 20 | symbol='debt', 21 | ) 22 | context.order_size = 10000 23 | context.security = symbol('SPY') # S&P5000 24 | context.window = window(maxlen=delta_t) 25 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 26 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 27 | 28 | def handle_data(context, data): 29 | c = context 30 | 31 | # Buy and hold strategy that enters on the first day of the 32 | # week and exits after one week. 33 | if (data[c.security].datetime.weekday()) == 0 and (len(c.window) == delta_t): # Monday and window full 34 | # Compute average over weeks in range [t-delta_t-1, t[ 35 | mean_indicator = np.mean(c.window) 36 | if mean_indicator is None: 37 | return 38 | 39 | # Exit previous positions 40 | order_target(c.security, 0) 41 | 42 | # Long or short depending on whether debt search 43 | # frequency went down or up, respectively. 44 | if data[c.query][c.query] > mean_indicator: 45 | order(c.security, -c.order_size) 46 | else: 47 | order(c.security, c.order_size) 48 | 49 | if c.query in data[c.query]: 50 | c.window.append(data[c.query][c.query]) 51 | record(debt_avg=np.mean(c.window)) -------------------------------------------------------------------------------- /algorithms/FrankPSch/R178 S0.82 DD22 _Going live on IB with this algo.. any advice__.py: -------------------------------------------------------------------------------- 1 | from pytz import timezone 2 | import numpy as np 3 | 4 | def initialize(context): 5 | 6 | set_symbol_lookup_date('2015-01-01') 7 | ######################################## 8 | context.secs = symbols('SPY', # S&P 500 9 | 'TLT', # T Bonds 10 | 'GLD', # Gold 11 | 'QQQ', # Nasdaq 100 12 | 'EEM', # MSCI EM 13 | 'VGK') # Europe 14 | ####################################### 15 | set_benchmark(sid(22739)) 16 | context.day_count = -1 17 | set_commission(commission.PerTrade(cost=1)) 18 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.25, price_impact=0.1)) 19 | 20 | context.trading_freq = 30 21 | context.n = 150 # sample size 22 | 23 | #trade at the beginning of each month at market open 24 | schedule_function(trade, date_rules.month_start(), time_rules.market_open()) 25 | 26 | def handle_data(context, data): 27 | 28 | lev = context.account.leverage 29 | record(lev = lev) 30 | 31 | def trade(context,data): 32 | ### calculating the zscores ############# 33 | stock = context.secs 34 | p = history(bar_count=context.n, frequency='1d', field='price') 35 | p10 = p.iloc[-10:] # previous 10 days 36 | mu = np.mean(p[stock]) # n day mavg 37 | mu10 = np.mean(p10[stock]) # 10 day mavg 38 | sigma = np.std(p[stock]) 39 | z = (mu10-mu)/sigma 40 | z = z.order(ascending=True) 41 | zmean = float(sum(z)/len(z)) 42 | ########################################## 43 | 44 | # begin trade logic 45 | if zmean < -1: 46 | for stock in z.index: 47 | # first check if there are open orders 48 | if get_open_orders(stock): 49 | continue 50 | order_target_percent(stock, 0) 51 | else: 52 | counter = 1.0 53 | fraction = 0.96 / ((len(z) * (len(z)+1.0)) / 2.0) 54 | for stock in z.index: 55 | # first check if there are open orders 56 | if get_open_orders(stock): 57 | continue 58 | order_target_percent(stock, counter * fraction) 59 | counter += 1.0 60 | 61 | record(zmean = zmean) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Template Algorithm.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a template algorithm on Quantopian for you to adapt and fill in. 3 | """ 4 | from quantopian.algorithm import attach_pipeline, pipeline_output 5 | from quantopian.pipeline import Pipeline 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.factors import AverageDollarVolume 8 | from quantopian.pipeline.filters.morningstar import Q1500US 9 | 10 | def initialize(context): 11 | """ 12 | Called once at the start of the algorithm. 13 | """ 14 | # Rebalance every day, 1 hour after market open. 15 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(hours=1)) 16 | 17 | # Record tracking variables at the end of each day. 18 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 19 | 20 | # Create our dynamic stock selector. 21 | attach_pipeline(make_pipeline(), 'my_pipeline') 22 | 23 | def make_pipeline(): 24 | """ 25 | A function to create our dynamic stock selector (pipeline). Documentation on 26 | pipeline can be found here: https://www.quantopian.com/help#pipeline-title 27 | """ 28 | 29 | # Base universe set to the Q500US 30 | base_universe = Q1500US() 31 | 32 | # Factor of yesterday's close price. 33 | yesterday_close = USEquityPricing.close.latest 34 | 35 | pipe = Pipeline( 36 | screen = base_universe, 37 | columns = { 38 | 'close': yesterday_close, 39 | } 40 | ) 41 | return pipe 42 | 43 | def before_trading_start(context, data): 44 | """ 45 | Called every day before market open. 46 | """ 47 | context.output = pipeline_output('my_pipeline') 48 | 49 | # These are the securities that we are interested in trading each day. 50 | context.security_list = context.output.index 51 | 52 | def my_assign_weights(context, data): 53 | """ 54 | Assign weights to securities that we want to order. 55 | """ 56 | pass 57 | 58 | def my_rebalance(context,data): 59 | """ 60 | Execute orders according to our schedule_function() timing. 61 | """ 62 | pass 63 | 64 | def my_record_vars(context, data): 65 | """ 66 | Plot variables at the end of each day. 67 | """ 68 | pass 69 | 70 | def handle_data(context,data): 71 | """ 72 | Called every minute. 73 | """ 74 | pass 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /algorithms/FrankPSch/zR6252 S1.26 DD53 _QuantCon 2016_ Peculiarities of Volatility by Dr. Ernest Chan_.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import math 4 | from quantopian.pipeline import Pipeline 5 | from quantopian.algorithm import attach_pipeline, pipeline_output 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.factors import CustomFactor 8 | from quantopian.pipeline.data.quandl import yahoo_index_vix 9 | #from quantopian.pipeline.data.quandl import cboe_vix 10 | 11 | NDays = 5 12 | 13 | class ImpliedVolatility(CustomFactor): 14 | inputs = [yahoo_index_vix.close] 15 | #inputs = [cboe_vix] 16 | #window_length=NDays 17 | def compute(self, today, assets, out, vix): 18 | #out[:] = np.mean(vix, axis=0) # NB one identical column for every asset 19 | out[:] = np.mean(vix) # Does same as above, but more correct for ANTICIPATE CHANGE: https://www.quantopian.com/posts/upcoming-changes-to-quandl-datasets-in-pipeline-vix-vxv-etc-dot 20 | 21 | 22 | def initialize(context): 23 | 24 | context.vxx = sid(38054) 25 | context.xiv = sid(40516) 26 | context.spy = sid(8554) 27 | # I just replaced XIV by QQQ, VXX by IEF in last Burrito Dan code and run back-test from 2007-06-01 28 | 29 | set_benchmark(context.xiv) 30 | 31 | pipe = Pipeline() 32 | attach_pipeline(pipe, 'example') 33 | 34 | iv = ImpliedVolatility(window_length=NDays) 35 | #iv = ImpliedVolatility() 36 | pipe.add(iv, 'iv') 37 | 38 | schedule_function(func=allocate, 39 | time_rule=time_rules.market_open(), 40 | half_days=True) 41 | 42 | 43 | def before_trading_start(context, data): 44 | 45 | output = pipeline_output('example') 46 | output = output.dropna() #makes a copy 47 | iv = output["iv"].iloc[0] 48 | hv = calculate_hv(context, data, NDays) 49 | 50 | context.vrp = iv-hv 51 | 52 | record(ImpliedVolatility=iv) 53 | record(HistoricVolatility=hv) 54 | #record(VRP=iv-hv) 55 | 56 | 57 | def calculate_hv(context, data, days): 58 | close = data.history(context.spy, ["price"], days+1, "1d") 59 | close["ret"] = (np.log(close.price) - np.log(close.price).shift(1)) 60 | return close.ret.std()*math.sqrt(252)*100 61 | 62 | 63 | def allocate(context, data): 64 | if context.vrp > 0: 65 | order_target_percent(context.vxx, 0.00) 66 | order_target_percent(context.xiv, 1.00) 67 | else: 68 | order_target_percent(context.vxx, 1.00) 69 | order_target_percent(context.xiv, 0.00) -------------------------------------------------------------------------------- /algorithms/FrankPSch/D-37 S-0.7 DD40 _Cash Return Algorithm_.py: -------------------------------------------------------------------------------- 1 | from __future__ import division 2 | from quantopian.algorithm import attach_pipeline, pipeline_output 3 | from quantopian.pipeline import Pipeline 4 | from quantopian.pipeline.data.builtin import USEquityPricing 5 | from quantopian.pipeline.experimental import QTradableStocksUS 6 | from quantopian.pipeline.factors import CustomFactor 7 | import quantopian.optimize as opt 8 | import quantopian.algorithm as algo 9 | 10 | from scipy import stats 11 | import numpy as np 12 | import pandas as pd 13 | import math 14 | 15 | from quantopian.pipeline.data import Fundamentals 16 | 17 | def make_pipeline(): 18 | cash_return = Fundamentals.cash_return.latest 19 | universe = QTradableStocksUS() & cash_return.notnull() 20 | 21 | ranking = cash_return.rank(mask=universe) 22 | 23 | longs = ranking.percentile_between(95, 100) 24 | shorts = ranking.percentile_between(1, 5) 25 | 26 | long_short_screen = (longs | shorts) 27 | 28 | pipe = Pipeline(columns = { 29 | 'longs':longs, 30 | 'shorts':shorts, 31 | }, 32 | screen = long_short_screen) 33 | return pipe 34 | 35 | def initialize(context): 36 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 37 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 38 | 39 | attach_pipeline(make_pipeline(), 'my_pipe') 40 | 41 | schedule_function(rebalance, 42 | date_rules.every_day(), 43 | time_rules.market_open(minutes=7)) 44 | 45 | schedule_function(record_var, 46 | date_rules.every_day(), 47 | time_rules.market_close(minutes=7)) 48 | 49 | def before_trading_start(context, data): 50 | context.output = pipeline_output('my_pipe') 51 | context.longs = context.output[context.output.longs] 52 | context.shorts = context.output[context.output.shorts] 53 | context.security_list = context.shorts.index.union(context.longs.index) 54 | 55 | def rebalance(context, data): 56 | weight = 1.00000 / len(context.security_list) 57 | 58 | for stock in context.security_list: 59 | if stock in context.longs.index: 60 | order_target_percent(stock, weight) 61 | 62 | elif stock in context.shorts.index: 63 | order_target_percent(stock, -weight) 64 | 65 | for stock in context.portfolio.positions: 66 | if stock not in context.security_list: 67 | order_target_percent(stock, 0) 68 | 69 | def record_var(context, data): 70 | record(leverage = context.account.leverage) -------------------------------------------------------------------------------- /algorithms/FrankPSch/R197 S0.54 DD34 _DJIA with Momentum for Mr. Shibanov_.py: -------------------------------------------------------------------------------- 1 | # Здесь мы используем стратегию, в которой работает фактор "Моментум", # т.е. заходим вдолгую в те активы, которые за прошедший период времени # росли наиболее сильно. 2 | # Код для сортировки "успешных" акций был позаимствован отсюда: # https://www.quantopian.com/posts/quick-and-dirty-momentum-strategy 3 | from operator import itemgetter 4 | 5 | def initialize(context): 6 | set_long_only() 7 | context.topMom = 1 8 | context.rebal_int = 3 9 | context.lookback = 250 10 | set_symbol_lookup_date('2015-01-01') 11 | #В качестве выборки взяты компании из индекса Доу-Джонса, которые там находились в 2006 году 12 | context.stocks = symbols('GE', 'XOM', 'PG', 'UTX', 'MMM', 'IBM', 'MRK', 'AXP', 'MSD', 'BA', 'KO', 'CAT', 'JPM', 'DIS', 'JNJ', 'WMT', 'HD', 'INTC', 'MSFT', 'PFT', 'VZ', 'GM') 13 | schedule_function(rebalance, 14 | date_rule=date_rules.month_start(), 15 | time_rule=time_rules.market_open()) 16 | 17 | 18 | def rebalance(context, data): 19 | #Создали список акций по моментуму 20 | MomList = GenerateMomentumList(context, data) 21 | 22 | 23 | for stock in context.portfolio.positions: 24 | order_target(stock, 0) 25 | #Это наш бенчмарк, который мы также рисуем на графике для наглядности 26 | spy = symbol('SPY') 27 | 28 | # weight = /context.topMom 29 | weight = 1 30 | 31 | #Идем в длинную по самому первому в рейтинге MomList, то есть выбираем самый быстрорастущий! 32 | for l in MomList: 33 | stock = l[0] 34 | if stock in data and data[stock].close_price > data[stock].mavg(200): 35 | order_percent(stock, weight) 36 | pass 37 | 38 | 39 | # Тут мы генерируем рейтинг акций, ранжируя их по скорости месячного роста 40 | def GenerateMomentumList(context, data): 41 | 42 | MomList = [] 43 | price_history = history(bar_count=context.lookback, frequency="1d", field='price') 44 | #Здесь old - месяц назад 45 | #Добавляем для каждой акции ее прирост за месяц 46 | for stock in context.stocks: 47 | now = price_history[stock].ix[-1] 48 | old = price_history[stock].ix[0] 49 | pct_change = (now - old) / old 50 | MomList.append([stock, pct_change, price_history[stock].ix[0]]) 51 | 52 | 53 | MomList = sorted(MomList, key=itemgetter(1), reverse=True) 54 | #Отсортировали, сделали так, чтобы показывался 55 | MomList = MomList[0:context.topMom] 56 | #Выбираем наилучший! 57 | print (MomList[0][0].symbol) 58 | 59 | return MomList 60 | 61 | 62 | def change(one, two): 63 | return(( two - one)/one) 64 | 65 | def handle_data(context, data): 66 | pass -------------------------------------------------------------------------------- /algorithms/FrankPSch/_Second Attempt at ML - Stochastic Gradient Descent Method Using Hinge Loss Function_.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | 4 | def initialize(context): 5 | set_universe(universe.DollarVolumeUniverse(97, 99)) 6 | context.bet_amount = 100000.0 7 | context.max_notional=1000000.1 8 | context.min_notional=-100000.0 9 | 10 | 11 | def handle_data(context, data): 12 | 13 | for stock in data: 14 | 15 | if caltheta(data,stock,5) is None: 16 | continue 17 | 18 | (theta,historicalPrices) = caltheta(data,stock,5) 19 | indicator=np.dot(theta,historicalPrices) 20 | # normalize 21 | hlen=sum([k*k for k in historicalPrices]) 22 | tlen=sum([j*j for j in theta]) 23 | indicator/=float(hlen*tlen) #now indicator lies between [-1,1] 24 | 25 | current_Prices = data[stock].price 26 | notional = context.portfolio.positions[stock].amount * current_Prices 27 | 28 | 29 | if indicator>=0 and notionalcontext.min_notional: 34 | order(stock,indicator*context.bet_amount) 35 | log.info("%f shares of %s sold." %(context.bet_amount*indicator,stock)) 36 | 37 | 38 | 39 | @batch_transform(refresh_period=1,window_length=60) 40 | def caltheta(datapanel, sid, num): 41 | prices=datapanel['price'][sid] 42 | for i in range(len(prices)): 43 | if prices[i] is None: 44 | return None 45 | testX=[[prices[i] for i in range(j,j+4)] for j in range(0,60,5)] 46 | avg=[np.average(testX[k]) for k in range(len(testX))] 47 | testY=[np.sign(prices[5*i+4]-avg[i]) for i in range(len(testX))] 48 | theta=hlsgdA(testX, testY, 0.01, randomIndex, num) 49 | priceh=prices[-4:] #get historical data for the last four days 50 | return (theta,priceh) 51 | 52 | 53 | # stochastic gradient descent using hinge loss function 54 | def hlsgdA(X, Y, l, nextIndex, numberOfIterations): 55 | theta=np.zeros(len(X[0])) 56 | best=np.zeros(len(X[0])) 57 | e=0 58 | omega=1.0/(2*len(Y)) 59 | while e= 1.0] 58 | 59 | # Calculate the targeted weight 60 | wt = lev*(1.0 - wt_core) / len(pos_mom) if len(pos_mom) !=0 else 0 61 | 62 | # Loop through tactical assets and order target percentages 63 | for etf in tact_etf: 64 | if data.can_trade(etf): 65 | if etf in pos_mom.index: 66 | order_target_percent(etf, wt) 67 | else: 68 | order_target(etf, 0) 69 | 70 | 71 | def before_trading_start(context,data): 72 | # Record data 73 | record(leverage = context.account.leverage) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Cloned from _Reply to_ Portfolio Optimization with the Minimax algorithm [help needed]_.py: -------------------------------------------------------------------------------- 1 | import cvxpy as cvx 2 | import pandas as pd 3 | import numpy as np 4 | import quantopian.algorithm as algo 5 | import quantopian.optimize as qopt 6 | 7 | def get_minimax_weights(returns, target_loss=0.03): 8 | num_stocks = len(returns.columns) 9 | mean = returns.mean(axis=0).values 10 | A = returns.as_matrix() 11 | x = cvx.Variable(num_stocks) 12 | objective = cvx.Maximize(mean.T * x) 13 | 14 | constraints = [ 15 | x >= 0, 16 | A * x >= -target_loss, 17 | cvx.sum_entries(x) == 1.0 18 | ] 19 | prob = cvx.Problem(objective, constraints) 20 | prob.solve(verbose=True) 21 | print(prob.value) 22 | print(x.value) 23 | w = pd.Series(data=np.asarray(x.value).flatten(), index=returns.columns) 24 | w = w / w.abs().sum() 25 | return w 26 | 27 | def get_RCK_weights(returns, minimalWealthFraction=0.7, confidence=0.3,max_expo=0.25): 28 | n = len(returns.columns) 29 | pi = np.array([1. / len(returns)] * len(returns)) 30 | r = (returns+1.).as_matrix().T 31 | b_rck = cvx.Variable(n) 32 | lambda_rck = cvx.Parameter(sign='positive') 33 | lambda_rck.value = np.log(confidence) / np.log(minimalWealthFraction) 34 | growth_rate = pi.T * cvx.log(r.T * b_rck) 35 | risk_constraint = cvx.log_sum_exp(np.log(pi) - lambda_rck * cvx.log(r.T * b_rck)) <= 0 36 | constraints = [cvx.sum_entries(b_rck) == 1, b_rck >= 0, b_rck<=max_expo, risk_constraint] 37 | rck = cvx.Problem(cvx.Maximize(growth_rate), constraints) 38 | rck.solve(verbose=False) 39 | #print rck.value 40 | #print b_rck.value 41 | w = pd.Series(data=np.asarray(b_rck.value).flatten(), index=returns.columns) 42 | w = w / w.abs().sum() 43 | return w 44 | 45 | 46 | def initialize(context): 47 | context.securities= [ 48 | sid(25904), # VFH (Vanguard Financials ETF) 49 | sid(25906), # VHT (Vanguard Health Care ETF) 50 | sid(25905), # VGT (Vanguard Information Technology ETF) 51 | sid(26667), # VDE (Vanguard Energy ETF) 52 | sid(25902), # VCR (Vanguard Consumer Discretionary ETF) 53 | sid(22445), # IBB (iShares Nasdaq Biotechnology Index Fund) 54 | sid(39479), # IBB (iShares Nasdaq Biotechnology Index Fund) 55 | sid(22887), # EDV VANGUARD treasury 56 | sid(25899), # VB = Vanguard small cap 57 | sid(25898) # VAW (Vanguard Materials ETF) 58 | ] 59 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(hours=1)) 60 | 61 | def my_rebalance(context,data): 62 | returns = data.history(context.securities, 'price', 400, '1d').pct_change().dropna() 63 | try: 64 | w=get_RCK_weights(returns) 65 | order_ptf(w) 66 | except: 67 | pass 68 | 69 | def order_ptf(weights): 70 | algo.order_optimal_portfolio( 71 | objective=qopt.TargetWeights(weights), 72 | constraints=[ 73 | qopt.MaxGrossExposure(1.0), 74 | ] 75 | ) -------------------------------------------------------------------------------- /algorithms/FrankPSch/xxx R0028 S1.5 DD3 _Ernie Chan's EWA_EWC pair trade with Kalman filter_.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pytz 3 | 4 | 5 | def initialize(context): 6 | context.ewa = sid(14516) 7 | context.ewc = sid(14517) 8 | 9 | context.delta = 0.0001 10 | context.Vw = context.delta / (1 - context.delta) * np.eye(2) 11 | context.Ve = 0.001 12 | 13 | context.beta = np.zeros(2) 14 | context.P = np.zeros((2, 2)) 15 | context.R = None 16 | 17 | context.pos = None 18 | context.day = None 19 | 20 | set_slippage(slippage.FixedSlippage(spread=0)) 21 | set_commission(commission.PerShare(cost=0)) 22 | 23 | 24 | def handle_data(context, data): 25 | exchange_time = get_datetime().astimezone(pytz.timezone('US/Eastern')) 26 | 27 | # update Kalman filter and exectue a trade during the last 5 mins of trading each day 28 | if exchange_time.hour == 15 and exchange_time.minute >= 55: 29 | # only execute this once per day 30 | if context.day is not None and context.day == exchange_time.day: 31 | return 32 | context.day = exchange_time.day 33 | 34 | x = np.asarray([data.current(context.ewa, 'price'), 1.0]).reshape((1, 2)) 35 | y = data.current(context.ewc, 'price') 36 | 37 | # update Kalman filter with latest price 38 | if context.R is not None: 39 | context.R = context.P + context.Vw 40 | else: 41 | context.R = np.zeros((2, 2)) 42 | 43 | yhat = x.dot(context.beta) 44 | 45 | Q = x.dot(context.R).dot(x.T) + context.Ve 46 | sqrt_Q = np.sqrt(Q) 47 | e = y - yhat 48 | K = context.R.dot(x.T) / Q 49 | context.beta = context.beta + K.flatten() * e 50 | context.P = context.R - K * x.dot(context.R) 51 | 52 | record(beta=context.beta[0], alpha=context.beta[1]) 53 | if e < 5: 54 | record(spread=float(e), Q_upper=float(sqrt_Q), Q_lower=float(-sqrt_Q)) 55 | 56 | if context.pos is not None: 57 | if context.pos == 'long' and e > -sqrt_Q: 58 | #log.info('closing long') 59 | order_target(context.ewa, 0) 60 | order_target(context.ewc, 0) 61 | context.pos = None 62 | elif context.pos == 'short' and e < sqrt_Q: 63 | #log.info('closing short') 64 | order_target(context.ewa, 0) 65 | order_target(context.ewc, 0) 66 | context.pos = None 67 | 68 | if context.pos is None: 69 | if e < -sqrt_Q: 70 | #log.info('opening long') 71 | order(context.ewc, 1000) 72 | order(context.ewa, -1000 * context.beta[0]) 73 | context.pos = 'long' 74 | elif e > sqrt_Q: 75 | #log.info('opening short') 76 | order(context.ewc, -1000) 77 | order(context.ewa, 1000 * context.beta[0]) 78 | context.pos = 'short' -------------------------------------------------------------------------------- /algorithms/1nad/Example_MA_crossover.py: -------------------------------------------------------------------------------- 1 | ''' 2 | TIPS: 3 | For recorded values see: Full Backtest/Activity/Custom Data 4 | ''' 5 | from quantopian.algorithm import attach_pipeline, pipeline_output 6 | from quantopian.pipeline import Pipeline, CustomFactor 7 | import quantopian.pipeline.filters as Filters 8 | import quantopian.pipeline.factors as Factors 9 | import pandas as pd 10 | import numpy as np 11 | from quantopian.pipeline.data.builtin import USEquityPricing 12 | 13 | 14 | MY_STOCKS = symbols('AAPL') 15 | WEIGHT = 1.0 / len(MY_STOCKS) 16 | 17 | 18 | def initialize(context): 19 | attach_pipeline(pipe_definition(context), name='my_data') 20 | 21 | schedule_function(trade, date_rules.every_day(), time_rules.market_open()) 22 | schedule_function(record_vars, date_rules.every_day(), time_rules.market_close()) 23 | 24 | context.security = symbol('SPY') 25 | context.invested = False 26 | 27 | def pipe_definition(context): 28 | universe = Filters.StaticAssets(MY_STOCKS) 29 | close_price = USEquityPricing.close.latest 30 | short = Factors.SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=20, mask=universe) 31 | long = Factors.SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=60, mask=universe) 32 | 33 | return Pipeline( 34 | columns = { 35 | 'close_price' : close_price, 36 | 'short' : short, 37 | 'long' : long, 38 | }, 39 | screen = universe, 40 | ) 41 | 42 | def before_trading_start(context, data): 43 | context.output = pipeline_output('my_data') 44 | 45 | def trade(context, data): 46 | context.output 47 | 48 | open_rules = 'short > long' 49 | open_these = context.output.query(open_rules).index.tolist() 50 | 51 | for stock in open_these: 52 | if stock not in context.portfolio.positions and data.can_trade(stock): 53 | order_target_percent(stock, WEIGHT) 54 | #Log example 55 | print('buy :' + str(WEIGHT)) 56 | cpp = context.portfolio.positions 57 | log.info(cpp) 58 | cpp_symbols = map(lambda x: x.symbol, cpp) 59 | log.info(cpp_symbols) 60 | 61 | close_rules = 'short < long' 62 | close_these = context.output.query(close_rules).index.tolist() 63 | 64 | for stock in close_these: 65 | if stock in context.portfolio.positions and data.can_trade(stock): 66 | order_target_percent(stock, 0) 67 | #Log example 68 | print('sell :' + str(WEIGHT)) 69 | cpp = context.portfolio.positions 70 | log.info(cpp) 71 | cpp_symbols = map(lambda x: x.symbol, cpp) 72 | log.info(cpp_symbols) 73 | 74 | def record_vars(context, data): 75 | record( 76 | short_mavg = context.output.short, 77 | long_mavg = context.output.long, 78 | price = context.output.close_price, 79 | leverage=context.account.leverage, 80 | positions=len(context.portfolio.positions) 81 | ) -------------------------------------------------------------------------------- /algorithms/FrankPSch/R326 S0.58 DD60 _The Q500US and Q1500US_.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a template algorithm on Quantopian for you to adapt and fill in. 3 | """ 4 | from quantopian.algorithm import attach_pipeline, pipeline_output 5 | from quantopian.pipeline import Pipeline 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.factors import AverageDollarVolume 8 | from quantopian.pipeline.filters import Q1500US 9 | def initialize(context): 10 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 11 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 12 | """ 13 | Called once at the start of the algorithm. 14 | """ 15 | # Rebalance every day, 1 hour after market open. 16 | schedule_function(my_rebalance, date_rules.week_start(days_offset=1), time_rules.market_open(hours=1)) 17 | # Record tracking variables at the end of each day. 18 | # schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 19 | # Create our dynamic stock selector. 20 | attach_pipeline(make_pipeline(), 'my_pipeline') 21 | 22 | 23 | def make_pipeline(): 24 | """ 25 | A function to create our dynamic stock selector (pipeline). Documentation on 26 | pipeline can be found here: https://www.quantopian.com/help#pipeline-title 27 | """ 28 | 29 | # Create a dollar volume factor. 30 | dollar_volume = AverageDollarVolume(window_length=1) 31 | # Pick the top 1% of stocks ranked by dollar volume. 32 | high_dollar_volume = dollar_volume.percentile_between(99, 100) 33 | pipe = Pipeline( 34 | # screen = (high_dollar_volume & Q500US()), 35 | screen = Q1500US(), 36 | columns = { 37 | 'dollar_volume': dollar_volume 38 | } 39 | ) 40 | return pipe 41 | 42 | 43 | def before_trading_start(context, data): 44 | """ 45 | Called every day before market open. 46 | """ 47 | context.output = pipeline_output('my_pipeline') 48 | # These are the securities that we are interested in trading each day. 49 | context.security_list = context.output.index 50 | 51 | 52 | def my_assign_weights(context, data): 53 | """ 54 | Assign weights to securities that we want to order. 55 | """ 56 | pass 57 | 58 | 59 | def my_rebalance(context,data): 60 | """ 61 | Execute orders according to our schedule_function() timing. 62 | """ 63 | # pass 64 | weight = 1.0/len(context.security_list) 65 | for stock in context.security_list: 66 | if data.can_trade(stock): 67 | order_target_percent(stock,weight) 68 | for stock in context.portfolio.positions.keys(): 69 | if stock not in context.security_list: 70 | if data.can_trade(stock): 71 | order_target_percent(stock,0) 72 | 73 | 74 | def my_record_vars(context, data): 75 | """ 76 | Plot variables at the end of each day. 77 | """ 78 | pass -------------------------------------------------------------------------------- /algorithms/FrankPSch/nil _Pair trading using $10,00,000 equity_.py: -------------------------------------------------------------------------------- 1 | # Put any initialization logic here. The context object will be passed to 2 | # the other methods in your algorithm. 3 | import numpy as np 4 | 5 | def initialize(context): 6 | context.asset1 =symbol('ABGB') 7 | context.asset2 = symbol('FSLR') 8 | context.price1 = 0 9 | context.price2 = 0 10 | context.pos = 0 11 | context.deltas=[] 12 | 13 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 14 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 15 | 16 | 17 | # Will be called on every trade event for the securities you specify. 18 | def handle_data(context, data): 19 | # Implement your algorithm logic here. 20 | 21 | # data[sid(X)] holds the trade event data for that security. 22 | # context.portfolio holds the current portfolio state. 23 | 24 | # Place orders with the order(SID, amount) method. 25 | 26 | # TODO: implement your own logic here. 27 | curp1 = data.current(context.asset1, 'price') 28 | curp2 = data.current(context.asset2, 'price') 29 | #print(curp1, curp2) 30 | if context.price1 == 0 or context.price2 == 0: 31 | context.price1 = curp1 32 | context.price2 = curp2 33 | return 34 | delta = curp1 - context.price1 - (curp2 - context.price2) 35 | context.deltas.append(delta) 36 | #hedge ratio 37 | 38 | #ratio = curp1 / curp2 39 | if context.pos == 0: 40 | if delta > 5: 41 | #share1 = int(context.portfolio.cash*0.4 / curp1) 42 | #share2 = int(context.portfolio.cash*0.4 / curp2) 43 | share = int(context.portfolio.cash * 0.8 / (curp1 + curp2)) 44 | order(context.asset1, -share) 45 | order(context.asset2, share) 46 | context.pos = 1 47 | log.info('Open: sell {} shares of {}, buy {} shares of {}'.format(share, context.asset1, share, context.asset2)) 48 | elif delta < -5: 49 | #share1 = int(context.portfolio.cash*0.4 / curp1) 50 | #share2 = int(context.portfolio.cash*0.4 / curp2) 51 | share = int(context.portfolio.cash * 0.8 / (curp1 + curp2)) 52 | order(context.asset1, share) 53 | order(context.asset2, -share) 54 | context.pos = -1 55 | log.info('Open: buy {} shares of {}, sell {} shares of {}'.format(share, context.asset1, share, context.asset2)) 56 | else: 57 | if context.pos == 1 and delta < 0: 58 | order_target(context.asset1, 0) 59 | order_target(context.asset2, 0) 60 | context.pos = 0 61 | log.info('Close: buy {}, sell {}'.format(context.asset1, context.asset2)) 62 | elif context.pos == -1 and delta > 0: 63 | order_target(context.asset1, 0) 64 | order_target(context.asset2, 0) 65 | context.pos = 0 66 | log.info('Close: sell {}, buy {}'.format(context.asset1, context.asset2)) 67 | 68 | record(delta = delta) 69 | #record(assets = context.portfolio.portfolio_value) 70 | #arr = np.array(context.deltas) 71 | #log.info('mean: {}, std: {}'.format(arr.mean(), arr.std())) -------------------------------------------------------------------------------- /algorithms/FrankPSch/xx R0114 S0.47 DD40 cls_opn_crs() _Holding Spy Overnight_.py: -------------------------------------------------------------------------------- 1 | # https://www.quantopian.com/posts/holding-spy-overnight 2 | spy = sid(8554) 3 | 4 | def initialize(context): 5 | # Fill orders with no volume check? Are we 100% sure? 6 | #set_slippage(slippage.FixedSlippage(spread=0.0)) 7 | # Fill orders with no volume limit, set outrageously high for testing only. 8 | # With starting capital turned down, nothing for this to chew on 9 | #set_slippage(slippage.VolumeShareSlippage(volume_limit= 1e6 )) 10 | 11 | minut = 120 12 | schedule_function(close_pos, date_rules.every_day(), time_rules.market_open (minutes=minut)) 13 | schedule_function(open_pos, date_rules.every_day(), time_rules.market_close(minutes=minut)) 14 | 15 | # end is non-inclusive, at 390 will not run on 390 the last minute of the day. 16 | # Set to 391 to run 390 and see incomplete orders. How is that possible? 17 | for i in range(1, 390, 1): # start, end, every i 18 | 19 | break # comment out or remove to activate 20 | 21 | schedule_function(profit_or_stop, date_rules.every_day(), time_rules.market_open(minutes=i)) 22 | 23 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 24 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 25 | 26 | def profit_or_stop(context, data): 27 | for s in context.portfolio.positions: 28 | cb = context.portfolio.positions[s].cost_basis 29 | prc = data.current(s, 'price') 30 | if prc > cb * 1.002: 31 | if orders_just_so(context, s): 32 | continue 33 | order_target(s, 0) 34 | #log.info(' profit prc {} cb {} {}'.format(prc, cb, '%.3f' % (prc / cb))) 35 | elif prc < cb * .95: 36 | if orders_just_so(context, s): 37 | continue 38 | order_target(s, 0) 39 | log.info('stoploss prc {} cb {} {}'.format(prc, cb, '%.3f' % (prc / cb))) 40 | 41 | def open_pos(context, data): # pos stands for position 42 | oo = get_open_orders(spy) 43 | for o in oo: 44 | cancel_order(o.id) 45 | order_target_percent(spy, 1.0) 46 | #log.info('open') 47 | 48 | def close_pos(context, data): 49 | oo = get_open_orders(spy) 50 | for o in oo: 51 | cancel_order(o.id) 52 | order_target(spy, 0) 53 | #log.info('close') 54 | 55 | def orders_just_so(context, s): 56 | oo = get_open_orders(s) 57 | for o in oo: # returns are assuming only one order 58 | if cls_opn_crs(context, s, o) in [1, 3]: # Opening 59 | cancel_order(o.id) # Cancel opening order 60 | return 0 # To allow the close 61 | else: 62 | return 1 # Already closing, signal to skip adding another close order 63 | 64 | def cls_opn_crs(c, s, o): 65 | # https://www.quantopian.com/posts/order-state-on-partial-fills-close-open-or-crossover 66 | if o.stop or o.limit: return 0 # ... assuming you're using stop, limit only to close 67 | if c.portfolio.positions[s].amount * o.amount < 0: # close or x 68 | if abs(c.portfolio.positions[s].amount) < abs(o.amount - o.filled): 69 | if abs(c.portfolio.positions[s].amount) - abs(o.filled) < 0: 70 | return 3 # crossed now opening 71 | else: return 2 # cross closing 72 | else: return 0 # close 73 | else: return 1 # open -------------------------------------------------------------------------------- /algorithms/FrankPSch/R290 S0.62 DD50 _Trading strategy for team_.py: -------------------------------------------------------------------------------- 1 | from quantopian.algorithm import attach_pipeline, pipeline_output 2 | from quantopian.pipeline import Pipeline 3 | from quantopian.pipeline.data.builtin import USEquityPricing 4 | from quantopian.pipeline.data import morningstar 5 | from quantopian.pipeline.factors import CustomFactor, Returns 6 | from quantopian.pipeline.filters import Q1500US 7 | from quantopian.pipeline.filters import Q500US 8 | import pandas as pd 9 | import numpy as np 10 | 11 | class MarketCap(CustomFactor): 12 | #рыночная капитализация - количество акций на их цену 13 | inputs = [morningstar.valuation.shares_outstanding, USEquityPricing.close] 14 | window_length = 1 15 | 16 | def compute(self, today, assets, out, shares, close_price): 17 | out[:] = shares * close_price 18 | 19 | class BookToPrice(CustomFactor): 20 | #берем b/p как 1/(p/b) 21 | inputs = [morningstar.valuation_ratios.pb_ratio] 22 | window_length = 1 23 | 24 | def compute(self, today, assets, out, pb): 25 | out[:] = 1 / pb 26 | class Quality(CustomFactor): 27 | #return on equity 28 | inputs = [morningstar.operation_ratios.roe] 29 | window_length = 1 30 | 31 | def compute(self, today, assets, out, roe): 32 | out[:] = roe[-1] 33 | def make_pipeline(context): 34 | 35 | pipe = Pipeline() 36 | # Q1500US - вселенная из 1500 самых ликвидных активов 37 | universe = Q1500US() 38 | market_cap = MarketCap(mask=universe) 39 | market_cap_rank = market_cap.rank() 40 | # берем половину активов с большой капитализацией 41 | market_cap_high = market_cap_rank.top(750) 42 | quality=Quality(mask=market_cap_high) 43 | quality_rank=quality.rank() 44 | # 100 самых целесообразных в плане бизнеса 45 | qualit=quality_rank.top(100) 46 | book_to_price = BookToPrice(mask=qualit) 47 | book_to_price_rank = book_to_price.rank() 48 | # 50 недооцененных в низким b/p 49 | highbp = book_to_price_rank.top(15) 50 | securities_to_trade = ( highbp) 51 | pipe = Pipeline( 52 | columns={ 53 | 'highbp':highbp, 54 | }, 55 | screen = securities_to_trade 56 | ) 57 | 58 | 59 | return pipe 60 | 61 | def initialize(context): 62 | 63 | # будем ребалансировать наш портфель каждый январь в начале, через 1.5 часа после открытия 64 | 65 | attach_pipeline(make_pipeline(context), 'my_pipeline') 66 | schedule_function(rebalance, 67 | date_rules.month_start(days_offset=0), 68 | time_rules.market_open(hours=1, minutes=30)) 69 | 70 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 71 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 72 | 73 | def before_trading_start(context, data): 74 | # включаем все отобранные активы в наш портфель 75 | context.output = pipeline_output('my_pipeline') 76 | 77 | context.highbp = context.output[context.output['highbp']] 78 | 79 | context.security_list = context.highbp.index.tolist() 80 | 81 | 82 | def rebalance(context,data): 83 | # у нас будет равно-взвешенный портфель 84 | today = get_datetime('US/Eastern') 85 | if today.month==1: 86 | for stock in context.portfolio.positions: 87 | if stock not in context.security_list: 88 | if data.can_trade(stock): 89 | order_target_percent(stock, 0) 90 | print context.security_list 91 | for security in context.security_list: 92 | if data.can_trade(security): 93 | order_target_percent(security, 0.066) 94 | record(leverage = context.account.leverage) -------------------------------------------------------------------------------- /algorithms/FrankPSch/E data _Accern Alphaone Long Short_.py: -------------------------------------------------------------------------------- 1 | from quantopian.algorithm import attach_pipeline, pipeline_output 2 | from quantopian.pipeline import Pipeline 3 | from quantopian.pipeline.data.builtin import USEquityPricing 4 | from quantopian.pipeline.factors import CustomFactor 5 | from quantopian.pipeline.data.accern import alphaone_free as alphaone 6 | 7 | import pandas as pd 8 | import numpy as np 9 | 10 | 11 | # Calculates the average impact of the sentiment over the window length 12 | class AvgImpact(CustomFactor): 13 | 14 | def compute(self, today, assets, out, sentiment, impact): 15 | np.mean((sentiment*impact), axis=0, out=out) 16 | 17 | 18 | class AvgDailyDollarVolumeTraded(CustomFactor): 19 | 20 | inputs = [USEquityPricing.close, USEquityPricing.volume] 21 | window_length = 20 22 | 23 | def compute(self, today, assets, out, close_price, volume): 24 | out[:] = np.mean(close_price * volume, axis=0) 25 | 26 | 27 | # Put any initialization logic here. The context object will be passed to 28 | # the other methods in your algorithm. 29 | def initialize(context): 30 | 31 | pipe = Pipeline() 32 | pipe = attach_pipeline(pipe, name='sentiment_metrics') 33 | 34 | # Add our AvgImpact factor to the pipeline 35 | pipe.add(AvgImpact(inputs=[alphaone.article_sentiment, alphaone.impact_score], window_length=7), "avg_impact") 36 | 37 | dollar_volume = AvgDailyDollarVolumeTraded() 38 | 39 | # Screen out low liquidity securities. 40 | pipe.set_screen(dollar_volume > 10**7) 41 | context.shorts = None 42 | context.longs = None 43 | # context.spy = sid(8554) 44 | 45 | schedule_function(rebalance, date_rules.week_start(), time_rules.market_open(hours=1)) 46 | set_commission(commission.PerShare(cost=0, min_trade_cost=0)) 47 | set_slippage(slippage.FixedSlippage(spread=0)) 48 | 49 | 50 | def before_trading_start(context, data): 51 | results = pipeline_output('sentiment_metrics').dropna() 52 | longs = results[results['avg_impact'] > 0] 53 | shorts = results[results['avg_impact'] < 0] 54 | long_ranks = longs["avg_impact"].rank().order() 55 | short_ranks = shorts['avg_impact'].rank().order() 56 | short_quartile = int(len(short_ranks.index)*.01) 57 | long_quartile = int(len(long_ranks.index)*.01) 58 | context.shorts = short_ranks.tail(short_quartile) 59 | context.longs = long_ranks.head(long_quartile) 60 | 61 | # The pipe character "|" is the pandas union operator 62 | update_universe(context.longs.index | context.shorts.index) 63 | 64 | 65 | # Will be called on every trade event for the securities you specify. 66 | def handle_data(context, data): 67 | record(lever=context.account.leverage, 68 | exposure=context.account.net_leverage, 69 | num_pos=len(context.portfolio.positions), 70 | oo=len(get_open_orders())) 71 | 72 | 73 | def rebalance(context, data): 74 | 75 | for security in context.shorts.index: 76 | if get_open_orders(security): 77 | continue 78 | if security in data: 79 | order_target_percent(security, -1.0 / len(context.shorts)) 80 | 81 | for security in context.longs.index: 82 | if get_open_orders(security): 83 | continue 84 | if security in data: 85 | order_target_percent(security, 1.0 / len(context.longs)) 86 | 87 | for security in context.portfolio.positions: 88 | if get_open_orders(security): 89 | continue 90 | if security in data: 91 | if security not in (context.longs.index | context.shorts.index): 92 | order_target_percent(security, 0) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Cloned from _New Strategy - Presenting the “Quality Companies in an Uptrend” Model_.py: -------------------------------------------------------------------------------- 1 | import quantopian.algorithm as algo 2 | from quantopian.pipeline import Pipeline 3 | from quantopian.pipeline.data.builtin import USEquityPricing 4 | from quantopian.pipeline.data import Fundamentals 5 | from quantopian.pipeline.filters import Q500US 6 | 7 | def initialize(context): 8 | 9 | set_slippage(slippage.FixedSlippage(spread = 0.0)) 10 | algo.attach_pipeline(make_pipeline(), 'pipeline') 11 | 12 | #Schedule Functions 13 | schedule_function(trade, date_rules.month_end() , time_rules.market_close(minutes=30)) 14 | schedule_function(trade_bonds, date_rules.month_end(), time_rules.market_close(minutes=20)) 15 | 16 | #This is for the trend following filter 17 | context.spy = sid(8554) 18 | context.TF_filter = False 19 | context.TF_lookback = 126 20 | 21 | #Set number of securities to buy and bonds fund (when we are out of stocks) 22 | context.Target_securities_to_buy = 20.0 23 | context.bonds = sid(23870) 24 | 25 | #Other parameters 26 | context.top_n_roe_to_buy = 50 #First sort by ROE 27 | context.relative_momentum_lookback = 126 #Momentum lookback 28 | context.momentum_skip_days = 10 29 | context.top_n_relative_momentum_to_buy = 20 #Number to buy 30 | 31 | 32 | def make_pipeline(): 33 | 34 | # Base universe set to the Q500US 35 | universe = Q500US() 36 | 37 | roe = Fundamentals.roe.latest 38 | 39 | pipe = Pipeline(columns={'roe': roe},screen=universe) 40 | return pipe 41 | 42 | def before_trading_start(context, data): 43 | 44 | context.output = algo.pipeline_output('pipeline') 45 | context.security_list = context.output.index 46 | 47 | def trade(context, data): 48 | 49 | ############Trend Following Regime Filter############ 50 | TF_hist = data.history(context.spy , "close", 140, "1d") 51 | TF_check = TF_hist.pct_change(context.TF_lookback).iloc[-1] 52 | 53 | if TF_check > 0.0: 54 | context.TF_filter = True 55 | else: 56 | context.TF_filter = False 57 | ############Trend Following Regime Filter End############ 58 | 59 | #DataFrame of Prices for our 500 stocks 60 | prices = data.history(context.security_list,"close", 180, "1d") 61 | #DF here is the output of our pipeline, contains 500 rows (for 500 stocks) and one column - ROE 62 | df = context.output 63 | 64 | #Grab top 50 stocks with best ROE 65 | top_n_roe = df['roe'].nlargest(context.top_n_roe_to_buy) 66 | #Calculate the momentum of our top ROE stocks 67 | quality_momentum = prices[top_n_roe.index][:-context.momentum_skip_days].pct_change(context.relative_momentum_lookback).iloc[-1] 68 | #Grab stocks with best momentum 69 | top_n_by_momentum = quality_momentum.nlargest(context.top_n_relative_momentum_to_buy) 70 | 71 | for x in context.portfolio.positions: 72 | if (x.sid == context.bonds): 73 | pass 74 | elif x not in top_n_by_momentum: 75 | order_target_percent(x, 0) 76 | #print('GETTING OUT OF',x) 77 | 78 | for x in top_n_by_momentum.index: 79 | if x not in context.portfolio.positions and context.TF_filter==True: 80 | order_target_percent(x, (1.0 / context.Target_securities_to_buy)) 81 | #print('GETTING IN',x) 82 | 83 | 84 | def trade_bonds(context , data): 85 | amount_of_current_positions=0 86 | if context.portfolio.positions[context.bonds].amount == 0: 87 | amount_of_current_positions = len(context.portfolio.positions) 88 | if context.portfolio.positions[context.bonds].amount > 0: 89 | amount_of_current_positions = len(context.portfolio.positions) - 1 90 | percent_bonds_to_buy = (context.Target_securities_to_buy - amount_of_current_positions) * (1.0 / context.Target_securities_to_buy) 91 | order_target_percent(context.bonds , percent_bonds_to_buy) -------------------------------------------------------------------------------- /algorithms/FrankPSch/xx R0750 S1.04 DD34 B-0.04 _Gap Up strategy_.py: -------------------------------------------------------------------------------- 1 | from quantopian.algorithm import attach_pipeline, pipeline_output 2 | from quantopian.pipeline import Pipeline, CustomFactor 3 | from quantopian.pipeline.data.builtin import USEquityPricing 4 | from quantopian.pipeline.factors import AverageDollarVolume 5 | 6 | from quantopian.pipeline.experimental import QTradableStocksUS 7 | import pandas as pd 8 | import numpy as np 9 | 10 | 11 | def logging(msgs): 12 | dt = get_datetime('US/Eastern') 13 | youbi = dt.strftime("%w") 14 | youbidict = {0: "Sun", 1: "Mon", 2: "Tue", 3: "Wed", 4: "Thu", 5: "Fri", 6: "Sat"} 15 | msgs = '\t%s\t%s:\t%s'%(dt.strftime('%Y/%m/%d %H:%M (ET)'), youbidict[int(youbi)], msgs) 16 | log.info(msgs) 17 | 18 | 19 | class ValueDaybeforeYesterday(CustomFactor): 20 | window_length = 2 21 | def compute(self, today, assets, out, values): 22 | out[:] = values[0] 23 | 24 | 25 | class ChangeAverage(CustomFactor): 26 | def compute(self, today, assets, out, values): 27 | mean = pd.DataFrame(values).pct_change().mean() 28 | out[:] = mean.values 29 | 30 | class ChangeAverageLog(CustomFactor): 31 | def compute(self, today, assets, out, values): 32 | df = pd.DataFrame(values) 33 | mean = (df.shift(1) / df).mean().apply(np.log) 34 | out[:] = mean.values 35 | 36 | def make_pipeline(context): 37 | pipe = Pipeline() 38 | base_universe = QTradableStocksUS() 39 | dollar_volume = AverageDollarVolume(window_length=30) 40 | high_dollar_volume = dollar_volume.percentile_between(98, 100) 41 | 42 | close_day_before_yeseterday = ValueDaybeforeYesterday(inputs = [USEquityPricing.close]) 43 | volume_day_before_yeseterday = ValueDaybeforeYesterday(inputs = [USEquityPricing.volume]) 44 | pipe.add(close_day_before_yeseterday, "close_day_before_yeseterday") 45 | 46 | return_change_mean = ChangeAverage(inputs = [USEquityPricing.close], window_length = 5) 47 | volume_change_mean = ChangeAverage(inputs = [USEquityPricing.volume], window_length = 5) 48 | 49 | 50 | my_screen = base_universe & high_dollar_volume #& (return_change_mean < 0) 51 | pipe.set_screen(my_screen) 52 | return pipe 53 | 54 | 55 | def initialize(context): 56 | attach_pipeline(make_pipeline(context), 'pipe') 57 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open()) 58 | schedule_function(my_close, date_rules.every_day(), time_rules.market_open(minutes=40)) 59 | 60 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 61 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 62 | 63 | 64 | def before_trading_start(context, data): 65 | context.output = pipeline_output('pipe') 66 | 67 | def calc_gap(context, data): 68 | 69 | sids = context.output.index 70 | 71 | df = pd.DataFrame() 72 | if len(sids)>0: 73 | open_price = data.current(sids,'price').rename("open") 74 | df = pd.concat([context.output, open_price], axis = 1) 75 | df['gap'] = df['open'] / df['close_day_before_yeseterday'] - 1 76 | df = df[(df['gap'] > 0.05) ]#& (df['gap'] < 1.0) 77 | return df 78 | 79 | def my_rebalance(context, data): 80 | targets = calc_gap(context, data) 81 | 82 | 83 | if not targets.empty: 84 | cnt = len(targets) 85 | 86 | targets['nomalized_gap'] = targets.gap /targets.gap.abs().sum() 87 | for sid in targets.index: 88 | # order_percent(sid, -1.0 / cnt) 89 | logging("{0}\t{1: .5f}".format(sid.symbol, targets['gap'].loc[sid])) 90 | order_percent(sid, targets['nomalized_gap'].loc[sid] * -1.0) 91 | #logging("{0}\t{1: .5f}".format(sid.symbol, targets['nomalized_gap'].loc[sid] * -1.0)) 92 | 93 | 94 | 95 | def my_close(context, data): 96 | if len(context.portfolio.positions) > 0: 97 | for sid in context.portfolio.positions: 98 | order_target(sid, 0) -------------------------------------------------------------------------------- /algorithms/FrankPSch/R43x S1.31 DD-50 _Another Another Volatility Trading Strategy_.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import math 4 | from quantopian.pipeline import Pipeline 5 | from quantopian.algorithm import attach_pipeline, pipeline_output 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.factors import CustomFactor 8 | from quantopian.pipeline.data.quandl import cboe_vix 9 | from scipy import optimize 10 | 11 | NDays = 5 #5 12 | 13 | class ImpliedVolatility(CustomFactor): 14 | inputs = [cboe_vix.vix_close] 15 | outputs = ['md', 'lst'] 16 | def compute(self, today, assets, out, vix): 17 | df = pd.DataFrame(np.array(vix), columns=['vix']) 18 | out.md[:] = df.quantile(.5) 19 | out.lst[:] = vix[-1] 20 | 21 | def initialize(context): 22 | context.vxx = symbol('IEF') 23 | context.xiv = symbol('SPY') 24 | 25 | context.spy = symbol('SPY') 26 | 27 | #set_benchmark(context.xiv) 28 | set_benchmark(context.spy) # fsc 29 | 30 | pipe = Pipeline() 31 | attach_pipeline(pipe, 'example') 32 | 33 | iv = ImpliedVolatility(window_length = NDays) 34 | pipe.add(iv, 'iv') 35 | 36 | schedule_function(func=allocate, 37 | time_rule=time_rules.market_open(), 38 | half_days=True) 39 | 40 | def before_trading_start(context, data): 41 | 42 | output = pipeline_output('example') 43 | output = output.dropna() 44 | 45 | #implied vol 46 | md, lst = output["iv"].iloc[0] 47 | context.hv = calculate_hv(context, data, NDays) 48 | 49 | calculate_gv(context, data, context.spy) 50 | 51 | context.vrp = md - context.hv 52 | context.volUp = context.gv1 - lst 53 | context.volUp2 = context.gv2 - context.gv1 54 | 55 | record(hv = context.hv, iv = md, gv1 = context.gv1, gv2 = context.gv2) 56 | 57 | def calculate_hv(context, data, days): 58 | close = data.history(context.spy, ["price"], (days+1), "1d") 59 | close["ret"] = (np.log(close.price) - np.log(close.price).shift(1)) 60 | return close.ret.std()*math.sqrt(252)*100 61 | 62 | def GARCH11_logL(param, r, context): 63 | omega, alpha, beta = param 64 | n = len(r) 65 | s = np.ones(n)*0.01 66 | s[2] = np.var(r[0:3]) 67 | for i in range(3, n): 68 | s[i] = omega + alpha*r[i-1]**2 + beta*(s[i-1]) # GARCH(1,1) model 69 | context.last_sigma2 = s[-1] 70 | logL = -((-np.log(s) - r**2/s).sum()) 71 | return logL 72 | 73 | def calculate_gv(context, data, asset): 74 | days = 200 75 | r=np.array(data.history(asset,'price',days,'1d')[:-1]) 76 | r=np.diff(np.log(r)) 77 | 78 | R = optimize.fmin(GARCH11_logL,np.array([.1,.1,.1]),args=(r,context),full_output=1) 79 | #print("omega = %.6f\nbeta = %.6f\nalpha = %.6f r=%.6f\n") % (R[0][0],R[0][2],R[0] [1],r[-1]) 80 | omega = R[0][0] 81 | alpha = R[0][1] 82 | beta = R[0][2] 83 | 84 | uconSigma2 = omega/(1-alpha-beta) 85 | 86 | #calculation of GV(t+1) 87 | sigma21 = omega + alpha*(r[-1])**2 + beta*context.last_sigma2 88 | 89 | #calculation of GV(t+2) 90 | sigma22 = uconSigma2+(alpha+beta)**2*(context.last_sigma2-uconSigma2) 91 | 92 | #normalised to percentage 93 | context.gv1 = 100*math.sqrt(sigma21*252) 94 | context.gv2 = 100*math.sqrt(sigma22*252) 95 | 96 | return 97 | 98 | 99 | def allocate(context, data): 100 | 101 | if context.volUp > 0 and context.volUp2 > 0 and context.vrp < 0 : 102 | order_target_percent(context.vxx, 1.00) 103 | order_target_percent(context.xiv, 0.00) 104 | 105 | if context.volUp < 0 and context.vrp > 0: 106 | order_target_percent(context.vxx, 0.00) 107 | order_target_percent(context.xiv, 1.00) 108 | else: 109 | order_target_percent(context.vxx, 0.00) 110 | order_target_percent(context.xiv, 0.00) -------------------------------------------------------------------------------- /algorithms/FrankPSch/zR6178 S1.43 DD48 _Another Volatility Trading Strategy_.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import math 4 | from quantopian.pipeline import Pipeline 5 | from quantopian.algorithm import attach_pipeline, pipeline_output 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.factors import CustomFactor 8 | from quantopian.pipeline.data.quandl import cboe_vix 9 | from scipy import optimize 10 | 11 | NDays = 5 #5 12 | 13 | 14 | class ImpliedVolatility(CustomFactor): 15 | inputs = [cboe_vix.vix_close] 16 | outputs = ['md', 'lst'] 17 | def compute(self, today, assets, out, vix): 18 | df = pd.DataFrame(np.array(vix), columns=['vix']) 19 | out.md[:] = df.quantile(.5) 20 | out.lst[:] = vix[-1] 21 | 22 | 23 | def initialize(context): 24 | 25 | # using less volatile instruments SPY and IEF 26 | context.vxx = sid(38054) 27 | context.xiv = sid(40516) 28 | context.spy = sid(8554) 29 | 30 | set_benchmark(context.xiv) 31 | 32 | pipe = Pipeline() 33 | attach_pipeline(pipe, 'example') 34 | 35 | iv = ImpliedVolatility(window_length = NDays) 36 | pipe.add(iv, 'iv') 37 | 38 | schedule_function(func=allocate, 39 | time_rule=time_rules.market_open(), 40 | half_days=True) 41 | 42 | 43 | def before_trading_start(context, data): 44 | 45 | output = pipeline_output('example') 46 | output = output.dropna() 47 | #implied vol 48 | md, lst = output["iv"].iloc[0] 49 | context.hv = calculate_hv(context, data, NDays) 50 | 51 | calculate_gv(context, data, context.spy) 52 | 53 | context.vrp = md-context.hv 54 | context.volUp = context.gv1-lst 55 | context.volUp2 = context.gv2 - context.gv1 56 | 57 | record(hv = context.hv, iv = md, gv1 = context.gv1, gv2 = context.gv2) 58 | 59 | 60 | def calculate_hv(context, data, days): 61 | close = data.history(context.spy, ["price"], (days+1), "1d") 62 | close["ret"] = (np.log(close.price) - np.log(close.price).shift(1)) 63 | return close.ret.std()*math.sqrt(252)*100 64 | 65 | 66 | def GARCH11_logL(param, r, context): 67 | omega, alpha, beta = param 68 | n = len(r) 69 | s = np.ones(n)*0.01 70 | s[2] = np.var(r[0:3]) 71 | for i in range(3, n): 72 | s[i] = omega + alpha*r[i-1]**2 + beta*(s[i-1]) # GARCH(1,1) model 73 | context.last_sigma2 = s[-1] 74 | logL = -((-np.log(s) - r**2/s).sum()) 75 | return logL 76 | 77 | 78 | def calculate_gv(context, data, asset): 79 | days = 200 80 | r=np.array(data.history(asset,'price',days,'1d')[:-1]) 81 | r=np.diff(np.log(r)) 82 | 83 | R = optimize.fmin(GARCH11_logL,np.array([.1,.1,.1]),args=(r,context),full_output=1) 84 | #print("omega = %.6f\nbeta = %.6f\nalpha = %.6f r=%.6f\n") % (R[0][0],R[0][2],R[0] [1],r[-1]) 85 | omega = R[0][0] 86 | alpha = R[0][1] 87 | beta = R[0][2] 88 | 89 | uconSigma2 = omega/(1-alpha-beta) 90 | 91 | #calculation of GV(t+1) 92 | sigma21 = omega + alpha*(r[-1])**2 + beta*context.last_sigma2 93 | 94 | #calculation of GV(t+2) 95 | sigma22 = uconSigma2+(alpha+beta)**2*(context.last_sigma2-uconSigma2) 96 | 97 | #normalised to percentage 98 | context.gv1 = 100*math.sqrt(sigma21*252) 99 | context.gv2 = 100*math.sqrt(sigma22*252) 100 | 101 | return 102 | 103 | 104 | def allocate(context, data): 105 | 106 | if context.volUp > 0 and context.volUp2 > 0 and context.vrp < 0 : 107 | order_target_percent(context.vxx, 1.00) 108 | order_target_percent(context.xiv, 0.00) 109 | 110 | if context.vrp > 0 and context.volUp < 0: 111 | order_target_percent(context.vxx, 0.00) 112 | order_target_percent(context.xiv, 1.00) 113 | else: 114 | order_target_percent(context.vxx, 0.00) 115 | order_target_percent(context.xiv, 0.00) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Cloned from _Reply to_ Getting Yesterdays Close Price_.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a sample algorithm on Quantopian showing the use of previous close price. 3 | """ 4 | 5 | # Import necessary Pipeline modules 6 | from quantopian.pipeline import Pipeline, CustomFactor 7 | from quantopian.algorithm import attach_pipeline, pipeline_output 8 | 9 | # Import specific filters and factors which will be used 10 | from quantopian.pipeline.filters import QTradableStocksUS, StaticAssets 11 | from quantopian.pipeline.factors import Returns 12 | 13 | # Import datasets which will be used 14 | from quantopian.pipeline.data.builtin import USEquityPricing 15 | 16 | # import optimize 17 | import quantopian.optimize as opt 18 | 19 | # Import pandas 20 | import pandas as pd 21 | 22 | def initialize(context): 23 | """ 24 | Initialize constants, create pipeline, and schedule functions 25 | This uses the default slippage and commission models 26 | """ 27 | # Universe we wish to trade 28 | # Place one or more desired symbols below 29 | context.MY_STOCKS = symbols('SPY', 'GLD') 30 | 31 | # Create our weights (evenly weighted) 32 | context.WEIGHT = 1.0 / len(context.MY_STOCKS) 33 | 34 | # Make our pipeline and attach to the algo 35 | attach_pipeline(make_pipeline(context), 'my_pipe') 36 | 37 | # Place orders 38 | schedule_function( 39 | func=place_orders_using_optimize, 40 | date_rule=date_rules.week_start(), 41 | time_rule=time_rules.market_open() 42 | ) 43 | 44 | 45 | def make_pipeline(context): 46 | """ 47 | Define a pipeline. 48 | """ 49 | # Specify the universe of securities 50 | base_universe = StaticAssets(context.MY_STOCKS) 51 | 52 | # Create any needed factors. 53 | close_price = USEquityPricing.close.latest 54 | 55 | close_1_yr_ago_factor = Factor_N_Days_Ago( 56 | inputs=[USEquityPricing.close], 57 | window_length=252) 58 | 59 | close_1_yr_ago_calculated = close_price / (Returns(window_length=252) + 1.0) 60 | 61 | # Create our pipeline 62 | return Pipeline( 63 | columns={ 64 | 'close_price': close_price, 65 | 'close_1_yr_ago_factor': close_1_yr_ago_factor, 66 | 'close_1_yr_ago_calculated': close_1_yr_ago_calculated, 67 | }, 68 | screen=base_universe 69 | ) 70 | 71 | 72 | def before_trading_start(context, data): 73 | """ 74 | Run our pipeline to fetch the actual data. 75 | It's a good practice to place the pipeline execution here. 76 | This gets allocated more time than scheduled functions. 77 | """ 78 | context.output = pipeline_output('my_pipe') 79 | 80 | log.info(context.output) 81 | 82 | 83 | def place_orders_using_optimize(context, data): 84 | """ 85 | Use Optimize to place orders all at once 86 | """ 87 | # Make a series of the securities to order and associated weights 88 | # Ensure that all the short weights are negative (this is what tells opt to short them) 89 | weights = pd.Series(context.WEIGHT, context.output.index) 90 | 91 | # Create our TargetWeights objective 92 | target_weights = opt.TargetWeights(weights) 93 | 94 | # Execute the order_optimal_portfolio method with above objective and constraint 95 | # No need to loop through the stocks. 96 | # The order_optimal_portfolio does all the ordering at one time 97 | # Also closes any positions not in 'weights' 98 | # As a bonus also checks for 'can_trade' 99 | # Could set constraints here if desired 100 | order_optimal_portfolio( 101 | objective = target_weights, 102 | constraints = [] 103 | ) 104 | 105 | ######## CUSTOM FACTORS ########### 106 | 107 | class Factor_N_Days_Ago(CustomFactor): 108 | """ 109 | Returns the factor value N days ago where window_length=N 110 | This is the price adjusted as of the current simulation day. 111 | """ 112 | def compute(self, today, assets, out, close_price): 113 | out[:] = close_price[0] -------------------------------------------------------------------------------- /algorithms/FrankPSch/R195 S1.19 DD13.15 Lever1 _Classic RSI2 Mean-Reversion Strategy (SPY_TLT)_.py: -------------------------------------------------------------------------------- 1 | #Published By: Quant Prophet, LLC 2 | #Author: Kory Hoang 3 | #Description: this is a simple mean-reversion strategy that uses the RSI2 technical indicator which was originally developed and popularized by Cesar Alvarez. Most people are familiar with the RSI14 but the RSI2 is a much more powerful tool for short-term market timing that works well in both momentum and mean-reversion strtegies. The algorithm monitors the 2-day RSI of SPY (S&P500) and TLT (Long-Term US Treasury), both of which are well-known as mean-reverting assets. When an asset's RSI2 dips below 30 ("Oversold"), go long with 50% of the portfolio. When its RSI2 crosses above 70 ("Overbought"), sell the position and go to cash. The vanilla version of this strategy generates good risk-adjusted performance but still underperforms the S&P 500, for the most part. However, using leverage can increase the risk/reward profile in order to outperform the S&P 500 while still maintaining lower risk. I'm using 2x leverge for this strategy. 4 | 5 | import talib 6 | 7 | def initialize(context): 8 | 9 | schedule_function(setAlerts, date_rules.every_day(), time_rules.market_close()) 10 | schedule_function(rebalance, date_rules.every_day(), time_rules.market_open()) 11 | 12 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 13 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 14 | 15 | set_benchmark(symbol('SPY')) 16 | 17 | context.stock = symbol('SPY') #Equity asset 18 | context.bond = symbol('TLT') #Bond asset 19 | context.rsi_period = 2 20 | context.OB1 = 80 #Overbought threshold 1 21 | context.OS1 = 40 #Oversold threshold 1 22 | context.OB2 = 60 #Overbought threshold 2 23 | context.OS2 = 30 #Oversold threshold 2 24 | context.pct_alloc1 = 0.50 25 | context.pct_alloc2 = 0.50 26 | context.leverage = 1.00 27 | 28 | #Alert to buy or sell next day. 29 | context.buyStockAlert = False 30 | context.sellStockAlert = False 31 | context.buyBondAlert = False 32 | context.sellBondAlert = False 33 | 34 | def setAlerts(context, data): 35 | 36 | stock_price = data.history(context.stock, 'price', 3, '1d') 37 | bond_price = data.history(context.bond, 'price', 3, '1d') 38 | 39 | rsi1 = talib.RSI(stock_price, context.rsi_period) 40 | rsi2 = talib.RSI(bond_price, context.rsi_period) 41 | 42 | if rsi1[-1] < context.OS1 and data.can_trade(context.stock): 43 | #order_target_percent(stock, context.pct_alloc1 * leverage) 44 | context.buyStockAlert = True 45 | elif rsi1[-1] > context.OB1 and data.can_trade(context.stock): 46 | #order_target_percent(stock, 0.00 * leverage) 47 | context.sellStockAlert = True 48 | 49 | if rsi2[-1] < context.OS2 and data.can_trade(context.bond): 50 | #order_target_percent(bond, context.pct_alloc2 * leverage) 51 | context.buyBondAlert = True 52 | elif rsi2[-1] > context.OB2 and data.can_trade(context.bond): 53 | #order_target_percent(bond, 0.00 * leverage) 54 | context.sellBondAlert = True 55 | 56 | record(leverage = context.account.leverage) 57 | 58 | def rebalance(context, data): 59 | 60 | if context.buyStockAlert and data.can_trade(context.stock) and context.portfolio.positions[context.stock].amount == 0: 61 | order_target_percent(context.stock, context.pct_alloc1 * context.leverage) 62 | context.buyStockAlert = False 63 | if context.sellStockAlert and data.can_trade(context.stock): 64 | order_target_percent(context.stock, 0.00 * context.leverage) 65 | context.sellStockAlert = False 66 | 67 | if context.buyBondAlert and data.can_trade(context.bond) and context.portfolio.positions[context.bond].amount == 0: 68 | order_target_percent(context.bond, context.pct_alloc2 * context.leverage) 69 | context.buyBondAlert = False 70 | if context.sellBondAlert and data.can_trade(context.bond): 71 | order_target_percent(context.bond, 0.00 * context.leverage) 72 | context.sellBondAlert = False -------------------------------------------------------------------------------- /algorithms/FrankPSch/R220 S0.56 DD56 _Investment management._.py: -------------------------------------------------------------------------------- 1 | from quantopian.algorithm import attach_pipeline, pipeline_output 2 | from quantopian.pipeline import Pipeline 3 | from quantopian.pipeline.data.builtin import USEquityPricing 4 | from quantopian.pipeline.factors import CustomFactor, AverageDollarVolume 5 | from quantopian.pipeline.data import morningstar 6 | 7 | import pandas as pd 8 | import numpy as np 9 | 10 | 11 | 12 | class Value(CustomFactor): 13 | 14 | inputs = [morningstar.balance_sheet.tangible_book_value, 15 | morningstar.valuation_ratios.fcf_yield, 16 | morningstar.valuation.market_cap, 17 | morningstar.operation_ratios.long_term_debt_equity_ratio] 18 | 19 | window_length = 1 20 | 21 | def compute(self, today, assets, out, book_value, fcf, cap, debt): 22 | value_table = pd.DataFrame(index=assets) 23 | value_table["fcf"] = fcf[-1] 24 | value_table["bm"] = cap[-1] / book_value[-1] 25 | value_table["debt"] = debt[-1] 26 | out[:] = value_table.rank().mean(axis=1) 27 | 28 | 29 | class Momentum(CustomFactor): 30 | 31 | inputs = [USEquityPricing.close] 32 | window_length = 252 33 | 34 | def compute(self, today, assets, out, close): 35 | out[:] = close[-16] / close[0] 36 | 37 | 38 | class Quality(CustomFactor): 39 | 40 | inputs = [morningstar.income_statement.gross_profit, morningstar.balance_sheet.total_assets] 41 | window_length = 1 42 | 43 | def compute(self, today, assets, out, gross_profit, total_assets): 44 | out[:] = gross_profit[-1] / total_assets[-1] 45 | 46 | 47 | def before_trading_start(context, data): 48 | results = pipeline_output('factors').dropna() 49 | ranks = results.rank().mean(axis=1).order() 50 | 51 | 52 | context.hold = ranks[results["momentum"] > 1].tail(40) 53 | context.hold /= context.hold.sum() 54 | 55 | context.security_list = context.hold.tolist() 56 | 57 | 58 | 59 | def initialize(context): 60 | pipe = Pipeline() 61 | pipe = attach_pipeline(pipe, name='factors') 62 | 63 | value = Value() 64 | momentum = Momentum() 65 | quality = Quality() 66 | 67 | pipe.add(value, "value") 68 | pipe.add(momentum, "momentum") 69 | pipe.add(quality, "quality") 70 | 71 | dollar_volume = AverageDollarVolume(window_length=20) 72 | 73 | pipe.set_screen(dollar_volume > 10**6) 74 | 75 | context.spy = sid(8554) 76 | context.hold = None 77 | 78 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 79 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 80 | 81 | schedule_function(rebalance, date_rules.month_start()) 82 | schedule_function(cancel_open_orders, date_rules.every_day(), 83 | time_rules.market_close()) 84 | schedule_function(record_vars, date_rules.every_day(), time_rules.market_close()) 85 | 86 | 87 | def record_vars(context, data): 88 | record(lever=context.account.leverage, 89 | exposure=context.account.net_leverage, 90 | num_pos=len(context.portfolio.positions), 91 | oo=len(get_open_orders())) 92 | 93 | 94 | def cancel_open_orders(context, data): 95 | open_orders = get_open_orders() 96 | for security in open_orders: 97 | for order in open_orders[security]: 98 | cancel_order(order) 99 | 100 | 101 | def rebalance(context, data): 102 | 103 | for security in context.portfolio.positions: 104 | if get_open_orders(security): 105 | continue 106 | if data.can_trade(security) and security not in context.hold: 107 | order_target_percent(security, 0) 108 | 109 | 110 | 111 | for security in context.hold.index: 112 | if get_open_orders(security): 113 | continue 114 | if data.can_trade(security): 115 | order_target_percent(security, context.hold[security]) 116 | 117 | 118 | def handle_data(context, data): 119 | pass -------------------------------------------------------------------------------- /algorithms/FrankPSch/zR2099 S1.2 DD50 AAPL IBM _Fundamental data for particular stocks_.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Simple algorithm to maintain equal dollar value of securities. 3 | Algorithm holds long positions only. 4 | Security universe is fixed. 5 | Selection within universe is based upon meeting fundamental criteria. 6 | ''' 7 | 8 | # import pipeline methods 9 | from quantopian.algorithm import attach_pipeline, pipeline_output 10 | from quantopian.pipeline import Pipeline 11 | import quantopian.optimize as opt 12 | 13 | # import built in factors and filters 14 | import quantopian.pipeline.factors as Factors 15 | import quantopian.pipeline.filters as Filters 16 | 17 | # import any datasets we need 18 | from quantopian.pipeline.data.builtin import USEquityPricing 19 | from quantopian.pipeline.data import Fundamentals 20 | 21 | # import numpy and pandas just in case 22 | import numpy as np 23 | import pandas as pd 24 | 25 | 26 | # Here we specify the securities 'universe' to trade 27 | 28 | SECURITY_UNIVERSE = symbols( 29 | 'AAPL', 30 | 'IBM', 31 | 'AMZN', 32 | 'NFLX', 33 | ) 34 | 35 | 36 | def initialize(context): 37 | """ 38 | Called once at the start of the algorithm. 39 | """ 40 | 41 | # Set commision model 42 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) 43 | 44 | # Ensure no short trading (just a precaution) 45 | set_long_only() 46 | 47 | # Create and attach pipeline to get data 48 | attach_pipeline(my_pipeline(context), name='my_pipeline') 49 | 50 | 51 | # Place orders once a day 52 | schedule_function(enter_trades, date_rules.every_day(), time_rules.market_open()) 53 | 54 | # Record tracking variables at the end of each day. 55 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 56 | 57 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 58 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 59 | 60 | 61 | def my_pipeline(context): 62 | ''' 63 | Define the pipline data columns 64 | ''' 65 | 66 | # Create filter for just the securities we want to trade 67 | universe = Filters.StaticAssets(SECURITY_UNIVERSE) 68 | 69 | # Create the fundamental factors we want to use in our trade decisions 70 | pb_ratio = Fundamentals.pb_ratio.latest 71 | pe_ratio = Fundamentals.pe_ratio.latest 72 | 73 | 74 | # Define our pipeline 75 | return Pipeline( 76 | columns = { 77 | 'pb_ratio' : pb_ratio, 78 | 'pe_ratio' : pe_ratio, 79 | }, 80 | screen = universe, 81 | ) 82 | 83 | 84 | def before_trading_start(context, data): 85 | 86 | # Get the data 87 | context.output = pipeline_output('my_pipeline') 88 | 89 | 90 | def enter_trades(context, data): 91 | 92 | # First determine which securities we want to be holding 93 | # Place selection logic in the query method 94 | securities_to_hold = context.output.query('pe_ratio > 1.0').index 95 | 96 | # Next create a series with the weights for each stock 97 | # Here we assume equal weight for each stock 98 | weight = 1.0 / len(securities_to_hold) 99 | weights = pd.Series(index = securities_to_hold, data = weight) 100 | 101 | # Next create a TargetWeights object using our weights series 102 | # This will become our ordering objective 103 | target_weights = opt.TargetWeights(weights) 104 | 105 | # Finally, execute the order_optimal_portfolio method 106 | # No need to loop through the stocks. 107 | # The order_optimal_portfolio does all the ordering at one time 108 | # Also closes any positions not in 'securities_to_hold' 109 | # We also don't impose any constraints. Just adjust to desired weights 110 | order_optimal_portfolio(objective = target_weights, constraints = []) 111 | 112 | 113 | def my_record_vars(context, data): 114 | """ 115 | Plot variables at the end of each day. 116 | """ 117 | 118 | record(securities = len(context.portfolio.positions)) -------------------------------------------------------------------------------- /algorithms/FrankPSch/E70 _Reply to_ Forex data __.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | #globals for get_avg batch transform decorator 4 | R_P = 1 #refresh period in days 5 | W_L = 5 #window length in days 6 | 7 | def initialize(context): 8 | #['AMD', 'CERN', 'COST', 'DELL', 'GPS', 'INTC', 'MMM'] 9 | context.stocks = [sid(351), sid(1419), sid(1787), sid(25317), sid(3321), sid(3951), sid(4922)] 10 | 11 | context.m = len(context.stocks) 12 | context.b_t = np.ones(context.m) / context.m 13 | context.eps = 1 #change epsilon here 14 | context.init = False 15 | 16 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 17 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 18 | 19 | def handle_data(context, data): 20 | 21 | # get prices 22 | prices = get_prices(data,context.stocks) 23 | if prices == None: 24 | return 25 | 26 | if not context.init: 27 | rebalance_portfolio(context, data, context.b_t) 28 | context.init = True 29 | return 30 | 31 | m = context.m 32 | 33 | x_tilde = np.zeros(m) 34 | 35 | b = np.zeros(m) 36 | 37 | # find relative moving average price for each security 38 | for i, stock in enumerate(context.stocks): 39 | x_tilde[i] = np.mean(prices[:,i])/prices[W_L-1,i] 40 | 41 | ########################### 42 | # Inside of OLMAR (algo 2) 43 | 44 | x_bar = x_tilde.mean() 45 | 46 | # Calculate terms for lambda (lam) 47 | dot_prod = np.dot(context.b_t, x_tilde) 48 | num = context.eps - dot_prod 49 | denom = (np.linalg.norm((x_tilde-x_bar)))**2 50 | 51 | # test for divide-by-zero case 52 | if denom == 0.0: 53 | lam = 0 # no portolio update 54 | else: 55 | lam = max(0, num/denom) 56 | 57 | b = context.b_t + lam*(x_tilde-x_bar) 58 | 59 | b_norm = simplex_projection(b) 60 | 61 | rebalance_portfolio(context, data, b_norm) 62 | 63 | # update portfolio 64 | context.b_t = b_norm 65 | 66 | log.debug(b_norm) 67 | 68 | log.debug(np.sum(b_norm)) 69 | 70 | @batch_transform(refresh_period=R_P, window_length=W_L) # set globals R_P & W_L above 71 | 72 | def get_prices(datapanel,sids): 73 | return datapanel['price'].as_matrix(sids) 74 | 75 | def rebalance_portfolio(context, data, desired_port): 76 | #rebalance portfolio 77 | current_amount = np.zeros_like(desired_port) 78 | desired_amount = np.zeros_like(desired_port) 79 | 80 | if not context.init: 81 | positions_value = context.portfolio.starting_cash 82 | else: 83 | positions_value = context.portfolio.positions_value + context.portfolio.cash 84 | 85 | for i, stock in enumerate(context.stocks): 86 | current_amount[i] = context.portfolio.positions[stock].amount 87 | desired_amount[i] = desired_port[i]*positions_value/data[stock].price 88 | 89 | diff_amount = desired_amount - current_amount 90 | 91 | for i, stock in enumerate(context.stocks): 92 | order(stock, diff_amount[i]) #order_stock 93 | 94 | def simplex_projection(v, b=1): 95 | """Projection vectors to the simplex domain 96 | 97 | Implemented according to the paper: Efficient projections onto the 98 | l1-ball for learning in high dimensions, John Duchi, et al. ICML 2008. 99 | Implementation Time: 2011 June 17 by Bin@libin AT pmail.ntu.edu.sg 100 | Optimization Problem: min_{w}\| w - v \|_{2}^{2} 101 | s.t. sum_{i=1}^{m}=z, w_{i}\geq 0 102 | 103 | Input: A vector v \in R^{m}, and a scalar z > 0 (default=1) 104 | Output: Projection vector w 105 | 106 | :Example: 107 | >>> proj = simplex_projection([.4 ,.3, -.4, .5]) 108 | >>> print proj 109 | array([ 0.33333333, 0.23333333, 0. , 0.43333333]) 110 | >>> print proj.sum() 111 | 1.0 112 | 113 | Original matlab implementation: John Duchi (jduchi@cs.berkeley.edu) 114 | Python-port: Copyright 2012 by Thomas Wiecki (thomas.wiecki@gmail.com). 115 | """ 116 | 117 | v = np.asarray(v) 118 | p = len(v) 119 | 120 | # Sort v into u in descending order 121 | v = (v > 0) * v 122 | u = np.sort(v)[::-1] 123 | sv = np.cumsum(u) 124 | 125 | rho = np.where(u > (sv - b) / np.arange(1, p+1))[0][-1] 126 | theta = np.max([0, (sv[rho] - b) / (rho+1)]) 127 | w = (v - theta) 128 | w[w<0] = 0 129 | return w -------------------------------------------------------------------------------- /algorithms/FrankPSch/R143 S0.68 DD29 _QuantCon 2016_ Dual Momentum Strategy_.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is a template algorithm on Quantopian for you to adapt and fill in. 3 | """ 4 | from __future__ import division 5 | from quantopian.algorithm import attach_pipeline, pipeline_output 6 | from quantopian.pipeline import Pipeline 7 | from quantopian.pipeline.data.builtin import USEquityPricing 8 | from quantopian.pipeline.factors import AverageDollarVolume, CustomFactor, Returns 9 | from quantopian.pipeline import CustomFilter 10 | import numpy as np 11 | import pandas as pd 12 | from scipy import stats 13 | 14 | 15 | 16 | 17 | 18 | 19 | class SecurityInList(CustomFactor): 20 | inputs = [] 21 | window_length = 1 22 | securities = [] 23 | def compute(self, today, assets, out): 24 | out[:] = np.in1d(assets, self.securities) 25 | 26 | def initialize(context): 27 | """ 28 | Called once at the start of the algorithm. 29 | """ 30 | set_benchmark(sid(8554)) 31 | # Rebalance every day, 1 hour after market open. 32 | schedule_function(my_assign_weights, date_rules.month_start(),time_rules.market_open()) 33 | schedule_function(my_rebalance, date_rules.month_start(), time_rules.market_open(hours=1)) 34 | 35 | # Record tracking variables at the end of each day. 36 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 37 | 38 | # Create our dynamic stock selector. 39 | context.return_period = 100 40 | 41 | context.mom1 = mom1 = sid(8554) 42 | context.mom2 = mom2 = sid(33486) 43 | context.tbill = tbill = sid(23911) 44 | context.tlt = tlt = sid(23921) 45 | context.agg = agg = sid(25485) 46 | 47 | sec_list = [mom1,mom2,tlt,tbill,agg] 48 | attach_pipeline(make_pipeline(sec_list, context), 'my_pipeline') 49 | 50 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 51 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 52 | # Momentum ETFs 53 | 54 | 55 | def make_pipeline(sec_list, context): 56 | """ 57 | A function to create our dynamic stock selector (pipeline). Documentation on 58 | pipeline can be found here: https://www.quantopian.com/help#pipeline-title 59 | """ 60 | 61 | # Return Factors 62 | mask = SecurityInList() 63 | mask.securities = sec_list 64 | mask = mask.eq(1) 65 | yr_returns = Returns(window_length=context.return_period, mask=mask) 66 | 67 | pipe = Pipeline( 68 | screen = mask, 69 | columns = { 70 | 'yr_returns': yr_returns 71 | } 72 | ) 73 | return pipe 74 | 75 | def before_trading_start(context, data): 76 | """ 77 | Called every day before market open. 78 | """ 79 | context.output = pipeline_output('my_pipeline') 80 | 81 | def my_assign_weights(context, data): 82 | 83 | context.weights = pd.Series(index=context.output.index) 84 | returns = context.output['yr_returns'] 85 | 86 | if returns[context.mom1] > returns[context.mom2]: 87 | 88 | if returns[context.mom1] < 0: 89 | context.weights[context.tbill] = .5 90 | context.weights[context.agg] = .5 91 | 92 | elif returns[context.mom1] > returns[context.tbill]: 93 | context.weights[context.mom1] = 1 94 | 95 | else: 96 | context.weights[context.agg] = 1 97 | 98 | else: 99 | 100 | if returns[context.mom2] > returns[context.tbill]: 101 | context.weights[context.mom2] = 1 102 | else: 103 | context.weights[context.agg] = 1 104 | 105 | context.weights.fillna(0,inplace=True) 106 | def my_rebalance(context,data): 107 | """ 108 | Execute orders according to our schedule_function() timing. 109 | """ 110 | 111 | 112 | for stock,weight in context.weights.iteritems(): 113 | if data.can_trade(stock): 114 | order_target_percent(stock,weight) 115 | 116 | 117 | def my_record_vars(context, data): 118 | """ 119 | Plot variables at the end of each day. 120 | """ 121 | record(leverage=context.account.leverage) 122 | 123 | def handle_data(context,data): 124 | """ 125 | Called every minute. 126 | """ 127 | pass -------------------------------------------------------------------------------- /algorithms/FrankPSch/R043 S0.96 DD20 _Pipeline Trading Universe - Best Practice_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Utilizes the filters for a good trading universe laid out by Scott Sanderson: 3 | https://www.quantopian.com/posts/string-columns-now-available-in-pipeline 4 | """ 5 | from quantopian.algorithm import attach_pipeline, pipeline_output 6 | from quantopian.pipeline import Pipeline 7 | from quantopian.pipeline.data import morningstar as mstar 8 | from quantopian.pipeline.data.builtin import USEquityPricing 9 | from quantopian.pipeline.factors import AverageDollarVolume, SimpleMovingAverage 10 | from quantopian.pipeline.filters.morningstar import IsPrimaryShare 11 | from quantopian.pipeline.filters.morningstar import Q1500US 12 | 13 | def initialize(context): 14 | # Equity numbers for the mean reversion algorithm. 15 | context.num_securities = 20 16 | context.num_short = context.num_securities // 2 17 | context.num_long = context.num_securities - context.num_short 18 | 19 | schedule_function(my_rebalance, date_rules.week_start(), time_rules.market_open(hours=1)) 20 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 21 | 22 | attach_pipeline(my_pipeline(context), 'my_pipeline') 23 | 24 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 25 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 26 | 27 | 28 | def my_pipeline(context): 29 | pipe = Pipeline() 30 | """ 31 | The original algorithm used the following filters: 32 | 1. common stock 33 | 2 & 3. not limited partnership - name and database check 34 | 4. database has fundamental data 35 | 5. not over the counter 36 | 6. not when issued 37 | 7. not depository receipts 38 | 8. primary share 39 | 9. high dollar volume 40 | Check Scott's notebook for more details. 41 | 42 | This updated version uses Q1500US, one of the pipeline's built-in base universes. 43 | Lesson 11 from the Pipeline tutorial offers a great overview of using multiple 44 | filters vs using the built-in base universes: 45 | https://www.quantopian.com/tutorials/pipeline#lesson11 46 | 47 | More detail on the selection criteria of this filter can be found here: 48 | https://www.quantopian.com/posts/the-q500us-and-q1500us 49 | """ 50 | base_universe = Q1500US() 51 | 52 | # The example algorithm - mean reversion. Note the tradable filter used as a mask. 53 | sma_10 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=10, 54 | mask=base_universe) 55 | sma_30 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=30, 56 | mask=base_universe) 57 | rel_diff = (sma_10 - sma_30) / sma_30 58 | 59 | top_rel_diff = rel_diff.top(context.num_short) 60 | pipe.add(top_rel_diff, 'top_rel_diff') 61 | bottom_rel_diff = rel_diff.bottom(context.num_long) 62 | pipe.add(bottom_rel_diff, 'bottom_rel_diff') 63 | 64 | return pipe 65 | 66 | # Get the pipeline output and specify which equities to trade. 67 | def before_trading_start(context, data): 68 | context.output = pipeline_output('my_pipeline') 69 | context.short_set = set(context.output[context.output['top_rel_diff']].index) 70 | context.long_set = set(context.output[context.output['bottom_rel_diff']].index) 71 | context.security_set = context.long_set.union(context.short_set) 72 | 73 | # Rebalance weekly. 74 | def my_rebalance(context,data): 75 | for stock in context.security_set: 76 | if data.can_trade(stock): 77 | if stock in context.long_set: 78 | order_target_percent(stock, 1. / context.num_securities) 79 | elif stock in context.short_set: 80 | order_target_percent(stock, -1. / context.num_securities) 81 | 82 | for stock in context.portfolio.positions: 83 | if stock not in context.security_set and data.can_trade(stock): 84 | order_target_percent(stock, 0) 85 | 86 | # Record variables. 87 | def my_record_vars(context, data): 88 | shorts = longs = 0 89 | for position in context.portfolio.positions.itervalues(): 90 | if position.amount < 0: 91 | shorts += 1 92 | elif position.amount > 0: 93 | longs += 1 94 | record(leverage=context.account.leverage, short_count=shorts, long_count=longs) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Try Again _MACD signal_.py: -------------------------------------------------------------------------------- 1 | #Author: Kory Hoang 2 | #Developer: Mohammed Khalfan 3 | #Email: hoang.kory@gmail.com 4 | 5 | #Imports 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | import statsmodels.api as sm 8 | import quantopian.pipeline.data 9 | import numpy as np 10 | import pandas as pd 11 | import talib 12 | import scipy 13 | 14 | def initialize(context): 15 | 16 | set_benchmark(symbol('GDXJ')) 17 | context.GDXJ = symbol('GDXJ') 18 | context.allocation = 1 19 | 20 | context.TakeProfitPct = 0.25 21 | context.StopLossPct = 0.05 22 | context.BuyPrice = 0 23 | 24 | context.bought = False 25 | context.sold = False 26 | 27 | # 30 min scheduler 28 | for x in [0,1,2,3,4,5]: 29 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(hours=x, minutes=29)) 30 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(hours=x, minutes=59)) 31 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_close()) 32 | 33 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 34 | 35 | #Set commission and slippage 36 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 37 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 38 | 39 | def my_rebalance(context,data): 40 | GDXJ_prices = data.history(context.GDXJ, "price", 10000, "1m").resample('30T', closed='right', label='right') .last().dropna() 41 | #GDXJ_prices = data.history(context.GDXJ, "price", 100, "1d") 42 | 43 | ema12 = talib.EMA(GDXJ_prices,12) 44 | ema26 = talib.EMA(GDXJ_prices,26) 45 | macd = ema12 - ema26 46 | signal = talib.EMA(macd,9) 47 | 48 | record(SIG=macd[-1] - signal[-1]) 49 | record(MACD=macd[-1]) 50 | 51 | if macd[-2] < signal[-2] and macd[-1] >= signal[-1] and not context.bought: 52 | set_fixed_stop_long(context, data) 53 | order_target_percent(context.GDXJ, context.allocation) 54 | context.bought = True 55 | context.sold = False 56 | 57 | if macd[-1] < signal[-1] and not context.sold: 58 | set_fixed_stop_short(context, data) 59 | order_target_percent(context.GDXJ, -context.allocation) 60 | context.bought = False 61 | context.sold = True 62 | 63 | def my_record_vars(context, data): 64 | leverage = context.account.leverage 65 | #record(leverage=leverage) 66 | 67 | def set_fixed_stop_long(context, data): 68 | #Only call this once when the stock is bought 69 | if data.can_trade(context.GDXJ): 70 | price = data.current(context.GDXJ, 'price') 71 | context.BuyPrice = price 72 | context.SellLossPrice= price - (context.StopLossPct * price) 73 | context.SellProfitPrice= (price * context.TakeProfitPct) + price 74 | 75 | 76 | def set_fixed_stop_short(context, data): 77 | #Only call this once when the stock is bought 78 | if data.can_trade(context.GDXJ): 79 | price = data.current(context.GDXJ, 'price') 80 | context.BuyPrice = price 81 | context.SellLossPrice= price + (context.StopLossPct * price) 82 | context.SellProfitPrice= price - (price * context.TakeProfitPct) 83 | 84 | def handle_data(context, data): 85 | #If we have a position check sell conditions 86 | if context.portfolio.positions[context.GDXJ].amount != 0 and context.bought: 87 | price = data.current(context.GDXJ, 'price') 88 | 89 | if price > context.SellProfitPrice and len(get_open_orders()) == 0: 90 | order_target_percent(context.GDXJ, 0) 91 | context.bought = False 92 | if price < context.SellLossPrice and len(get_open_orders()) == 0: 93 | order_target_percent(context.GDXJ, 0) 94 | context.bought = False 95 | 96 | if context.portfolio.positions[context.GDXJ].amount != 0 and context.sold: 97 | price = data.current(context.GDXJ, 'price') 98 | 99 | if price < context.SellProfitPrice and len(get_open_orders()) == 0: 100 | order_target_percent(context.GDXJ, 0) 101 | context.sold = False 102 | if price > context.SellLossPrice and len(get_open_orders()) == 0: 103 | order_target_percent(context.GDXJ, 0) 104 | context.sold = False -------------------------------------------------------------------------------- /algorithms/FrankPSch/E _MACD signal_.py: -------------------------------------------------------------------------------- 1 | #Author: Kory Hoang 2 | #Developer: Mohammed Khalfan 3 | #Email: hoang.kory@gmail.com 4 | 5 | #Imports 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | import statsmodels.api as sm 8 | import quantopian.pipeline.data 9 | import numpy as np 10 | import pandas as pd 11 | import talib 12 | import scipy 13 | 14 | def initialize(context): 15 | 16 | set_benchmark(symbol('GDXJ')) 17 | context.GDXJ = symbol('GDXJ') 18 | context.allocation = 1 19 | 20 | context.TakeProfitPct = 0.25 21 | context.StopLossPct = 0.05 22 | context.BuyPrice = 0 23 | 24 | context.bought = False 25 | context.sold = False 26 | 27 | # 30 min scheduler 28 | for x in [0,1,2,3,4,5]: 29 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(hours=x, minutes=29)) 30 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open(hours=x, minutes=59)) 31 | 32 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_close()) 33 | 34 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 35 | 36 | #Set commission and slippage 37 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 38 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 39 | 40 | def my_rebalance(context,data): 41 | GDXJ_prices = data.history(context.GDXJ, "price", 10000, "1m").resample('30T', closed='right', label='right') .last().dropna() 42 | #GDXJ_prices = data.history(context.GDXJ, "price", 100, "1d") 43 | 44 | ema12 = talib.EMA(GDXJ_prices,12) 45 | ema26 = talib.EMA(GDXJ_prices,26) 46 | macd = ema12 - ema26 47 | signal = talib.EMA(macd,9) 48 | 49 | record(SIG=macd[-1] - signal[-1]) 50 | record(MACD=macd[-1]) 51 | 52 | if macd[-2] < signal[-2] and macd[-1] >= signal[-1] and not context.bought: 53 | set_fixed_stop_long(context, data) 54 | order_target_percent(context.GDXJ, context.allocation) 55 | context.bought = True 56 | context.sold = False 57 | 58 | if macd[-1] < signal[-1] and not context.sold: 59 | set_fixed_stop_short(context, data) 60 | order_target_percent(context.GDXJ, -context.allocation) 61 | context.bought = False 62 | context.sold = True 63 | 64 | def my_record_vars(context, data): 65 | leverage = context.account.leverage 66 | #record(leverage=leverage) 67 | 68 | def set_fixed_stop_long(context, data): 69 | #Only call this once when the stock is bought 70 | if data.can_trade(context.GDXJ): 71 | price = data.current(context.GDXJ, 'price') 72 | context.BuyPrice = price 73 | context.SellLossPrice= price - (context.StopLossPct * price) 74 | context.SellProfitPrice= (price * context.TakeProfitPct) + price 75 | 76 | 77 | def set_fixed_stop_short(context, data): 78 | #Only call this once when the stock is bought 79 | if data.can_trade(context.GDXJ): 80 | price = data.current(context.GDXJ, 'price') 81 | context.BuyPrice = price 82 | context.SellLossPrice= price + (context.StopLossPct * price) 83 | context.SellProfitPrice= price - (price * context.TakeProfitPct) 84 | 85 | def handle_data(context, data): 86 | #If we have a position check sell conditions 87 | if context.portfolio.positions[context.GDXJ].amount != 0 and context.bought: 88 | price = data.current(context.GDXJ, 'price') 89 | 90 | if price > context.SellProfitPrice and len(get_open_orders()) == 0: 91 | order_target_percent(context.GDXJ, 0) 92 | context.bought = False 93 | if price < context.SellLossPrice and len(get_open_orders()) == 0: 94 | order_target_percent(context.GDXJ, 0) 95 | context.bought = False 96 | 97 | if context.portfolio.positions[context.GDXJ].amount != 0 and context.sold: 98 | price = data.current(context.GDXJ, 'price') 99 | 100 | if price < context.SellProfitPrice and len(get_open_orders()) == 0: 101 | order_target_percent(context.GDXJ, 0) 102 | context.sold = False 103 | if price > context.SellLossPrice and len(get_open_orders()) == 0: 104 | order_target_percent(context.GDXJ, 0) 105 | context.sold = False -------------------------------------------------------------------------------- /algorithms/FrankPSch/Sentdex Long-Short Equity 1.py: -------------------------------------------------------------------------------- 1 | """ 2 | This algorithm uses Sentdex's dataset to create a long-short 3 | equity strategy. It uses the `sentiment_signal`, which is a measure of 4 | the sentiment from over 20 different major news sources like CNBC, WSJ, 5 | Yahoo and more. This value is then used to rank each security where the 6 | top 25 with the highest scores are longed at an equal weight and the 7 | bottom 25 with the lowest scores are shorted with an equal weight. 8 | """ 9 | 10 | 11 | from quantopian.algorithm import attach_pipeline, pipeline_output 12 | from quantopian.pipeline import Pipeline 13 | from quantopian.pipeline.data.builtin import USEquityPricing 14 | from quantopian.pipeline.factors import CustomFactor 15 | 16 | # The sample version available from 15 Oct 2012 - 11 Jan 2016 17 | from quantopian.pipeline.data.sentdex import sentiment_free as sentdex 18 | # The premium version found at https://www.quantopian.com/data/sentdex/sentiment 19 | # from quantopian.pipeline.data.sentdex import sentiment as sentdex 20 | 21 | import pandas as pd 22 | import numpy as np 23 | 24 | 25 | # Calculates the average impact of the sentiment over the window length 26 | class AvgSentiment(CustomFactor): 27 | 28 | def compute(self, today, assets, out, impact): 29 | np.mean(impact, axis=0, out=out) 30 | 31 | 32 | class AvgDailyDollarVolumeTraded(CustomFactor): 33 | 34 | inputs = [USEquityPricing.close, USEquityPricing.volume] 35 | window_length = 20 36 | 37 | def compute(self, today, assets, out, close_price, volume): 38 | out[:] = np.mean(close_price * volume, axis=0) 39 | 40 | 41 | # Put any initialization logic here. The context object will be passed to 42 | # the other methods in your algorithm. 43 | def initialize(context): 44 | window_length = 3 45 | pipe = Pipeline() 46 | pipe = attach_pipeline(pipe, name='sentiment_metrics') 47 | dollar_volume = AvgDailyDollarVolumeTraded() 48 | 49 | # Add our AvgSentiment factor to the pipeline using a 3 day moving average 50 | pipe.add(AvgSentiment(inputs=[sentdex.sentiment_signal], window_length=window_length), "avg_sentiment") 51 | 52 | # Screen out low liquidity securities. 53 | pipe.set_screen((dollar_volume > 10**7)) 54 | context.shorts = None 55 | context.longs = None 56 | # context.spy = sid(8554) 57 | 58 | # Set commissions and slippage to zero to evaluate alpha generation 59 | # of the strategy 60 | set_commission(commission.PerShare(cost=0, min_trade_cost=0)) 61 | set_slippage(slippage.FixedSlippage(spread=0)) 62 | 63 | schedule_function(rebalance, date_rules.every_day(), time_rules.market_open(hours=1)) 64 | schedule_function(record_vars, date_rules.every_day(), time_rules.market_close()) 65 | 66 | def before_trading_start(context, data): 67 | results = pipeline_output('sentiment_metrics').dropna() 68 | 69 | # Separate securities into longs and shorts 70 | longs = results[results['avg_sentiment'] > 0] 71 | shorts = results[results['avg_sentiment'] < 0] 72 | 73 | # Order them in their individual segments 74 | long_ranks = longs["avg_sentiment"].rank().order() 75 | short_ranks = shorts['avg_sentiment'].rank().order() 76 | 77 | # Take the minimum number of stocks available 78 | num_stocks = min([25, len(long_ranks.index), len(short_ranks.index)]) 79 | 80 | # Find the top 25 stocks to long and bottom 25 to short 81 | context.shorts = short_ranks.tail(num_stocks) 82 | context.longs = long_ranks.head(num_stocks) 83 | 84 | 85 | def record_vars(context, data): 86 | record(lever=context.account.leverage, 87 | exposure=context.account.net_leverage, 88 | num_pos=len(context.portfolio.positions)) 89 | 90 | 91 | def rebalance(context, data): 92 | 93 | for security in context.shorts.index: 94 | if data.can_trade(security): 95 | order_target_percent(security, -1.0 / len(context.shorts)) 96 | 97 | for security in context.longs.index: 98 | if data.can_trade(security): 99 | order_target_percent(security, 1.0 / len(context.longs)) 100 | 101 | for security in context.portfolio.positions: 102 | if data.can_trade(security): 103 | if security not in (context.longs.index | context.shorts.index): 104 | order_target_percent(security, 0) 105 | -------------------------------------------------------------------------------- /algorithms/FrankPSch/R029 S0.22 DD61 _BM Size_.py: -------------------------------------------------------------------------------- 1 | from quantopian.algorithm import attach_pipeline, pipeline_output 2 | from quantopian.algorithm import order_optimal_portfolio 3 | from quantopian.pipeline import Pipeline 4 | from quantopian.pipeline.data.builtin import USEquityPricing 5 | from quantopian.pipeline.factors import SimpleMovingAverage, AverageDollarVolume, Latest 6 | from quantopian.pipeline.data import Fundamentals 7 | from quantopian.pipeline.filters.fundamentals import Q1500US 8 | import quantopian.optimize as opt 9 | from operator import truediv 10 | 11 | def initialize(context): 12 | """ 13 | Called once at the start of the algorithm. 14 | """ 15 | set_long_only() 16 | schedule_function(my_rebalance, 17 | date_rules.month_start(), time_rules.market_open()) 18 | 19 | # Record tracking variables at the end of each day. 20 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 21 | 22 | # Create our dynamic stock selector 23 | my_pipe =make_pipeline() 24 | attach_pipeline(my_pipe, 'my_pipeline') 25 | 26 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 27 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 28 | 29 | 30 | def make_pipeline(): 31 | """ 32 | A function to create our dynamic stock selector (pipeline). Documentation on 33 | pipeline can be found here: https://www.quantopian.com/help#pipeline-title 34 | """ 35 | 36 | #Chose only "good stocks", i.e. they do no trade OTC, are not depositary receips, liquid enough etc. 37 | base_universe = Q1500US() 38 | 39 | #Chose low cap and high b/m stocks 40 | cap = Latest(inputs=[Fundamentals.market_cap], 41 | mask=base_universe) 42 | 43 | bm = Latest(inputs=[Fundamentals.book_value_yield], mask=base_universe) 44 | 45 | hbm = bm.percentile_between(80,100) 46 | lcap = cap.percentile_between(0,20) 47 | 48 | #Filtering out our pipeline 49 | ts = (lcap & hbm) 50 | 51 | return Pipeline( 52 | columns={ 53 | 'cap' :cap 54 | }, 55 | screen=ts, 56 | ) 57 | 58 | 59 | 60 | def compute_weights(context, data): 61 | """ 62 | Assign weights to securities that we want to order. 63 | """ 64 | 65 | weights = {} 66 | 67 | #Value weighted portfolio 68 | for sec in context['sec_list']: 69 | if data.can_trade(sec): 70 | weights[sec]=context['caps'][sec] 71 | else: 72 | weights[sec]=0 73 | #deviding each security's cap by sum of all caps 74 | cap_sum = sum(weights.values()) 75 | 76 | for sec in weights.keys(): 77 | weights[sec]=weights[sec]/cap_sum 78 | 79 | 80 | return weights 81 | 82 | 83 | 84 | 85 | def before_trading_start(context, data): 86 | """ 87 | Called every day before market open. 88 | """ 89 | pipeline_results = pipeline_output('my_pipeline') 90 | 91 | #time series inexed by secutities; holds market cap 92 | context['caps']=pipeline_results['cap'] 93 | 94 | # These are the securities that we are interested in trading each day. 95 | context['sec_list'] = [] 96 | for i in pipeline_results.index.values: 97 | context['sec_list'].append(i) 98 | 99 | 100 | 101 | def my_rebalance(context,data): 102 | """ 103 | Execute orders according to our schedule_function() timing. 104 | 105 | 106 | """ 107 | 108 | target_weights = compute_weights(context, data) 109 | 110 | today = get_datetime() 111 | #testing 112 | context['a'] = target_weights[context['sec_list'][1]] 113 | log.info('weight of first secutity: ' +str(context['a'])) 114 | 115 | #Rebalancing in June 116 | if today.month == 6 and target_weights: 117 | order_optimal_portfolio( 118 | objective=opt.TargetWeights(target_weights), 119 | constraints=[],) 120 | 121 | log.info('month: ' + str(today.month)) 122 | 123 | def my_record_vars(context, data): 124 | """ 125 | Plot variables at the end of each day. 126 | """ 127 | maxw = max(compute_weights(context, data).values()) 128 | 129 | record(number_of_stocks=len(compute_weights(context, data).keys()), biggest_weight=maxw) 130 | 131 | """ 132 | Called every minute. 133 | """ -------------------------------------------------------------------------------- /algorithms/FrankPSch/Cloned from _GARCH Volatility (RV(t+1) - IV) Revisited_.py: -------------------------------------------------------------------------------- 1 | from quantopian.algorithm import attach_pipeline, pipeline_output 2 | from quantopian.pipeline import Pipeline 3 | from quantopian.pipeline.data.builtin import USEquityPricing 4 | from quantopian.pipeline.factors import AverageDollarVolume, CustomFactor 5 | from zipline.utils.tradingcalendar import get_early_closes,trading_day 6 | import numpy as np 7 | import pandas as pd 8 | from scipy import optimize 9 | import statsmodels as sm 10 | #from quantopian.pipeline.data.quandl import cboe_vix,cboe_vxn 11 | import math 12 | 13 | def GARCH11_logL(param, r, context): 14 | omega, alpha, beta = param 15 | n = len(r) 16 | s = np.ones(n)*0.01 17 | s[2] = np.var(r[0:3]) 18 | for i in range(3, n): 19 | s[i] = omega + alpha*r[i-1]**2 + beta*(s[i-1]) # GARCH(1,1) model 20 | context.last_sigma = s[-1] 21 | logL = -((-np.log(s) - r**2/s).sum()) 22 | return logL 23 | 24 | def initialize(context): 25 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_close(hours=0,minutes=5)) 26 | fetch_csv('http://www.cboe.com/publish/scheduledtask/mktdata/datahouse/vixcurrent.csv', skiprows=1, \ 27 | date_column='Date',pre_func=preview, symbol='vx1',post_func=rename_col,date_format='%Y-%m-%d') 28 | 29 | context.vxx = symbol('VXX') 30 | 31 | # pipe = Pipeline() 32 | # avg = AverageDollarVolume(window_length=1).top(1) 33 | # pipe.add(VIX(),'vix') 34 | # pipe.set_screen(avg) 35 | # attach_pipeline(pipe,'my_pipeline') 36 | 37 | context.volatility_threshhold = .02 38 | context.stop_price = 0 39 | context.stop_pct = 0.15 40 | 41 | def set_trailing_stop(context, data): 42 | if context.portfolio.positions[context.vxx].amount: 43 | price = data.current(context.vxx,'price') 44 | sign = np.sign(context.portfolio.positions[context.vxx].amount) 45 | if sign > 0: 46 | context.stop_price = max(context.stop_price, (1-context.stop_pct) * price) 47 | else: 48 | context.stop_price = min(context.stop_price, (1+context.stop_pct) * price) 49 | 50 | def my_rebalance(context,data): 51 | 52 | set_trailing_stop(context,data) 53 | sign = np.sign(context.portfolio.positions[context.vxx].amount) 54 | price = data.current(context.vxx,'price') 55 | 56 | if sign > 0 and price < context.stop_price: 57 | order_target(context.vxx, 0) 58 | context.stop_price = 0 59 | print("trailing stop long") 60 | return 61 | 62 | if sign < 0 and price > context.stop_price: 63 | order_target(context.vxx, 0) 64 | context.stop_price = 0 65 | print("trailing stop short") 66 | return 67 | 68 | days = 200 69 | r=np.array(data.history(symbol('SPY'),'price',days,'1d')[:-1]) 70 | r=np.diff(np.log(r)) 71 | 72 | R = optimize.fmin(GARCH11_logL,np.array([.1,.1,.1]),args=(r,context),full_output=1) 73 | print(("omega = %.6f\nbeta = %.6f\nalpha = %.6f r=%.6f\n") % (R[0][0],R[0][2],R[0][1],r[-1])) 74 | 75 | omega = R[0][0] 76 | alpha = R[0][1] 77 | beta = R[0][2] 78 | 79 | sigma2 = omega + alpha*(r[-1])**2 + beta*context.last_sigma 80 | sigma = math.sqrt(sigma2) 81 | 82 | rv = 100*math.sqrt(sigma2*252) 83 | iv = data.current('vx1','close') 84 | record(rv = rv, iv = iv) 85 | 86 | delta = rv - iv 87 | if delta > 0.01: 88 | order_target_percent(context.vxx,1) 89 | elif delta < -0.01: 90 | order_target_percent(context.vxx,-1) 91 | 92 | # 93 | # Data pipeline functions 94 | # 95 | # class VIX(CustomFactor): 96 | # inputs = [cboe_vix.vix_close] 97 | # window_length = 1 98 | 99 | # def compute(self, today, assets, out, vix): 100 | # out[:] = vix[-1] 101 | 102 | def rename_col(df): 103 | df = df.rename(columns={'VIX Close': 'close'}) 104 | df = df.fillna(method='ffill') 105 | df = df[['close','sid']] 106 | # Correct look-ahead bias in mapping data to times 107 | df = shift_to_today(df) 108 | log.info(' \n %s ' % df.tail()) 109 | return df 110 | 111 | def shift_to_today(df): 112 | todayts = get_environment('end') 113 | tdays = 1 114 | 115 | if todayts.date() > df[-1:].index[0].date() : 116 | tdays = max(0, len(pd.date_range(df[-1:].index[0],todayts, freq=trading_day)) - 1) 117 | 118 | log.info("Shift time to {} today={} last={}".format(tdays, todayts.date(),df[-1:].index[0].date())) 119 | return df.tshift(tdays, freq=trading_day) 120 | 121 | def preview(df): 122 | log.info(' \n %s ' % df.head()) 123 | return df -------------------------------------------------------------------------------- /algorithms/FrankPSch/R083 S1.51 D5 _Free Cashflow Yield_.py: -------------------------------------------------------------------------------- 1 | """ 2 | Trading Strategy using Fundamental Data 3 | 1. Look at stocks in the Q1500US. 4 | 2. Go long in the top decile of stocks by FCF yield 5 | 3. Go short in the bottom decile of stocks by FCF yield. 6 | 4. Rebalance weekly at market open. 7 | """ 8 | 9 | from quantopian.algorithm import attach_pipeline, pipeline_output 10 | from quantopian.pipeline import Pipeline 11 | from quantopian.pipeline.data import Fundamentals 12 | from quantopian.pipeline.filters import Q1500US 13 | 14 | 15 | def initialize(context): 16 | 17 | # Rebalance weekly at open 18 | schedule_function(rebalance,date_rule=date_rules.week_start(),time_rule=time_rules.market_open()) 19 | #Record end of day positions 20 | schedule_function(my_record_vars, date_rules.week_start(), time_rules.market_close()) 21 | attach_pipeline(make_pipeline(), 'fundamentals_pipeline') 22 | 23 | def make_pipeline(): 24 | #Get free cash flow yield from morningstart database (FCF/price) 25 | fcf = Fundamentals.fcf_yield.latest.rank(mask = Q1500US(), method ='average') 26 | universe = ( 27 | Q1500US() 28 | & fcf.notnull() 29 | #& is_fresh 30 | # & volatility_filter 31 | ) 32 | #Sort into deciles 33 | num_quantiles = 5 34 | fcf_quantiles = fcf.quantiles(num_quantiles) 35 | #Build Pipeline, long top, short bottom decile 36 | pipe = Pipeline(screen=universe, columns = {'FCF': fcf, 'longs': fcf_quantiles.eq(num_quantiles-1), 'shorts': fcf_quantiles.eq(0)}) 37 | 38 | return pipe 39 | 40 | """ 41 | Runs our fundamentals pipeline before the market opens every week 42 | """ 43 | def before_trading_start(context, data): 44 | 45 | context.pipe_output = pipeline_output('fundamentals_pipeline') 46 | 47 | #Long top decile of FCF yield 48 | context.longs = context.pipe_output[context.pipe_output['longs']].index 49 | 50 | # Short bottom decile of FCF yield 51 | context.shorts = context.pipe_output[context.pipe_output['shorts']].index 52 | 53 | def rebalance(context, data): 54 | 55 | my_positions = context.portfolio.positions 56 | 57 | 58 | if (len(context.longs) > 0) and (len(context.shorts) > 0): 59 | 60 | # Equally weight all of our long positions and all of our short positions. 61 | long_weight = 0.5/len(context.longs) 62 | short_weight = -0.5/len(context.shorts) 63 | 64 | # Get our target names for our long and short baskets. We can display these 65 | # later. 66 | target_long_symbols = [s.symbol for s in context.longs] 67 | target_short_symbols = [s.symbol for s in context.shorts] 68 | 69 | log.info("Opening long positions each worth %.2f of our portfolio in: %s" \ 70 | % (long_weight, ','.join(target_long_symbols))) 71 | 72 | log.info("Opening long positions each worth %.2f of our portfolio in: %s" \ 73 | % (short_weight, ','.join(target_short_symbols))) 74 | 75 | # Open long positions in our high p/e stocks. 76 | for security in context.longs: 77 | if data.can_trade(security): 78 | if security not in my_positions: 79 | order_target_percent(security, long_weight) 80 | else: 81 | log.info("Didn't open long position in %s" % security) 82 | 83 | # Open short positions in our low p/e stocks. 84 | for security in context.shorts: 85 | if data.can_trade(security): 86 | if security not in my_positions: 87 | order_target_percent(security, short_weight) 88 | else: 89 | log.info("Didn't open short position in %s" % security) 90 | 91 | 92 | closed_positions = [] 93 | 94 | # Close our previous positions that are no longer in our pipeline. 95 | for security in my_positions: 96 | if security not in context.longs and security not in context.shorts \ 97 | and data.can_trade(security): 98 | order_target_percent(security, 0) 99 | closed_positions.append(security) 100 | 101 | log.info("Closing our positions in %s." % ','.join([s.symbol for s in closed_positions])) 102 | 103 | def my_record_vars(context, data): 104 | """ 105 | Record variables at the end of each rebalancing period. 106 | """ 107 | longs = shorts = 0 108 | for position in context.portfolio.positions.itervalues(): 109 | if position.amount > 0: 110 | longs += 1 111 | elif position.amount < 0: 112 | shorts += 1 113 | # Record our variables. 114 | record(leverage=context.account.leverage, long_count=longs, short_count=shorts) -------------------------------------------------------------------------------- /algorithms/1nad/Cloned from _Reply to_ The Pipeline API, Dividends and Splits - What You Need to Know_.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This algorithm takes the top 2000 companies by market cap (the Russell 2000) and ranks them by their 10 day returns. It longs in the top 10% and shorts the bottom 10% and rebalances monthly. 3 | ''' 4 | 5 | from quantopian.algorithm import attach_pipeline, pipeline_output 6 | from quantopian.pipeline import Pipeline 7 | from quantopian.pipeline import CustomFactor 8 | from quantopian.pipeline.data.builtin import USEquityPricing 9 | from quantopian.pipeline.data import morningstar 10 | 11 | 12 | # Create custom factor to calculate the returns 13 | class Returns(CustomFactor): 14 | 15 | # Pre-declare inputs and window_length 16 | inputs = [USEquityPricing.close] 17 | 18 | # Compute factor1 value 19 | def compute(self, today, assets, out, close): 20 | out[:] = 1-((close[0]-close[-1])/close[-1]) 21 | 22 | # Create custom factor to calculate a market cap based on yesterday's close 23 | class MarketCap(CustomFactor): 24 | 25 | # Pre-declare inputs and window_length 26 | inputs = [USEquityPricing.close, morningstar.valuation.shares_outstanding] 27 | window_length = 1 28 | 29 | # Compute market cap value 30 | def compute(self, today, assets, out, close, shares): 31 | out[:] = close[-1] * shares[-1] 32 | 33 | def initialize(context): 34 | 35 | context.long_leverage = 0.50 36 | context.short_leverage = -0.50 37 | 38 | pipe = Pipeline() 39 | attach_pipeline(pipe, 'ranked_2000') 40 | 41 | # Get the share class using .latest to get the most recent value 42 | share_class = morningstar.share_class_reference.is_primary_share.latest 43 | 44 | # Create and apply a filter representing the top 2000 equities by MarketCap every day 45 | # Mask out non primary share classes 46 | # This is an approximation of the Russell 2000 47 | mkt_cap = MarketCap() 48 | top_2000 = mkt_cap.top(2000, mask=share_class.eq(1)) 49 | pipe.set_screen(top_2000) 50 | 51 | # add a 10 day returns factor to the pipeline 52 | # note we are declaring the window_length here becase no default was declared 53 | returns_10 = Returns(window_length=10) 54 | pipe.add(returns_10, 'returns_10') 55 | # add a factor to rank the returns, mask this with the top_2000 filters 56 | pipe.add(returns_10.rank(mask=top_2000, ascending=False), 'returns_10_rank') 57 | 58 | # Scedule my rebalance function 59 | schedule_function(func=rebalance, 60 | date_rule=date_rules.month_start(days_offset=0), 61 | time_rule=time_rules.market_open(hours=0,minutes=30), 62 | half_days=True) 63 | 64 | 65 | def before_trading_start(context, data): 66 | # Call pipelive_output to get the output 67 | # Note this is a dataframe where the index is the SIDs for all securities to pass my screen 68 | # and the colums are the factors which I added to the pipeline 69 | context.output = pipeline_output('ranked_2000') 70 | log.info(len(context.output)) 71 | 72 | # Narrow down the securities to only the top 500 & update my universe 73 | context.long_list = context.output.sort(['returns_10_rank'], ascending=True).iloc[:200] 74 | context.short_list = context.output.sort(['returns_10_rank'], ascending=True).iloc[-200:] 75 | 76 | update_universe(context.long_list.index.union(context.short_list.index)) 77 | 78 | 79 | def handle_data(context, data): 80 | 81 | # Record and plot the leverage of our portfolio over time. 82 | record(leverage = context.account.leverage) 83 | 84 | print "Long List" 85 | log.info("\n" + str(context.long_list.sort(['returns_10_rank'], ascending=True).head(10))) 86 | 87 | print "Short List" 88 | log.info("\n" + str(context.short_list.sort(['returns_10_rank'], ascending=True).head(10))) 89 | 90 | # This rebalancing is called according to our schedule_function settings. 91 | def rebalance(context,data): 92 | 93 | long_weight = context.long_leverage / float(len(context.long_list)) 94 | short_weight = context.short_leverage / float(len(context.short_list)) 95 | 96 | 97 | for long_stock in context.long_list.index: 98 | if long_stock in data: 99 | order_target_percent(long_stock, long_weight) 100 | 101 | for short_stock in context.short_list.index: 102 | if short_stock in data: 103 | order_target_percent(short_stock, short_weight) 104 | 105 | for stock in context.portfolio.positions.iterkeys(): 106 | if stock not in context.long_list.index and stock not in context.short_list.index: 107 | order_target(stock, 0) 108 | -------------------------------------------------------------------------------- /algorithms/FrankPSch/R769 S1.57 DD16 _William's Volatility Fix - help_.py: -------------------------------------------------------------------------------- 1 | #Author: Kory Hoang 2 | #Developer: Mohammed Khalfan 3 | #Email: hoang.kory@gmail.com 4 | 5 | #Imports 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | import statsmodels.api as sm 8 | import quantopian.pipeline.data 9 | import numpy as np 10 | import talib 11 | import scipy 12 | import math 13 | 14 | def initialize(context): 15 | #set_benchmark(symbol('XIV')) 16 | context.XIV = symbol('XIV') 17 | context.VXX = symbol('VXX') 18 | 19 | context.wvf_length = 50 20 | context.ema1 = 5 21 | context.ema2 = 20 22 | context.StopLossPct = 0.03 23 | 24 | context.BuyPrice = 0 25 | context.SellLossPrice = 0 26 | context.SellProfitPrice = 0 27 | context.sell = False 28 | 29 | #Schedules 30 | schedule_function(check_rsi, date_rules.every_day(), time_rules.market_close(), False) 31 | schedule_function(market_open, date_rules.every_day(), time_rules.market_open(), False) 32 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 33 | 34 | #Set commission and slippage 35 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 36 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 37 | set_long_only() 38 | 39 | 40 | def market_open(context,data): 41 | if context.sell: 42 | context.sell = False 43 | if context.portfolio.positions[context.XIV].amount > 0 and len(get_open_orders()) == 0: 44 | order_target_percent(context.XIV, 0) 45 | 46 | def check_rsi(context,data): 47 | 48 | vxx_highs = data.history(context.VXX, "high", context.wvf_length*2, "1d") 49 | vxx_prices = data.history(context.VXX, "price", context.wvf_length*2, "1d") 50 | vxx_lows = data.history(context.VXX, "low", context.wvf_length*2, "1d") 51 | vxx_highest = vxx_highs.rolling(window = context.wvf_length, center=False).max() 52 | WVF = ((vxx_highest - vxx_lows)/(vxx_highest)) * 100 53 | 54 | context.SmoothedWVF1 = talib.EMA(WVF, timeperiod=context.ema1) 55 | context.SmoothedWVF2 = talib.EMA(WVF, timeperiod=context.ema2) 56 | SMA30VXX = talib.SMA(vxx_prices, 30) 57 | SMA5VXX = talib.SMA(vxx_prices, 5) 58 | 59 | record(WVF1=WVF[-1]) 60 | #record(SMA30=SMA30VXX[-1]) USELESS WITHOUT VXX PRICE! 61 | record(EMA5=context.SmoothedWVF1[-1]) 62 | record(EMA20=context.SmoothedWVF2[-1]) 63 | print("VXX[-2]: {} VXX[-1]: {} SMA5: {} SMA30[-2]: {} SMA30[-1]: {} WVF[-2]: {} WVF[-1]: {} SmoothedWVF1[-2]: {} SmoothedWVF1[-1]: {} SmoothedWVF2[-2]: {} SmoothedWVF2[-1]: {}".format(vxx_prices[-2], vxx_prices[-1], SMA5VXX[-1], SMA30VXX[-2], SMA30VXX[-1], WVF[-2], WVF[-1], context.SmoothedWVF1[-2], context.SmoothedWVF1[-1], context.SmoothedWVF2[-2], context.SmoothedWVF2[-1])) 64 | 65 | ## BUY RULES 66 | if context.portfolio.positions[context.XIV].amount == 0: 67 | if ((WVF[-1] > context.SmoothedWVF1[-1] and WVF[-2] < context.SmoothedWVF1[-2] and WVF[-1] < context.SmoothedWVF2[-1]) or (WVF[-1] > context.SmoothedWVF1[-1] and WVF[-2] < context.SmoothedWVF1[-2] and WVF[-1] > context.SmoothedWVF2[-1] and WVF[-2] < context.SmoothedWVF2[-2])) and vxx_prices[-1] < SMA5VXX[-1]: 68 | set_fixed_stop(context, data) 69 | order_target_percent(context.XIV, 1.0) 70 | print("bought") 71 | 72 | ## SELL RULES 73 | if context.portfolio.positions[context.XIV].amount > 0 and len(get_open_orders()) == 0: 74 | #if vxx crosses above SMA30: sell 75 | if vxx_prices[-2] < SMA30VXX[-2] and vxx_prices[-1] > SMA30VXX[-1]: 76 | context.sell = True 77 | print("vxx crosses above SMA30: sell") 78 | 79 | #if wvf crosses under smoothwvf2: sell 80 | if WVF[-2] > context.SmoothedWVF2[-2] and WVF[-1] < context.SmoothedWVF2[-1]: 81 | context.sell = True 82 | print("wvf crosses under smoothwvf2: sell") 83 | 84 | def set_fixed_stop(context, data): 85 | #Only call this once when the stock is bought 86 | if data.can_trade(context.XIV): 87 | price = data.current(context.XIV, 'price') 88 | context.BuyPrice = price 89 | context.SellLossPrice= price - (context.StopLossPct * price) 90 | 91 | def handle_data(context, data): 92 | #If we have a position check sell conditions 93 | if context.portfolio.positions[context.XIV].amount > 0: 94 | price = data.current(context.XIV, 'price') 95 | if price < context.SellLossPrice and len(get_open_orders()) == 0: 96 | order_target_percent(context.XIV, 0) 97 | context.sell = False 98 | print("SL hit") 99 | 100 | def my_record_vars(context, data): 101 | leverage = context.account.leverage 102 | record(leverage=leverage*10) -------------------------------------------------------------------------------- /algorithms/FrankPSch/E75 _Trading VIX - Quandl Data Now In Pipeline For Backtesting And Live Trading_.py: -------------------------------------------------------------------------------- 1 | # Below is an implementation using VIX Term Structure Following, to determine entry and exit points for 2 | # trading the volatility ETFs VXX (S&P 500 short term futures) and XIV (inverse S&P 500 short term futures). 3 | 4 | # For more information on this strategy check out: 5 | 6 | # https://marketsci.wordpress.com/2012/04/11/strategy-1-for-trading-volatility-etps-term-structure-following/ 7 | # https://marketsci.wordpress.com/2012/12/20/trading-vxxxiv-by-blindly-following-the-vix-futures-term-structure/ 8 | # https://marketsci.wordpress.com/2012/04/13/back-to-basics-y-ax-b/ 9 | 10 | 11 | from quantopian.pipeline import Pipeline 12 | from quantopian.algorithm import attach_pipeline, pipeline_output 13 | from quantopian.pipeline.data.builtin import USEquityPricing 14 | from quantopian.pipeline.factors import CustomFactor 15 | from quantopian.pipeline.data.quandl import yahoo_index_vix 16 | 17 | import pandas as pd 18 | import numpy as np 19 | from scipy import stats 20 | 21 | # Helper funtion for calculating the intercept. 22 | def _intercept(x, y): 23 | return stats.linregress(x, y)[1] 24 | 25 | # Calculate the impact of the term structure (see more about the 'impact' at the link above). Basically, 26 | # isolate how much of the movement of VXX isn't due to the VIX index. As a handwavy model we'll 27 | # run a simple regression of the changes in the VIX to the changes in VXX, and use the 28 | # intercept term as an estimation of the 'impact.' 29 | class TermStructureImpact(CustomFactor): 30 | # Pre-declare inputs and window_length 31 | inputs = [yahoo_index_vix.close, USEquityPricing.close] 32 | window_length = 20 33 | def compute(self, today, assets, out, vix, close): 34 | # Get the prices series of just VXX and calculate its daily returns. 35 | vxx_returns = pd.DataFrame(close, columns=assets)[sid(38054)].pct_change()[1:] 36 | # Since there isn't a ticker for the raw VIX Pipeline feeds us the value of the 37 | # VIX for each day in the 'window_length' for each asset. Which kind of makes sense 38 | # -- the VIX is the same value for every security. 39 | # Since I have a fixed universe I'll just use VXX, one of my securities, to get a single series of 40 | # VIX data. You could use any security or integer index to any column, but I'll use one of my 41 | # securities just to keep things straight in my head. 42 | vix_returns = pd.DataFrame(vix).pct_change()[0].iloc[1:] 43 | # Calculate the 'impact.' 44 | alpha = _intercept(vix_returns, vxx_returns) 45 | out[:] = alpha 46 | 47 | 48 | # Put any initialization logic here. The context object will be passed to 49 | # the other methods in your algorithm. 50 | def initialize(context): 51 | 52 | # Set these to zero to evaulate the signal generating ability of the algorithm. 53 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 54 | set_commission(commission.PerShare(cost=0.01, min_trade_cost=1.0)) # FSC for IB 55 | 56 | # Create, register and name a pipeline in initialize. 57 | pipe = Pipeline() 58 | attach_pipeline(pipe, 'example') 59 | 60 | # Add the TermStrucutreImpact factor to the Pipeline 61 | ts_impact = TermStructureImpact() 62 | pipe.add(ts_impact, 'ts_impact') 63 | 64 | # Define our securities, global variables, and schedule when to trade. 65 | context.vxx = sid(38054) 66 | context.xiv = sid(40516) 67 | 68 | context.impact = 0 69 | 70 | schedule_function(allocate, date_rules.every_day(), time_rules.market_open(minutes=30)) 71 | 72 | 73 | def before_trading_start(context, data): 74 | # Pipeline_output returns the constructed dataframe. 75 | output = pipeline_output('example') 76 | output = output.dropna() 77 | context.impact = output["ts_impact"].loc[context.vxx] # Again, the value of the 'impact' is the same for all securities, but I'll just index on VXX again. 78 | 79 | 80 | # Will be called on every trade event for the securities you specify. 81 | def record_vars(context, data): 82 | record(lever=context.account.leverage, impact=context.impact) 83 | 84 | 85 | # Allocate based on whether the 'impact' is positive or negative. 86 | # If the 'impact' is positive, go long VXX. If the 'impact' is negative, go long XIV. 87 | def allocate(context, data): 88 | if context.impact > 0: 89 | if data.can_trade(context.xiv): 90 | order_target_percent(context.xiv, 0) 91 | if data.can_trade(context.vxx): 92 | order_target_percent(context.vxx, 1) 93 | elif context.impact < 0: 94 | if data.can_trade(context.vxx): 95 | order_target_percent(context.vxx, 0) 96 | if data.can_trade(context.xiv): 97 | order_target_percent(context.xiv, 1) 98 | else: 99 | log.info("Term Structure Impact is Zero") -------------------------------------------------------------------------------- /algorithms/FrankPSch/Cloned from _New Strategy — “In & Out”_.py: -------------------------------------------------------------------------------- 1 | # In and out strategy 2 | 3 | #Imports 4 | import quantopian.algorithm as algo 5 | from quantopian.pipeline import Pipeline 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.factors import CustomFactor 8 | import quantopian.optimize as opt 9 | import pandas as pd 10 | import numpy as np 11 | 12 | #Settings (variables and scheduling functions) 13 | def initialize(context): 14 | set_commission(commission.PerShare(cost=0.0075, min_trade_cost=1.00)) 15 | context.daycounttot = 0 #count of total days since start 16 | context.in_out = 1 #start with being 'in' the market 17 | context.waitdays = 15 #min days of being out; 3 trading weeks 18 | context.outday = 0 #daycounttot when in_out=0 19 | context.spy_in = 0 #when SPY drops 30% go 'in' no matter what 20 | context.spyinday = 0 #daycounttot when spy_in=1 21 | context.SPY = symbol('SPY') 22 | context.XLI = symbol('XLI') #to capture drop in industrials 23 | context.DBB = symbol('DBB') #to capture drop in materials 24 | context.BIL = symbol('SHY') #to capture interest rate incr. 25 | context.alternative = [symbol('IEF'), symbol('TLT')] #investment if 'out' of the market 26 | algo.attach_pipeline(make_pipeline(context), 'pipeline') 27 | # Schedule functions 28 | schedule_function( #daily check re getting 'out' of market 29 | check_out, 30 | date_rules.every_day(), 31 | time_rules.market_open(minutes = 75) 32 | ) 33 | schedule_function( #weekly regular trading (getting 'in') 34 | trade, 35 | date_rules.week_start(days_offset=4), 36 | time_rules.market_open(minutes = 75) 37 | ) 38 | 39 | class OwnMax(CustomFactor): 40 | inputs = [USEquityPricing.close] 41 | def compute(self, today, asset_ids, out, input_factor): 42 | # Calculates the column-wise max, ignoring NaNs 43 | out[:] = np.nanmax(input_factor, axis=0) 44 | 45 | class OwnShift(CustomFactor): 46 | inputs = [USEquityPricing.close] 47 | def compute(self, today, assets, out, input_factor): 48 | out[:] = input_factor[0] 49 | 50 | def make_pipeline(context): 51 | out_xli = (USEquityPricing.close.latest / OwnShift(window_length=58) [context.XLI] - 1) < -0.07 52 | out_dbb = (USEquityPricing.close.latest / OwnShift(window_length=58) [context.DBB] - 1) < -0.07 53 | out_bil = (USEquityPricing.close.latest / OwnShift(window_length=58) [context.BIL] - 1) < -0.60/100 54 | in_spy = ((USEquityPricing.close.latest / OwnMax(window_length = 252) [context.SPY]) < 0.7) 55 | 56 | pipe = Pipeline(columns={ 57 | 'out_xli': out_xli, 58 | 'out_dbb': out_dbb, 59 | 'out_bil': out_bil, 60 | 'in_spy': in_spy, 61 | }, 62 | ) 63 | return pipe 64 | 65 | def check_out(context, data): #runs daily to determine w/h to exit 66 | df_big = algo.pipeline_output('pipeline') 67 | 68 | #full weight on SPY, subject to the following conditions 69 | context.stock_weights = pd.Series(index=[context.SPY], data=1) 70 | 71 | #check whether XLI, DBB or BIL drop sign. (get out) 72 | if df_big.loc[context.XLI, 'out_xli'] | df_big.loc[context.DBB, 'out_dbb'] | df_big.loc[context.BIL, 'out_bil']: 73 | context.in_out = 0 74 | context.outday = context.daycounttot 75 | if context.daycounttot >= context.outday+context.waitdays: 76 | context.in_out = 1 77 | 78 | #check whether SPY drops sign. (stay in/go in) 79 | if df_big.loc[context.SPY, 'in_spy']: 80 | context.spy_in = 1 81 | context.spyinday = context.daycounttot 82 | if context.daycounttot >= context.spyinday+context.waitdays: 83 | context.spy_in = 0 84 | 85 | #condition regarding getting out 86 | context.out = context.in_out==0 & context.spy_in==0 87 | if context.out: 88 | context.stock_weights = context.stock_weights*0 89 | 90 | #open alternative positions using remaining balance 91 | alt_weight = max(1.0 - context.stock_weights.sum(), 0) / len(context.alternative) 92 | context.alt_weights = pd.Series(index=context.alternative, data=alt_weight) 93 | 94 | #buy alternative and sell SPY if getting out 95 | if context.out: 96 | total_weights = pd.concat([context.stock_weights, context.alt_weights]) 97 | target_weights = opt.TargetWeights(total_weights) 98 | order_optimal_portfolio( 99 | objective = target_weights, 100 | constraints = [] 101 | ) 102 | 103 | #increase total day counts by 1 104 | context.daycounttot = context.daycounttot+1 105 | 106 | def trade(context, data): #runs weekly; trade/rebalance stocks 107 | total_weights = pd.concat([context.stock_weights, context.alt_weights]) 108 | target_weights = opt.TargetWeights(total_weights) 109 | order_optimal_portfolio( 110 | objective = target_weights, 111 | constraints = [] 112 | ) -------------------------------------------------------------------------------- /algorithms/FrankPSch/Peter Bakker live from _Reply to_ The SPY who loved WVF (or Just another Volatility SPY strategy)_.py: -------------------------------------------------------------------------------- 1 | #Imports 2 | import statsmodels.api as sm 3 | import quantopian.pipeline.data 4 | import numpy as np 5 | import talib 6 | import scipy 7 | 8 | def initialize(context): 9 | 10 | set_benchmark(symbol('SPY')) 11 | context.start = 1 12 | context.stocks = [ 13 | sid(37514), 14 | sid(21508) 15 | ] 16 | 17 | context.XIV = sid(40516) #VELOCITYSHARES DAILY INVERSE VIX SHORT TERM ETN 18 | context.VXX = sid(38054) #IPATH S&P 500 VIX SHORT-TERM FUTURES ETN 19 | 20 | #Variables 21 | context.watch_list = [] 22 | context.run_count = 0 23 | context.opt_pass_count = 0 24 | context.eps_vals = [] 25 | context.Safety_Weight = 0.00 26 | context.maxBuy = 0.50 27 | 28 | #Schedules 29 | schedule_function(my_rebalance, date_rules.every_day(), time_rules.market_open()) 30 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 31 | for i in range(25, 385, 25): # (start, end, every i minutes) 32 | schedule_function(watch, date_rules.every_day(), time_rules.market_open(minutes=i)) 33 | 34 | #Set slippage,commision, and long only restriction 35 | set_long_only() 36 | 37 | 38 | def my_rebalance(context,data): 39 | 40 | # my_assigned_weights(context, data) 41 | 42 | n = 28 43 | WFV_limit= 14.5 44 | vxx_prices = data.history(context.VXX, "price", n + 2, "1d")[:-1] 45 | vxx_lows = data.history(context.VXX, "low", n + 2, "1d")[:-1] 46 | vxx_highest = vxx_prices.rolling(window = n, center=False).max() 47 | 48 | WVF = ((vxx_highest - vxx_lows)/(vxx_highest)) * 100 49 | record(WVF=WVF[-1]) 50 | 51 | xn = 28 52 | xiv_prices = data.history(context.XIV, "price", xn + 2, "1d")[:-1] 53 | xiv_lows = data.history(context.XIV, "low", xn + 2, "1d")[:-1] 54 | xiv_highest = xiv_prices.rolling(window = xn, center=False).max() 55 | 56 | XWVF = ((xiv_highest - xiv_lows)/(xiv_highest)) * 100 57 | record(XWVF=XWVF[-1]) 58 | 59 | if (WVF[-1] >= WFV_limit and WVF[-2] < WFV_limit): 60 | BuyStock = context.XIV 61 | context.Safety_Weight = 0.0 62 | if context.XIV not in context.portfolio.positions: 63 | order_target_percent(BuyStock, context.maxBuy) 64 | message = 'BUY: {stock}' 65 | log.info(message.format(stock=BuyStock.symbol)) 66 | if (WVF[-1] < WFV_limit and WVF[-2] >= WFV_limit) or (WVF[-1] < XWVF[-1] and WVF[-2] >= XWVF[-2]): 67 | if context.XIV in context.portfolio.positions: 68 | SellStock = context.XIV 69 | order_target_percent(SellStock, 0.00) 70 | message = 'Sell: {stock}' 71 | log.info(message.format(stock=SellStock.symbol)) 72 | context.Safety_Weight = 1.00 73 | 74 | def my_record_vars(context, data): 75 | 76 | leverage = context.account.leverage 77 | record(leverage=leverage) 78 | 79 | def watch(context, data): # On schedule, process any sids in watch_list 80 | 81 | prices = data.history(context.watch_list, 'close', 2, '1d') # Daily, couple days 82 | for s in context.watch_list: 83 | if s not in context.portfolio.positions: # If sold elsewhere, drop it from watch 84 | context.watch_list.remove(s) 85 | continue 86 | 87 | # Slope of prices, minute 88 | slp = slope(data.history(s, 'close', 60, '1m').dropna()) # Minutes, note dropna(), important 89 | if slp < 0: # Close if downward 90 | log.info('sell {} at {} prv {} {}%'.format(s.symbol, data.current(s, 'price'), '%.2f' % prices[s][0], '%.0f' % (100 * data.current(s, 'price') / prices[s][0]) )) 91 | order_target(s, 0) # Close/sell 92 | context.watch_list.remove(s) 93 | 94 | # Any new for price jump watch_list 95 | prices = data.history(context.portfolio.positions.keys(), 'close', 2, '1d') # Couple days 96 | for s in context.portfolio.positions: # Add to watch_list with price jump 97 | if not data.can_trade(s): continue 98 | if data.current(s, 'price') > 1.10 * prices[s][0]: # If price has jumped upward 99 | if s in context.watch_list: continue 100 | log.info('{} to watch_list at {} prv {} {}%'.format(s.symbol, data.current(s, 'price'), '%.2f' % prices[s][0], '%.0f' % (100 * data.current(s, 'price') / prices[s][0]) )) 101 | context.watch_list.append(s) 102 | 103 | 104 | def slope(in_list): # Return slope of regression line. [Make sure this list contains no nans] 105 | 106 | return sm.OLS(in_list, sm.add_constant(range(-len(in_list) + 1, 1))).fit().params[-1] # slope 107 | 108 | def handle_data(context,data): 109 | 110 | if context.start == 1: 111 | context.start = 0 112 | BuyStock = context.XIV 113 | order_target_percent(BuyStock, 1.0) -------------------------------------------------------------------------------- /algorithms/FrankPSch/E62 _XIV Shotgun - Trading Inverse VIX with WVF_.py: -------------------------------------------------------------------------------- 1 | #Author: Kory Hoang 2 | #Developers: Jacob Lower & Mohammed Khalfan 3 | #For collaboration requests, email: hoang.kory@gmail.com 4 | 5 | #Imports 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | import statsmodels.api as sm 8 | import quantopian.pipeline.data 9 | import numpy as np 10 | import talib 11 | import scipy 12 | import math 13 | 14 | def initialize(context): 15 | #set_benchmark(symbol('XIV')) 16 | context.XIV = symbol('XIV') 17 | context.VXX = symbol('VXX') 18 | context.BOND = symbol('IEF') 19 | context.num_trades = 0 20 | 21 | context.rsi_length = 3 22 | context.rsi_trigger = 50 23 | context.wvf_length = 100 24 | context.ema1 = 10 25 | context.ema2 = 30 26 | context.TakeProfitPct = 0.25 27 | context.StopLossPct = 0.03 28 | context.XIVpct = 1.0 29 | context.BONDpct = 1.0 30 | 31 | context.BuyPrice = 0 32 | context.SellLossPrice = 0 33 | context.SellProfitPrice = 0 34 | context.sell = False 35 | 36 | #Schedules 37 | schedule_function(check_rsi, date_rules.every_day(), time_rules.market_close(), False) 38 | schedule_function(market_open, date_rules.every_day(), time_rules.market_open(), False) 39 | schedule_function(my_record_vars, date_rules.every_day(), time_rules.market_close()) 40 | 41 | #Set commission and slippage 42 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 43 | set_commission(commission.PerShare(cost=0.01, min_trade_cost=1.0)) # FSC for IB 44 | 45 | set_long_only() 46 | 47 | 48 | def market_open(context,data): 49 | if context.sell: 50 | context.sell = False 51 | if context.portfolio.positions[context.XIV].amount > 0 and len(get_open_orders()) == 0: 52 | order_target_percent(context.XIV, 0) 53 | order_target_percent(context.BOND, context.BONDpct) 54 | 55 | def check_rsi(context,data): 56 | 57 | vxx_prices = data.history(context.VXX, "high", context.wvf_length*2, "1d") 58 | vxx_lows = data.history(context.VXX, "low", context.wvf_length*2, "1d") 59 | vxx_highest = vxx_prices.rolling(window = context.wvf_length, center=False).max() 60 | WVF = ((vxx_highest - vxx_lows)/(vxx_highest)) * 100 61 | 62 | rsi = talib.RSI(vxx_prices, timeperiod=context.rsi_length) 63 | 64 | context.SmoothedWVF1 = talib.EMA(WVF, timeperiod=context.ema1) 65 | context.SmoothedWVF2 = talib.EMA(WVF, timeperiod=context.ema2) 66 | 67 | record(WVF1=WVF[-1]) 68 | record(RSI=rsi[-1]) 69 | record(EMA10=context.SmoothedWVF1[-1]) 70 | record(EMA30=context.SmoothedWVF2[-1]) 71 | 72 | print("vxx_low: ", vxx_lows[-1]) 73 | print("vxx_highest: ", vxx_highest[-1]) 74 | print("WVF: ", WVF[-1]) 75 | print("context.SmoothedWVF1: ", context.SmoothedWVF1[-1]) 76 | print("context.SmoothedWVF2: ", context.SmoothedWVF2[-1]) 77 | 78 | ## BUY RULES 79 | #if WVF crosses over smoothwvf1 and wvf < smoothwvf2 80 | if ((WVF[-1] > context.SmoothedWVF1[-1] and WVF[-2] < context.SmoothedWVF1[-2] and WVF[-1] < context.SmoothedWVF2[-1]) or (context.SmoothedWVF1[-2] < context.SmoothedWVF2[-2] and context.SmoothedWVF1[-1] > context.SmoothedWVF2[-1]) or (WVF[-1] > context.SmoothedWVF1[-1] and WVF[-2] < context.SmoothedWVF1[-2] and WVF[-1] > context.SmoothedWVF2[-1] and WVF[-2] < context.SmoothedWVF2[-2])) and context.portfolio.positions[context.XIV].amount == 0: 81 | set_fixed_stop(context, data) 82 | order_target_percent(context.XIV, 1.0) 83 | order_target_percent(context.BOND, 0) 84 | 85 | ## SELL RULES 86 | if context.portfolio.positions[context.XIV].amount > 0 and len(get_open_orders()) == 0: 87 | #if rsi crosses over rsi_trigger 88 | if rsi[-2] < context.rsi_trigger and rsi[-1] > context.rsi_trigger: 89 | context.sell = True 90 | 91 | #if wvf crosses under smoothwvf2: sell 92 | elif WVF[-2] > context.SmoothedWVF2[-2] and WVF[-1] < context.SmoothedWVF2[-1]: 93 | context.sell = True 94 | 95 | def set_fixed_stop(context, data): 96 | #Only call this once when the stock is bought 97 | if data.can_trade(context.XIV): 98 | price = data.current(context.XIV, 'price') 99 | context.BuyPrice = price 100 | context.SellLossPrice= price - (context.StopLossPct * price) 101 | context.SellProfitPrice= (price * context.TakeProfitPct) + price 102 | 103 | def handle_data(context, data): 104 | #If we have a position check sell conditions 105 | if context.portfolio.positions[context.XIV].amount > 0: 106 | price = data.current(context.XIV, 'price') 107 | if price > context.SellProfitPrice and len(get_open_orders()) == 0: 108 | order_target_percent(context.XIV, 0) 109 | order_target_percent(context.BOND, context.BONDpct) 110 | context.sell = False 111 | if price < context.SellLossPrice and len(get_open_orders()) == 0: 112 | order_target_percent(context.XIV, 0) 113 | order_target_percent(context.BOND, context.BONDpct) 114 | context.sell = False 115 | 116 | def my_record_vars(context, data): 117 | leverage = context.account.leverage 118 | record(leverage=leverage) -------------------------------------------------------------------------------- /algorithms/FrankPSch/_Computing the Fama-French Factors with Pipeline_.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | from quantopian.algorithm import attach_pipeline, pipeline_output 4 | from quantopian.pipeline import Pipeline 5 | from quantopian.pipeline import CustomFactor 6 | from quantopian.pipeline.data.builtin import USEquityPricing 7 | from quantopian.pipeline.data import morningstar 8 | 9 | # time frame on which we want to compute Fama-French 10 | normal_days = 31 11 | # approximate the number of trading days in that period 12 | # this is the number of trading days we'll look back on, 13 | # on every trading day. 14 | business_days = int(0.69 * normal_days) 15 | 16 | class Returns(CustomFactor): 17 | """ 18 | this factor outputs the returns over the period defined by 19 | business_days, ending on the previous trading day, for every security. 20 | """ 21 | window_length = business_days 22 | inputs = [USEquityPricing.close] 23 | def compute(self,today,assets,out,price): 24 | out[:] = (price[-1] - price[0]) / price[0] * 100 25 | 26 | class MarketEquity(CustomFactor): 27 | """ 28 | this factor outputs the market cap of every security on the day. 29 | """ 30 | window_length = business_days 31 | inputs = [morningstar.valuation.market_cap] 32 | def compute(self,today,assets,out,mcap): 33 | out[:] = mcap[0] 34 | 35 | class BookEquity(CustomFactor): 36 | """ 37 | this factor outputs the book value of every security on the day. 38 | """ 39 | window_length = business_days 40 | inputs = [morningstar.balance_sheet.tangible_book_value] 41 | def compute(self,today,assets,out,book): 42 | out[:] = book[0] 43 | 44 | class CommonStock(CustomFactor): 45 | """ 46 | this factor outputs 1.0 for all securities that are either common stock or SPY, 47 | and outputs 0.0 for all other securities. This is to filter out ETFs and other 48 | types of share that we do not wish to consider. 49 | """ 50 | window_length = business_days 51 | inputs = [morningstar.share_class_reference.is_primary_share] 52 | def compute(self,today,assets,out, share_class): 53 | out[:] = ((share_class[-1].astype(bool)) | (assets == 8554)).astype(float) 54 | 55 | def initialize(context): 56 | """ 57 | use our factors to add our pipes and screens. 58 | """ 59 | pipe = Pipeline() 60 | attach_pipeline(pipe, 'ff_example') 61 | 62 | common_stock = CommonStock() 63 | # filter down to securities that are either common stock or SPY 64 | pipe.set_screen(common_stock.eq(1)) 65 | mkt_cap = MarketEquity() 66 | pipe.add(mkt_cap,'market_cap') 67 | 68 | book_equity = BookEquity() 69 | # book equity over market equity 70 | be_me = book_equity/mkt_cap 71 | pipe.add(be_me,'be_me') 72 | 73 | returns = Returns() 74 | pipe.add(returns,'returns') 75 | schedule_function(func=print_fama_french, date_rule=date_rules.every_day()) 76 | 77 | def print_fama_french(context, data): 78 | # print the Fama-French factors for the period defined by business_days 79 | # ending on the previous trading day. 80 | print(context.rm_rf, context.smb, context.hml) 81 | 82 | def before_trading_start(context,data): 83 | """ 84 | every trading day, we use our pipes to construct the Fama-French 85 | portfolios, and then calculate the Fama-French factors appropriately. 86 | """ 87 | spy = sid(8554) 88 | 89 | factors = pipeline_output('ff_example') 90 | 91 | # get the data we're going to use 92 | returns = factors['returns'] 93 | mkt_cap = factors.sort(['market_cap'], ascending=True) 94 | be_me = factors.sort(['be_me'], ascending=True) 95 | 96 | # to compose the six portfolios, split our universe into portions 97 | half = int(len(mkt_cap)*0.5) 98 | small_caps = mkt_cap[:half] 99 | big_caps = mkt_cap[half:] 100 | 101 | thirty = int(len(be_me)*0.3) 102 | seventy = int(len(be_me)*0.7) 103 | growth = be_me[:thirty] 104 | neutral = be_me[thirty:seventy] 105 | value = be_me[seventy:] 106 | 107 | # now use the portions to construct the portfolios. 108 | # note: these portfolios are just lists (indices) of equities 109 | small_value = small_caps.index.intersection(value.index) 110 | small_neutral = small_caps.index.intersection(neutral.index) 111 | small_growth = small_caps.index.intersection(growth.index) 112 | 113 | big_value = big_caps.index.intersection(value.index) 114 | big_neutral = big_caps.index.intersection(neutral.index) 115 | big_growth = big_caps.index.intersection(growth.index) 116 | 117 | # take the mean to get the portfolio return, assuming uniform 118 | # allocation to its constituent equities. 119 | sv = returns[small_value].mean() 120 | sn = returns[small_neutral].mean() 121 | sg = returns[small_growth].mean() 122 | 123 | bv = returns[big_value].mean() 124 | bn = returns[big_neutral].mean() 125 | bg = returns[big_growth].mean() 126 | 127 | # computing Rm-Rf (Market Returns - Risk-Free Returns). we take the 128 | # rate of risk-free returns to be zero, so this is simply SPY's returns. 129 | # have to set an initial dummy value 130 | context.rm_rf = float('nan') 131 | if spy in returns.index: 132 | context.rm_rf = returns.loc[spy] 133 | 134 | # computing SMB 135 | context.smb = (sv + sn + sg)/3 - (bv + bn + bg)/3 136 | 137 | # computing HML 138 | context.hml = (sv + bv)/2 - (sg + bg)/2 -------------------------------------------------------------------------------- /algorithms/FrankPSch/R101 S0.78 DD21 V02 Luke _Beta Zero-Targeting - Automatic - Never worry about Beta again_.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Zero-Beta targeting example. 3 | Automatically adjust proportions of spy and tlt to hold Beta to around 0.0 or beta_target. 4 | c.beta_limit is one strictness adjustment, there are others. 5 | In terms of *effect* on Beta generally: 6 | - Longs (many) tend to be like SPY (increase) 7 | - Short often acts similar to TLT here (decrease) 8 | 9 | Standalone version - Just copy the schedule_function at your desired interval and the beta_balance function into any algorithm and specify the % of your portfolio that the beta hedge will occupy. You will need to lower your algorithm's leverage accordingly. Not yet tested with algorithms that use SPY and TLT already! 10 | ''' 11 | 12 | def initialize(context): 13 | #Backtester settings 14 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 15 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 16 | 17 | #Balance Beta 18 | schedule_function(beta_balance, date_rules.week_start(), time_rules.market_open()) 19 | 20 | def handle_data(context, data): 21 | pass 22 | 23 | def before_trading_start(context, data): 24 | record(lev = context.account.leverage) 25 | pass 26 | 27 | 28 | 29 | def beta_balance(context, data): 30 | ########### Variables ################################### 31 | spy = sid(8554) 32 | tlt = sid(23921) 33 | beta_lev = 1.0 # Percentage of portfolio you wish to act as a beta hedge 34 | beta = 1.0 # Assumed starting beta 35 | beta_target = 0.0 # Target any Beta you wish 36 | beta_limit = .01 # Pos/neg threshold, balance only outside of this either side of target 37 | record_beta = True # Graph beta over time 38 | record_spy_ratio = True # Graph the percentage of beta adjust "spy" 39 | log_info = True #log of adjustments to beta 40 | ########################################################## 41 | import pandas as panda_var # Python will only do once, makes this portable. Move to top of algo for better efficiency. 42 | import numpy as numpy_var # Python will only do once, makes this portable. Move to top of algo for better efficiency. 43 | 44 | try: context.beta_df 45 | except: context.beta_df = panda_var.DataFrame([], columns=['pf', 'spy']) 46 | 47 | if get_open_orders(spy) or not data.can_trade(spy) or get_open_orders(tlt) or not data.can_trade(tlt): 48 | log.error("Beta Stocks Not Tradeable") 49 | return 50 | 51 | spy_price = data.current(spy, 'price') 52 | spy_amt = context.portfolio.positions[spy].amount 53 | tlt_price = data.current(tlt, 'price') 54 | tlt_amt = context.portfolio.positions[tlt].amount 55 | port_val = context.portfolio.portfolio_value 56 | spy_val = spy_amt * spy_price 57 | spy_ratio = spy_val / port_val 58 | 59 | context.beta_df = context.beta_df.append({ # Beta calc prep 60 | 'pf' : port_val, 61 | 'spy': spy_price}, ignore_index=True) 62 | context.beta_df['spy_chg'] = context.beta_df.spy.pct_change() 63 | context.beta_df[ 'pf_chg'] = context.beta_df.pf.pct_change() 64 | context.beta_df = context.beta_df.ix[-252:] # trim to one year 65 | 66 | 67 | 68 | if not context.portfolio.positions: # Initial positions to start, only if none exist 69 | spy_goal_val = (port_val * beta_lev) 70 | spy_goal_shares = numpy_var.floor(spy_goal_val / spy_price) 71 | spy_shares = (spy_goal_shares - spy_amt) 72 | order(spy, spy_shares) 73 | return 74 | 75 | if len(context.beta_df.spy.values) < 3: return 76 | 77 | beta = context.beta_df.pf_chg.cov(context.beta_df.spy_chg) / context.beta_df.spy_chg.var() 78 | 79 | if record_beta: 80 | record(beta_calculated = beta) 81 | 82 | bzat = beta - beta_target # bzat is beta-zero adjusted for target 83 | if -beta_limit < bzat < beta_limit: # Skip if inside boundaries 84 | return 85 | 86 | # -------- Adjust positions to move toward target Beta -------- 87 | # Reduce spy & increase tlt or visa-versa 88 | # The further away from target Beta, the stronger the adjustment. 89 | # https://www.quantopian.com/posts/scaling for explanation of next line ... 90 | def scale(wild, a_lo, a_hi, b_lo, b_hi): 91 | ''' Based on wild value relative to a_lo_hi range, 92 | return its analog within b_hi_lo, with min b_lo and max b_hi 93 | ''' 94 | return min(b_hi, max(b_lo, (b_hi * (wild - a_lo)) / (a_hi - a_lo))) 95 | 96 | temperance = scale(abs(bzat), 0, .30, .35, .80) # Not straight Beta, a portion of it. 97 | adjust = min(beta_lev,max(0.0, spy_ratio - (bzat * temperance))) # spy ratio no higher than spy_limit_hi or lower than 0 98 | 99 | if log_info: 100 | log.info('beta {} spy {} to {}'.format('%.2f' % beta, '%.2f' % spy_ratio, '%.2f' % adjust)) 101 | 102 | if record_spy_ratio: 103 | record(Beta_spy_ratio = adjust/beta_lev) 104 | 105 | spy_goal_val = (port_val * adjust) 106 | spy_goal_shares = numpy_var.floor(spy_goal_val / spy_price) 107 | spy_shares = (spy_goal_shares - spy_amt) 108 | 109 | tlt_goal_val = (port_val * (beta_lev - adjust)) 110 | tlt_goal_shares = numpy_var.floor(tlt_goal_val / tlt_price) 111 | tlt_shares = (tlt_goal_shares - tlt_amt) 112 | 113 | order(spy, spy_shares) 114 | order(tlt, tlt_shares) -------------------------------------------------------------------------------- /algorithms/FrankPSch/R150 S0.57 DD53 _[Investment Management course] Smart Momentum Strategy_.py: -------------------------------------------------------------------------------- 1 | ''' 2 | For algorithm explanations and sources, please see the report 3 | Pipeline code is based on Quantopian Tutorial 2: Pipeline 4 | Trading code is based on Quantopian Sample Mean Reversion Algorithm 5 | ''' 6 | 7 | from quantopian.algorithm import order_optimal_portfolio 8 | from quantopian.algorithm import attach_pipeline, pipeline_output 9 | from quantopian.pipeline import Pipeline 10 | from quantopian.pipeline.data.builtin import USEquityPricing 11 | import quantopian.optimize as opt 12 | from quantopian.pipeline.data import Fundamentals 13 | from quantopian.pipeline.data import morningstar 14 | from quantopian.pipeline.factors import Returns, MarketCap 15 | from quantopian.pipeline.filters.fundamentals import Q1500US 16 | 17 | def initialize(context): 18 | #Start rebalancing procedure at the end of each month, at market open 19 | schedule_function( 20 | my_rebalance, 21 | date_rules.month_end(), 22 | time_rules.market_open() 23 | ) 24 | 25 | #Record variables at the end of each day. 26 | schedule_function( 27 | my_record_vars, 28 | date_rules.every_day(), 29 | time_rules.market_close() 30 | ) 31 | 32 | # Create our pipeline and attach it to our algorithm. 33 | my_pipe = make_pipeline() 34 | attach_pipeline(my_pipe, 'my_pipeline') 35 | 36 | def make_pipeline(): 37 | #0. Select top-1500 liquid stocks 38 | base_universe = Q1500US() 39 | 40 | #1. Market Capitalization Filter, select top 1200 out of 1500 41 | market_cap = MarketCap(mask=base_universe) 42 | top_market_cap = market_cap.top(1200) 43 | 44 | #2. B/M Filter, select top 5000 out of all stocks (~8200) 45 | btom = morningstar.valuation_ratios.book_value_yield.latest 46 | top_btom = btom.top(5000) 47 | 48 | #3. Interception of 1st and 2nd filters results, on average returns ~1000 stocks 49 | top_cap_btom = top_market_cap & top_btom 50 | 51 | #4. Top Performers filter, select top 100 52 | latest_return_7_1 = Returns( 53 | inputs=[USEquityPricing.close], 54 | window_length=147, 55 | mask=top_cap_btom 56 | )/Returns( 57 | inputs=[USEquityPricing.close], 58 | window_length=21, 59 | mask=top_cap_btom 60 | ) 61 | top_performers = latest_return_7_1.top(100) 62 | 63 | #5. Smoothest Returns filter, select 50 smoothest 64 | r_7 = Returns(window_length = 21, mask=top_performers) 65 | r_6 = (Returns(window_length = 42, mask=top_performers)+1)/(r_7+1)-1 66 | r_5 = (Returns(window_length = 63, mask=top_performers)+1)/((r_7+1)*(r_6+1))-1 67 | r_4 = (Returns(window_length = 84, mask=top_performers)+1)/((r_7+1)*(r_6+1)*(r_5+1))-1 68 | r_3 = (Returns(window_length = 105, mask=top_performers)+1)/((r_7+1)*(r_6+1)*(r_5+1)*(r_4+1))-1 69 | r_2 = (Returns(window_length = 126, mask=top_performers)+1)/((r_7+1)*(r_6+1)*(r_5+1)*(r_4+1)*(r_3+1))-1 70 | r_1 = (Returns(window_length = 147, mask=top_performers)+1)/((r_7+1)*(r_6+1)*(r_5+1)*(r_4+1)*(r_3+1)*(r_2+1))-1 71 | r_mean = (r_1+r_2+r_3+r_4+r_5+r_6)/6.0 72 | varr = ((r_1-r_mean) ** 2+(r_2-r_mean) ** 2+(r_3-r_mean) ** 2+(r_4-r_mean) ** 2+(r_5-r_mean) ** 2+(r_6-r_mean) ** 2)/6.0 #Sample variance of monthly returns of each stock 73 | top_smooth = varr.bottom(50) 74 | 75 | #6. Screening filter, if (tradeable) then buy this stock 76 | tradeable = top_smooth 77 | 78 | return Pipeline( 79 | screen=tradeable, 80 | columns={ 81 | 'Tradeable': tradeable 82 | } 83 | ) 84 | def compute_target_weights(context, data): #Computes weights on each stock we are intrested in 85 | # Initialize empty target weights dictionary. 86 | # This will map securities to their target weight. 87 | weights = {} 88 | 89 | #Set weights to (tradeable) stocks to create equally-weighted portfolio 90 | if context.tradeable: 91 | long_weight = 1.0 / len(context.tradeable) 92 | else: 93 | return weights 94 | 95 | # Exit positions in our portfolio if they are not (tradeable) 96 | for security in context.portfolio.positions: 97 | if security not in context.tradeable and data.can_trade(security): 98 | weights[security] = 0 99 | 100 | for security in context.tradeable: 101 | weights[security] = long_weight 102 | 103 | return weights 104 | 105 | def before_trading_start(context, data): 106 | # Gets our pipeline output every day. 107 | pipe_results = pipeline_output('my_pipeline') 108 | 109 | # Go long in (tradeable) stocks 110 | context.tradeable = [] 111 | for sec in pipe_results[pipe_results['Tradeable']].index.tolist(): 112 | if data.can_trade(sec): 113 | context.tradeable.append(sec) 114 | 115 | def my_rebalance(context, data): #Rebalances the portfolio 116 | # Calculate target weights to rebalance 117 | target_weights = compute_target_weights(context, data) 118 | 119 | # If we have target weights, rebalance our portfolio 120 | # Rebalance portfolio in the end of each month except January 121 | today = get_datetime() 122 | if today.month != 1: 123 | if target_weights: 124 | order_optimal_portfolio( 125 | objective=opt.TargetWeights(target_weights), 126 | constraints=[], 127 | ) 128 | 129 | def my_record_vars(context, data): #Tracks number of long positions 130 | longs = 0 131 | for position in context.portfolio.positions.itervalues(): 132 | if position.amount > 0: 133 | longs += 1 134 | 135 | #Record our variables. 136 | record( 137 | long_count=longs 138 | ) -------------------------------------------------------------------------------- /algorithms/FrankPSch/xx R0065 S0.58 DD15 _Algo with Support Vector Machine in Pipeline_.py: -------------------------------------------------------------------------------- 1 | from quantopian.pipeline import Pipeline, CustomFilter, CustomFactor 2 | from quantopian.algorithm import attach_pipeline, pipeline_output 3 | from quantopian.pipeline.factors import Latest 4 | from quantopian.pipeline.data.builtin import USEquityPricing 5 | from quantopian.pipeline.data.psychsignal import aggregated_twitter_withretweets_stocktwits as st 6 | from sklearn.preprocessing import StandardScaler 7 | from quantopian.pipeline.factors import SimpleMovingAverage 8 | from quantopian.pipeline.filters import Q500US 9 | import numpy as np 10 | from sklearn.svm import SVC 11 | from sklearn.naive_bayes import GaussianNB 12 | import pandas as pd 13 | 14 | 15 | class Prediction(CustomFactor): 16 | def compute(self, today, asset_ids, out, bull_msgs, bear_msgs, close_prices, open_prices): 17 | predictions = [] 18 | for i in range(close_prices.shape[1]): 19 | bull_msg = bull_msgs[:, i] 20 | bear_msg = bear_msgs[:, i] 21 | result = (close_prices[:, i] > open_prices[:, i]) * 2 - 1 22 | df = pd.DataFrame(data={'bull':bull_msg.flatten(), 'bear': bear_msg.flatten(), \ 23 | 'result': result.flatten()}) 24 | 25 | # before shifting, we must record the last values as they will be used 26 | # to run the model on for the prediction. 27 | df['bull_ma'] = df['bull'].rolling(window=10).mean() #.shift(1) 28 | df['bear_ma'] = df['bear'].rolling(window=10).mean() #.shift(1) 29 | df['bull_rs'] = df['bull'].rolling(window=5).apply(compute_slope) #.shift(1) 30 | df['bear_rs'] = df['bear'].rolling(window=5).apply(compute_slope) #.shift(1) 31 | 32 | scaler = StandardScaler() 33 | try: 34 | features = ['bull_rs', 'bear_rs'] 35 | X_live = df[features][-1:] 36 | df[features] = df[features].shift(1) 37 | df.dropna(inplace=True) 38 | X_train = scaler.fit_transform(df[features]) 39 | y_train = df['result'] 40 | 41 | model = GaussianNB() 42 | prediction = model.fit(X_train, y_train).predict(scaler.transform(X_live))[0] 43 | 44 | predictions.append(prediction) 45 | except: 46 | predictions.append(1) 47 | 48 | out[:] = predictions 49 | 50 | 51 | def custom_pipeline(context): 52 | sma_10 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=10) 53 | sma_50 = SimpleMovingAverage(inputs = [USEquityPricing.close], window_length=50) 54 | 55 | # for testing only 56 | small_universe = SidInList(sid_list = (24)) 57 | 58 | #changed to be easier to read. 59 | my_screen = (Q500US() & \ 60 | (sma_10 > sma_50) & \ 61 | (st.bull_scored_messages.latest > 10)) 62 | 63 | prediction = Prediction(inputs=[st.bull_scored_messages, st.bear_scored_messages, \ 64 | USEquityPricing.close, USEquityPricing.open],\ 65 | window_length=200, mask=small_universe) 66 | 67 | return Pipeline( 68 | columns={ 69 | 'sma10': sma_10, 70 | 'close': USEquityPricing.close.latest, 71 | 'prediction': prediction 72 | }, 73 | screen=my_screen) 74 | 75 | 76 | def initialize(context): 77 | 78 | #ADDED TO MONITOR LEVERAGE MINUTELY. 79 | context.minLeverage = [0] 80 | context.maxLeverage = [0] 81 | 82 | attach_pipeline(custom_pipeline(context), 'custom_pipeline') 83 | 84 | schedule_function(evaluate, date_rules.every_day(), time_rules.market_open(minutes=1)) 85 | schedule_function(sell, date_rules.every_day(), time_rules.market_open()) 86 | schedule_function(buy, date_rules.every_day(), time_rules.market_open(minutes = 5)) 87 | 88 | context.longs = [] 89 | context.shorts = [] 90 | 91 | set_slippage(slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)) # Default 92 | set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.0)) # FSC for IB 93 | 94 | 95 | def before_trading_start(context, data): 96 | context.results = pipeline_output('custom_pipeline') 97 | 98 | 99 | class SidInList(CustomFilter): 100 | """ 101 | Filter returns True for any SID included in parameter tuple passed at creation. 102 | Usage: my_filter = SidInList(sid_list=(23911, 46631)) 103 | """ 104 | inputs = [] 105 | window_length = 1 106 | params = ('sid_list',) 107 | 108 | def compute(self, today, assets, out, sid_list): 109 | out[:] = np.in1d(assets, sid_list) 110 | 111 | 112 | def compute_slope(a): 113 | x = np.arange(0, len(a)) 114 | y = np.array(a) 115 | A = np.vstack([x, np.ones(len(x))]).T 116 | m, c = np.linalg.lstsq(A, y)[0] 117 | return m 118 | 119 | 120 | def evaluate (context, data): 121 | context.longs = [] 122 | 123 | for sec in context.results.index: 124 | if context.results.loc[sec, 'prediction'] == 1: 125 | print "Here" 126 | if sec not in context.portfolio.positions: 127 | context.longs.append(sec) 128 | 129 | 130 | def sell (context,data): 131 | for sec in context.portfolio.positions: 132 | if sec not in context.longs: 133 | order_target_percent(sec, 0.0) 134 | 135 | 136 | def buy (context,data): 137 | for sec in context.longs: 138 | order_target_percent(sec, 1.0 / (len(context.longs) + len(context.portfolio.positions))) -------------------------------------------------------------------------------- /algorithms/FrankPSch/hivebot _Mean Reversion and Momentum Switching Model_.py: -------------------------------------------------------------------------------- 1 | # Import the libraries we will use here. 2 | from quantopian.algorithm import attach_pipeline, pipeline_output 3 | from quantopian.pipeline import Pipeline, CustomFilter 4 | from quantopian.pipeline.factors import AverageDollarVolume, Returns 5 | from quantopian.pipeline import CustomFactor 6 | from quantopian.pipeline.data.psychsignal import aggregated_twitter_withretweets_stocktwits as psychsignal 7 | 8 | import pandas as pd 9 | import numpy as np 10 | 11 | trading_symbols = (sid(8554), # SPY 12 | sid(2174), # DIA 13 | sid(19920), # QQQ 14 | sid(21519), # IWM 15 | sid(21513), # IVV 16 | sid(21520), # IWV 17 | sid(34385), # VEA 18 | sid(28073), # XBI 19 | sid(19658), # XLK 20 | sid(19661), # XLV 21 | sid(19659), # XLP 22 | sid(19660), # XLU 23 | sid(19655), # XLE 24 | sid(19657), # XLI 25 | sid(22972), # EFA 26 | sid(14522), # EWL 27 | sid(14520), # EWJ 28 | sid(14529), # EWU 29 | sid(27102), # VWO 30 | sid(33655), # HYG 31 | sid(19654), # XLB 32 | sid(19662), # XLY 33 | sid(32275), # XRT 34 | sid(26432), # FEZ 35 | sid(14516), # EWA 36 | sid(14519), # EWH 37 | sid(32270), # SSO 38 | sid(39214), # TQQQ 39 | sid(22739), # VTI 40 | sid(38533), # UPRO 41 | sid(21512), # IVE 42 | sid(26669), # VNQ 43 | sid(21518), # IWF 44 | sid(21507), # IJH 45 | sid(21517), # IWD 46 | sid(25909), # VTV 47 | sid(28364), # VIG 48 | sid(25910), # VUG 49 | sid(21508), # IJR 50 | sid(32620), # PFF 51 | sid(12915), # MDY 52 | sid(25647), # DVY 53 | sid(21516), # IWB 54 | sid(32888), # VYM 55 | sid(25907), # VO 56 | sid(40107), # VOO 57 | sid(21514), # IVW 58 | sid(25899), # VB 59 | sid(22908), # IWR 60 | sid(21786)) # IWO 61 | 62 | anchor_symbol = sid(8554) 63 | 64 | class SidInList(CustomFilter): 65 | inputs = [] 66 | window_length = 1 67 | params = ('sid_list',) 68 | 69 | def compute(self, today, assets, out, sid_list): 70 | out[:] = np.in1d(assets, sid_list) 71 | 72 | def initialize(context): 73 | my_sid_filter = SidInList( 74 | sid_list = (anchor_symbol) 75 | ) 76 | pipe = Pipeline(screen = my_sid_filter) 77 | attach_pipeline(pipe, 'my_pipeline') 78 | 79 | url = 'http://hive.psychsignal.com/public/historical/hivebot/SPY' 80 | fetch_csv(url, 81 | date_column='date', 82 | symbol='spy_sas', 83 | usecols=['SAS'], 84 | date_format='%Y-%m-%d') 85 | 86 | schedule_function(rebalance, 87 | date_rules.every_day(),#(days_offset=1), 88 | time_rules.market_open(hours=0, minutes=30)) 89 | 90 | def handle_data(context, data): 91 | context.SAS = data.current('spy_sas','SAS') 92 | 93 | def my_pipeline(context): 94 | my_sid_filter = SidInList( 95 | sid_list = (anchor_symbol) 96 | ) 97 | 98 | pipe = Pipeline( 99 | columns = {}, 100 | screen = my_sid_filter, 101 | ) 102 | 103 | return pipe 104 | 105 | 106 | def before_trading_start(context, data): 107 | record(leverage_ratio=context.account.leverage) 108 | context.output = pipeline_output('my_pipeline') 109 | 110 | def rebalance(context,data): 111 | sas_thresh = 0.66 112 | sas = context.SAS 113 | bull_weight = 1.0 / len(trading_symbols) 114 | bear_weight = -0.8 / len(trading_symbols) 115 | momo_thresh = 0. 116 | revs_thresh = 0. 117 | price_history = data.history(anchor_symbol, "price", 40, "1d") 118 | momo1 = (price_history.ix[-1] - price_history.ix[0]) / price_history.ix[0] 119 | momo2 = (price_history.ix[-1] - price_history.ix[-2]) / price_history.ix[-2] 120 | for trading_symbol in trading_symbols: 121 | #price_history = data.history(trading_symbol, "price", 40, "1d") 122 | #momo1 = (price_history.ix[-1] - price_history.ix[0]) / price_history.ix[0] 123 | #momo2 = (price_history.ix[-1] - price_history.ix[-2]) / price_history.ix[-2] 124 | pos_weight1 = 0 125 | pos_weight2 = 0 126 | if sas > sas_thresh: 127 | # momo mode 128 | # check if momo1 or momo2 is triggered 129 | if momo1 > momo_thresh: 130 | pos_weight1 = bull_weight 131 | elif momo1 < -momo_thresh: 132 | pos_weight1 = bear_weight 133 | if momo2 > momo_thresh: 134 | pos_weight2 = bull_weight 135 | elif momo2 < -momo_thresh: 136 | pos_weight2 = bear_weight 137 | else: 138 | # mean reversion mode 139 | # chick if momo1 is triggered 140 | if momo1 > revs_thresh: 141 | pos_weight1 = 2. * bear_weight 142 | elif momo1 < -revs_thresh: 143 | pos_weight1 = 2. * bull_weight 144 | 145 | pos_weight = pos_weight1 + pos_weight2 146 | order_target_percent(trading_symbol, pos_weight) 147 | 148 | del price_history 149 | del momo1 150 | del momo2 151 | del sas -------------------------------------------------------------------------------- /algorithms/FrankPSch/xxx R639 S0.65 DD80 _Trading strategy_.py: -------------------------------------------------------------------------------- 1 | from quantopian.algorithm import attach_pipeline, pipeline_output 2 | from quantopian.pipeline import Pipeline 3 | from quantopian.pipeline.data.builtin import USEquityPricing 4 | from quantopian.pipeline.data import morningstar 5 | from quantopian.pipeline.factors import CustomFactor, Returns 6 | from quantopian.pipeline.filters import Q1500US 7 | from quantopian.pipeline.filters import Q500US 8 | import pandas as pd 9 | import numpy as np 10 | class Volatility(CustomFactor): 11 | #оцениваем волатильность на основании данных прошлого года 12 | inputs = [USEquityPricing.close] 13 | window_length = 252 14 | 15 | def compute(self, today, assets, out, close): 16 | close = pd.DataFrame(data=close, columns=assets) 17 | # берем логарифм цены, разность между этими логарфмами и считаем ст.отклон. 18 | out[:] = np.log(close).diff().std() 19 | class MarketCap(CustomFactor): 20 | #рыночная капитализация - количество акций на их цену 21 | inputs = [morningstar.valuation.shares_outstanding, USEquityPricing.close] 22 | window_length = 1 23 | 24 | def compute(self, today, assets, out, shares, close_price): 25 | out[:] = shares * close_price 26 | 27 | class BookToPrice(CustomFactor): 28 | #берем b/p как 1/(p/b) 29 | inputs = [morningstar.valuation_ratios.pb_ratio] 30 | window_length = 1 31 | 32 | def compute(self, today, assets, out, pb): 33 | out[:] = 1 / pb 34 | class Quality(CustomFactor): 35 | #return on equity 36 | inputs = [morningstar.operation_ratios.roe] 37 | window_length = 1 38 | 39 | def compute(self, today, assets, out, roe): 40 | out[:] = roe[-1] 41 | def make_pipeline(context): 42 | 43 | pipe = Pipeline() 44 | # Q1500US - вселенная из 1500 самых ликвидных активов 45 | universe = Q1500US() 46 | market_cap = MarketCap(mask=universe) 47 | market_cap_rank = market_cap.rank() 48 | # берем половину активов с большой капитализацией 49 | market_cap_high = market_cap_rank.top(750) 50 | volatility=Volatility(mask=market_cap_high) 51 | volatility_rank=volatility.rank() 52 | # оставляем 1/3 наименее волатильных 53 | volatility_low=volatility_rank.bottom(250) 54 | quality=Quality(mask=volatility_low) 55 | quality_rank=quality.rank() 56 | # 100 самых целесообразных в плане бизнеса 57 | qualit=quality_rank.top(120) # was 100 58 | book_to_price = BookToPrice(mask=qualit) 59 | book_to_price_rank = book_to_price.rank() 60 | # 50 недооцененных в низким b/p 61 | highbp = book_to_price_rank.top(110) # was 50 62 | securities_to_trade = ( highbp) 63 | pipe = Pipeline( 64 | columns={ 65 | 'highbp':highbp, 66 | }, 67 | screen = securities_to_trade 68 | ) 69 | 70 | 71 | return pipe 72 | 73 | def initialize(context): 74 | 75 | # будем ребалансировать наш портфель каждый январь в начале, через 1.5 часа после открытия 76 | 77 | attach_pipeline(make_pipeline(context), 'my_pipeline') 78 | schedule_function(rebalance, 79 | date_rules.month_start(days_offset=0), 80 | time_rules.market_open(hours=1, minutes=30)) 81 | 82 | def before_trading_start(context, data): 83 | # включаем все отобранные активы в наш портфель 84 | context.output = pipeline_output('my_pipeline') 85 | 86 | context.highbp = context.output[context.output['highbp']] 87 | 88 | context.security_list = context.highbp.index.tolist() 89 | 90 | 91 | def rebalance(context,data): 92 | # у нас будет равно-взвешенный портфель 93 | today = get_datetime('US/Eastern') 94 | if (today.month==1) or (today.month==4) or (today.month==7) or (today.month==10): 95 | # print context.security_list 96 | for security in context.security_list: 97 | if data.can_trade(security): 98 | order_target_percent(security, 0.02) 99 | 100 | # @KSENIA: your algo will not sell assets that are not in the target list anymore. 101 | # As US1500 is an unstable universe you need something like this in the rebalance function 102 | for security in context.portfolio.positions: 103 | if security not in context.security_list: 104 | order_target_percent(security, 0.0) 105 | 106 | record(leverage = context.account.leverage) 107 | 108 | """ 109 | Mods (Guy Fleury) 18/12/17: 110 | Increased stake to $10 million 111 | 112 | Total Returns 602.47% 113 | Benchmark Returns 176.22% 114 | Alpha 0.09 115 | Beta 1.30 116 | Sharpe 1.28 117 | Sortino 1.86 118 | Volatility 0.21 119 | Max Drawdown -19.83% 120 | Total Profit: $60.2 million. 121 | 122 | Mods: 123 | Increased tradable candidates 124 | Set rebalance twice a year. 125 | 126 | Total Returns 1573.34% 127 | Benchmark Returns 176.22% 128 | Alpha 0.12 129 | Beta 2.11 130 | Sharpe 1.25 131 | Sortino 1.81 132 | Volatility 0.33 133 | Max Drawdown -36.93% 134 | Total Profit: $157 million 135 | 136 | Mods: 137 | Set rebalance to three times a year. 138 | 139 | Total Returns 2191.37% 140 | Benchmark Returns 176.22% 141 | Alpha 0.13 142 | Beta 2.39 143 | Sharpe 1.26 144 | Sortino 1.83 145 | Volatility 0.37 146 | Max Drawdown -40.33% 147 | Total Profit: $219.1 million 148 | added: $61.8 million just for rebalancing 3x a year. 149 | 150 | Mods: 151 | Set rebalance to four times a year. 152 | Increased tradable candidates 153 | 154 | Total Returns 3809.66% 155 | Benchmark Returns 176.22% 156 | Alpha 0.16 157 | Beta 2.95 158 | Sharpe 1.24 159 | Sortino 1.82 160 | Volatility 0.46 161 | Max Drawdown -50.96% 162 | Total Profit: $380.9 million 163 | added: $161.8 million to previous scenario 164 | 165 | Mods: 166 | Set initial stake to $50 million 167 | Increased tradable candidates 168 | 169 | Total Returns 2861.72% 170 | Benchmark Returns 176.22% 171 | Alpha 0.13 172 | Beta 2.84 173 | Sharpe 1.20 174 | Sortino 1.75 175 | Volatility 0.44 176 | Max Drawdown -51.26% 177 | Total Profit: $1,430,862,069 178 | 179 | """ --------------------------------------------------------------------------------