예제 #1
0
def parse_order_status_http(
    account_id: AccountId,
    instrument: Instrument,
    data: Dict[str, Any],
    report_id: UUID4,
    ts_init: int,
) -> OrderStatusReport:
    client_id_str = data.get("clientId")
    price = data.get("price")
    avg_px = data["avgFillPrice"]
    created_at = int(
        pd.to_datetime(data["createdAt"], utc=True).to_datetime64())
    return OrderStatusReport(
        account_id=account_id,
        instrument_id=InstrumentId(Symbol(data["market"]), FTX_VENUE),
        client_order_id=ClientOrderId(client_id_str)
        if client_id_str is not None else None,
        venue_order_id=VenueOrderId(str(data["id"])),
        order_side=OrderSide.BUY if data["side"] == "buy" else OrderSide.SELL,
        order_type=parse_order_type(data=data, price_str="price"),
        time_in_force=TimeInForce.IOC if data["ioc"] else TimeInForce.GTC,
        order_status=parse_order_status(data),
        price=instrument.make_price(price) if price is not None else None,
        quantity=instrument.make_qty(data["size"]),
        filled_qty=instrument.make_qty(data["filledSize"]),
        avg_px=Decimal(str(avg_px)) if avg_px is not None else None,
        post_only=data["postOnly"],
        reduce_only=data["reduceOnly"],
        report_id=report_id,
        ts_accepted=created_at,
        ts_last=created_at,
        ts_init=ts_init,
    )
예제 #2
0
    def _generate_external_order_status(self, instrument: Instrument,
                                        data: Dict[str, Any]) -> None:
        client_id_str = data.get("clientId")
        price = data.get("price")
        created_at = int(
            pd.to_datetime(data["createdAt"], utc=True).to_datetime64())
        report = OrderStatusReport(
            account_id=self.account_id,
            instrument_id=InstrumentId(Symbol(data["market"]), FTX_VENUE),
            client_order_id=ClientOrderId(client_id_str)
            if client_id_str is not None else None,
            venue_order_id=VenueOrderId(str(data["id"])),
            order_side=OrderSide.BUY
            if data["side"] == "buy" else OrderSide.SELL,
            order_type=parse_order_type(data=data, price_str="price"),
            time_in_force=TimeInForce.IOC if data["ioc"] else TimeInForce.GTC,
            order_status=OrderStatus.ACCEPTED,
            price=instrument.make_price(price) if price is not None else None,
            quantity=instrument.make_qty(data["size"]),
            filled_qty=instrument.make_qty(0),
            avg_px=None,
            post_only=data["postOnly"],
            reduce_only=data["reduceOnly"],
            report_id=self._uuid_factory.generate(),
            ts_accepted=created_at,
            ts_last=created_at,
            ts_init=self._clock.timestamp_ns(),
        )

        self._send_order_status_report(report)
예제 #3
0
def parse_trigger_order_status_http(
    account_id: AccountId,
    instrument: Instrument,
    triggers: Dict[int, VenueOrderId],
    data: Dict[str, Any],
    report_id: UUID4,
    ts_init: int,
) -> OrderStatusReport:
    order_id = data["id"]
    parent_order_id = triggers.get(order_id)  # Map trigger to parent
    client_id_str = data.get("clientId")
    trigger_price = data.get("triggerPrice")
    order_price = data.get("orderPrice")
    avg_px = data["avgFillPrice"]
    triggered_at = data["triggeredAt"]
    trail_value = data["trailValue"]
    created_at = int(
        pd.to_datetime(data["createdAt"], utc=True).to_datetime64())
    return OrderStatusReport(
        account_id=account_id,
        instrument_id=instrument.id,
        client_order_id=ClientOrderId(client_id_str)
        if client_id_str is not None else None,
        venue_order_id=parent_order_id or VenueOrderId(str(order_id)),
        order_side=OrderSide.BUY if data["side"] == "buy" else OrderSide.SELL,
        order_type=parse_order_type(data=data),
        time_in_force=TimeInForce.GTC,
        order_status=parse_order_status(data),
        price=instrument.make_price(order_price)
        if order_price is not None else None,
        trigger_price=instrument.make_price(trigger_price)
        if trigger_price is not None else None,
        trigger_type=TriggerType.LAST,
        trailing_offset=Decimal(str(trail_value))
        if trail_value is not None else None,
        offset_type=TrailingOffsetType.PRICE,
        quantity=instrument.make_qty(data["size"]),
        filled_qty=instrument.make_qty(data["filledSize"]),
        avg_px=Decimal(str(avg_px)) if avg_px is not None else None,
        post_only=False,
        reduce_only=data["reduceOnly"],
        report_id=report_id,
        ts_accepted=created_at,
        ts_triggered=int(
            pd.to_datetime(triggered_at, utc=True).to_datetime64())
        if triggered_at is not None else 0,
        ts_last=created_at,
        ts_init=ts_init,
    )
    def test_base_to_dict_returns_expected_dict(self):
        # Arrange, Act
        result = Instrument.base_to_dict(BTCUSDT_BINANCE)

        # Assert
        assert result == {
            "type": "Instrument",
            "id": "BTCUSDT.BINANCE",
            "native_symbol": "BTCUSDT",
            "asset_class": "CRYPTO",
            "asset_type": "SPOT",
            "quote_currency": "USDT",
            "is_inverse": False,
            "price_precision": 2,
            "price_increment": "0.01",
            "size_precision": 6,
            "size_increment": "0.000001",
            "multiplier": "1",
            "lot_size": None,
            "max_quantity": "9000.000000",
            "min_quantity": "0.000001",
            "max_notional": None,
            "min_notional": "10.00000000 USDT",
            "max_price": "1000000.00",
            "min_price": "0.01",
            "margin_init": "0",
            "margin_maint": "0",
            "maker_fee": "0.001",
            "taker_fee": "0.001",
            "ts_event": 0,
            "ts_init": 0,
            "info": None,
        }
예제 #5
0
def parse_trade_report(
    account_id: AccountId,
    instrument: Instrument,
    data: Dict[str, Any],
    report_id: UUID4,
    ts_init: int,
) -> TradeReport:
    return TradeReport(
        account_id=account_id,
        instrument_id=instrument.id,
        venue_order_id=VenueOrderId(str(data["orderId"])),
        trade_id=TradeId(str(data["tradeId"])),
        order_side=OrderSide.BUY if data["side"] == "buy" else OrderSide.SELL,
        last_qty=instrument.make_qty(data["size"]),
        last_px=instrument.make_price(data["price"]),
        commission=Money(data["fee"], Currency.from_str(data["feeCurrency"])),
        liquidity_side=LiquiditySide.TAKER
        if data["liquidity"] == "taker" else LiquiditySide.MAKER,
        report_id=report_id,
        ts_event=int(pd.to_datetime(data["time"], utc=True).to_datetime64()),
        ts_init=ts_init,
    )
예제 #6
0
def merge_existing_data(catalog: DataCatalog, cls: type, df: pd.DataFrame) -> pd.DataFrame:
    """
    Handle existing data for instrument subclasses.

    Instruments all live in a single file, so merge with existing data.
    For all other classes, simply return data unchanged.
    """
    if cls not in Instrument.__subclasses__():
        return df
    else:
        try:
            existing = catalog.instruments(instrument_type=cls)
            return existing.append(df.drop(["type"], axis=1)).drop_duplicates()
        except pa.lib.ArrowInvalid:
            return df
예제 #7
0
def parse_position_report(
    account_id: AccountId,
    instrument: Instrument,
    data: Dict[str, Any],
    report_id: UUID4,
    ts_init: int,
) -> PositionStatusReport:
    net_size = data["netSize"]
    return PositionStatusReport(
        account_id=account_id,
        instrument_id=instrument.id,
        position_side=PositionSide.LONG
        if net_size > 0 else PositionSide.SHORT,
        quantity=instrument.make_qty(abs(net_size)),
        report_id=report_id,
        ts_last=ts_init,
        ts_init=ts_init,
    )
예제 #8
0
# -------------------------------------------------------------------------------------------------
#  Copyright (C) 2015-2021 Nautech Systems Pty Ltd. All rights reserved.
#  https://nautechsystems.io
#
#  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
#  You may not use this file except in compliance with the License.
#  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
# -------------------------------------------------------------------------------------------------
from nautilus_trader.model.instruments.base import Instrument
from nautilus_trader.serialization.arrow.serializer import register_parquet

for cls in Instrument.__subclasses__():
    register_parquet(cls, partition_keys=tuple())