Version: 2.4.1 (code unchanged on current master)
Poloniex._trade (poloniex.py#L55-L82) has three problems, all visible against the sample message in its own docstring:
{
'channel': 'trades',
'data': [{
'symbol': 'BTC_USDT',
'amount': '364.89973',
'quantity': '0.017',
'takerSide': 'sell',
'createTime': 1661120814818,
'price': '21464.69',
'id': '60183607',
'ts': 1661120814823
}]
}
1. Trade.amount is set to quote notional, not base quantity
The handler emits the raw amount field as Trade.amount. But in Poloniex's trades channel, amount is the quote-currency notional and quantity is the base-unit size. In the docstring sample itself: 21464.69 × 0.017 = 364.89973 — i.e. amount == price × quantity exactly. I also verified this live: across received messages, amount / (price × quantity) == 1.0 with no deviation.
Every other exchange adapter populates Trade.amount with base units, so Poloniex trades come out inflated by a factor of ~price (a 0.017 BTC trade is reported as 364.9 "BTC"). It should be Decimal(entry['quantity']).
2. Trade id is passed as the exchange positional
Trade.__init__ is (exchange, symbol, side, amount, price, timestamp, id=None, type=None, raw=None), but the handler passes msg['data'][0]['id'] as the first positional:
t = Trade(
msg['data'][0]['id'], # <- lands in Trade.exchange
self.exchange_symbol_to_std_symbol(msg['data'][0]['symbol']),
...
)
Result: Trade.exchange is '60183607' instead of 'POLONIEX', and Trade.id is None. The first argument should be self.id, with id=str(entry['id']) passed as the keyword.
3. Only data[0] is parsed; the rest of a batch is dropped
data is a list and Poloniex does deliver multiple trades per message, but the handler only reads msg['data'][0], silently discarding the others.
Suggested fix
async def _trade(self, msg: dict, timestamp: float):
for entry in msg['data']:
t = Trade(
self.id,
self.exchange_symbol_to_std_symbol(entry['symbol']),
SELL if entry['takerSide'] == 'sell' else BUY,
Decimal(entry['quantity']),
Decimal(entry['price']),
self.timestamp_normalize(entry['ts']),
id=str(entry['id']),
raw=msg
)
await self.callback(TRADES, t, timestamp)
Happy to open a PR if that helps.
Version: 2.4.1 (code unchanged on current master)
Poloniex._trade(poloniex.py#L55-L82) has three problems, all visible against the sample message in its own docstring:{ 'channel': 'trades', 'data': [{ 'symbol': 'BTC_USDT', 'amount': '364.89973', 'quantity': '0.017', 'takerSide': 'sell', 'createTime': 1661120814818, 'price': '21464.69', 'id': '60183607', 'ts': 1661120814823 }] }1.
Trade.amountis set to quote notional, not base quantityThe handler emits the raw
amountfield asTrade.amount. But in Poloniex's trades channel,amountis the quote-currency notional andquantityis the base-unit size. In the docstring sample itself:21464.69 × 0.017 = 364.89973— i.e.amount == price × quantityexactly. I also verified this live: across received messages,amount / (price × quantity) == 1.0with no deviation.Every other exchange adapter populates
Trade.amountwith base units, so Poloniex trades come out inflated by a factor of ~price (a 0.017 BTC trade is reported as 364.9 "BTC"). It should beDecimal(entry['quantity']).2. Trade id is passed as the
exchangepositionalTrade.__init__is(exchange, symbol, side, amount, price, timestamp, id=None, type=None, raw=None), but the handler passesmsg['data'][0]['id']as the first positional:Result:
Trade.exchangeis'60183607'instead of'POLONIEX', andTrade.idisNone. The first argument should beself.id, withid=str(entry['id'])passed as the keyword.3. Only
data[0]is parsed; the rest of a batch is droppeddatais a list and Poloniex does deliver multiple trades per message, but the handler only readsmsg['data'][0], silently discarding the others.Suggested fix
Happy to open a PR if that helps.