Beispiel #1
0
def parse_forex_contract(
    details: ContractDetails,
) -> CurrencyPair:
    price_precision: int = _tick_size_to_precision(details.minTick)
    timestamp = time.time_ns()
    instrument_id = InstrumentId(
        symbol=Symbol(f"{details.contract.symbol}/{details.contract.currency}"),
        venue=Venue(details.contract.primaryExchange or details.contract.exchange),
    )
    return CurrencyPair(
        instrument_id=instrument_id,
        native_symbol=Symbol(details.contract.localSymbol),
        base_currency=Currency.from_str(details.contract.currency),
        quote_currency=Currency.from_str(details.contract.symbol),
        price_precision=price_precision,
        size_precision=Quantity.from_int(1),
        price_increment=Price(details.minTick, price_precision),
        size_increment=Quantity(details.sizeMinTick or 1, 1),
        lot_size=None,
        max_quantity=None,
        min_quantity=None,
        max_notional=None,
        min_notional=None,
        max_price=None,
        min_price=None,
        margin_init=Decimal(0),
        margin_maint=Decimal(0),
        maker_fee=Decimal(0),
        taker_fee=Decimal(0),
        ts_event=timestamp,
        ts_init=timestamp,
    )
    def test_currency_equality(self):
        # Arrange
        currency1 = Currency(
            code="AUD",
            precision=2,
            iso4217=36,
            name="Australian dollar",
            currency_type=CurrencyType.FIAT,
        )

        currency2 = Currency(
            code="AUD",
            precision=2,
            iso4217=36,
            name="Australian dollar",
            currency_type=CurrencyType.FIAT,
        )

        currency3 = Currency(
            code="GBP",
            precision=2,
            iso4217=826,
            name="British pound",
            currency_type=CurrencyType.FIAT,
        )

        # Act, Assert
        assert currency1 == currency1
        assert currency1 == currency2
        assert currency1 != currency3
    def default_fx_ccy(symbol: Symbol, leverage: Decimal=Decimal("50")) -> Instrument:
        """
        Return a default FX currency pair instrument from the given symbol.

        Parameters
        ----------
        symbol : Symbol
            The currency pair symbol.
        leverage : Decimal, optional
            The leverage for the instrument.

        Raises
        ------
        ValueError
            If the symbol.code length is not in range [6, 7].

        """
        PyCondition.not_none(symbol, "symbol")
        PyCondition.in_range_int(len(symbol.code), 6, 7, "len(symbol)")

        base_currency = symbol.code[:3]
        quote_currency = symbol.code[-3:]

        # Check tick precision of quote currency
        if quote_currency == 'JPY':
            price_precision = 3
        else:
            price_precision = 5

        return Instrument(
            symbol=symbol,
            asset_class=AssetClass.FX,
            asset_type=AssetType.SPOT,
            base_currency=Currency.from_str(base_currency),
            quote_currency=Currency.from_str(quote_currency),
            settlement_currency=Currency.from_str(quote_currency),
            is_inverse=False,
            price_precision=price_precision,
            size_precision=0,
            tick_size=Decimal(f"{1 / 10 ** price_precision:.{price_precision}f}"),
            multiplier=Decimal("1"),
            leverage=leverage,
            lot_size=Quantity("1000"),
            max_quantity=Quantity("1e7"),
            min_quantity=Quantity("1000"),
            max_price=None,
            min_price=None,
            max_notional=Money(50000000.00, USD),
            min_notional=Money(1000.00, USD),
            margin_init=Decimal("0.03"),
            margin_maint=Decimal("0.03"),
            maker_fee=Decimal("0.00002"),
            taker_fee=Decimal("0.00002"),
            financing={},
            timestamp=UNIX_EPOCH,
        )
    def test_register_adds_currency_to_internal_currency_map(self):
        # Arrange, Act
        one_inch = Currency(
            code="1INCH",
            precision=8,
            iso4217=0,
            name="1INCH",
            currency_type=CurrencyType.CRYPTO,
        )
        Currency.register(one_inch)

        result = Currency.from_str("1INCH")

        assert result == one_inch
Beispiel #5
0
    def test_add_currency(self):
        # Arrange
        currency = Currency(
            code="1INCH",
            precision=8,
            iso4217=0,
            name="1INCH",
            currency_type=CurrencyType.CRYPTO,
        )

        # Act
        self.cache.add_currency(currency)

        # Assert
        self.assertEqual(currency, Currency.from_str("1INCH"))
    def test_register_when_overwrite_true_overwrites_internal_currency_map(
            self):
        # Arrange, Act
        another_aud = Currency(
            code="AUD",
            precision=8,
            iso4217=0,
            name="AUD",
            currency_type=CurrencyType.CRYPTO,
        )
        Currency.register(another_aud, overwrite=False)

        result = Currency.from_str("AUD")

        assert result != another_aud
    def test_is_crypto(self, string, expected):
        # Arrange
        # Act
        result = Currency.is_crypto(string)

        # Assert
        assert result == expected
    def test_from_str(self, string, expected):
        # Arrange
        # Act
        result = Currency.from_str(string)

        # Assert
        assert result == expected
Beispiel #9
0
    def test_is_fiat(self, string, expected):
        # Arrange
        # Act
        result = Currency.is_fiat(string)

        # Assert
        self.assertEqual(expected, result)
Beispiel #10
0
    def _parse_futures_contract(
        self,
        instrument_id: InstrumentId,
        asset_class: AssetClass,
        details: ContractDetails,
    ) -> Future:
        price_precision: int = self._tick_size_to_precision(details.minTick)
        timestamp = time.time_ns()
        future = Future(
            instrument_id=instrument_id,
            local_symbol=Symbol(details.contract.localSymbol),
            asset_class=asset_class,
            currency=Currency.from_str(details.contract.currency),
            price_precision=price_precision,
            price_increment=Price(details.minTick, price_precision),
            multiplier=Quantity.from_int(int(details.contract.multiplier)),
            lot_size=Quantity.from_int(1),
            underlying=details.underSymbol,
            expiry_date=datetime.datetime.strptime(
                details.contract.lastTradeDateOrContractMonth, "%Y%m%d"
            ).date(),
            ts_event=timestamp,
            ts_init=timestamp,
        )

        return future
Beispiel #11
0
def parse_future_contract(
    details: ContractDetails,
) -> Future:
    price_precision: int = _tick_size_to_precision(details.minTick)
    timestamp = time.time_ns()
    instrument_id = InstrumentId(
        symbol=Symbol(details.contract.localSymbol),
        venue=Venue(details.contract.primaryExchange or details.contract.exchange),
    )
    return Future(
        instrument_id=instrument_id,
        native_symbol=Symbol(details.contract.localSymbol),
        asset_class=sec_type_to_asset_class(details.underSecType),
        currency=Currency.from_str(details.contract.currency),
        price_precision=price_precision,
        price_increment=Price(details.minTick, price_precision),
        multiplier=Quantity.from_int(int(details.contract.multiplier)),
        lot_size=Quantity.from_int(1),
        underlying=details.underSymbol,
        expiry_date=datetime.datetime.strptime(
            details.contract.lastTradeDateOrContractMonth, "%Y%m%d"
        ).date(),
        ts_event=timestamp,
        ts_init=timestamp,
    )
Beispiel #12
0
def parse_option_contract(
    details: ContractDetails,
) -> Option:
    price_precision: int = _tick_size_to_precision(details.minTick)
    timestamp = time.time_ns()
    instrument_id = InstrumentId(
        symbol=Symbol(details.contract.localSymbol.replace("  ", "")),
        venue=Venue(details.contract.primaryExchange or details.contract.exchange),
    )
    asset_class = {
        "STK": AssetClass.EQUITY,
    }[details.underSecType]
    kind = {
        "C": OptionKind.CALL,
        "P": OptionKind.PUT,
    }[details.contract.right]
    return Option(
        instrument_id=instrument_id,
        native_symbol=Symbol(details.contract.localSymbol),
        asset_class=asset_class,
        currency=Currency.from_str(details.contract.currency),
        price_precision=price_precision,
        price_increment=Price(details.minTick, price_precision),
        multiplier=Quantity.from_int(int(details.contract.multiplier)),
        lot_size=Quantity.from_int(1),
        underlying=details.underSymbol,
        strike_price=Price.from_str(str(details.contract.strike)),
        expiry_date=datetime.datetime.strptime(
            details.contract.lastTradeDateOrContractMonth, "%Y%m%d"
        ).date(),
        kind=kind,
        ts_event=timestamp,
        ts_init=timestamp,
    )
    def test_is_fiat(self, string, expected):
        # Arrange
        # Act
        result = Currency.is_fiat(string)

        # Assert
        assert expected == result
Beispiel #14
0
def betfair_account_to_account_state(
    account_detail,
    account_funds,
    event_id,
    updated_ns,
    timestamp_ns,
    account_id="001",
) -> AccountState:
    currency = Currency.from_str(account_detail["currencyCode"])
    balance = float(account_funds["availableToBetBalance"])
    locked = -float(account_funds["exposure"])
    free = balance - locked
    return AccountState(
        account_id=AccountId(issuer=BETFAIR_VENUE.value, number=account_id),
        account_type=AccountType.CASH,
        base_currency=currency,
        reported=True,
        balances=[
            AccountBalance(
                currency=currency,
                total=Money(balance, currency),
                locked=Money(locked, currency),
                free=Money(free, currency),
            ),
        ],
        info={"funds": account_funds, "detail": account_detail},
        event_id=event_id,
        updated_ns=updated_ns,
        timestamp_ns=timestamp_ns,
    )
Beispiel #15
0
def parse_trade_report_http(
    account_id: AccountId,
    instrument_id: InstrumentId,
    data: BinanceFuturesAccountTrade,
    report_id: UUID4,
    ts_init: int,
) -> TradeReport:
    return TradeReport(
        account_id=account_id,
        instrument_id=instrument_id,
        venue_order_id=VenueOrderId(str(data.orderId)),
        venue_position_id=PositionId(
            f"{instrument_id}-{data.positionSide.value}"),
        trade_id=TradeId(str(data.id)),
        order_side=OrderSide[data.side.value],
        last_qty=Quantity.from_str(data.qty),
        last_px=Price.from_str(data.price),
        commission=Money(data.commission,
                         Currency.from_str(data.commissionAsset)),
        liquidity_side=LiquiditySide.MAKER
        if data.maker else LiquiditySide.TAKER,
        report_id=report_id,
        ts_event=millis_to_nanos(data.time),
        ts_init=ts_init,
    )
    def test_from_str(self, string, expected):
        # Arrange
        # Act
        result = Currency.from_str(string)

        # Assert
        self.assertEqual(expected, result)
    def test_from_str_given_unknown_code_returns_none(self):
        # Arrange
        # Act
        result = Currency.from_str("SOME_CURRENCY")

        # Assert
        self.assertIsNone(result)
def betfair_account_to_account_state(
    account_detail,
    account_funds,
    event_id,
    ts_event,
    ts_init,
    account_id="001",
) -> AccountState:
    currency = Currency.from_str(account_detail["currencyCode"])
    balance = float(account_funds["availableToBetBalance"])
    locked = -float(
        account_funds["exposure"]) if account_funds["exposure"] else 0.0
    free = balance - locked
    return AccountState(
        account_id=AccountId(issuer=BETFAIR_VENUE.value, number=account_id),
        account_type=AccountType.BETTING,
        base_currency=currency,
        reported=False,
        balances=[
            AccountBalance(
                total=Money(balance, currency),
                locked=Money(locked, currency),
                free=Money(free, currency),
            ),
        ],
        margins=[],
        info={
            "funds": account_funds,
            "detail": account_detail
        },
        event_id=event_id,
        ts_event=ts_event,
        ts_init=ts_init,
    )
Beispiel #19
0
    def _create_engine(
        self,
        config: BacktestEngineConfig,
        venue_configs: List[BacktestVenueConfig],
        data_configs: List[BacktestDataConfig],
    ):
        # Build the backtest engine
        engine = BacktestEngine(config=config)

        # Add instruments
        for config in data_configs:
            if is_nautilus_class(config.data_type):
                instruments = config.catalog().instruments(
                    instrument_ids=config.instrument_id, as_nautilus=True)
                for instrument in instruments or []:
                    engine.add_instrument(instrument)

        # Add venues
        for config in venue_configs:
            engine.add_venue(
                venue=Venue(config.name),
                venue_type=VenueType[config.venue_type],
                oms_type=OMSType[config.oms_type],
                account_type=AccountType[config.account_type],
                base_currency=Currency.from_str(config.base_currency),
                starting_balances=[
                    Money.from_str(m) for m in config.starting_balances
                ],
                book_type=BookTypeParser.from_str_py(config.book_type),
            )
        return engine
    def test_currency_equality(self):
        # Arrange
        currency1 = Currency("AUD",
                             precision=2,
                             currency_type=CurrencyType.FIAT)
        currency2 = Currency("AUD",
                             precision=2,
                             currency_type=CurrencyType.FIAT)
        currency3 = Currency("GBP",
                             precision=2,
                             currency_type=CurrencyType.FIAT)

        # Act
        # Assert
        self.assertTrue(currency1 == currency1)
        self.assertTrue(currency1 == currency2)
        self.assertTrue(currency1 != currency3)
Beispiel #21
0
 def _news_event_from_dict(data):
     data.update(
         {
             "impact": getattr(NewsImpact, data["impact"]),
             "currency": Currency.from_str(data["currency"]),
         }
     )
     return NewsEventData(**data)
Beispiel #22
0
 def news_event_parser(df, state=None):
     for _, row in df.iterrows():
         yield NewsEventData(
             name=str(row["Name"]),
             impact=getattr(NewsImpact, row["Impact"]),
             currency=Currency.from_str(row["Currency"]),
             ts_event=maybe_dt_to_unix_nanos(pd.Timestamp(row["Start"])),
             ts_init=maybe_dt_to_unix_nanos(pd.Timestamp(row["Start"])),
         )
Beispiel #23
0
def test_account_statement(betfair_client, uuid, clock):
    detail = betfair_client.account.get_account_details()
    funds = betfair_client.account.get_account_funds()
    result = betfair_account_to_account_state(
        account_detail=detail,
        account_funds=funds,
        event_id=uuid,
        timestamp_ns=clock.timestamp_ns(),
    )
    expected = AccountState(
        AccountId(issuer="betfair", identifier="Testy-McTest"),
        [Money(1000.0, Currency.from_str("AUD"))],
        [Money(1000.0, Currency.from_str("AUD"))],
        [Money(-0.00, Currency.from_str("AUD"))],
        {"funds": funds, "detail": detail},
        uuid,
        result.timestamp_ns,
    )
    assert result == expected
Beispiel #24
0
    def test_load_currencies_when_currencies_in_database_returns_expected(self):
        # Arrange
        aud = Currency.from_str("AUD")
        self.database.add_currency(aud)

        # Act
        result = self.database.load_currencies()

        # Assert
        assert result == {"AUD": aud}
    def test_currency_hash(self):
        # Arrange
        currency = Currency("AUD",
                            precision=2,
                            currency_type=CurrencyType.FIAT)

        # Act
        # Assert
        self.assertEqual(int, type(hash(currency)))
        self.assertEqual(hash(currency), hash(currency))
def parse_account_margins_http(assets: List[BinanceFuturesAssetInfo]) -> List[MarginBalance]:
    margins: List[MarginBalance] = []
    for a in assets:
        currency: Currency = Currency.from_str(a.asset)
        margin = MarginBalance(
            initial=Money(Decimal(a.initialMargin), currency),
            maintenance=Money(Decimal(a.maintMargin), currency),
        )
        margins.append(margin)

    return margins
    def test_str_repr(self):
        # Arrange
        currency = Currency("AUD",
                            precision=2,
                            currency_type=CurrencyType.FIAT)

        # Act
        # Assert
        self.assertEqual("AUD", str(currency))
        self.assertEqual("Currency(code=AUD, precision=2, type=FIAT)",
                         repr(currency))
    def test_currency_hash(self):
        # Arrange
        currency = Currency(
            code="AUD",
            precision=2,
            iso4217=36,
            name="Australian dollar",
            currency_type=CurrencyType.FIAT,
        )

        # Act, Assert
        assert isinstance(hash(currency), int)
        assert hash(currency) == hash(currency)
Beispiel #29
0
    def test_default_fx_with_3_dp_returns_expected_instrument(self):
        # Arrange
        loader = TestInstrumentProvider()

        # Act
        instrument = loader.default_fx_ccy(Symbol("USD/JPY", Venue("SIM")))

        # Assert
        self.assertEqual(Symbol("USD/JPY", Venue("SIM")), instrument.symbol)
        self.assertEqual(3, instrument.price_precision)
        self.assertEqual(Decimal("0.001"), instrument.tick_size)
        self.assertEqual(
            Currency(code='JPY', precision=2, currency_type=CurrencyType.FIAT),
            instrument.quote_currency)
    def test_default_fx_with_5_dp_returns_expected_instrument(self):
        # Arrange
        loader = InstrumentLoader()

        # Act
        instrument = loader.default_fx_ccy(Symbol("AUD/USD", Venue('FXCM')))

        # Assert
        self.assertEqual(Symbol("AUD/USD", Venue('FXCM')), instrument.symbol)
        self.assertEqual(5, instrument.price_precision)
        self.assertEqual(Decimal("0.00001"), instrument.tick_size)
        self.assertEqual(
            Currency(code='USD', precision=2, currency_type=CurrencyType.FIAT),
            instrument.quote_currency)