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, )
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)
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, }
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, )
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
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, )
# ------------------------------------------------------------------------------------------------- # 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())