Beware! Trading pair format has changed. It is a breaking change

My trading app suddenly stopped working

After a few hours of debugging, the cause was identified to be a recent change to how trading pairs are specified

For example
The format used to be BTCUSD
It is now BTC/USD (with a forward slash separator)

I noticed in the developer documentation it states backwards compatibility. This does not appear to be entirely true. It may be possible to place trades using the previous format, but I have a web socket that listens to trade events. The coin pair comes through as the new format, causing a currency pair inconsistency between the trade placed and the notification event for the executed trade.

“Note that symbology for trading pairs has changed from our previous format, where BTC/USD was previosly referred to as BTCUSD. Our API has made proper changes to support the legacy convention as well for backwards compatibility.”

1 Like

Hi @Robotronic

The team is aware of the issue, we are on working to fix this.
We will reach you once it’s been resolved, thank you

1 Like

Hi @Robotronic

The fixing has been deployed in sandbox and staging.
Thank you


The problem still exists in the sandbox

Placing an order works but the trade event (reported via web socket subscription) reports the new format as the currency pair, even though the old format was used in the order execution

This causes problems for any code logic that is keyed off the currency pair as reported in the trade event in the web socket. This is because the currency pair does not match the pair specified in the trade.

As a fix, I’ll update to the new format. The issue is backwards compatibility. the old format no longer works in web sockets because web sockets uses the new format regardless.

Hi @Robotronic
could you please to share me, how do you retrieve the assets data? please also share us the payload and screen shoot of the result

i just retried it and seems it’s all good.
the endpoint:

thank you

To be clear, the problem is with the web stream, not a regular request to place an order.

The problem cannot be demonstrated with just a regular request, payload and response.

The expectation is that the currency pair received in a trade event message, notified via a web socket should match the currency pair specified in the request to create the order.

It does not. It is not backwards compatible when using a web socket to listen to trades

Code to create a web socket and listen to trade events is similar to below -

socket = new WebSocket(“wss://”);

// Helper method to convert binary stream data to text
const binaryToString = (buf: any): string => String.fromCharCode.apply(null, new Uint16Array(buf));

const auth = { action: ‘authenticate’, data: { key_id: process.env.API_KEY, secret_key: process.env.SECRET_KEY, } };

const onTradeEvent = async (event: any) => { const message = binaryToString(event);

socket.once(‘open’, () => { socket.send(JSON.stringify(auth)); socket.on(‘message’, onTradeEvent); });

Sample event message received

Notice the currency pair. received It is ETH/USD ( the new format, forward slash) This is despite the order using the legacy format of ETHUSD (old format, no forward slash)

It is not backward compatible when using a web stream to listen to trade events.


Hi @Robotronic thanks for the brief, we will check on our event stream function

Hi @Robotronic we found the order d9d9db5c-9314-49d2-9148-a37b90aa9503 was placed with symbol: ETH/USD

please let us know if the order is not align with yours. thank you

Hi @Robotronic
I just want to clarify.

In paper, we set it to have the crypto in the new format (BTC/USD). While, in production we still have it in old format (BTCUSD), and we still don’t have any ETA to implement the new format to production.

Please let me know, if you want your paper account’s config as the old one. We can help you to change it by our ops team.

Thank you

No it does not align

I can upgrade my code to work with the new format, but the point is , it is not backwards compatible. When rolled out to product it will break some apps, unless the apps are upgraded to support the new format

Explained a different way

Here is the problem

Create an order using the old the old currency pair format - ETHUSD

Behind the scenes this is automagically updated to the new format ETH/USD ( fine so far)

Query a transaction

The new format is returned ( even though the order was created using the old format

This is asymmetrical and can break code that uses the currency pair as a key to some business logic

1 Like

@Radzi_Purba_LPCA, this change also broke functionality in our Portfolio Management application.

Feather Finance users with positions on crypto pairs before the change started seeing two positions (one new, one old) when trading those same pairs after the change (for the same reason described by @Robotronic). That is, any trade done after the change creates a positions on the new pair, whereas the legacy position on the old currency pair remained unchanged.

Is there an official communication channel where Alpaca broadcasts upcoming changes so that developers can prepare ahead of time?


1 Like

Not sure what is being asked here

I don’t want my account to have a customized workaround

Any solution should apply to all developers

It’s worse than I initially thought. It’s not only a backwards compatibility breaking problem. It doesn’t even work if following an upgrade path

  1. Create an order using the new format ETH/USD
  2. call get positions API

get positions returns the old format ETHUSD

Hi @Robotronic thanks for the brief. I have escalated the issue to our engineering team.

just want to make it sure, so we have two issues here:

  1. when we place the crypto order with asset’s old format, the returned success response is in a new asset format.
  2. when we place the crypto order with asset’s new format, in the get positions endpoint, we have it in the old format.

here are my postman:

1 Like

Hi @Radzi_Purba_LPCA,

Your post correctly summarizes the root cause of the issues faced by Feather Finance users. Thanks for doing that.

Perhaps you should also add a 3rd bullet to cover the web socket use case described by @Robotronic?

Also, while discussing this with your engineering team, maybe you could point out that, in actual fact, this change was not backward compatible. It would be great if breaking changes such as this one were clearly communicated to the community ahead of time (e.g. in a dedicated Slack channel or in a dedicated mailing list).


Hi @Xavier_Robitaille

Thanks for the feed back, i have also bring this up. Hope we can do it better for future deployment.
Your suggestion is greatly appreciated, thank you

1 Like


RE - just want to make it sure, so we have two issues here:

  1. when we place the crypto order with asset’s old format, the returned success response is in a new asset format.
  2. when we place the crypto order with asset’s new format, in the get positions endpoint, we have it in the old format.

There are at least 3 issues,
Another failing test case is to place orders using the old format (example ETHUSD)
Open a web socket and subscribe to trade events, The current pair received is ETH/USD

1 Like

Great stuff thanks for sharing

Is this fixed? I’m having this issue with the new Alpaca-py API.

The CryptoDataStream method is not streaming ETH/BTC nor ETHBTC. It works with ETHUSD and BTCUSD

from import StockDataStream, CryptoDataStream
from import DataFeed
from dotenv import load_dotenv
import os

# keys required
stock_wss_client = StockDataStream(
    # feed = DataFeed.IEX
    feed = DataFeed.SIP

crypto_wss_client = CryptoDataStream(

# print(crypto_wss_client)

# async handler
async def quote_data_handler(data):
    # quote data will arrive here

crypto_wss_client.subscribe_quotes(quote_data_handler, "ETHBTC")
# crypto_wss_client.subscribe_quotes(quote_data_handler, "ETH/BTC")
# crypto_wss_client.subscribe_quotes(quote_data_handler, "BTCUSD", "ETHUSD")

# stock_wss_client.subscribe_quotes(quote_data_handler, "SPY")
# stock_wss_client.subscribe_quotes(quote_data_handler, "NDAQ")