architect-py 5.1.6__tar.gz → 5.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {architect_py-5.1.6 → architect_py-5.2.0}/PKG-INFO +1 -1
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/__init__.py +1 -1
- architect_py-5.2.0/architect_py/async_cpty.py +422 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py.egg-info/PKG-INFO +1 -1
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py.egg-info/SOURCES.txt +1 -0
- architect_py-5.2.0/examples/external_cpty.py +83 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/pyproject.toml +1 -1
- {architect_py-5.1.6 → architect_py-5.2.0}/scripts/add_imports_to_inits.py +6 -2
- architect_py-5.1.6/examples/external_cpty.py +0 -78
- {architect_py-5.1.6 → architect_py-5.2.0}/LICENSE +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/README.md +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/async_client.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/client.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/client.pyi +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/common_types/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/common_types/order_dir.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/common_types/time_in_force.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/common_types/tradable_product.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/base_model.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/client.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/enums.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/exceptions.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/fragments.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/get_execution_info_query.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/get_execution_infos_query.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/get_first_notice_date_query.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/get_future_series_query.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/get_product_info_query.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/get_product_infos_query.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/input_types.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/juniper_base_client.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/search_symbols_query.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/user_id_query.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/client.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Accounts/AccountsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Accounts/AccountsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Accounts/ResetPaperAccountRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Accounts/ResetPaperAccountResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Accounts/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/AlgoOrder.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/AlgoOrderRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/AlgoOrdersRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/AlgoOrdersResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/CreateAlgoOrderRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/PauseAlgoRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/PauseAlgoResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/StartAlgoRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/StartAlgoResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/StopAlgoRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/StopAlgoResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Algo/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/AlgoHelper/AlgoParamTypes.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/AlgoHelper/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Auth/AuthInfoRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Auth/AuthInfoResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Auth/CreateJwtRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Auth/CreateJwtResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Auth/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/DepositsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/DepositsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/OptionsTransactionsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/OptionsTransactionsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/RqdAccountStatisticsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/RqdAccountStatisticsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/StatementUrlRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/StatementUrlResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/StatementsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/StatementsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/WithdrawalsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/WithdrawalsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Boss/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Core/ConfigRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Core/ConfigResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Core/RestartCptyRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Core/RestartCptyResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Core/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Cpty/CptyRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Cpty/CptyResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Cpty/CptyStatus.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Cpty/CptyStatusRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Cpty/CptysRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Cpty/CptysResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Cpty/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/AccountHistoryRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/AccountHistoryResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/AccountSummariesRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/AccountSummariesResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/AccountSummary.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/AccountSummaryRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/HistoricalFillsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/HistoricalFillsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/HistoricalOrdersRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/HistoricalOrdersResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Folio/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Health/HealthCheckRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Health/HealthCheckResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Health/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/ArrayOfL1BookSnapshot.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/Candle.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/HistoricalCandlesRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/HistoricalCandlesResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/L1BookSnapshot.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/L1BookSnapshotRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/L1BookSnapshotsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/L2BookSnapshot.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/L2BookSnapshotRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/L2BookUpdate.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/Liquidation.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/MarketStatus.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/MarketStatusRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/SubscribeCandlesRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/SubscribeCurrentCandlesRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/SubscribeL1BookSnapshotsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/SubscribeL2BookUpdatesRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/SubscribeLiquidationsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/SubscribeManyCandlesRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/SubscribeTickersRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/SubscribeTradesRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/Ticker.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/TickerRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/TickerUpdate.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/TickersRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/TickersResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/Trade.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Marketdata/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/Cancel.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/CancelAllOrdersRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/CancelAllOrdersResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/CancelOrderRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/OpenOrdersRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/OpenOrdersResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/Order.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/PendingCancelsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/PendingCancelsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/PlaceOrderRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Oms/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsChain.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeks.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsChainGreeksRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsChainRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsContract.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsContractGreeksRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsContractRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsExpirations.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsExpirationsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsGreeks.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsWraps.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/OptionsWrapsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/OptionsMarketdata/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Orderflow/Dropcopy.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Orderflow/DropcopyRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Orderflow/Orderflow.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Orderflow/OrderflowRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Orderflow/SubscribeOrderflowRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Orderflow/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/DownloadProductCatalogRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/DownloadProductCatalogResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/ExecutionInfoRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/ExecutionInfoResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/PruneExpiredSymbolsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/PruneExpiredSymbolsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/SubscribeSymbology.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/SymbologyRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/SymbologySnapshot.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/SymbologyUpdate.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/SymbolsRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/SymbolsResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/UploadProductCatalogRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/UploadProductCatalogResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/UploadSymbologyRequest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/UploadSymbologyResponse.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/Symbology/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/models/definitions.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/orderflow.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/resolve_endpoint.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/server.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/grpc/utils.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/conftest.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_book_building.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_encoding.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_marketdata.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_order_entry.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_orderflow.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_portfolio_management.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_positions.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_rounding.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_symbology.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/tests/test_sync_client.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/utils/nearest_tick.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/utils/nearest_tick_2.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/utils/orderbook.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/utils/pandas.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/utils/price_bands.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py/utils/symbol_parsing.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py.egg-info/dependency_links.txt +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py.egg-info/requires.txt +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/architect_py.egg-info/top_level.txt +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/__init__.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/book_subscription.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/candles.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/config.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/funding_rate_mean_reversion_algo.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/order_sending.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/orderflow_channel.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/orderflow_streaming.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/stream_l1_marketdata.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/stream_l2_marketdata.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/termutils.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/trades.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/tutorial_async.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/examples/tutorial_sync.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/scripts/correct_sync_interface.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/scripts/generate_functions_md.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/scripts/postprocess_grpc.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/scripts/preprocess_grpc_schema.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/scripts/prune_graphql_schema.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/setup.cfg +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/templates/exceptions.py +0 -0
- {architect_py-5.1.6 → architect_py-5.2.0}/templates/juniper_base_client.py +0 -0
@@ -0,0 +1,422 @@
|
|
1
|
+
import asyncio
|
2
|
+
import logging
|
3
|
+
import uuid
|
4
|
+
from datetime import datetime
|
5
|
+
from decimal import Decimal
|
6
|
+
from typing import AsyncIterable, Dict, Optional, Sequence, Union
|
7
|
+
|
8
|
+
import grpc
|
9
|
+
import msgspec
|
10
|
+
|
11
|
+
from .grpc.client import dec_hook
|
12
|
+
from .grpc.models.Cpty.CptyRequest import (
|
13
|
+
CancelOrder,
|
14
|
+
Login,
|
15
|
+
Logout,
|
16
|
+
PlaceOrder,
|
17
|
+
UnannotatedCptyRequest,
|
18
|
+
)
|
19
|
+
from .grpc.models.Cpty.CptyResponse import (
|
20
|
+
ReconcileOpenOrders,
|
21
|
+
Symbology,
|
22
|
+
UpdateAccountSummary,
|
23
|
+
)
|
24
|
+
from .grpc.models.definitions import (
|
25
|
+
AccountIdOrName,
|
26
|
+
AccountPosition,
|
27
|
+
AccountStatistics,
|
28
|
+
CptyLoginRequest,
|
29
|
+
CptyLogoutRequest,
|
30
|
+
ExecutionInfo,
|
31
|
+
FillKind,
|
32
|
+
OrderDir,
|
33
|
+
OrderId,
|
34
|
+
OrderRejectReason,
|
35
|
+
UserId,
|
36
|
+
)
|
37
|
+
from .grpc.models.Oms.Cancel import Cancel
|
38
|
+
from .grpc.models.Oms.Order import Order
|
39
|
+
from .grpc.models.Orderflow.OrderflowRequest import (
|
40
|
+
OrderflowRequestUnannotatedResponseType,
|
41
|
+
TaggedCancelReject,
|
42
|
+
TaggedFill,
|
43
|
+
TaggedOrderAck,
|
44
|
+
TaggedOrderCanceled,
|
45
|
+
TaggedOrderOut,
|
46
|
+
TaggedOrderReject,
|
47
|
+
)
|
48
|
+
from .grpc.models.Orderflow.SubscribeOrderflowRequest import SubscribeOrderflowRequest
|
49
|
+
from .grpc.utils import encoder
|
50
|
+
|
51
|
+
FILLS_NS = uuid.UUID("c4b64693-40d2-5613-8d13-bf35b89f92e0")
|
52
|
+
|
53
|
+
|
54
|
+
class AsyncCpty:
|
55
|
+
"""
|
56
|
+
To implement an external cpty, subclass `AsyncCpty` and implement the callback
|
57
|
+
stubs `on_login`, `on_place_order`, etc. Use provided methods `ack_order`,
|
58
|
+
`out_order`, etc. to drive orderflow events to consumers.
|
59
|
+
|
60
|
+
Call `add_execution_info` to add execution info for a symbol.
|
61
|
+
|
62
|
+
Call `serve` to start the server and wait for termination.
|
63
|
+
|
64
|
+
For manual control of the grpc server, create your own `grpc.aio.Server`
|
65
|
+
and call `_add_method_handlers` to add the method handlers.
|
66
|
+
|
67
|
+
You can use as much or as little of this helper as desired.
|
68
|
+
"""
|
69
|
+
|
70
|
+
def __init__(self, execution_venue: str):
|
71
|
+
self.execution_venue = execution_venue
|
72
|
+
self.execution_venue_fills_ns = uuid.uuid5(FILLS_NS, execution_venue)
|
73
|
+
self.execution_info: Dict[str, Dict[str, ExecutionInfo]] = {}
|
74
|
+
self.cpty_notifications: dict[int, CptyNotifications] = {}
|
75
|
+
self.orderflow_subscriptions: dict[int, OrderflowSubscription] = {}
|
76
|
+
self.next_subscription_id = 1
|
77
|
+
|
78
|
+
def add_execution_info(self, symbol: str, execution_info: ExecutionInfo):
|
79
|
+
"""
|
80
|
+
Add execution info for a symbol.
|
81
|
+
"""
|
82
|
+
self.execution_info[self.execution_venue][symbol] = execution_info
|
83
|
+
|
84
|
+
async def on_login(self, _request: CptyLoginRequest):
|
85
|
+
raise NotImplementedError
|
86
|
+
|
87
|
+
async def on_logout(self, _request: CptyLogoutRequest):
|
88
|
+
raise NotImplementedError
|
89
|
+
|
90
|
+
async def on_place_order(self, _order: Order):
|
91
|
+
"""
|
92
|
+
Called when the cpty receives an order to place.
|
93
|
+
|
94
|
+
Call `ack_order` or `reject_order` to advance the order state;
|
95
|
+
otherwise, the order will be left in the `PENDING` state.
|
96
|
+
"""
|
97
|
+
raise NotImplementedError
|
98
|
+
|
99
|
+
async def on_cancel_order(
|
100
|
+
self, _cancel: Cancel, _original_order: Optional[Order] = None
|
101
|
+
):
|
102
|
+
"""
|
103
|
+
Called when the cpty receives a cancel order request.
|
104
|
+
|
105
|
+
Call `reject_cancel` if there's a problem with canceling the order;
|
106
|
+
make sure to reference the `cancel.cancel_id` to identify the cancel.
|
107
|
+
|
108
|
+
Args:
|
109
|
+
cancel: The cancel order request.
|
110
|
+
original_order: The original order that was cancelled, if the OMS knows it.
|
111
|
+
"""
|
112
|
+
raise NotImplementedError
|
113
|
+
|
114
|
+
async def get_open_orders(self) -> Sequence[Order]:
|
115
|
+
"""
|
116
|
+
Get all open orders. This is called at least once per client
|
117
|
+
connection/login. Return a list of known open orders.
|
118
|
+
"""
|
119
|
+
return []
|
120
|
+
|
121
|
+
def ack_order(self, order_id: OrderId, *, exchange_order_id: Optional[str] = None):
|
122
|
+
"""
|
123
|
+
Acknowledge an order has reached the exchange.
|
124
|
+
|
125
|
+
Optionally, provide the exchange order id to correlate with the order;
|
126
|
+
this helps with order reconciliation.
|
127
|
+
"""
|
128
|
+
order_ack = TaggedOrderAck(order_id, exchange_order_id)
|
129
|
+
self._put_orderflow_event(order_ack)
|
130
|
+
|
131
|
+
def reject_order(
|
132
|
+
self,
|
133
|
+
order_id: OrderId,
|
134
|
+
*,
|
135
|
+
reject_reason: OrderRejectReason,
|
136
|
+
reject_message: Optional[str] = None,
|
137
|
+
):
|
138
|
+
"""
|
139
|
+
Reject an order.
|
140
|
+
"""
|
141
|
+
order_reject = TaggedOrderReject(order_id, reject_reason, reject_message)
|
142
|
+
self._put_orderflow_event(order_reject)
|
143
|
+
|
144
|
+
def out_order(self, order_id: OrderId, *, canceled: bool = False):
|
145
|
+
"""
|
146
|
+
Notify that an order is outed. If it was outed because of a cancel,
|
147
|
+
pass `canceled=True`. For all other reasons, pass `canceled=False`.
|
148
|
+
"""
|
149
|
+
if canceled:
|
150
|
+
order_out = TaggedOrderCanceled(order_id)
|
151
|
+
else:
|
152
|
+
order_out = TaggedOrderOut(order_id)
|
153
|
+
self._put_orderflow_event(order_out)
|
154
|
+
|
155
|
+
def fill_order(
|
156
|
+
self,
|
157
|
+
*,
|
158
|
+
dir: OrderDir,
|
159
|
+
exchange_fill_id: str,
|
160
|
+
# if not provided, a suitable uuiv5 will be generated from the exchange_fill_id
|
161
|
+
fill_id: Optional[str] = None,
|
162
|
+
fill_kind: FillKind = FillKind.Normal,
|
163
|
+
price: Decimal,
|
164
|
+
quantity: Decimal,
|
165
|
+
symbol: str,
|
166
|
+
trade_time: datetime,
|
167
|
+
account: AccountIdOrName,
|
168
|
+
is_taker: bool,
|
169
|
+
fee: Optional[Decimal] = None,
|
170
|
+
fee_currency: Optional[str] = None,
|
171
|
+
order_id: OrderId,
|
172
|
+
trader: Optional[UserId] = None,
|
173
|
+
):
|
174
|
+
"""
|
175
|
+
Notify that an order has been filled, either partially or in full.
|
176
|
+
"""
|
177
|
+
now = datetime.now()
|
178
|
+
if fill_id is None:
|
179
|
+
fill_id = str(uuid.uuid5(self.execution_venue_fills_ns, exchange_fill_id))
|
180
|
+
self._put_orderflow_event(
|
181
|
+
TaggedFill(
|
182
|
+
dir,
|
183
|
+
fill_id,
|
184
|
+
fill_kind,
|
185
|
+
price,
|
186
|
+
quantity,
|
187
|
+
symbol,
|
188
|
+
int(trade_time.timestamp()),
|
189
|
+
trade_time.microsecond * 1000,
|
190
|
+
self.execution_venue,
|
191
|
+
account,
|
192
|
+
1 if is_taker else 0,
|
193
|
+
int(now.timestamp()),
|
194
|
+
now.microsecond * 1000,
|
195
|
+
fee,
|
196
|
+
fee_currency,
|
197
|
+
order_id,
|
198
|
+
trader,
|
199
|
+
exchange_fill_id,
|
200
|
+
)
|
201
|
+
)
|
202
|
+
|
203
|
+
def reject_cancel(
|
204
|
+
self,
|
205
|
+
cancel_id: str,
|
206
|
+
*,
|
207
|
+
reject_reason: str,
|
208
|
+
reject_message: Optional[str] = None,
|
209
|
+
):
|
210
|
+
"""
|
211
|
+
Reject a cancel.
|
212
|
+
"""
|
213
|
+
self._put_orderflow_event(
|
214
|
+
TaggedCancelReject(cancel_id, reject_reason, reject_message)
|
215
|
+
)
|
216
|
+
|
217
|
+
def _put_orderflow_event(self, event):
|
218
|
+
for sub_id, sub in self.orderflow_subscriptions.items():
|
219
|
+
try:
|
220
|
+
sub.queue.put_nowait(event)
|
221
|
+
except asyncio.QueueFull:
|
222
|
+
logging.warn(f"orderflow subscription queue full #{sub_id}")
|
223
|
+
|
224
|
+
def update_account_summary(
|
225
|
+
self,
|
226
|
+
account: AccountIdOrName,
|
227
|
+
*,
|
228
|
+
is_snapshot: bool,
|
229
|
+
timestamp: datetime,
|
230
|
+
balances: Optional[Dict[str, Decimal]] = None,
|
231
|
+
positions: Optional[Dict[str, AccountPosition]] = None,
|
232
|
+
cash_excess: Optional[Decimal] = None,
|
233
|
+
equity: Optional[Decimal] = None,
|
234
|
+
yesterday_equity: Optional[Decimal] = None,
|
235
|
+
position_margin: Optional[Decimal] = None,
|
236
|
+
purchasing_power: Optional[Decimal] = None,
|
237
|
+
realized_pnl: Optional[Decimal] = None,
|
238
|
+
unrealized_pnl: Optional[Decimal] = None,
|
239
|
+
):
|
240
|
+
"""
|
241
|
+
Update account summary, as reported by the exchange.
|
242
|
+
|
243
|
+
Not all fields are required--fill only the fields that are relevant.
|
244
|
+
"""
|
245
|
+
positions_dict = None
|
246
|
+
if positions is not None:
|
247
|
+
positions_dict = {}
|
248
|
+
for symbol, position in positions.items():
|
249
|
+
positions_dict[symbol] = [position]
|
250
|
+
self._put_cpty_event(
|
251
|
+
UpdateAccountSummary(
|
252
|
+
account,
|
253
|
+
is_snapshot,
|
254
|
+
int(timestamp.timestamp()),
|
255
|
+
timestamp.microsecond * 1000,
|
256
|
+
balances,
|
257
|
+
positions_dict,
|
258
|
+
AccountStatistics(
|
259
|
+
cash_excess=cash_excess,
|
260
|
+
equity=equity,
|
261
|
+
yesterday_equity=yesterday_equity,
|
262
|
+
position_margin=position_margin,
|
263
|
+
purchasing_power=purchasing_power,
|
264
|
+
realized_pnl=realized_pnl,
|
265
|
+
unrealized_pnl=unrealized_pnl,
|
266
|
+
),
|
267
|
+
)
|
268
|
+
)
|
269
|
+
|
270
|
+
def _put_cpty_event(self, event):
|
271
|
+
for sub_id, sub in self.cpty_notifications.items():
|
272
|
+
try:
|
273
|
+
sub.queue.put_nowait(event)
|
274
|
+
except asyncio.QueueFull:
|
275
|
+
logging.warn(f"cpty notification queue full #{sub_id}")
|
276
|
+
|
277
|
+
async def Cpty(
|
278
|
+
self,
|
279
|
+
request_iterator: AsyncIterable[UnannotatedCptyRequest],
|
280
|
+
context: grpc.aio.ServicerContext,
|
281
|
+
):
|
282
|
+
context.set_code(grpc.StatusCode.OK)
|
283
|
+
await context.send_initial_metadata([])
|
284
|
+
logged_in: Optional[Login] = None
|
285
|
+
subscription_id = self.next_subscription_id
|
286
|
+
self.next_subscription_id += 1
|
287
|
+
|
288
|
+
def cleanup_subscription(_context):
|
289
|
+
if subscription_id is not None:
|
290
|
+
try:
|
291
|
+
del self.cpty_notifications[subscription_id]
|
292
|
+
logging.debug(f"cleaned up cpty notification #{subscription_id}")
|
293
|
+
except KeyError:
|
294
|
+
pass
|
295
|
+
|
296
|
+
context.add_done_callback(cleanup_subscription)
|
297
|
+
async for request in request_iterator:
|
298
|
+
logging.debug(f"Cpty: {request}")
|
299
|
+
if not logged_in and not isinstance(request, Login):
|
300
|
+
logging.error("not logged in, skipping request")
|
301
|
+
continue
|
302
|
+
if isinstance(request, Login):
|
303
|
+
try:
|
304
|
+
await self.on_login(request)
|
305
|
+
logged_in = request
|
306
|
+
logging.debug(f"registered cpty notification #{subscription_id}")
|
307
|
+
self.cpty_notifications[subscription_id] = CptyNotifications(
|
308
|
+
account=request.account,
|
309
|
+
trader=request.trader,
|
310
|
+
)
|
311
|
+
except NotImplementedError:
|
312
|
+
logging.error("on_login not implemented")
|
313
|
+
if logged_in:
|
314
|
+
# send symbology info to client
|
315
|
+
yield Symbology(self.execution_info)
|
316
|
+
# send open orders to client
|
317
|
+
open_orders = await self.get_open_orders()
|
318
|
+
yield ReconcileOpenOrders(list(open_orders))
|
319
|
+
elif isinstance(request, Logout):
|
320
|
+
try:
|
321
|
+
del self.cpty_notifications[subscription_id]
|
322
|
+
logged_in = None
|
323
|
+
await self.on_logout(request)
|
324
|
+
except NotImplementedError:
|
325
|
+
logging.error("on_logout not implemented")
|
326
|
+
elif isinstance(request, PlaceOrder):
|
327
|
+
try:
|
328
|
+
await self.on_place_order(request)
|
329
|
+
except NotImplementedError:
|
330
|
+
logging.error("on_place_order not implemented")
|
331
|
+
elif isinstance(request, CancelOrder):
|
332
|
+
try:
|
333
|
+
await self.on_cancel_order(request.cancel, request.original_order)
|
334
|
+
except NotImplementedError:
|
335
|
+
logging.error("on_cancel_order not implemented")
|
336
|
+
else:
|
337
|
+
logging.error(f"unhandled cpty request: {request}")
|
338
|
+
|
339
|
+
async def SubscribeOrderflow(
|
340
|
+
self, request: SubscribeOrderflowRequest, context: grpc.aio.ServicerContext
|
341
|
+
):
|
342
|
+
context.set_code(grpc.StatusCode.OK)
|
343
|
+
await context.send_initial_metadata([])
|
344
|
+
logging.debug(f"Orderflow: {request}")
|
345
|
+
subscription_id = self.next_subscription_id
|
346
|
+
self.next_subscription_id += 1
|
347
|
+
logging.debug(f"registered orderflow subscription #{subscription_id}")
|
348
|
+
|
349
|
+
def cleanup_subscription(_context):
|
350
|
+
del self.orderflow_subscriptions[subscription_id]
|
351
|
+
logging.debug(f"cleaned up orderflow subscription #{subscription_id}")
|
352
|
+
|
353
|
+
context.add_done_callback(cleanup_subscription)
|
354
|
+
subscription = OrderflowSubscription(request)
|
355
|
+
self.orderflow_subscriptions[subscription_id] = subscription
|
356
|
+
while True:
|
357
|
+
next_item = await subscription.queue.get()
|
358
|
+
yield next_item
|
359
|
+
|
360
|
+
def _add_cpty_method_handlers(self, server: grpc.aio.Server):
|
361
|
+
decoder = msgspec.json.Decoder(type=UnannotatedCptyRequest, dec_hook=dec_hook)
|
362
|
+
rpc_method_handlers = {
|
363
|
+
"Cpty": grpc.stream_stream_rpc_method_handler(
|
364
|
+
self.Cpty,
|
365
|
+
request_deserializer=decoder.decode,
|
366
|
+
response_serializer=encoder.encode,
|
367
|
+
),
|
368
|
+
}
|
369
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
370
|
+
"json.architect.Cpty", rpc_method_handlers
|
371
|
+
)
|
372
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
373
|
+
|
374
|
+
def _add_orderflow_method_handlers(self, server: grpc.aio.Server):
|
375
|
+
decoder = msgspec.json.Decoder(
|
376
|
+
type=SubscribeOrderflowRequest, dec_hook=dec_hook
|
377
|
+
)
|
378
|
+
rpc_method_handlers = {
|
379
|
+
"SubscribeOrderflow": grpc.unary_stream_rpc_method_handler(
|
380
|
+
self.SubscribeOrderflow,
|
381
|
+
request_deserializer=decoder.decode,
|
382
|
+
response_serializer=encoder.encode,
|
383
|
+
),
|
384
|
+
}
|
385
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
386
|
+
"json.architect.Orderflow", rpc_method_handlers
|
387
|
+
)
|
388
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
389
|
+
|
390
|
+
def _add_method_handlers(self, server: grpc.aio.Server):
|
391
|
+
self._add_cpty_method_handlers(server)
|
392
|
+
self._add_orderflow_method_handlers(server)
|
393
|
+
|
394
|
+
async def serve(self, bind: str):
|
395
|
+
server = grpc.aio.server()
|
396
|
+
self._add_method_handlers(server)
|
397
|
+
server.add_insecure_port(bind)
|
398
|
+
await server.start()
|
399
|
+
logging.info(f"grpc server started on {bind}")
|
400
|
+
await server.wait_for_termination()
|
401
|
+
|
402
|
+
|
403
|
+
class CptyNotifications:
|
404
|
+
account: Optional[AccountIdOrName] = None
|
405
|
+
trader: Optional[str] = None
|
406
|
+
queue: asyncio.Queue[Union[Symbology, ReconcileOpenOrders, UpdateAccountSummary]]
|
407
|
+
|
408
|
+
def __init__(
|
409
|
+
self, account: Optional[AccountIdOrName] = None, trader: Optional[str] = None
|
410
|
+
):
|
411
|
+
self.account = account
|
412
|
+
self.trader = trader
|
413
|
+
self.queue = asyncio.Queue()
|
414
|
+
|
415
|
+
|
416
|
+
class OrderflowSubscription:
|
417
|
+
request: SubscribeOrderflowRequest
|
418
|
+
queue: asyncio.Queue[OrderflowRequestUnannotatedResponseType]
|
419
|
+
|
420
|
+
def __init__(self, request: SubscribeOrderflowRequest):
|
421
|
+
self.request = request
|
422
|
+
self.queue = asyncio.Queue()
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import asyncio
|
2
|
+
import logging
|
3
|
+
import random
|
4
|
+
import string
|
5
|
+
|
6
|
+
from architect_py import (
|
7
|
+
Cancel,
|
8
|
+
CptyLoginRequest,
|
9
|
+
CptyLogoutRequest,
|
10
|
+
Order,
|
11
|
+
)
|
12
|
+
from architect_py.async_cpty import *
|
13
|
+
|
14
|
+
|
15
|
+
class ExampleCpty(AsyncCpty):
|
16
|
+
def __init__(self):
|
17
|
+
super().__init__("EXAMPLE")
|
18
|
+
|
19
|
+
async def on_login(self, request: CptyLoginRequest):
|
20
|
+
print(
|
21
|
+
f"👋 got login request from trader={request.trader} and account={request.account}"
|
22
|
+
)
|
23
|
+
|
24
|
+
async def on_logout(self, request: CptyLogoutRequest):
|
25
|
+
print("👋 got logout request")
|
26
|
+
|
27
|
+
async def on_place_order(self, order: Order):
|
28
|
+
# pretend we're connected to something, ack the order within 1s,
|
29
|
+
# then randomly out or fill the order after 3s
|
30
|
+
print(f"🎟️ place order: {order}")
|
31
|
+
asyncio.create_task(mock_order_lifecycle(self, order))
|
32
|
+
|
33
|
+
async def on_cancel_order(
|
34
|
+
self, cancel: Cancel, _original_order: Optional[Order] = None
|
35
|
+
):
|
36
|
+
self.reject_cancel(
|
37
|
+
cancel.cancel_id,
|
38
|
+
reject_reason="cancels always get rejected in this example",
|
39
|
+
)
|
40
|
+
|
41
|
+
async def get_open_orders(self) -> Sequence[Order]:
|
42
|
+
return []
|
43
|
+
|
44
|
+
|
45
|
+
def random_id(length=10):
|
46
|
+
CHARS = string.ascii_uppercase + string.digits
|
47
|
+
return "".join(random.choice(CHARS) for _ in range(length))
|
48
|
+
|
49
|
+
|
50
|
+
async def mock_order_lifecycle(cpty: ExampleCpty, order: Order):
|
51
|
+
await asyncio.sleep(1)
|
52
|
+
exchange_order_id = random_id()
|
53
|
+
print(f"🎟️ ack order: {order.id} with exchange_order_id={exchange_order_id}")
|
54
|
+
cpty.ack_order(order.id, exchange_order_id=exchange_order_id)
|
55
|
+
|
56
|
+
await asyncio.sleep(3)
|
57
|
+
if random.random() < 0.5:
|
58
|
+
now = datetime.now()
|
59
|
+
print(f"🎟️ fill order: {order.id}")
|
60
|
+
cpty.fill_order(
|
61
|
+
order_id=order.id,
|
62
|
+
exchange_fill_id=random_id(),
|
63
|
+
dir=order.dir,
|
64
|
+
price=Decimal(13.37),
|
65
|
+
quantity=order.quantity,
|
66
|
+
symbol=order.symbol,
|
67
|
+
trade_time=now,
|
68
|
+
account=order.account,
|
69
|
+
is_taker=True,
|
70
|
+
)
|
71
|
+
else:
|
72
|
+
print(f"🎟️ out order: {order.id}")
|
73
|
+
cpty.out_order(order.id, canceled=False)
|
74
|
+
|
75
|
+
|
76
|
+
async def serve():
|
77
|
+
cpty = ExampleCpty()
|
78
|
+
await cpty.serve("[::]:50051")
|
79
|
+
|
80
|
+
|
81
|
+
if __name__ == "__main__":
|
82
|
+
logging.basicConfig(level=logging.DEBUG)
|
83
|
+
asyncio.run(serve())
|
@@ -115,7 +115,9 @@ def main(architect_path: Path, output: Path):
|
|
115
115
|
|
116
116
|
unique = sorted(set(model_all))
|
117
117
|
model_lines.append("")
|
118
|
-
|
118
|
+
|
119
|
+
model_lines_all_list = ", ".join(f'"{n}"' for n in model_all)
|
120
|
+
model_lines.append(f"__all__ = [{model_lines_all_list}]")
|
119
121
|
model_lines.append("")
|
120
122
|
|
121
123
|
(models_root / "__init__.py").write_text("\n".join(model_lines))
|
@@ -123,7 +125,9 @@ def main(architect_path: Path, output: Path):
|
|
123
125
|
# 3) write __all__
|
124
126
|
unique = sorted(set(all_names))
|
125
127
|
import_lines.append("") # blank line
|
126
|
-
|
128
|
+
|
129
|
+
import_lines_all_list = ", ".join(f'"{n}"' for n in unique)
|
130
|
+
import_lines.append(f"__all__ = [{import_lines_all_list}]")
|
127
131
|
|
128
132
|
import_lines.append("") # blank line
|
129
133
|
|
@@ -1,78 +0,0 @@
|
|
1
|
-
import time
|
2
|
-
from concurrent import futures
|
3
|
-
from decimal import Decimal
|
4
|
-
from typing import Iterator
|
5
|
-
|
6
|
-
import grpc
|
7
|
-
|
8
|
-
from architect_py import (
|
9
|
-
CptyLoginRequest,
|
10
|
-
CptyLogoutRequest,
|
11
|
-
ExecutionInfo,
|
12
|
-
MinOrderQuantityUnit,
|
13
|
-
SimpleDecimal,
|
14
|
-
Unit,
|
15
|
-
)
|
16
|
-
from architect_py.grpc.models.Cpty.CptyResponse import Symbology
|
17
|
-
from architect_py.grpc.models.Orderflow.OrderflowRequest import CancelOrder, PlaceOrder
|
18
|
-
from architect_py.grpc.server import (
|
19
|
-
CptyServicer,
|
20
|
-
OrderflowServicer,
|
21
|
-
add_CptyServicer_to_server,
|
22
|
-
add_OrderflowServicer_to_server,
|
23
|
-
)
|
24
|
-
|
25
|
-
|
26
|
-
class MockCptyServicer(CptyServicer, OrderflowServicer):
|
27
|
-
def Cpty(self, request_iterator: Iterator, context):
|
28
|
-
context.set_code(grpc.StatusCode.OK)
|
29
|
-
context.send_initial_metadata({})
|
30
|
-
# send symbology
|
31
|
-
yield Symbology(
|
32
|
-
execution_info={
|
33
|
-
"FOO Crypto/USD": {
|
34
|
-
"MOCK": ExecutionInfo(
|
35
|
-
execution_venue="MOCK",
|
36
|
-
exchange_symbol=None,
|
37
|
-
tick_size=SimpleDecimal(Decimal("0.01")),
|
38
|
-
step_size=Decimal("0.1"),
|
39
|
-
min_order_quantity=Decimal(0),
|
40
|
-
min_order_quantity_unit=MinOrderQuantityUnit(Unit.base),
|
41
|
-
is_delisted=False,
|
42
|
-
initial_margin=None,
|
43
|
-
maintenance_margin=None,
|
44
|
-
),
|
45
|
-
}
|
46
|
-
}
|
47
|
-
)
|
48
|
-
for req in request_iterator:
|
49
|
-
if isinstance(req, CptyLoginRequest):
|
50
|
-
print("login message received", req)
|
51
|
-
elif isinstance(req, CptyLogoutRequest):
|
52
|
-
print("logout message received", req)
|
53
|
-
elif isinstance(req, PlaceOrder):
|
54
|
-
print("place_order message received", req)
|
55
|
-
elif isinstance(req, CancelOrder):
|
56
|
-
print("cancel_order message received", req)
|
57
|
-
|
58
|
-
def SubscribeOrderflow(self, request, context):
|
59
|
-
context.set_code(grpc.StatusCode.OK)
|
60
|
-
context.send_initial_metadata({})
|
61
|
-
print("client subscribed to orderflow")
|
62
|
-
time.sleep(1000)
|
63
|
-
|
64
|
-
|
65
|
-
def serve():
|
66
|
-
thread_pool = futures.ThreadPoolExecutor(max_workers=10)
|
67
|
-
server = grpc.server(thread_pool)
|
68
|
-
servicer = MockCptyServicer()
|
69
|
-
add_CptyServicer_to_server(servicer, server)
|
70
|
-
add_OrderflowServicer_to_server(servicer, server)
|
71
|
-
server.add_insecure_port("[::]:50051")
|
72
|
-
server.start()
|
73
|
-
print("server started on port 50051")
|
74
|
-
server.wait_for_termination()
|
75
|
-
|
76
|
-
|
77
|
-
if __name__ == "__main__":
|
78
|
-
serve()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{architect_py-5.1.6 → architect_py-5.2.0}/architect_py/graphql_client/get_execution_info_query.py
RENAMED
File without changes
|