ccxt 4.1.1 → 4.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/js/src/bingx.js CHANGED
@@ -1528,6 +1528,8 @@ export default class bingx extends Exchange {
1528
1528
  * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1529
1529
  * @param {object} [params] extra parameters specific to the bingx api endpoint
1530
1530
  * @param {bool} [params.postOnly] true to place a post only order
1531
+ * @param {string} [params.timeInForce] spot supports 'PO' and 'IOC', swap supports 'PO', 'GTC', 'IOC' and 'FOK'
1532
+ * @param {bool} [params.reduceOnly] *swap only* true or false whether the order is reduce only
1531
1533
  * @param {float} [params.triggerPrice] *swap only* triggerPrice at which the attached take profit / stop loss order will be triggered
1532
1534
  * @param {float} [params.stopLossPrice] *swap only* stop loss trigger price
1533
1535
  * @param {float} [params.takeProfitPrice] *swap only* take profit trigger price
@@ -1535,8 +1537,10 @@ export default class bingx extends Exchange {
1535
1537
  */
1536
1538
  await this.loadMarkets();
1537
1539
  const market = this.market(symbol);
1540
+ let postOnly = undefined;
1538
1541
  let response = undefined;
1539
- const [marketType, query] = this.handleMarketTypeAndParams('createOrder', market, params);
1542
+ let marketType = undefined;
1543
+ [marketType, params] = this.handleMarketTypeAndParams('createOrder', market, params);
1540
1544
  type = type.toUpperCase();
1541
1545
  const request = {
1542
1546
  'symbol': market['id'],
@@ -1544,51 +1548,16 @@ export default class bingx extends Exchange {
1544
1548
  'side': side.toUpperCase(),
1545
1549
  };
1546
1550
  const isMarketOrder = type === 'MARKET';
1547
- const isSpotMarket = marketType === 'spot';
1548
- let stopPriceRaw = undefined;
1549
- let stopPrice = undefined;
1550
- let stopLossPrice = undefined;
1551
- let takeProfitPrice = undefined;
1552
- if (!isSpotMarket) {
1553
- stopPriceRaw = this.safeValue2(params, 'stopPrice', 'triggerPrice');
1554
- if (stopPriceRaw !== undefined) {
1555
- stopPrice = this.priceToPrecision(symbol, stopPriceRaw);
1556
- }
1557
- stopLossPrice = this.safeValue(params, 'stopLossPrice');
1558
- takeProfitPrice = this.safeValue(params, 'takeProfitPrice');
1559
- }
1560
- if ((stopLossPrice !== undefined) && (takeProfitPrice !== undefined)) {
1561
- throw new InvalidOrder('Order is either a takeProfit order or a stopLoss order');
1562
- }
1563
- if ((type === 'LIMIT') || (type === 'TRIGGER_LIMIT')) {
1564
- request['price'] = this.priceToPrecision(symbol, price);
1565
- if ((stopPrice !== undefined)) {
1566
- request['type'] = 'TRIGGER_LIMIT';
1567
- request['stopPrice'] = stopPrice;
1568
- }
1569
- if (type === 'TRIGGER_LIMIT') {
1570
- if (stopPrice === undefined) {
1571
- throw new InvalidOrder('TRIGGER_LIMIT requires a triggerPrice / stopPrice');
1572
- }
1573
- request['stopPrice'] = stopPrice;
1574
- }
1575
- }
1576
- if (isMarketOrder || (type === 'TRIGGER_MARKET')) {
1577
- if ((stopPrice !== undefined)) {
1578
- request['type'] = 'TRIGGER_MARKET';
1579
- request['stopPrice'] = stopPrice;
1551
+ const isSpot = marketType === 'spot';
1552
+ const timeInForce = this.safeStringUpper(params, 'timeInForce');
1553
+ if (timeInForce === 'IOC') {
1554
+ request['timeInForce'] = 'IOC';
1555
+ }
1556
+ if (isSpot) {
1557
+ [postOnly, params] = this.handlePostOnly(isMarketOrder, timeInForce === 'POC', params);
1558
+ if (postOnly || (timeInForce === 'POC')) {
1559
+ request['timeInForce'] = 'POC';
1580
1560
  }
1581
- if (type === 'TRIGGER_MARKET') {
1582
- if (stopPrice === undefined) {
1583
- throw new InvalidOrder('TRIGGER_MARKET requires a triggerPrice / stopPrice');
1584
- }
1585
- request['stopPrice'] = stopPrice;
1586
- }
1587
- }
1588
- const exchangeSpecificTifParam = this.safeStringUpperN(params, ['force', 'timeInForce']);
1589
- let postOnly = undefined;
1590
- [postOnly, params] = this.handlePostOnly(isMarketOrder, exchangeSpecificTifParam === 'POC', params);
1591
- if (isSpotMarket) {
1592
1561
  const createMarketBuyOrderRequiresPrice = this.safeValue(this.options, 'createMarketBuyOrderRequiresPrice', true);
1593
1562
  if (createMarketBuyOrderRequiresPrice && isMarketOrder && (side === 'buy')) {
1594
1563
  if (price === undefined) {
@@ -1604,35 +1573,77 @@ export default class bingx extends Exchange {
1604
1573
  else {
1605
1574
  request['quantity'] = this.amountToPrecision(symbol, amount);
1606
1575
  }
1576
+ if (!isMarketOrder) {
1577
+ request['price'] = this.priceToPrecision(symbol, price);
1578
+ }
1579
+ response = await this.spotV1PrivatePostTradeOrder(this.extend(request, params));
1607
1580
  }
1608
1581
  else {
1582
+ [postOnly, params] = this.handlePostOnly(isMarketOrder, timeInForce === 'PostOnly', params);
1583
+ if (postOnly || (timeInForce === 'PostOnly')) {
1584
+ request['timeInForce'] = 'PostOnly';
1585
+ }
1586
+ else if (timeInForce === 'GTC') {
1587
+ request['timeInForce'] = 'GTC';
1588
+ }
1589
+ else if (timeInForce === 'FOK') {
1590
+ request['timeInForce'] = 'FOK';
1591
+ }
1592
+ if ((type === 'LIMIT') || (type === 'TRIGGER_LIMIT') || (type === 'STOP') || (type === 'TAKE_PROFIT')) {
1593
+ request['price'] = this.priceToPrecision(symbol, price);
1594
+ }
1595
+ const triggerPrice = this.safeNumber2(params, 'stopPrice', 'triggerPrice');
1596
+ const stopLossPrice = this.safeNumber(params, 'stopLossPrice');
1597
+ const takeProfitPrice = this.safeNumber(params, 'takeProfitPrice');
1598
+ const isTriggerOrder = triggerPrice !== undefined;
1599
+ const isStopLossPriceOrder = stopLossPrice !== undefined;
1600
+ const isTakeProfitPriceOrder = takeProfitPrice !== undefined;
1601
+ if (isTriggerOrder) {
1602
+ request['stopPrice'] = this.priceToPrecision(symbol, triggerPrice);
1603
+ if (isMarketOrder || (type === 'TRIGGER_MARKET')) {
1604
+ request['type'] = 'TRIGGER_MARKET';
1605
+ }
1606
+ else if ((type === 'LIMIT') || (type === 'TRIGGER_LIMIT')) {
1607
+ request['type'] = 'TRIGGER_LIMIT';
1608
+ }
1609
+ }
1610
+ else if (isStopLossPriceOrder || isTakeProfitPriceOrder) {
1611
+ // This can be used to set the stop loss and take profit, but the position needs to be opened first
1612
+ if (isStopLossPriceOrder) {
1613
+ request['stopPrice'] = this.priceToPrecision(symbol, stopLossPrice);
1614
+ if (isMarketOrder || (type === 'STOP_MARKET')) {
1615
+ request['type'] = 'STOP_MARKET';
1616
+ }
1617
+ else if ((type === 'LIMIT') || (type === 'STOP')) {
1618
+ request['type'] = 'STOP';
1619
+ }
1620
+ }
1621
+ else if (isTakeProfitPriceOrder) {
1622
+ request['stopPrice'] = this.priceToPrecision(symbol, takeProfitPrice);
1623
+ if (isMarketOrder || (type === 'TAKE_PROFIT_MARKET')) {
1624
+ request['type'] = 'TAKE_PROFIT_MARKET';
1625
+ }
1626
+ else if ((type === 'LIMIT') || (type === 'TAKE_PROFIT')) {
1627
+ request['type'] = 'TAKE_PROFIT';
1628
+ }
1629
+ }
1630
+ }
1631
+ const reduceOnly = this.safeValue(params, 'reduceOnly', false);
1632
+ let positionSide = undefined;
1633
+ if (reduceOnly) {
1634
+ positionSide = (side === 'buy') ? 'SHORT' : 'LONG';
1635
+ }
1636
+ else {
1637
+ positionSide = (side === 'buy') ? 'LONG' : 'SHORT';
1638
+ }
1639
+ request['positionSide'] = positionSide;
1609
1640
  request['quantity'] = this.amountToPrecision(symbol, amount);
1610
- }
1611
- if ((stopLossPrice !== undefined)) {
1612
- request['type'] = 'STOP_MARKET';
1613
- request['stopPrice'] = this.priceToPrecision(symbol, stopLossPrice);
1614
- }
1615
- if ((takeProfitPrice !== undefined)) {
1616
- request['type'] = 'TAKE_PROFIT_MARKET';
1617
- request['stopPrice'] = this.priceToPrecision(symbol, takeProfitPrice);
1618
- }
1619
- if (postOnly) {
1620
- request['timeInForce'] = 'POC';
1621
- }
1622
- else if (exchangeSpecificTifParam === 'POC') {
1623
- request['timeInForce'] = 'POC';
1624
- }
1625
- else if (!isSpotMarket) {
1626
- request['timeInForce'] = 'GTC';
1627
- }
1628
- if (isSpotMarket) {
1629
- response = await this.spotV1PrivatePostTradeOrder(this.extend(request, query));
1630
- }
1631
- else {
1632
- response = await this.swapV2PrivatePostTradeOrder(this.extend(request, query));
1641
+ params = this.omit(params, ['reduceOnly', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice']);
1642
+ response = await this.swapV2PrivatePostTradeOrder(this.extend(request, params));
1633
1643
  }
1634
1644
  //
1635
1645
  // spot
1646
+ //
1636
1647
  // {
1637
1648
  // "code": 0,
1638
1649
  // "msg": "",
@@ -1652,23 +1663,25 @@ export default class bingx extends Exchange {
1652
1663
  //
1653
1664
  // swap
1654
1665
  //
1655
- // {
1656
- // "code": 0,
1657
- // "msg": "",
1658
- // "data": {
1659
- // "order": {
1660
- // "symbol": "BTC-USDT",
1661
- // "orderId": 1590973236294713344,
1662
- // "side": "BUY",
1663
- // "positionSide": "LONG",
1664
- // "type": "LIMIT"
1665
- // }
1666
- // }
1667
- // }
1666
+ // {
1667
+ // "code": 0,
1668
+ // "msg": "",
1669
+ // "data": {
1670
+ // "order": {
1671
+ // "symbol": "BTC-USDT",
1672
+ // "orderId": 1709036527545438208,
1673
+ // "side": "BUY",
1674
+ // "positionSide": "LONG",
1675
+ // "type": "TRIGGER_LIMIT",
1676
+ // "clientOrderID": "",
1677
+ // "workingType": ""
1678
+ // }
1679
+ // }
1680
+ // }
1668
1681
  //
1669
- const data = this.safeValue(response, 'data');
1670
- const first = this.safeValue(data, 'order', data);
1671
- return this.parseOrder(first, market);
1682
+ const data = this.safeValue(response, 'data', {});
1683
+ const order = this.safeValue(data, 'order', data);
1684
+ return this.parseOrder(order, market);
1672
1685
  }
1673
1686
  parseOrder(order, market = undefined) {
1674
1687
  //
@@ -1738,65 +1751,68 @@ export default class bingx extends Exchange {
1738
1751
  //
1739
1752
  // fetchOrder, fetchOpenOrders, fetchClosedOrders
1740
1753
  //
1741
- // {
1742
- // "symbol": "LINK-USDT",
1743
- // "orderId": 1585839271162413056,
1744
- // "side": "BUY",
1745
- // "positionSide": "LONG",
1746
- // "type": "TRIGGER_MARKET",
1747
- // "origQty": "5.0",
1748
- // "price": "9",
1749
- // "executedQty": "0.0",
1750
- // "avgPrice": "0",
1751
- // "cumQuote": "0",
1752
- // "stopPrice": "5",
1753
- // "profit": "0.0000",
1754
- // "commission": "0.000000",
1755
- // "status": "CANCELLED",
1756
- // "time": 1667631605000,
1757
- // "updateTime": 1667631605000
1758
- // }
1754
+ // {
1755
+ // "symbol": "BTC-USDT",
1756
+ // "orderId": 1709036527545438208,
1757
+ // "side": "BUY",
1758
+ // "positionSide": "LONG",
1759
+ // "type": "TRIGGER_LIMIT",
1760
+ // "origQty": "0.0010",
1761
+ // "price": "22000.0",
1762
+ // "executedQty": "0.0000",
1763
+ // "avgPrice": "0.0",
1764
+ // "cumQuote": "",
1765
+ // "stopPrice": "23000.0",
1766
+ // "profit": "",
1767
+ // "commission": "",
1768
+ // "status": "NEW",
1769
+ // "time": 1696301035187,
1770
+ // "updateTime": 1696301035187,
1771
+ // "clientOrderId": "",
1772
+ // "leverage": "",
1773
+ // "takeProfit": "",
1774
+ // "stopLoss": "",
1775
+ // "advanceAttr": 0,
1776
+ // "positionID": 0,
1777
+ // "takeProfitEntrustPrice": 0,
1778
+ // "stopLossEntrustPrice": 0,
1779
+ // "orderType": "",
1780
+ // "workingType": "MARK_PRICE"
1781
+ // }
1759
1782
  //
1760
1783
  const positionSide = this.safeString(order, 'positionSide');
1761
1784
  const marketType = (positionSide === undefined) ? 'spot' : 'swap';
1762
1785
  const marketId = this.safeString(order, 'symbol');
1763
1786
  const symbol = this.safeSymbol(marketId, market, '-', marketType);
1764
- const orderId = this.safeString(order, 'orderId');
1765
- const side = this.safeStringLower(order, 'side');
1766
- const type = this.safeStringLower(order, 'type');
1767
1787
  const timestamp = this.safeInteger2(order, 'time', 'transactTime');
1768
- const lastTradeTimestamp = this.safeInteger(order, 'updateTime');
1769
- const price = this.safeString(order, 'price');
1770
- const average = this.safeString(order, 'avgPrice');
1771
- const amount = this.safeString(order, 'origQty');
1772
- const filled = this.safeString(order, 'executedQty');
1773
- const statusId = this.safeString(order, 'status');
1774
1788
  const fee = {
1775
1789
  'currency': this.safeString(order, 'feeAsset'),
1776
1790
  'rate': this.safeString2(order, 'fee', 'commission'),
1777
1791
  };
1778
- const clientOrderId = this.safeString(order, 'clientOrderId');
1779
1792
  return this.safeOrder({
1780
1793
  'info': order,
1781
- 'id': orderId,
1782
- 'clientOrderId': clientOrderId,
1794
+ 'id': this.safeString(order, 'orderId'),
1795
+ 'clientOrderId': this.safeString(order, 'clientOrderId'),
1783
1796
  'timestamp': timestamp,
1784
1797
  'datetime': this.iso8601(timestamp),
1785
- 'lastTradeTimestamp': lastTradeTimestamp,
1798
+ 'lastTradeTimestamp': this.safeInteger(order, 'updateTime'),
1799
+ 'lastUpdateTimestamp': this.safeInteger(order, 'updateTime'),
1786
1800
  'symbol': symbol,
1787
- 'type': type,
1801
+ 'type': this.safeStringLower(order, 'type'),
1788
1802
  'timeInForce': undefined,
1789
1803
  'postOnly': undefined,
1790
- 'side': side,
1791
- 'price': price,
1792
- 'stopPrice': this.safeNumber(order, 'triggerPrice'),
1793
- 'triggerPrice': this.safeNumber(order, 'triggerPrice'),
1794
- 'average': average,
1804
+ 'side': this.safeStringLower(order, 'side'),
1805
+ 'price': this.safeString(order, 'price'),
1806
+ 'stopPrice': this.safeNumber(order, 'stopPrice'),
1807
+ 'triggerPrice': this.safeNumber(order, 'stopPrice'),
1808
+ 'stopLossPrice': this.safeNumber(order, 'stopLoss'),
1809
+ 'takeProfitPrice': this.safeNumber(order, 'takeProfit'),
1810
+ 'average': this.safeString(order, 'avgPrice'),
1795
1811
  'cost': undefined,
1796
- 'amount': amount,
1797
- 'filled': filled,
1812
+ 'amount': this.safeString(order, 'origQty'),
1813
+ 'filled': this.safeString(order, 'executedQty'),
1798
1814
  'remaining': undefined,
1799
- 'status': this.parseOrderStatus(statusId),
1815
+ 'status': this.parseOrderStatus(this.safeString(order, 'status')),
1800
1816
  'fee': fee,
1801
1817
  'trades': undefined,
1802
1818
  }, market);
package/js/src/bitget.js CHANGED
@@ -3805,7 +3805,7 @@ export default class bitget extends Exchange {
3805
3805
  //
3806
3806
  const data = this.safeValue(response, 'data');
3807
3807
  if (data !== undefined) {
3808
- return this.safeValue2(data, 'orderList', 'data', []);
3808
+ return this.safeValue(data, 'orderList', data);
3809
3809
  }
3810
3810
  const parsedData = JSON.parse(response);
3811
3811
  return this.safeValue(parsedData, 'data', []);
@@ -267,6 +267,9 @@ export default class bitmart extends Exchange {
267
267
  previousFundingTimestamp: any;
268
268
  previousFundingDatetime: any;
269
269
  };
270
+ fetchPosition(symbol: string, params?: {}): Promise<import("./base/types.js").Position>;
271
+ fetchPositions(symbols?: string[], params?: {}): Promise<import("./base/types.js").Position[]>;
272
+ parsePosition(position: any, market?: any): import("./base/types.js").Position;
270
273
  nonce(): number;
271
274
  sign(path: any, api?: string, method?: string, params?: {}, headers?: any, body?: any): {
272
275
  url: string;
package/js/src/bitmart.js CHANGED
@@ -74,7 +74,9 @@ export default class bitmart extends Exchange {
74
74
  'fetchOrderBook': true,
75
75
  'fetchOrders': false,
76
76
  'fetchOrderTrades': true,
77
+ 'fetchPosition': true,
77
78
  'fetchPositionMode': false,
79
+ 'fetchPositions': true,
78
80
  'fetchStatus': true,
79
81
  'fetchTicker': true,
80
82
  'fetchTickers': true,
@@ -3759,6 +3761,180 @@ export default class bitmart extends Exchange {
3759
3761
  'previousFundingDatetime': undefined,
3760
3762
  };
3761
3763
  }
3764
+ async fetchPosition(symbol, params = {}) {
3765
+ /**
3766
+ * @method
3767
+ * @name bitmart#fetchPosition
3768
+ * @description fetch data on a single open contract trade position
3769
+ * @see https://developer-pro.bitmart.com/en/futures/#get-current-position-keyed
3770
+ * @param {string} symbol unified market symbol of the market the position is held in
3771
+ * @param {object} [params] extra parameters specific to the bitmart api endpoint
3772
+ * @returns {object} a [position structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#position-structure}
3773
+ */
3774
+ await this.loadMarkets();
3775
+ const market = this.market(symbol);
3776
+ const request = {
3777
+ 'symbol': market['id'],
3778
+ };
3779
+ const response = await this.privateGetContractPrivatePosition(this.extend(request, params));
3780
+ //
3781
+ // {
3782
+ // "code": 1000,
3783
+ // "message": "Ok",
3784
+ // "data": [
3785
+ // {
3786
+ // "symbol": "BTCUSDT",
3787
+ // "leverage": "10",
3788
+ // "timestamp": 1696392515269,
3789
+ // "current_fee": "0.0014250028",
3790
+ // "open_timestamp": 1696392256998,
3791
+ // "current_value": "27.4039",
3792
+ // "mark_price": "27.4039",
3793
+ // "position_value": "27.4079",
3794
+ // "position_cross": "3.75723474",
3795
+ // "maintenance_margin": "0.1370395",
3796
+ // "close_vol": "0",
3797
+ // "close_avg_price": "0",
3798
+ // "open_avg_price": "27407.9",
3799
+ // "entry_price": "27407.9",
3800
+ // "current_amount": "1",
3801
+ // "unrealized_value": "-0.004",
3802
+ // "realized_value": "-0.01644474",
3803
+ // "position_type": 1
3804
+ // }
3805
+ // ],
3806
+ // "trace":"4cad855074664097ac5ba5257c47305d.67.16963925142065945"
3807
+ // }
3808
+ //
3809
+ const data = this.safeValue(response, 'data', []);
3810
+ const first = this.safeValue(data, 0, {});
3811
+ return this.parsePosition(first, market);
3812
+ }
3813
+ async fetchPositions(symbols = undefined, params = {}) {
3814
+ /**
3815
+ * @method
3816
+ * @name bitmart#fetchPositions
3817
+ * @description fetch all open contract positions
3818
+ * @see https://developer-pro.bitmart.com/en/futures/#get-current-position-keyed
3819
+ * @param {string[]|undefined} symbols list of unified market symbols
3820
+ * @param {object} [params] extra parameters specific to the bitmart api endpoint
3821
+ * @returns {object[]} a list of [position structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#position-structure}
3822
+ */
3823
+ await this.loadMarkets();
3824
+ let market = undefined;
3825
+ let symbolsLength = undefined;
3826
+ if (symbols !== undefined) {
3827
+ symbolsLength = symbols.length;
3828
+ const first = this.safeString(symbols, 0);
3829
+ market = this.market(first);
3830
+ }
3831
+ const request = {};
3832
+ if (symbolsLength === 1) {
3833
+ // only supports symbols as undefined or sending one symbol
3834
+ request['symbol'] = market['id'];
3835
+ }
3836
+ const response = await this.privateGetContractPrivatePosition(this.extend(request, params));
3837
+ //
3838
+ // {
3839
+ // "code": 1000,
3840
+ // "message": "Ok",
3841
+ // "data": [
3842
+ // {
3843
+ // "symbol": "BTCUSDT",
3844
+ // "leverage": "10",
3845
+ // "timestamp": 1696392515269,
3846
+ // "current_fee": "0.0014250028",
3847
+ // "open_timestamp": 1696392256998,
3848
+ // "current_value": "27.4039",
3849
+ // "mark_price": "27.4039",
3850
+ // "position_value": "27.4079",
3851
+ // "position_cross": "3.75723474",
3852
+ // "maintenance_margin": "0.1370395",
3853
+ // "close_vol": "0",
3854
+ // "close_avg_price": "0",
3855
+ // "open_avg_price": "27407.9",
3856
+ // "entry_price": "27407.9",
3857
+ // "current_amount": "1",
3858
+ // "unrealized_value": "-0.004",
3859
+ // "realized_value": "-0.01644474",
3860
+ // "position_type": 1
3861
+ // },
3862
+ // ],
3863
+ // "trace":"4cad855074664097ac5ba5257c47305d.67.16963925142065945"
3864
+ // }
3865
+ //
3866
+ const positions = this.safeValue(response, 'data', []);
3867
+ const result = [];
3868
+ for (let i = 0; i < positions.length; i++) {
3869
+ result.push(this.parsePosition(positions[i]));
3870
+ }
3871
+ symbols = this.marketSymbols(symbols);
3872
+ return this.filterByArrayPositions(result, 'symbol', symbols, false);
3873
+ }
3874
+ parsePosition(position, market = undefined) {
3875
+ //
3876
+ // {
3877
+ // "symbol": "BTCUSDT",
3878
+ // "leverage": "10",
3879
+ // "timestamp": 1696392515269,
3880
+ // "current_fee": "0.0014250028",
3881
+ // "open_timestamp": 1696392256998,
3882
+ // "current_value": "27.4039",
3883
+ // "mark_price": "27.4039",
3884
+ // "position_value": "27.4079",
3885
+ // "position_cross": "3.75723474",
3886
+ // "maintenance_margin": "0.1370395",
3887
+ // "close_vol": "0",
3888
+ // "close_avg_price": "0",
3889
+ // "open_avg_price": "27407.9",
3890
+ // "entry_price": "27407.9",
3891
+ // "current_amount": "1",
3892
+ // "unrealized_value": "-0.004",
3893
+ // "realized_value": "-0.01644474",
3894
+ // "position_type": 1
3895
+ // }
3896
+ //
3897
+ const marketId = this.safeString(position, 'symbol');
3898
+ market = this.safeMarket(marketId, market);
3899
+ const symbol = market['symbol'];
3900
+ const timestamp = this.safeInteger(position, 'timestamp');
3901
+ const side = this.safeInteger(position, 'position_type');
3902
+ const maintenanceMargin = this.safeString(position, 'maintenance_margin');
3903
+ const notional = this.safeString(position, 'current_value');
3904
+ const collateral = this.safeString(position, 'position_cross');
3905
+ const maintenanceMarginPercentage = Precise.stringDiv(maintenanceMargin, notional);
3906
+ const marginRatio = Precise.stringDiv(maintenanceMargin, collateral);
3907
+ return this.safePosition({
3908
+ 'info': position,
3909
+ 'id': undefined,
3910
+ 'symbol': symbol,
3911
+ 'timestamp': timestamp,
3912
+ 'datetime': this.iso8601(timestamp),
3913
+ 'lastUpdateTimestamp': undefined,
3914
+ 'hedged': undefined,
3915
+ 'side': (side === 1) ? 'long' : 'short',
3916
+ 'contracts': this.safeNumber(position, 'current_amount'),
3917
+ 'contractSize': this.safeNumber(market, 'contractSize'),
3918
+ 'entryPrice': this.safeNumber(position, 'entry_price'),
3919
+ 'markPrice': this.safeNumber(position, 'mark_price'),
3920
+ 'lastPrice': undefined,
3921
+ 'notional': this.parseNumber(notional),
3922
+ 'leverage': this.safeNumber(position, 'leverage'),
3923
+ 'collateral': this.parseNumber(collateral),
3924
+ 'initialMargin': undefined,
3925
+ 'initialMarginPercentage': undefined,
3926
+ 'maintenanceMargin': this.parseNumber(maintenanceMargin),
3927
+ 'maintenanceMarginPercentage': this.parseNumber(maintenanceMarginPercentage),
3928
+ 'unrealizedPnl': this.safeNumber(position, 'unrealized_value'),
3929
+ 'realizedPnl': this.safeNumber(position, 'realized_value'),
3930
+ 'liquidationPrice': undefined,
3931
+ 'marginMode': undefined,
3932
+ 'percentage': undefined,
3933
+ 'marginRatio': this.parseNumber(marginRatio),
3934
+ 'stopLossPrice': undefined,
3935
+ 'takeProfitPrice': undefined,
3936
+ });
3937
+ }
3762
3938
  nonce() {
3763
3939
  return this.milliseconds();
3764
3940
  }
package/js/src/bitrue.js CHANGED
@@ -832,7 +832,7 @@ export default class bitrue extends Exchange {
832
832
  'last': last,
833
833
  'previousClose': undefined,
834
834
  'change': undefined,
835
- 'percentage': this.safeString(ticker, 'percentChange'),
835
+ 'percentage': Precise.stringMul(this.safeString(ticker, 'percentChange'), '10000'),
836
836
  'average': undefined,
837
837
  'baseVolume': this.safeString(ticker, 'baseVolume'),
838
838
  'quoteVolume': this.safeString(ticker, 'quoteVolume'),
package/js/src/bybit.js CHANGED
@@ -4011,6 +4011,16 @@ export default class bybit extends Exchange {
4011
4011
  * @param {float} amount how much of currency you want to trade in units of base currency
4012
4012
  * @param {float} price the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
4013
4013
  * @param {object} [params] extra parameters specific to the bybit api endpoint
4014
+ * @param {float} [params.triggerPrice] The price that a trigger order is triggered at
4015
+ * @param {float} [params.stopLossPrice] The price that a stop loss order is triggered at
4016
+ * @param {float} [params.takeProfitPrice] The price that a take profit order is triggered at
4017
+ * @param {object} [params.takeProfit] *takeProfit object in params* containing the triggerPrice that the attached take profit order will be triggered
4018
+ * @param {float} [params.takeProfit.triggerPrice] take profit trigger price
4019
+ * @param {object} [params.stopLoss] *stopLoss object in params* containing the triggerPrice that the attached stop loss order will be triggered
4020
+ * @param {float} [params.stopLoss.triggerPrice] stop loss trigger price
4021
+ * @param {string} [params.triggerBy] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for triggerPrice
4022
+ * @param {string} [params.slTriggerBy] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for stopLoss
4023
+ * @param {string} [params.tpTriggerby] 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for takeProfit
4014
4024
  * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
4015
4025
  */
4016
4026
  this.checkRequiredSymbol('editOrder', symbol);
@@ -4053,9 +4063,9 @@ export default class bybit extends Exchange {
4053
4063
  if (amount !== undefined) {
4054
4064
  request['qty'] = this.amountToPrecision(symbol, amount);
4055
4065
  }
4056
- let triggerPrice = this.safeValue2(params, 'triggerPrice', 'stopPrice');
4057
- const stopLossTriggerPrice = this.safeValue(params, 'stopLossPrice');
4058
- const takeProfitTriggerPrice = this.safeValue(params, 'takeProfitPrice');
4066
+ let triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
4067
+ const stopLossTriggerPrice = this.safeString(params, 'stopLossPrice');
4068
+ const takeProfitTriggerPrice = this.safeString(params, 'takeProfitPrice');
4059
4069
  const stopLoss = this.safeValue(params, 'stopLoss');
4060
4070
  const takeProfit = this.safeValue(params, 'takeProfit');
4061
4071
  const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
@@ -4066,16 +4076,25 @@ export default class bybit extends Exchange {
4066
4076
  triggerPrice = isStopLossTriggerOrder ? stopLossTriggerPrice : takeProfitTriggerPrice;
4067
4077
  }
4068
4078
  if (triggerPrice !== undefined) {
4069
- request['triggerPrice'] = triggerPrice;
4079
+ const triggerPriceRequest = (triggerPrice === '0') ? triggerPrice : this.priceToPrecision(symbol, triggerPrice);
4080
+ request['triggerPrice'] = triggerPriceRequest;
4081
+ const triggerBy = this.safeString(params, 'triggerBy', 'LastPrice');
4082
+ request['triggerBy'] = triggerBy;
4070
4083
  }
4071
4084
  if (isStopLoss || isTakeProfit) {
4072
4085
  if (isStopLoss) {
4073
- const slTriggerPrice = this.safeValue2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss);
4074
- request['stopLoss'] = slTriggerPrice;
4086
+ const slTriggerPrice = this.safeString2(stopLoss, 'triggerPrice', 'stopPrice', stopLoss);
4087
+ const stopLossRequest = (slTriggerPrice === '0') ? slTriggerPrice : this.priceToPrecision(symbol, slTriggerPrice);
4088
+ request['stopLoss'] = stopLossRequest;
4089
+ const slTriggerBy = this.safeString(params, 'slTriggerBy', 'LastPrice');
4090
+ request['slTriggerBy'] = slTriggerBy;
4075
4091
  }
4076
4092
  if (isTakeProfit) {
4077
- const tpTriggerPrice = this.safeValue2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit);
4078
- request['takeProfit'] = tpTriggerPrice;
4093
+ const tpTriggerPrice = this.safeString2(takeProfit, 'triggerPrice', 'stopPrice', takeProfit);
4094
+ const takeProfitRequest = (tpTriggerPrice === '0') ? tpTriggerPrice : this.priceToPrecision(symbol, tpTriggerPrice);
4095
+ request['takeProfit'] = takeProfitRequest;
4096
+ const tpTriggerBy = this.safeString(params, 'tpTriggerBy', 'LastPrice');
4097
+ request['tpTriggerBy'] = tpTriggerBy;
4079
4098
  }
4080
4099
  }
4081
4100
  const clientOrderId = this.safeString(params, 'clientOrderId');
@@ -114,6 +114,7 @@ export default class coinbasepro extends Exchange {
114
114
  },
115
115
  'private': {
116
116
  'get': [
117
+ 'address-book',
117
118
  'accounts',
118
119
  'accounts/{id}',
119
120
  'accounts/{id}/holds',
package/js/src/deribit.js CHANGED
@@ -493,7 +493,7 @@ export default class deribit extends Exchange {
493
493
  const defaultCode = this.safeValue(this.options, 'code', 'BTC');
494
494
  const options = this.safeValue(this.options, methodName, {});
495
495
  const code = this.safeValue(options, 'code', defaultCode);
496
- return this.safeValue(params, 'code', code);
496
+ return this.safeValue2(params, 'code', code);
497
497
  }
498
498
  async fetchStatus(params = {}) {
499
499
  /**