def test_add_bars_adds_to_engine(self, capsys): # Arrange engine = BacktestEngine() bar_spec = BarSpecification( step=1, aggregation=BarAggregation.MINUTE, price_type=PriceType.BID, ) bar_type = BarType( instrument_id=USDJPY_SIM.id, bar_spec=bar_spec, aggregation_source=AggregationSource.EXTERNAL, # <-- important ) wrangler = BarDataWrangler( bar_type=bar_type, instrument=USDJPY_SIM, ) provider = TestDataProvider() bars = wrangler.process( provider.read_csv_bars("fxcm-usdjpy-m1-bid-2013.csv")[:2000]) # Act engine.add_instrument(USDJPY_SIM) engine.add_bars(data=bars) # Assert log = "".join(capsys.readouterr()) assert "Added USD/JPY.SIM Instrument." in log assert "Added 2,000 USD/JPY.SIM-1-MINUTE-BID-EXTERNAL Bar elements." in log
def setup(self): # Fixture Setup instrument = TestInstrumentProvider.adabtc_binance() bar_type = TestDataStubs.bartype_adabtc_binance_1min_last() self.wrangler = BarDataWrangler( bar_type=bar_type, instrument=instrument, )
def setup(self): # Fixture Setup instrument = TestInstrumentProvider.default_fx_ccy("GBP/USD") bar_type = TestDataStubs.bartype_gbpusd_1min_bid() self.wrangler = BarDataWrangler( bar_type=bar_type, instrument=instrument, )
def test_csv_reader_dataframe_separator(self): bar_type = TestDataStubs.bartype_adabtc_binance_1min_last() instrument = TestInstrumentProvider.adabtc_binance() wrangler = BarDataWrangler(bar_type, instrument) def parser(data): data["timestamp"] = data["timestamp"].astype("datetime64[ms]") bars = wrangler.process(data.set_index("timestamp")) return bars binance_spot_header = [ "timestamp", "open", "high", "low", "close", "volume", "ts_close", "quote_volume", "n_trades", "taker_buy_base_volume", "taker_buy_quote_volume", "ignore", ] reader = CSVReader(block_parser=parser, header=binance_spot_header, separator="|") in_ = process_files( glob_path=f"{TEST_DATA_DIR}/ADABTC_pipe_separated-1m-2021-11-*.csv", reader=reader, catalog=self.catalog, ) assert sum(in_.values()) == 10
class TestBarDataWrangler: def setup(self): # Fixture Setup instrument = TestInstrumentProvider.default_fx_ccy("GBP/USD") bar_type = TestDataStubs.bartype_gbpusd_1min_bid() self.wrangler = BarDataWrangler( bar_type=bar_type, instrument=instrument, ) def test_process(self): # Arrange, Act provider = TestDataProvider() bars = self.wrangler.process( provider.read_csv_bars("fxcm-gbpusd-m1-bid-2012.csv")[:1000]) # Assert assert len(bars) == 1000 assert bars[0].open == Price.from_str("1.57597") assert bars[0].high == Price.from_str("1.57606") assert bars[0].low == Price.from_str("1.57576") assert bars[0].close == Price.from_str("1.57576") assert bars[0].volume == Quantity.from_int(1000000) assert bars[0].ts_event == 1328054400000000000 assert bars[0].ts_init == 1328054400000000000 def test_process_with_default_volume_and_delta(self): # Arrange, Act provider = TestDataProvider() bars = self.wrangler.process( data=provider.read_csv_bars("fxcm-gbpusd-m1-bid-2012.csv")[:1000], default_volume=10, ts_init_delta=1_000_500, ) # Assert assert len(bars) == 1000 assert bars[0].open == Price.from_str("1.57597") assert bars[0].high == Price.from_str("1.57606") assert bars[0].low == Price.from_str("1.57576") assert bars[0].close == Price.from_str("1.57576") assert bars[0].volume == Quantity.from_int(10) # <-- default volume assert bars[0].ts_event == 1328054400000000000 assert bars[0].ts_init == 1328054400001000500 # <-- delta diff
def test_run_ema_cross_with_minute_trade_bars(self): # Arrange wrangler = BarDataWrangler( bar_type=BarType.from_str( "BTCUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL"), instrument=self.btcusdt, ) provider = TestDataProvider() # Build externally aggregated bars bars = wrangler.process(data=provider.read_csv_bars( "ftx-btc-perp-20211231-20220201_1m.csv")[:10000], ) self.engine.add_bars(bars) config = EMACrossConfig( instrument_id=str(self.btcusdt.id), bar_type="BTCUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL", trade_size=Decimal(0.001), fast_ema=10, slow_ema=20, ) strategy = EMACross(config=config) self.engine.add_strategy(strategy) # Act self.engine.run() # Assert assert strategy.fast_ema.count == 10000 assert self.engine.iteration == 10000 btc_ending_balance = self.engine.portfolio.account( self.venue).balance_total(BTC) usdt_ending_balance = self.engine.portfolio.account( self.venue).balance_total(USDT) assert btc_ending_balance == Money(9.57200000, BTC) assert usdt_ending_balance == Money(10017114.27716700, USDT)
def setup(self): # Fixture Setup config = BacktestEngineConfig( bypass_logging=False, run_analysis=False, risk_engine={ "bypass": True, # Example of bypassing pre-trade risk checks for backtests "max_notional_per_order": { "GBP/USD.SIM": 2_000_000 }, }, ) self.engine = BacktestEngine(config=config) self.venue = Venue("SIM") self.gbpusd = TestInstrumentProvider.default_fx_ccy("GBP/USD") # Setup wranglers bid_wrangler = BarDataWrangler( bar_type=BarType.from_str("GBP/USD.SIM-1-MINUTE-BID-EXTERNAL"), instrument=self.gbpusd, ) ask_wrangler = BarDataWrangler( bar_type=BarType.from_str("GBP/USD.SIM-1-MINUTE-ASK-EXTERNAL"), instrument=self.gbpusd, ) # Setup data provider = TestDataProvider() # Build externally aggregated bars bid_bars = bid_wrangler.process( data=provider.read_csv_bars("fxcm-gbpusd-m1-bid-2012.csv"), ) ask_bars = ask_wrangler.process( data=provider.read_csv_bars("fxcm-gbpusd-m1-ask-2012.csv"), ) self.engine.add_instrument(self.gbpusd) self.engine.add_bars(bid_bars) self.engine.add_bars(ask_bars) interest_rate_data = pd.read_csv( os.path.join(PACKAGE_ROOT, "data", "short-term-interest.csv")) fx_rollover_interest = FXRolloverInterestModule( rate_data=interest_rate_data) self.engine.add_venue( venue=self.venue, oms_type=OMSType.HEDGING, account_type=AccountType.MARGIN, base_currency=USD, starting_balances=[Money(1_000_000, USD)], modules=[fx_rollover_interest], )
class TestBarDataWranglerHeaderless: def setup(self): # Fixture Setup instrument = TestInstrumentProvider.adabtc_binance() bar_type = TestDataStubs.bartype_adabtc_binance_1min_last() self.wrangler = BarDataWrangler( bar_type=bar_type, instrument=instrument, ) def test_process(self): # Arrange, Act provider = TestDataProvider() config = { "names": [ "timestamp", "open", "high", "low", "close", "volume", "ts_close", "quote_volume", "n_trades", "taker_buy_base_volume", "taker_buy_quote_volume", "ignore", ] } data = provider.read_csv("ADABTC-1m-2021-11-27.csv", **config) data["timestamp"] = data["timestamp"].astype("datetime64[ms]") data = data.set_index("timestamp") bars = self.wrangler.process(data) # Assert assert len(bars) == 10 assert bars[0].open == Price.from_str("0.00002853") assert bars[0].high == Price.from_str("0.00002854") assert bars[0].low == Price.from_str("0.00002851") assert bars[0].close == Price.from_str("0.00002854") assert bars[0].volume == Quantity.from_str("36304.2") assert bars[0].ts_event == 1637971200000000000 assert bars[0].ts_init == 1637971200000000000
def setup(self): # Fixture Setup config = BacktestEngineConfig( bypass_logging=False, run_analysis=False, ) self.engine = BacktestEngine(config=config) self.venue = Venue("SIM") # Setup data bid_bar_type = BarType( instrument_id=GBPUSD_SIM.id, bar_spec=TestDataStubs.bar_spec_1min_bid(), aggregation_source=AggregationSource.EXTERNAL, # <-- important ) ask_bar_type = BarType( instrument_id=GBPUSD_SIM.id, bar_spec=TestDataStubs.bar_spec_1min_ask(), aggregation_source=AggregationSource.EXTERNAL, # <-- important ) bid_wrangler = BarDataWrangler( bar_type=bid_bar_type, instrument=GBPUSD_SIM, ) ask_wrangler = BarDataWrangler( bar_type=ask_bar_type, instrument=GBPUSD_SIM, ) provider = TestDataProvider() bid_bars = bid_wrangler.process( provider.read_csv_bars("fxcm-gbpusd-m1-bid-2012.csv")) ask_bars = ask_wrangler.process( provider.read_csv_bars("fxcm-gbpusd-m1-ask-2012.csv")) # Add data self.engine.add_instrument(GBPUSD_SIM) self.engine.add_bars(bid_bars) self.engine.add_bars(ask_bars) self.engine.add_venue( venue=self.venue, oms_type=OMSType.HEDGING, account_type=AccountType.MARGIN, base_currency=USD, starting_balances=[Money(1_000_000, USD)], )
def test_data_catalog_bars(self): # Arrange bar_type = TestDataStubs.bartype_adabtc_binance_1min_last() instrument = TestInstrumentProvider.adabtc_binance() wrangler = BarDataWrangler(bar_type, instrument) def parser(data): data["timestamp"] = data["timestamp"].astype("datetime64[ms]") bars = wrangler.process(data.set_index("timestamp")) return bars binance_spot_header = [ "timestamp", "open", "high", "low", "close", "volume", "ts_close", "quote_volume", "n_trades", "taker_buy_base_volume", "taker_buy_quote_volume", "ignore", ] reader = CSVReader(block_parser=parser, header=binance_spot_header) # Act _ = process_files( glob_path=f"{TEST_DATA_DIR}/ADABTC-1m-2021-11-*.csv", reader=reader, catalog=self.catalog, ) # Assert bars = self.catalog.bars() assert len(bars) == 21
log_level="INFO", risk_engine={ "bypass": True, # Example of bypassing pre-trade risk checks for backtests "max_notional_per_order": {"GBP/USD.SIM": 2_000_000}, }, ) # Build backtest engine engine = BacktestEngine(config=config) # Setup trading instruments SIM = Venue("SIM") GBPUSD_SIM = TestInstrumentProvider.default_fx_ccy("GBP/USD", SIM) # Setup wranglers bid_wrangler = BarDataWrangler( bar_type=BarType.from_str("GBP/USD.SIM-1-MINUTE-BID-EXTERNAL"), instrument=GBPUSD_SIM, ) ask_wrangler = BarDataWrangler( bar_type=BarType.from_str("GBP/USD.SIM-1-MINUTE-ASK-EXTERNAL"), instrument=GBPUSD_SIM, ) # Setup data provider = TestDataProvider() # Build externally aggregated bars bid_bars = bid_wrangler.process( data=provider.read_csv_bars("fxcm-gbpusd-m1-bid-2012.csv")[:10000], ) ask_bars = ask_wrangler.process( data=provider.read_csv_bars("fxcm-gbpusd-m1-ask-2012.csv")[:10000],