Alphanume

Guide

How to Request Short Locates with the TradeZero API

Check borrow availability, request TradeZero locate quotes, calculate the full lot cost, and confirm inventory before shorting Alphanume-ranked stocks.

A short sale starts by selling borrowed shares. A locate is the broker's process for finding shares you can borrow. An Alphanume rank tells you which stock the model flagged; it does not tell you whether shares are available or what they cost.

This example requires an Alphanume API key with access to Pre-Market Drop Risk. TradeZero handles the account and execution; Alphanume supplies the ranked candidates. TradeZero's API can use other data, but this starter is built around Alphanume. See dataset access and plans.

Download the Python starter, Windows wrapper, and offline tests. Extract it before running commands. The ZIP includes setup instructions and the complete source.

Check borrow before requesting a quote

After connecting the account, use tz.easy_to_borrow(symbol). The client reads GET /v1/api/accounts/{accountId}/is-easy-to-borrow/symbol/{symbol}. A response containing isEasyToBorrow: true lets the starter move to order construction without buying a new locate.

If the stock is hard to borrow, inspect existing inventory first. This starter requires one inventory row with enough available shares for the ticket. It does not add together different locate products and assume they can be used interchangeably.

Follow the quote lifecycle

The API steps below come from the deployed client's interface and are checked against TradeZero's short-locate reference. Notice the different account field names on quote and accept.

  1. Quote: POST to /v1/api/accounts/locates/quote with account, symbol, quantity and a unique quoteReqID.
  2. Poll: GET the account's /locates/history. Match the request ID and its possible .SU sibling. An acknowledgement alone is not a priced offer.
  3. Decide: compare the full quoted lot cost with your ticket's reference notional.
  4. Accept: POST to /v1/api/accounts/locates/accept with accountId and the selected quoteReqID. This is the paid step.
  5. Confirm: read /locates/inventory and confirm usable shares before sending the short order.

To decline, the client uses DELETE /v1/api/accounts/locates/cancel/accounts/{accountId}/quoteReqID/{quoteReqID}. The starter cancels an uneconomic or unavailable quote and skips that candidate. If acceptance is uncertain, it stops for reconciliation rather than spending again.

Calculate the cost of the whole lot

The starter rounds a locate request up to a multiple of 100 shares. A 40-share short at a $5 reference price has $200 of reference notional. At a locate price of $0.05 per share, the 100-share locate costs $5, or 2.5% of that notional. Calculating only 40 times the fee would understate the cost.

def locate_cost(quantity, price, fee):
    lots = math.ceil(quantity / 100) * 100
    return lots, lots * fee, lots * fee / (quantity * price)

This function returns the requested lot size, dollar cost and cost fraction. The starter's default cap is 1%; the example above would be skipped. That default is a teaching choice, not evidence that a 1% locate is profitable. A paid fee can remain spent even if the subsequent order does not fill.

Match the actual offer

def offered(history, quote_id):
    valid = [r for r in history if r.get("quoteReqID") in (quote_id, quote_id + ".SU")
             and str(r.get("locateStatus")) in ("65", "Offered")
             and math.isfinite(float(r.get("locatePrice") or 0)) and float(r.get("locatePrice") or 0) > 0]
    return min(valid, key=lambda r: float(r["locatePrice"])) if valid else None

The function ignores pending, unpriced and unrelated rows. When both matching pools have priced offers, it selects the cheaper one. The accepted identifier is saved before the request. After acceptance, the runner checks inventory again instead of treating an HTTP response as borrow confirmation.

Enable fees separately from order submission

Ordinary previews make no locate writes. In live entry mode, --submit alone still skips hard-to-borrow names without sufficient existing inventory. Adding --accept-locate-fees permits quote, accept and cancel calls for the Alphanume candidates. Read the complete run command in the ZIP's README before enabling it.

Common questions

Why did a successful quote request produce no shares?

The request and the offer are separate stages. Poll the matching history rows; unavailable inventory may never become a priced offer. The starter times out and skips instead of assuming borrow exists.

Can I test paid locates on paper?

The official locate workflow uses live inventory. Offline tests cover the starter's decisions without spending fees, but they cannot reproduce your account's real borrow supply.

Does covering automatically refund the locate?

The starter makes no refund assumption and does not implement credit-backs. Review the broker's applicable locate terms and any unused inventory separately.

Next: construct opening short orders. See the overview for the full sequence.

API documentation checked September 27, 2026. Route availability and account access can change. Examples describe the included starter; they do not establish trading performance.