Skip to content

v0.2.0

Choose a tag to compare

@aiiven aiiven released this 31 Oct 02:53
· 68 commits to main since this release
6e52008

Package version: 0.2.0. Git tag: v0.2.0.

This release replaces 0.1.0-alpha.49 and covers every change since it.
From 0.2.0 on, the Go, Python and Rust SDKs share one version number and
are released together. Versions are plain SemVer (0.2.0, 0.2.1, ...) and
git tags are vX.Y.Z; the alpha pre-release suffixes (0.1.0-alpha.N, tag
v0.1.0aN) are retired. Upgrade from any 0.1.0-alpha.* release: those
releases use hosts that no longer exist and a price scale 1,000 times off
against the current API.

Breaking

  • Trading prices now use the published fixed scale of 9 decimals: one
    price tick is 0.000000001 quote units.
    PRICE_TICK_SCALE is 9, so
    Price::from_decimal_str, Price::as_decimal, Price::format, order,
    trigger, trade, orderbook, market-overview and primary candle prices
    encode and decode at 1e-9. Earlier releases used 1e-6 and are 1,000
    times off against the current API. Code that builds Price::from_ticks
    values by hand must multiply its old tick values by 1,000.
  • OrdersService::subscribe streams account orders over the private
    WebSocket (/v1/ws/private) and returns a PrivateOrdersSubscription
    of PrivateOrdersEvents (Connected, Snapshot, Unit, Ready,
    Stale, Disconnected, Error) instead of a TypedSubscription<Order>. The
    realtime order channels it used are retired and no longer issue
    subscribe tokens. Snapshot and unit orders use the same Order model as
    the order reads; units also carry removed order IDs and order events.
    The call returns at once: the handshake result arrives as Connected or
    Error. The stream resumes from its last position after a gap or a
    reconnect, and calls for the same account share one server subscription.
    Ready arrives once per server subscription when the stream reaches the
    account's read boundary; wait for it before relying on the stream. A
    consumer that joins a ready stream gets it right after its catch-up
    snapshot. Stale carries an OrdersStale with stale, the lowercase
    reason (view_behind, order_unavailable, ...) and order_ids: with
    order_unavailable only those orders are not current, the rest of the
    view is and units keep arriving. A later report replaces the earlier one,
    and a consumer that joins a stale stream gets the current report.
  • Removed codecs::decode::order_from_bytes, the decoder for the retired
    order channel's publications.
  • ModifyTriggerParams.limit_price is removed: a trigger's child limit
    price is fixed at create, and the API rejects any modify that sets it.
  • CancelAllOrdersResult, CancelAllAfterResult, GetOrderResult,
    LifecycleFlowSummary, MarketTradesResult, GetTradesOpts and
    Trigger gain fields (below). These structs are not #[non_exhaustive],
    so code that builds them with struct literals must add them.

Fixed

  • POLYESTER_TESTNET_ENVIRONMENT and environment_from_name("testnet") now
    use https://api.testnet.polyester.com and wss://api.testnet.polyester.com.
    Earlier versions pointed at api-testnet.polyester.com, which does not
    exist, so every testnet call failed with a DNS error. The devnet preset and
    DEFAULT_API_URL / DEFAULT_WS_URL now use the documented
    api.devnet.polyester.com host.
  • An order create, trigger create, order cancel or order modify that was sent
    but not confirmed in time (ERROR_CODE_ORDER_CREATE_OUTCOME_UNKNOWN,
    ERROR_CODE_TRIGGER_CREATE_OUTCOME_UNKNOWN,
    ERROR_CODE_ORDER_CANCEL_OUTCOME_UNKNOWN,
    ERROR_CODE_ORDER_MODIFY_OUTCOME_UNKNOWN) now reports
    mutation_outcome_unknown() and is_retryable() true. It may still apply:
    read the order or trigger back before retrying. Earlier versions reported
    it as a definite failure. errors::order_codes lists these codes.
  • AUTH_TEMPORARILY_UNAVAILABLE is now retryable: the account request
    changed nothing, so send the same request again.
  • Stop-loss and take-profit triggers with a market child now send their
    slippage cap.
    max_slippage_ticks / max_slippage_bps were dropped on
    create, so the child used the pair's default market slippage instead of
    the requested cap. At most one of them is accepted, a sell child takes
    fewer than 10000 bps, and a limit child rejects them.
  • Order reads no longer report an attached-risk leg whose state is
    not_configured; the server sends that state for a leg the order does
    not have.
  • An API error whose order, auth, withdraw or transfer code is newer than
    this SDK version now reports code = "UNKNOWN_ERROR_CODE(<n>)" instead
    of ERROR_CODE_UNSPECIFIED or AUTH_UNSPECIFIED, so the server's code is
    never lost.

Added

  • Index-price triggers and attached legs: CreateTriggerParams.trigger_price_source
    (last, index or mark, the labels trigger reads use) is sent for
    stop-loss, take-profit and trailing-stop triggers, and
    RiskLeg.trigger_price_source / TrailingStop.trigger_price_source are
    sent on order create and modify. None watches the last trade price.
    Order reads now fill these leg fields, which are no longer deprecated, so
    a read leg can be sent back unchanged. An unknown label is a validation
    error, and TWAP and ladder triggers reject a price source.
  • CancelAllOrdersResult.listing_status: included, or
    not_retained_read_open_orders when a retry with the same request_id
    returns the original counts with an empty cancelled_orders. An empty
    retried list does not mean nothing was canceled.
  • CancelAllAfterResult.effective_scope: the account, symbol and side the
    armed switch cancels (DeadManSwitchScope); None when disabled.
  • GetOrderResult.executions_complete: true when the order's trades across
    every page add up to its filled quantity.
  • LifecycleFlowSummary.is_delayed: an open flow that has made no progress
    for well beyond its expected step time. Lifecycle reason
    deposit_source_not_confirmed.
  • Trigger reads name the cancel reasons account_repair,
    pair_drain_trigger, pair_drain_twap, pair_drain_ladder and
    pair_drain_attached_leg, and the failure reasons
    index_price_unavailable and trigger_would_trigger_immediately. Spot
    config reports halted pairs as PAIR_STATUS_HALTED.
  • Standalone BUY trailing stops: CreateTriggerParams.limit_price is the
    required maximum price of a BUY trailing stop (limit_price_ticks), and
    must be None for a SELL one. Trigger reads show a BUY trailing stop
    as an IOC limit child (order_type limit, time_in_force ioc) with
    the maximum price as Trigger.limit_price; the trailing details carry the
    trough price.
  • Trigger.max_slippage: the slippage cap of a stop-loss or take-profit
    market child, or of a trailing stop.
  • CancelAllOrdersResult.cancelled_orders (order ID and client order ID,
    oldest first, at most 200), total_cancelled and truncated.
  • Gap-free trade backfill: GetTradesOpts.after_trade_id (not combinable
    with start, end or page_token), and
    MarketTradesResult.complete_through_trade_id, next_after_trade_id and
    epoch_ends. Zero is a valid cursor and watermark.
  • OrderMutationResult (order create), ModifyOrderResult and accepted
    BatchCreateResultItems carry take_profit_trigger_id,
    stop_loss_trigger_id and trailing_stop_trigger_id: the public ID of
    each attached-risk leg's trigger, and None for a leg the order does not
    have. These structs are not #[non_exhaustive], so code that builds them
    with struct literals or destructures them exhaustively must add the new
    fields.
  • realtime::Client::subscribe_private_orders(account_id) and
    proto::privatews (the private WebSocket contract).
  • Trigger events report event_type = "activated" when a standalone
    trailing trigger's activation condition is met and tracking begins.
    trigger_event_type_from_label("activated") filters for them.
  • The generated proto and connect modules now include checkpoints::v1,
    claims::v1, rewards::v1, swap::v1 and swap::quickswap::v1. Their
    code was already in the package but was not compiled into the crate.
    These services have no Client wrappers: they need an interactive
    session or a broker key, which this API-key SDK does not use.

Changed

  • MaxSlippage::Ticks and the trigger create/modify max_slippage_ticks
    are now i64 absolute price ticks, matching the 64-bit contract fields.
  • Candle and market-overview base volume now use the base asset
    market_data_volume_scale from get_spot_config. Primary candle prices
    use the fixed price scale of 9.
  • Composite reference-candle OHLC uses the pair reference_price_scale.
    GetCandlesOpts.include_reference requests that series.
    MarketOverviewEntry.volume_24h_base is the decoded decimal when the
    catalog scale is known; volume_24h_base_scaled stays the integer.
  • The crate documentation link and the README links to the SDK capability
    matrix and market order price protection point at the public docs on
    polyester.com.