def generate_price_feed(instrument: str, start: datetime = None, end: datetime = None, persist_dir: str = 'c:/temp'): start = start or datetime(2005, 1, 1) # earliest date support by Oanda end = end or datetime.today() - timedelta(days=1) pd_h1 = read_price_df(instrument=instrument, granularity='H1', start=start, end=end) pd_d = read_price_df(instrument=instrument, granularity='D', start=start, end=end) pd_h1[['macd', 'signal']] = TA.MACD(pd_h1) pd_h1['ema_200'] = TA.EMA(pd_h1, period=200) pd_h1['atr'] = TA.ATR(pd_h1) pd_h1['rsi'] = TA.RSI(pd_h1) pd_d['atr'] = TA.ATR(pd_d) pd_d['rsi'] = TA.RSI(pd_d) pd_h1.reset_index(level=0, inplace=True) pd_h1 = pd_h1.apply(partial(_enrich, pd_d), axis=1).set_index('time') print(pd_h1) pd_h1.to_csv(f'{persist_dir}/{instrument.lower()}_macd.csv')
def output_feeds(instrument: str, st: datetime, et: datetime, short_win: int, long_win: int, ema_period: int, save_dir: str) -> pd.DataFrame: """ Output ohlc price feeds to csv for strategy back testing :param instrument: ccy_pair :param st: start date :param et: end date :param short_win: :param long_win: :param ema_period: :param save_dir: :return: """ pd_h1 = read_price_df(instrument=instrument, granularity='H1', start=st, end=et) pd_h1[f'last_{long_win}_high'] = pd_h1['high'].rolling(window=long_win * 24).max() pd_h1[f'last_{short_win}_high'] = pd_h1['high'].rolling(window=short_win * 24).max() pd_h1[f'last_{long_win}_low'] = pd_h1['low'].rolling(window=long_win * 24).min() pd_h1[f'last_{short_win}_low'] = pd_h1['low'].rolling(window=short_win * 24).min() pd_h1.to_csv(f'{save_dir}/{instrument.lower()}_h1.csv') pd_d = read_price_df(instrument=instrument, granularity='D', start=st, end=et) pd_d[f'last_{long_win}_high'] = pd_d['high'].rolling(window=long_win).max() pd_d[f'last_{short_win}_high'] = pd_d['high'].rolling( window=short_win).max() pd_d[f'last_{long_win}_low'] = pd_d['low'].rolling(window=long_win).min() pd_d[f'last_{short_win}_low'] = pd_d['low'].rolling(window=short_win).min() pd_d['atr'] = TA.ATR(pd_d, period=14) pd_d['adx'] = TA.ADX(pd_d, period=14) pd_d['rsi'] = TA.RSI(pd_d, period=14) pd_d[f'ema_{ema_period}'] = TA.EMA(pd_d, period=ema_period) pd_d.to_csv(f'{save_dir}/{instrument.lower()}_d.csv') pd_h1.reset_index(level=0, inplace=True) pd_merged = pd_h1.apply(partial(enrich, pd_d, ema_period), axis=1).set_index('time') logger.info(pd_merged.info()) pd_merged.to_csv(f"{save_dir}/{instrument.lower()}_h1_enrich.csv") logger.info(f'output feeds complete for [{instrument}]!') return pd_merged
def generate_signals(): df = read_price_df(instrument='GBP_USD', granularity='D', start=start_date, end=last_date) df['long_short'] = 0 df['short_mavg'] = df['close'].rolling(window=short_window, min_periods=1, center=False).mean() df['long_mavg'] = df['close'].rolling(window=long_window, min_periods=1, center=False).mean() df['long_short'][short_window:] = np.where(df['short_mavg'][short_window:] >= df['long_mavg'][short_window:], 1, 0) df['signal'] = df['long_short'].diff() print(df[['open', 'close', 'short_mavg', 'long_mavg', 'signal', 'long_short']]) df.to_csv(r'C:\temp\prices.csv') return df
def sample_data(instrument: str, start: datetime, end: datetime, short_window: int = 100, long_window: int = 350) -> pd.DataFrame: price_feed = read_price_df(instrument=instrument, granularity='D', start=start, end=end) price_feed[f'smma_{short_window}'] = TA.SMMA(price_feed, period=short_window, adjust=False) price_feed[f'smma_{long_window}'] = TA.SMMA(price_feed, period=long_window, adjust=False) price_feed['atr'] = TA.ATR(price_feed[['high', 'low', 'close']]) price_feed['signal'] = price_feed.apply(partial(signal, short_window, long_window), axis=1) return price_feed
def output_feeds(instrument: str, short_win: int, long_win: int, ema_period: int, save_dir: str, st: datetime, et: datetime = None) -> pd.DataFrame: """ Output daily ohlc price feeds to csv :param instrument: ccy_pair :param st: start date :param et: end date :param short_win: :param long_win: :param ema_period: :param save_dir: :return: """ pd_d = read_price_df(instrument=instrument, granularity='D', start=st, end=et) pd_d[f'last_{long_win}_high'] = pd_d['high'].rolling(window=long_win).max() pd_d[f'last_{short_win}_high'] = pd_d['high'].rolling( window=short_win).max() pd_d[f'last_{long_win}_low'] = pd_d['low'].rolling(window=long_win).min() pd_d[f'last_{short_win}_low'] = pd_d['low'].rolling(window=short_win).min() pd_d['atr'] = TA.ATR(pd_d, period=14) pd_d['adx'] = TA.ADX(pd_d, period=14) pd_d['rsi'] = TA.RSI(pd_d, period=14) pd_d[f'ema_{ema_period}'] = TA.EMA(pd_d, period=ema_period) pd_d.to_csv(f'{save_dir}/{instrument.lower()}_d.csv') logger.info(f'output feeds complete for [{instrument}]!') return pd_d
if ohlc['high'] > order.entry: # buy order filled order.fill(time) elif order.is_short: if ohlc['low'] < order.entry: # sell order filled order.fill(time) logging.info(f'{len(orders)} orders created.') return orders if __name__ == "__main__": from_date = datetime(2010, 1, 1) last_date = datetime(2020, 3, 31) logging.info(f'Reading date between {from_date} and {last_date}') ohlc = read_price_df(instrument='GBP_USD', granularity='H1', start=from_date, end=last_date) ohlc['last_8_high'] = ohlc['high'].rolling(8).max() ohlc['last_8_low'] = ohlc['low'].rolling(8).min() ohlc['diff_pips'] = (ohlc['last_8_high'] - ohlc['last_8_low']) * 10000 ohlc['returns'] = np.log(ohlc['close'] / ohlc['close'].shift(1)) logging.info(ohlc[['open', 'high', 'low', 'close', 'last_8_high', 'last_8_low', 'diff_pips', 'returns']]) back_tester = BackTester(strategy='London Breakout') dfs = [] for adj in (0, 5, 10,): orders = create_orders(ohlc, adj=adj / 10000) dfs.append(back_tester.run(ohlc, orders, print_stats=True, suffix=f'_{adj}')) for period in (14, 28, 50): ohlc['ema'] = wma(ohlc['close'], period)
import numpy as np from matplotlib import pyplot as plt from src.common import read_price_df # we formalize the momentum strategy by telling Python to take the mean log return over the # last 15, 30, 60, and 120 minute bars to derive the position in the instrument. # For example, # the mean log return for the last 15 minute bars gives the average value of the last 15 return observations. # 1. If this value is positive, we go/stay long the traded instrument; # 2. if it is negative we go/stay short. if __name__ == '__main__': from_dt = datetime(2015, 1, 1) end_dt = datetime(2020, 3, 31) df = read_price_df(instrument='GBP_USD', granularity='D', start=from_dt, end=end_dt) print(df) df['returns'] = np.log(df['close'] / df['close'].shift(1)) cols = [] for momentum in [15, 30, 60, 120]: col = 'position_%s' % momentum df[col] = np.sign(df['returns'].rolling(momentum).mean()) cols.append(col) strats = ['returns'] for col in cols: strat = 'strategy_%s' % col.split('_')[1]