Skip to content

Commit

Permalink
fix(ws): fix #22037 - concurrent subscription requests (#22309)
Browse files Browse the repository at this point in the history
* fix(ws): fix #22037 - concurrent subscription requests

* trigger build

* explitict cast

* fix second race condition

* add changes for watch multiple

* build fix

* build fix

---------

Co-authored-by: carlosmiei <43336371+carlosmiei@users.noreply.github.com>

[ci skip]
  • Loading branch information
Travis CI committed Apr 29, 2024
1 parent 4153572 commit eb2694e
Show file tree
Hide file tree
Showing 15 changed files with 1,946 additions and 1,136 deletions.
186 changes: 46 additions & 140 deletions cs/ccxt/exchanges/coinex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1884,7 +1884,7 @@ public override object parseOrder(object order, object market = null)
// "user_id": 3620173
// }
//
// Spot and Margin createOrder, createOrders, cancelOrders, editOrder v2
// Spot and Margin createOrder, createOrders, editOrder, cancelOrders, cancelOrder v2
//
// {
// "amount": "0.0001",
Expand Down Expand Up @@ -1916,7 +1916,7 @@ public override object parseOrder(object order, object market = null)
// "stop_id": 117180138153
// }
//
// Swap createOrder, createOrders, cancelOrders, editOrder v2
// Swap createOrder, createOrders, editOrder, cancelOrders, cancelOrder v2
//
// {
// "amount": "0.0001",
Expand Down Expand Up @@ -1976,7 +1976,7 @@ public override object parseOrder(object order, object market = null)
// "updated_at": 1714119054559
// }
//
// Swap and Spot stop cancelOrders v2
// Swap and Spot stop cancelOrders, cancelOrder v2
//
// {
// "amount": "0.0001",
Expand Down Expand Up @@ -2607,20 +2607,20 @@ public async override Task<object> cancelOrder(object id, object symbol = null,
* @method
* @name coinex#cancelOrder
* @description cancels an open order
* @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade018_cancle_stop_pending_order
* @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade015_cancel_order
* @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade024_cancel_order_by_client_id
* @see https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade025_cancel_stop_order_by_client_id
* @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http023_cancel_stop_order
* @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http021_cancel_order
* @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http042_cancel_order_by_client_id
* @see https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http043_cancel_stop_order_by_client_id
* @see https://docs.coinex.com/api/v2/spot/order/http/cancel-order
* @see https://docs.coinex.com/api/v2/spot/order/http/cancel-stop-order
* @see https://docs.coinex.com/api/v2/spot/order/http/cancel-order-by-client-id
* @see https://docs.coinex.com/api/v2/spot/order/http/cancel-stop-order-by-client-id
* @see https://docs.coinex.com/api/v2/futures/order/http/cancel-order
* @see https://docs.coinex.com/api/v2/futures/order/http/cancel-stop-order
* @see https://docs.coinex.com/api/v2/futures/order/http/cancel-order-by-client-id
* @see https://docs.coinex.com/api/v2/futures/order/http/cancel-stop-order-by-client-id
* @param {string} id order id
* @param {string} symbol unified symbol of the market the order was made in
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.clientOrderId] client order id, defaults to id if not passed
* @param {boolean} [params.stop] if stop order = true, default = false
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
* @param {boolean} [params.trigger] set to true for canceling a trigger order
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
parameters ??= new Dictionary<string, object>();
if (isTrue(isEqual(symbol, null)))
Expand All @@ -2629,180 +2629,86 @@ public async override Task<object> cancelOrder(object id, object symbol = null,
}
await this.loadMarkets();
object market = this.market(symbol);
object stop = this.safeValue(parameters, "stop");
object isTriggerOrder = this.safeBool2(parameters, "stop", "trigger");
object swap = getValue(market, "swap");
object request = new Dictionary<string, object>() {
{ "market", getValue(market, "id") },
};
object accountId = this.safeInteger(parameters, "account_id");
object marginMode = null;
var marginModeparametersVariable = this.handleMarginModeAndParams("cancelOrder", parameters);
marginMode = ((IList<object>)marginModeparametersVariable)[0];
parameters = ((IList<object>)marginModeparametersVariable)[1];
object clientOrderId = this.safeString2(parameters, "client_id", "clientOrderId");
if (isTrue(!isEqual(marginMode, null)))
if (isTrue(swap))
{
if (isTrue(isEqual(accountId, null)))
((IDictionary<string,object>)request)["market_type"] = "FUTURES";
} else
{
if (isTrue(!isEqual(marginMode, null)))
{
((IDictionary<string,object>)request)["market_type"] = "MARGIN";
} else
{
throw new BadRequest ((string)add(this.id, " cancelOrder() requires an account_id parameter for margin orders")) ;
((IDictionary<string,object>)request)["market_type"] = "SPOT";
}
((IDictionary<string,object>)request)["account_id"] = accountId;
}
object query = this.omit(parameters, new List<object>() {"stop", "account_id", "clientOrderId"});
object clientOrderId = this.safeString2(parameters, "client_id", "clientOrderId");
parameters = this.omit(parameters, new List<object>() {"stop", "trigger", "clientOrderId"});
object response = null;
if (isTrue(!isEqual(clientOrderId, null)))
{
((IDictionary<string,object>)request)["client_id"] = clientOrderId;
if (isTrue(stop))
if (isTrue(isTriggerOrder))
{
if (isTrue(swap))
{
response = await this.v1PerpetualPrivatePostOrderCancelStopByClientId(this.extend(request, query));
response = await this.v2PrivatePostFuturesCancelStopOrderByClientId(this.extend(request, parameters));
} else
{
response = await this.v1PrivateDeleteOrderStopPendingByClientId(this.extend(request, query));
response = await this.v2PrivatePostSpotCancelStopOrderByClientId(this.extend(request, parameters));
}
} else
{
if (isTrue(swap))
{
response = await this.v1PerpetualPrivatePostOrderCancelByClientId(this.extend(request, query));
response = await this.v2PrivatePostFuturesCancelOrderByClientId(this.extend(request, parameters));
} else
{
response = await this.v1PrivateDeleteOrderPendingByClientId(this.extend(request, query));
response = await this.v2PrivatePostSpotCancelOrderByClientId(this.extend(request, parameters));
}
}
} else
{
object idRequest = ((bool) isTrue(swap)) ? "order_id" : "id";
((IDictionary<string,object>)request)[(string)idRequest] = id;
if (isTrue(stop))
if (isTrue(isTriggerOrder))
{
((IDictionary<string,object>)request)["stop_id"] = this.parseToNumeric(id);
if (isTrue(swap))
{
response = await this.v1PerpetualPrivatePostOrderCancelStop(this.extend(request, query));
response = await this.v2PrivatePostFuturesCancelStopOrder(this.extend(request, parameters));
} else
{
response = await this.v1PrivateDeleteOrderStopPendingId(this.extend(request, query));
response = await this.v2PrivatePostSpotCancelStopOrder(this.extend(request, parameters));
}
} else
{
((IDictionary<string,object>)request)["order_id"] = this.parseToNumeric(id);
if (isTrue(swap))
{
response = await this.v1PerpetualPrivatePostOrderCancel(this.extend(request, query));
response = await this.v2PrivatePostFuturesCancelOrder(this.extend(request, parameters));
} else
{
response = await this.v1PrivateDeleteOrderPending(this.extend(request, query));
response = await this.v2PrivatePostSpotCancelOrder(this.extend(request, parameters));
}
}
}
//
// Spot and Margin
//
// {
// "code": 0,
// "data": {
// "amount": "0.0005",
// "asset_fee": "0",
// "avg_price": "0.00",
// "client_id": "",
// "create_time": 1650951627,
// "deal_amount": "0",
// "deal_fee": "0",
// "deal_money": "0",
// "fee_asset": null,
// "fee_discount": "1",
// "finished_time": null,
// "id": 74510932594,
// "left": "0.0005",
// "maker_fee_rate": "0.002",
// "market": "BTCUSDT",
// "money_fee": "0",
// "order_type": "limit",
// "price": "30000",
// "status": "not_deal",
// "stock_fee": "0",
// "taker_fee_rate": "0.002",
// "type": "buy"
// },
// "message": "Success"
// }
//
// Swap
//
// {
// "code": 0,
// "data": {
// "amount": "0.0005",
// "client_id": "",
// "create_time": 1651004578.618224,
// "deal_asset_fee": "0.00000000000000000000",
// "deal_fee": "0.00000000000000000000",
// "deal_profit": "0.00000000000000000000",
// "deal_stock": "0.00000000000000000000",
// "effect_type": 1,
// "fee_asset": "",
// "fee_discount": "0.00000000000000000000",
// "last_deal_amount": "0.00000000000000000000",
// "last_deal_id": 0,
// "last_deal_price": "0.00000000000000000000",
// "last_deal_role": 0,
// "last_deal_time": 0,
// "last_deal_type": 0,
// "left": "0.0005",
// "leverage": "3",
// "maker_fee": "0.00030",
// "market": "BTCUSDT",
// "order_id": 18221659097,
// "position_id": 0,
// "position_type": 1,
// "price": "30000.00",
// "side": 2,
// "source": "api.v1",
// "stop_id": 0,
// "taker_fee": "0.00050",
// "target": 0,
// "type": 1,
// "update_time": 1651004578.618224,
// "user_id": 3620173
// },
// "message": "OK"
// }
//
// Swap Stop
//
// {
// "code": 0,
// "data": {
// "amount": "0.0005",
// "client_id": "",
// "create_time": 1651034023.008771,
// "effect_type": 1,
// "fee_asset": "",
// "fee_discount": "0.00000000000000000000",
// "maker_fee": "0.00030",
// "market": "BTCUSDT",
// "order_id": 18256915101,
// "price": "31000.00",
// "side": 2,
// "source": "api.v1",
// "state": 1,
// "stop_price": "31500.00",
// "stop_type": 1,
// "taker_fee": "0.00050",
// "target": 0,
// "type": 1,
// "update_time": 1651034397.193624,
// "user_id": 3620173
// },
// "message":"OK"
// }
//
// Spot and Margin Stop
//
// {"code":0,"data":{},"message":"Success"}
//
object data = this.safeDict(response, "data");
object data = null;
if (isTrue(!isEqual(clientOrderId, null)))
{
object rows = this.safeList(response, "data", new List<object>() {});
data = this.safeDict(getValue(rows, 0), "data", new Dictionary<string, object>() {});
} else
{
data = this.safeDict(response, "data", new Dictionary<string, object>() {});
}
return this.parseOrder(data, market);
}

Expand Down
22 changes: 21 additions & 1 deletion cs/ccxt/exchanges/pro/mexc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,21 @@ public override object parseWsTrade(object trade, object market = null)
// "v": "5"
// }
//
//
// d: {
// p: '1.0005',
// v: '5.71',
// a: '5.712855',
// S: 1,
// T: 1714325698237,
// t: 'edafcd9fdc2f426e82443d114691f724',
// c: '',
// i: 'C02__413321238354677760043',
// m: 0,
// st: 0,
// n: '0.005712855',
// N: 'USDT'
// }
object timestamp = this.safeInteger(trade, "T");
object tradeId = this.safeString(trade, "t");
if (isTrue(isEqual(timestamp, null)))
Expand All @@ -788,6 +803,8 @@ public override object parseWsTrade(object trade, object market = null)
object rawSide = this.safeString(trade, "S");
object side = ((bool) isTrue((isEqual(rawSide, "1")))) ? "buy" : "sell";
object isMaker = this.safeInteger(trade, "m");
object feeAmount = this.safeNumber(trade, "n");
object feeCurrencyId = this.safeString(trade, "N");
return this.safeTrade(new Dictionary<string, object>() {
{ "info", trade },
{ "id", tradeId },
Expand All @@ -801,7 +818,10 @@ public override object parseWsTrade(object trade, object market = null)
{ "price", priceString },
{ "amount", amountString },
{ "cost", null },
{ "fee", null },
{ "fee", new Dictionary<string, object>() {
{ "cost", feeAmount },
{ "currency", this.safeCurrencyCode(feeCurrencyId) },
} },
}, market);
}

Expand Down
22 changes: 11 additions & 11 deletions cs/ccxt/wrappers/coinex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,14 +476,14 @@ public async Task<Order> EditOrder(string id, string symbol, string type, string
/// cancels an open order
/// </summary>
/// <remarks>
/// See <see href="https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade018_cancle_stop_pending_order"/> <br/>
/// See <see href="https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade015_cancel_order"/> <br/>
/// See <see href="https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade024_cancel_order_by_client_id"/> <br/>
/// See <see href="https://viabtc.github.io/coinex_api_en_doc/spot/#docsspot003_trade025_cancel_stop_order_by_client_id"/> <br/>
/// See <see href="https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http023_cancel_stop_order"/> <br/>
/// See <see href="https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http021_cancel_order"/> <br/>
/// See <see href="https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http042_cancel_order_by_client_id"/> <br/>
/// See <see href="https://viabtc.github.io/coinex_api_en_doc/futures/#docsfutures001_http043_cancel_stop_order_by_client_id"/> <br/>
/// See <see href="https://docs.coinex.com/api/v2/spot/order/http/cancel-order"/> <br/>
/// See <see href="https://docs.coinex.com/api/v2/spot/order/http/cancel-stop-order"/> <br/>
/// See <see href="https://docs.coinex.com/api/v2/spot/order/http/cancel-order-by-client-id"/> <br/>
/// See <see href="https://docs.coinex.com/api/v2/spot/order/http/cancel-stop-order-by-client-id"/> <br/>
/// See <see href="https://docs.coinex.com/api/v2/futures/order/http/cancel-order"/> <br/>
/// See <see href="https://docs.coinex.com/api/v2/futures/order/http/cancel-stop-order"/> <br/>
/// See <see href="https://docs.coinex.com/api/v2/futures/order/http/cancel-order-by-client-id"/> <br/>
/// See <see href="https://docs.coinex.com/api/v2/futures/order/http/cancel-stop-order-by-client-id"/> <br/>
/// <list type="table">
/// <item>
/// <term>params</term>
Expand All @@ -498,14 +498,14 @@ public async Task<Order> EditOrder(string id, string symbol, string type, string
/// </description>
/// </item>
/// <item>
/// <term>params.stop</term>
/// <term>params.trigger</term>
/// <description>
/// boolean : if stop order = true, default = false
/// boolean : set to true for canceling a trigger order
/// </description>
/// </item>
/// </list>
/// </remarks>
/// <returns> <term>object</term> An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}.</returns>
/// <returns> <term>object</term> an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}.</returns>
public async Task<Order> CancelOrder(string id, string symbol = null, Dictionary<string, object> parameters = null)
{
var res = await this.cancelOrder(id, symbol, parameters);
Expand Down

0 comments on commit eb2694e

Please sign in to comment.