def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, use_adj=False) # Add technical indicator: 200 day sma sma200 = SMA(self._ts, timeperiod=200) self._ts['sma200'] = sma200 # Add technical indicator: X day high, and X day low period_high = pd.Series(self._ts.close).rolling(self._period).max() period_low = pd.Series(self._ts.close).rolling(self._period).min() self._ts['period_high'] = period_high self._ts['period_low'] = period_low self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() # add S&P500 200 sma sp500 = pf.fetch_timeseries('^GSPC') sp500 = pf.select_tradeperiod(sp500, self._start, self._end, False) self._ts['sp500_close'] = sp500['close'] sp500_sma = SMA(sp500, timeperiod=200) self._ts['sp500_sma'] = sp500_sma self._algo()
def fetch_timeseries(self, symbols, start, end, fields=['high', 'low', 'close'], use_cache=True): """ read time series data for symbols """ for i, symbol in enumerate(symbols): if i == 0: ts = pf.fetch_timeseries(symbol, use_cache=use_cache) ts = pf.select_tradeperiod(ts, start, end, use_adj=True) self._add_symbol_columns(ts, symbol, ts, fields) ts.drop(columns=[ 'high', 'low', 'open', 'close', 'volume', 'adj_close' ], inplace=True) else: # add another symbol _ts = pf.fetch_timeseries(symbol, use_cache=use_cache) _ts = pf.select_tradeperiod(_ts, start, end, use_adj=True) self._add_symbol_columns(ts, symbol, _ts, fields) self.symbols = symbols return ts
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end) self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() self._algo()
def test_cache_dir_created(self): """ Check that a cache directory has been created. """ df = pf.fetch_timeseries(self.symbol, dir_name=self.dir_name, from_year=self.from_year) file_path = os.path.join(self.dir_name, self.symbol + ".csv") self.assertTrue(os.path.isfile(file_path))
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, use_adj=True) # Add technical indicator: 200 day sma sma200 = SMA(self._ts, timeperiod=200) self._ts['sma200'] = sma200 # Add technical indicator: X day sma sma = SMA(self._ts, timeperiod=self._sma) self._ts['sma'] = sma # Add technical indicator: X day high, and X day low period_high = pd.Series(self._ts.close).rolling(self._period).max() period_low = pd.Series(self._ts.close).rolling(self._period).min() self._ts['period_high'] = period_high self._ts['period_low'] = period_low self._ts, self._start = pf.finalize_timeseries(self._ts, self._start) self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() self._algo()
def run(self): self.ts = pf.fetch_timeseries(self.symbol) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, use_adj=True) # Add technical indicator: 200 sma regime filter self.ts['regime'] = \ pf.CROSSOVER(self.ts, timeperiod_fast=1, timeperiod_slow=200) # Add technical indicator: instrument risk, i.e. annual std self.ts['vola'] = \ pf.VOLATILITY(self.ts, lookback=20, time_frame='yearly') # Add technical indicator: X day sma sma = SMA(self.ts, timeperiod=self.sma) self.ts['sma'] = sma # Add technical indicator: X day high, and X day low period_high = pd.Series(self.ts.close).rolling(self.period).max() period_low = pd.Series(self.ts.close).rolling(self.period).min() self.ts['period_high'] = period_high self.ts['period_low'] = period_low self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo()
def run(self): # Fetch and select timeseries. self.ts = pf.fetch_timeseries(self.symbol, use_cache=self.options['use_cache']) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, use_adj=self.options['use_adj']) # Add technical indicator: 200 day sma regime filter. self.ts['regime'] = pf.CROSSOVER(self.ts, timeperiod_fast=1, timeperiod_slow=200) # Add technical indicators: X day high, and X day low. self.ts['period_high'] = pd.Series(self.ts.close).rolling( self.options['period']).max() self.ts['period_low'] = pd.Series(self.ts.close).rolling( self.options['period']).min() # Finalize timeseries. self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) # Create tlog and dbal objects. self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() # Run algo, get logs, and get stats. self._algo() self._get_logs() self._get_stats()
def run(self): self.ts = pf.fetch_timeseries(self.symbol, use_cache=self.options['use_cache']) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, self.options['use_adj']) # Add calendar columns self.ts = pf.calendar(self.ts) # Add momentum indicator for 3...18 months lookbacks = range(3, 18 + 1) for lookback in lookbacks: self.ts['mom' + str(lookback)] = pf.MOMENTUM(self.ts, lookback=lookback, time_frame='monthly', price='close', prevday=False) self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo() self._get_logs() self._get_stats()
def fetch_timeseries(self, symbols, start, end, fields=['open', 'high', 'low', 'close'], use_cache=True): """ Read time series data for symbols. Parameters ---------- symbols : list The list of symbols to fetch timeseries. start : datetime.datetime The desired start date for the strategy. end : datetime.datetime The desired end date for the strategy. fields : list, optional The list of fields to use for each symbol (default is ['open', 'high', 'low', 'close']). use_cache: bool, optional True to use data cache. False to retrieve from the internet (default is True). Returns ------- pd.DataFrame The timeseries of the symbols. """ for i, symbol in enumerate(symbols): if i == 0: ts = pf.fetch_timeseries(symbol, use_cache=use_cache) ts = pf.select_tradeperiod(ts, start, end, use_adj=True) self._add_symbol_columns(ts, symbol, ts, fields) ts.drop(columns=[ 'open', 'high', 'low', 'close', 'volume', 'adj_close' ], inplace=True) else: # Add another symbol. _ts = pf.fetch_timeseries(symbol, use_cache=use_cache) _ts = pf.select_tradeperiod(_ts, start, end, use_adj=True) self._add_symbol_columns(ts, symbol, _ts, fields) self.symbols = symbols return ts
def get_symbol_metadata(symbols=None, dir_name='data', from_year=None): """ Get symbol metadata for list of symbols. Filter out any filename prefixed with '__'. Parameters ---------- symbols : str or list, optional The symbol(s) for which to remove cached timeseries (default is None, which imples remove timeseries for all symbols). dir_name : str, optional The leaf data dir name (default is 'data). from_year: int, optional The start year for timeseries retrieval (default is None, which implies that all the available data is retrieved). Returns ------- pd.DataFrame Each row contains metadata for a symbol. """ cache_dir = _get_cache_dir(dir_name) if symbols: # If symbols is not a list, cast it to a list. if not isinstance(symbols, list): symbols = [symbols] else: filenames = ([ f for f in os.listdir(cache_dir) if f.endswith('.csv') and not f.startswith('__') ]) symbols = [os.path.splitext(filename)[0] for filename in filenames] # Make symbol names uppercase. symbols = [symbol.upper() for symbol in symbols] l = [] for i, symbol in enumerate(symbols): try: ts = pf.fetch_timeseries(symbol, dir_name=dir_name, use_cache=True, from_year=from_year) start = ts.index[0].to_pydatetime() end = ts.index[-1].to_pydatetime() num_years = _difference_in_years(start, end) start = start.strftime('%Y-%m-%d') end = end.strftime('%Y-%m-%d') t = (symbol, start, end, num_years) l.append(t) except RemoteDataError as e: print('\n({})'.format(e)) except Exception as e: print('\n({})'.format(e)) columns = ['symbol', 'start_date', 'end_date', 'num_years'] df = pd.DataFrame(l, columns=columns) return df
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, True, False) self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() self._algo()
def test_fetch_with_adj_prices(self, mocker): ''' Check that the _adj_prices method gets called. ''' ts = pf.fetch_timeseries(self.symbol, dir_name=self.dir_name) start = datetime.datetime(2000, 6, 30) end = datetime.datetime(2000, 12, 29) ts = pf.select_tradeperiod(ts, start, end, use_adj=True) mocker.assert_called_once()
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, self._use_adj) # Add technical indicator: day sma sma = SMA(self._ts, timeperiod=self._sma_period) self._ts['sma'] = sma self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() # add S&P500 200 sma regime filter ts = pf.fetch_timeseries('^GSPC') ts = pf.select_tradeperiod(ts, self._start, self._end, False) self._ts['regime'] = \ pf.CROSSOVER(ts, timeperiod_fast=1, timeperiod_slow=200) self._algo()
def test_fetch_with_config(self, *args): ''' Check the data fetch where we have a config file. ''' file_path = os.path.join(self.dir_path, "test_data", self.symbol + ".csv") if os.path.isfile(file_path): os.remove(file_path) df = pf.fetch_timeseries(self.symbol, dir_name="test_data") file_exists = os.path.isfile(file_path) self.assertTrue(file_exists)
def run(self): self.ts = pf.fetch_timeseries(self.symbol) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, use_adj=self.use_adj) self.ts, _ = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo()
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, self._use_adj) # Add technical indicator: day sma sma = SMA(self._ts, timeperiod=self._sma_period) self._ts['sma'] = sma self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() # add S&P500 200 sma sp500 = pf.fetch_timeseries('^GSPC') sp500 = pf.select_tradeperiod(sp500, self._start, self._end, False) self._ts['sp500_close'] = sp500['close'] sp500_sma = SMA(sp500, timeperiod=200) self._ts['sp500_sma'] = sp500_sma self._algo()
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, use_adj=False) # Add technical indicator: day sma sma = SMA(self._ts, timeperiod=self._sma_period) self._ts['sma'] = sma self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() self._algo()
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, use_adj=self._use_adj, pad=False) self._ts, _ = pf.finalize_timeseries(self._ts, self._start) self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() self._algo()
def run(self): self.ts = pf.fetch_timeseries(self.symbol, use_cache=self.options['use_cache']) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, self.options['use_adj']) # Add technical indicator: day sma self.ts['sma'] = SMA(self.ts, timeperiod=self.options['sma_period']) # add S&P500 200 sma regime filter ts = pf.fetch_timeseries('^GSPC') ts = pf.select_tradeperiod(ts, self.start, self.end, use_adj=False) self.ts['regime'] = \ pf.CROSSOVER(ts, timeperiod_fast=1, timeperiod_slow=200) self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo() self._get_logs() self._get_stats()
def test_select_tradeperiod_without_pad(self): """ Check the time period selection when pad=False. """ start = datetime.datetime(2000, 6, 30) end = datetime.datetime(2000, 12, 29) ts = pf.fetch_timeseries(self.symbol, dir_name=self.dir_name, from_year=self.from_year) ts = pf.select_tradeperiod(ts, start, end, pad=False) dates = sorted(ts.index.values.tolist()) ts_start_date = pd.Timestamp(dates[0]).to_pydatetime() self.assertTrue(start == ts_start_date) ts_end_date = pd.Timestamp(dates[-1]).to_pydatetime() self.assertTrue(end == ts_end_date)
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, use_adj=False) # Add technical indicator: X day high period_high = pd.rolling_max(self._ts.high, self._period) self._ts['period_high'] = period_high self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() self._algo()
def run(self): self.ts = pf.fetch_timeseries(self.symbol) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, self.use_adj) # Add technical indicator: day sma regime filter self.ts['regime'] = \ pf.CROSSOVER(self.ts, timeperiod_fast=1, timeperiod_slow=self.sma_period, band=self.percent_band) self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo()
def test_select_tradeperiod(self): """ Check the correct period is selected. """ start = datetime.datetime(2000, 6, 30) end = datetime.datetime(2000, 12, 29) ts = pf.fetch_timeseries(self.symbol, dir_name=self.dir_name, from_year=self.from_year) ts = pf.select_tradeperiod(ts, start, end) dates = sorted(ts.index.values.tolist()) ts_start_date = pd.Timestamp(dates[0]).to_pydatetime() start -= datetime.timedelta(365) # back dating by one year self.assertTrue(start == ts_start_date) ts_end_date = pd.Timestamp(dates[-1]).to_pydatetime() self.assertTrue(end == ts_end_date)
def run(self): self.ts = pf.fetch_timeseries(self.symbol) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end) # add regime filter self.ts['regime'] = \ pf.CROSSOVER(self.ts, timeperiod_fast=self.timeperiod_fast, timeperiod_slow=self.timeperiod_slow, band=self.percent_band) self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo()
def get_symbol_metadata(symbols=None, dir_name='data', from_year=None): """ Get symbol metadata for list of symbols. If symbols is None, get do for all timeseries. Filter out any filename prefixed with '__' """ cache_dir = _get_cache_dir(dir_name) if symbols: # in case user forgot to put single symbol in list if not isinstance(symbols, list): symbols = [symbols] else: filenames = ([ f for f in os.listdir(cache_dir) if f.endswith('.csv') and not f.startswith('__') ]) symbols = [os.path.splitext(filename)[0] for filename in filenames] # make symbol names uppercase symbols = [symbol.upper() for symbol in symbols] l = [] for i, symbol in enumerate(symbols): try: ts = pf.fetch_timeseries(symbol, dir_name=dir_name, use_cache=True, from_year=from_year) start = ts.index[0].to_pydatetime() end = ts.index[-1].to_pydatetime() num_years = _difference_in_years(start, end) start = start.strftime('%Y-%m-%d') end = end.strftime('%Y-%m-%d') t = (symbol, start, end, num_years) l.append(t) except RemoteDataError as e: print('\n({})'.format(e)) except Exception as e: print('\n({})'.format(e)) columns = ['symbol', 'start_date', 'end_date', 'num_years'] df = pd.DataFrame(l, columns=columns) return df
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, use_adj=False) # Add technical indicator: 200 day sma sma200 = SMA(self._ts, timeperiod=200) self._ts['sma200'] = sma200 # Add technical indicator: X day high, and X day low period_high = pd.Series(self._ts.high).rolling(self._period).max() period_low = pd.Series(self._ts.high).rolling(self._period).min() self._ts['period_high'] = period_high self._ts['period_low'] = period_low self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() self._algo()
def run(self): self.portfolio = pf.Portfolio() self.ts = self.portfolio.fetch_timeseries( self.symbols, self.start, self.end, use_cache=self.options['use_cache'], use_adj=self.options['use_adj']) # Add S&P500 200 sma regime filter ts = pf.fetch_timeseries('^GSPC') ts = pf.select_tradeperiod(ts, self.start, self.end, use_adj=False) self.ts['regime'] = \ pf.CROSSOVER(ts, timeperiod_fast=1, timeperiod_slow=200, band=3.5) # Add calendar columns self.ts = self.portfolio.calendar(self.ts) # Add technical indicator Momenteum for all symbols in portfolio. def _momentum(ts, ta_param, input_column): return pf.MOMENTUM(ts, lookback=ta_param, time_frame='monthly', price=input_column, prevday=False) lookbacks = range(3, 18 + 1) for lookback in lookbacks: self.ts = self.portfolio.add_technical_indicator( self.ts, ta_func=_momentum, ta_param=lookback, output_column_suffix='mom' + str(lookback), input_column_suffix='close') self.ts, self.start = self.portfolio.finalize_timeseries( self.ts, self.start) self.portfolio.init_trade_logs(self.ts) self._algo() self._get_logs() self._get_stats()
def run(self): self.ts = pf.fetch_timeseries(self.symbol) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end) # add regime filter self.ts['regime'] = \ pf.CROSSOVER(self.ts, timeperiod_fast=self.timeperiod_fast, timeperiod_slow=self.timeperiod_slow, band=self.percent_band) # Add technical indicator: volatility self.ts['vola'] = pf.VOLATILITY(self.ts) self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo()
def run(self): # Fetch and selct timeseries self.ts = pf.fetch_timeseries(self.symbol, use_cache=self.options['use_cache']) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, self.options['use_adj']) # Add technical indicator: day sma regime filter. self.ts['regime'] = \ pf.CROSSOVER(self.ts, timeperiod_fast=50, timeperiod_slow=200) # Finalize timeseries self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo() self._get_logs() self._get_stats()
def run(self): self._ts = pf.fetch_timeseries(self._symbol) self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, use_adj=False) # Add technical indicator: 200 day sma sma200 = SMA(self._ts, timeperiod=200) self._ts['sma200'] = sma200 # Add technical indicator: X day high, and X day low period_high = pd.rolling_max(self._ts.high, self._period) period_low = pd.rolling_min(self._ts.low, self._period) self._ts['period_high'] = period_high self._ts['period_low'] = period_low self._tlog = pf.TradeLog() self._dbal = pf.DailyBal() self._algo()
def run(self): """ Run the backtest. Don't adjust the start day because that may cause it not to match the start date of the strategy you are benchmarking against. Instead, you should pass in the start date calculated for the strategy. """ self.ts = pf.fetch_timeseries(self.symbol) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, use_adj=self.use_adj) self.ts, _ = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo() self._get_logs() self._get_stats()
def run(self): self.ts = pf.fetch_timeseries(self.symbol) self.ts = pf.select_tradeperiod(self.ts, self.start, self.end, use_adj=False) # Add technical indicator: 200 sma regime filter self.ts['regime'] = \ pf.CROSSOVER(self.ts, timeperiod_fast=1, timeperiod_slow=200) # Add technical indicator: X day high, and X day low period_high = pd.Series(self.ts.close).rolling(self.period).max() period_low = pd.Series(self.ts.close).rolling(self.period).min() self.ts['period_high'] = period_high self.ts['period_low'] = period_low self.ts, self.start = pf.finalize_timeseries(self.ts, self.start) self.tlog = pf.TradeLog(self.symbol) self.dbal = pf.DailyBal() self._algo()