def generate_orders(self,
                        state: dt.datetime,
                        backtest: PredefinedAssetBacktest = None) -> list:
        date = state.date()

        contract = Security(ric='TestRic')
        orders = []
        units_to_trade = 1
        """ enter trade is a TWAP order between 10 and 10:30 """
        exec_start = dt.datetime.combine(date, dt.time(10))
        exec_end = dt.datetime.combine(date, dt.time(10, 30))
        orders.append(
            OrderTWAP(instrument=contract,
                      quantity=units_to_trade,
                      generation_time=state,
                      window=TimeWindow(start=exec_start, end=exec_end),
                      source=str(self.__class__)))
        """ exit the intraday quantity at TWAP between 14 and 14:30 """
        twap_start = dt.datetime.combine(date, dt.time(14))
        twap_end = dt.datetime.combine(date, dt.time(14, 30))
        orders.append(
            OrderTWAP(instrument=contract,
                      quantity=units_to_trade * -1,
                      generation_time=state,
                      window=TimeWindow(start=twap_start, end=twap_end),
                      source=str(self.__class__)))
        return orders
 def generate_orders(self,
                     time: dt.datetime,
                     backtest: PredefinedAssetBacktest = None) -> list:
     date = time.date()
     if date == dt.date(2021, 1, 5):
         return [
             OrderMarketOnClose(instrument=Security(ric='TestRic'),
                                quantity=1,
                                generation_time=time,
                                execution_date=date,
                                source='Test')
         ]
     else:
         return []
Example #3
0
    def from_dict(cls,
                  values: dict) -> Optional[Union['Instrument', 'Security']]:
        from gs_quant.target.instrument import AssetClass, AssetType

        if not values:
            return None

        instrument_type = cls.asset_class_and_type_to_instrument().get(
            (get_enum_value(AssetClass, values.pop('asset_class')),
             get_enum_value(AssetType, values.pop('type'))))

        if instrument_type:
            return instrument_type._from_dict(values)
        else:
            from gs_quant.instrument import Security
            return Security.from_dict(values)
def test_backtest_predefined():
    # Test simple MOC order
    trigger = ExampleTestTrigger()
    strategy = Strategy(initial_portfolio=None, triggers=[trigger])
    start = dt.date(2021, 1, 4)
    mid = dt.date(2021, 1, 5)
    end = dt.date(2021, 1, 6)

    # these mocks are needed as the date functions need a GSSession
    gs_quant.backtests.predefined_asset_engine.is_business_day = mock.Mock(
        return_value=True)
    gs_quant.backtests.predefined_asset_engine.business_day_offset = mock.Mock(
        return_value=mid)

    data_mgr = DataManager()
    underlying = Security(ric='TestRic')
    close_prices = pd.Series(dtype=float)
    close_prices[start] = 1
    close_prices[mid] = 1.5
    close_prices[end] = 2
    data_mgr.add_data_source(close_prices, DataFrequency.DAILY, underlying,
                             ValuationFixingType.PRICE)

    engine = PredefinedAssetEngine(data_mgr=data_mgr)

    backtest = engine.run_backtest(strategy, start=start, end=end)
    perf = backtest.performance
    holdings = backtest.historical_holdings
    cash_asset = backtest.cash_asset

    # 100 on the initial date
    assert perf[start] == 100
    # 100 on the next day as we traded MOC
    assert perf[mid] == 100
    assert holdings[mid][cash_asset] == 100 - 1.5
    assert holdings[mid][underlying] == 1
    # 100.5 = 98.5 (cash) + 2 ( test asset)
    assert holdings[end][cash_asset] == 100 - 1.5
    assert holdings[end][underlying] == 1
    assert perf[end] == 100.5

    # Test TWAP orders with no ON positions
    twap_entry_mid = 16
    twap_exit_mid = 25

    twap_entry_end = 30
    twap_exit_end = 40

    data_twap = {
        dt.datetime.combine(mid, dt.time(10, 30)): twap_entry_mid,
        dt.datetime.combine(mid, dt.time(14, 30)): twap_exit_mid,
        dt.datetime.combine(end, dt.time(10, 30)): twap_entry_end,
        dt.datetime.combine(end, dt.time(14, 30)): twap_exit_end
    }

    data_mgr.add_data_source(pd.Series(data_twap), DataFrequency.REAL_TIME,
                             underlying, ValuationFixingType.PRICE)
    trigger = FuturesExample()
    strategy = Strategy(initial_portfolio=None, triggers=[trigger])
    engine = PredefinedAssetEngine(data_mgr=data_mgr,
                                   tz=timezone('Europe/London'))
    backtest = engine.run_backtest(strategy, start=start, end=end)
    perf = backtest.performance
    holdings = backtest.historical_holdings
    weights = backtest.historical_weights
    cash_asset = backtest.cash_asset

    # start: 100
    assert perf[start] == 100
    # mid: 100 + (twap_exit - twap_entry)
    assert perf[mid] == 100 - twap_entry_mid + twap_exit_mid
    assert holdings[mid][cash_asset] == perf[mid]
    assert underlying not in holdings[mid]
    assert weights[mid][cash_asset] == 1
    assert underlying not in weights[mid]
    # 100.5 = 98.5 (cash) + 2 ( test asset)
    assert perf[
        end] == 100 - twap_entry_mid + twap_exit_mid - twap_entry_end + twap_exit_end
    assert holdings[end][cash_asset] == perf[end]
    assert underlying not in holdings[end]
    assert weights[end][cash_asset] == 1
    assert underlying not in weights[end]