@@ -1324,7 +1324,7 @@ public function rollingWindowPriceChange(?string $symbol = null, array $symbols
13241324 } elseif (is_array ($ symbols ) && !empty ($ symbols )) {
13251325 $ request ['symbols ' ] = json_encode ($ symbols );
13261326 } else {
1327- throw new \Exception ("tradingDay (): Either symbol or symbols must be set " );
1327+ throw new \Exception ("rollingWindowPriceChange (): Either symbol or symbols must be set " );
13281328 }
13291329 if (!is_null ($ windowSize )) {
13301330 $ request ['windowSize ' ] = $ windowSize ;
@@ -1453,7 +1453,7 @@ public function balances(string $market_type = 'spot', array $params = [], strin
14531453 } else if ($ api_version === 'v3 ' ) {
14541454 $ url = "v3/balance " ;
14551455 } else {
1456- throw new \Exception ("Invalid API version specified. Use 'v2' or 'v3'. " );
1456+ throw new \Exception ("balances(): Invalid API version specified. Use 'v2' or 'v3'. " );
14571457 }
14581458 }
14591459 $ response = $ this ->httpRequest ($ url , "GET " , array_merge ($ request , $ params ), true );
@@ -1892,6 +1892,25 @@ public function get_headers_from_curl_response(string $header)
18921892 * @throws \Exception
18931893 */
18941894 public function order (string $ side , string $ symbol , $ quantity , $ price , string $ type = "LIMIT " , array $ params = [], bool $ test = false )
1895+ {
1896+ $ request = $ this ->createSpotOrderRequest ($ side , $ symbol , $ quantity , $ price , $ type , $ params );
1897+ $ sor = false ;
1898+ if (isset ($ request ['sor ' ])) {
1899+ $ sor = $ request ['sor ' ];
1900+ unset($ request ['sor ' ]);
1901+ }
1902+ $ url = $ sor ? "v3/sor/order " : "v3/order " ;
1903+ if ($ test ) {
1904+ $ url = $ url . "/test " ;
1905+ }
1906+ return $ this ->apiRequest ($ url , "POST " , $ request , true ); // sending only $request cuz $params are already added to $request inside createSpotOrderRequest
1907+ }
1908+
1909+ /**
1910+ * createSpotOrderRequest
1911+ * helper function to create a request for the spot order
1912+ */
1913+ protected function createSpotOrderRequest (string $ side , string $ symbol , $ quantity , $ price , string $ type = "LIMIT " , array $ params = [])
18951914 {
18961915 $ request = [
18971916 "symbol " => $ symbol ,
@@ -1946,16 +1965,7 @@ public function order(string $side, string $symbol, $quantity, $price, string $t
19461965 } else {
19471966 $ request ['newClientOrderId ' ] = $ this ->generateSpotClientOrderId ();
19481967 }
1949- $ sor = false ;
1950- if (isset ($ params ['sor ' ])) {
1951- $ sor = $ params ['sor ' ];
1952- unset($ params ['sor ' ]);
1953- }
1954- $ url = $ sor ? "v3/sor/order " : "v3/order " ;
1955- if ($ test ) {
1956- $ url = $ url . "/test " ;
1957- }
1958- return $ this ->apiRequest ($ url , "POST " , array_merge ($ request , $ params ), true );
1968+ return array_merge ($ request , $ params );
19591969 }
19601970
19611971 /**
@@ -1990,6 +2000,46 @@ public function sorOrder(string $side, string $symbol, $quantity, $price, string
19902000 return $ this ->order ($ side , $ symbol , $ quantity , $ price , $ type , $ params , $ test );
19912001 }
19922002
2003+ /**
2004+ * replaceOrder - cancels an existing order and places a new order on the same symbol
2005+ *
2006+ * @link https://developers.binance.com/docs/binance-spot-api-docs/rest-api/trading-endpoints#cancel-an-existing-order-and-send-a-new-order-trade
2007+ *
2008+ * @param string $side (mandatory) typically "BUY" or "SELL"
2009+ * @param string $symbol (mandatory) to buy or sell
2010+ * @param string $quantity (mandatory) in the order
2011+ * @param string $price (optional) for the order
2012+ * @param string $type (optional) is determined by the symbol bu typicall LIMIT, STOP_LOSS_LIMIT etc. (default is LIMIT)
2013+ * @param string $cancelOrderId (optional) the orderId of the order to be replaced (mandatory if cancelOrigClientOrderId is not set)
2014+ * @param string $cancelOrigClientOrderId (optional) the origClientOrderId of the order to be replaced (mandatory if cancelOrderId is not set)
2015+ * @param bool $allowFailure (optional) if true new order placement will be attempted even if cancel request fails (default is false)
2016+ * @param string $cancelRestrictions (optional) ONLY_NEW (cancel will succeed if the order status is NEW) or ONLY_PARTIALLY_FILLED (cancel will succeed if order status is PARTIALLY_FILLED)
2017+ * @param string $orderRateLimitExceededMode (optional) DO_NOTHING (default - will only attempt to cancel the order if account has not exceeded the unfilled order rate limit) or CANCEL_ONLY (will always cancel the order)
2018+ * @param array $params (optional) additional transaction options (same as for order())
2019+ *
2020+ * returns array containing the response
2021+ * @throws \Exception
2022+ */
2023+ public function replaceOrder (string $ side , string $ symbol , $ quantity , $ price , string $ type = "LIMIT " , ?string $ cancelOrderId = null , string $ cancelOrigClientOrderId = null , bool $ allowFailure = null , string $ cancelRestrictions = null , string $ orderRateLimitExceededMode = null , array $ params = [])
2024+ {
2025+ $ request = $ this ->createSpotOrderRequest ($ side , $ symbol , $ quantity , $ price , $ type , $ params );
2026+ if (!is_null ($ cancelOrderId )) {
2027+ $ request ['cancelOrderId ' ] = $ cancelOrderId ;
2028+ } else if (is_null ($ cancelOrigClientOrderId )) {
2029+ throw new \Exception ("replaceOrder(): Either cancelOrderId or cancelOrigClientOrderId must be set " );
2030+ }
2031+ if (!is_null ($ cancelOrigClientOrderId )) {
2032+ $ request ['cancelOrigClientOrderId ' ] = $ cancelOrigClientOrderId ;
2033+ }
2034+ $ request ['cancelReplaceMode ' ] = $ allowFailure ? 'ALLOW_FAILURE ' : 'STOP_ON_FAILURE ' ;
2035+ if (!is_null ($ cancelRestrictions )) {
2036+ $ request ['cancelRestrictions ' ] = $ cancelRestrictions ;
2037+ }
2038+ if (!is_null ($ orderRateLimitExceededMode )) {
2039+ $ request ['orderRateLimitExceededMode ' ] = $ orderRateLimitExceededMode ;
2040+ }
2041+ return $ this ->apiRequest ("v3/order/cancelReplace " , "POST " , $ request , true ); // only request is needed, params are already added to request inside createSpotOrderRequest
2042+ }
19932043 /**
19942044 * candlesticks get the candles for the given intervals
19952045 * 1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,1M
@@ -4750,10 +4800,10 @@ public function futuresBatchOrders(array $orders, array $params = [])
47504800 {
47514801 $ formatedOrders = $ this ->createBatchOrdersRequest ($ orders );
47524802 if (count ($ formatedOrders ) > 5 ) {
4753- throw new \Exception ('futuresBatchOrders: max 5 orders allowed ' );
4803+ throw new \Exception ('futuresBatchOrders() : max 5 orders allowed ' );
47544804 }
47554805 if (count ($ formatedOrders ) < 1 ) {
4756- throw new \Exception ('futuresBatchOrders: at least 1 order required ' );
4806+ throw new \Exception ('futuresBatchOrders() : at least 1 order required ' );
47574807 }
47584808 $ request = [];
47594809
@@ -4789,7 +4839,7 @@ public function futuresEditOrder(string $symbol, string $side, string $quantity,
47894839 $ request ['origClientOrderId ' ] = $ origClientOrderId ;
47904840 }
47914841 if (!$ origClientOrderId && !$ orderId ) {
4792- throw new \Exception ('futuresEditOrder: either orderId or origClientOrderId must be set ' );
4842+ throw new \Exception ('futuresEditOrder() : either orderId or origClientOrderId must be set ' );
47934843 }
47944844 if ($ orderId ) {
47954845 $ request ['orderId ' ] = $ orderId ;
@@ -4888,7 +4938,7 @@ public function futuresCancel(string $symbol, $orderid, $params = [])
48884938 if ($ orderid ) {
48894939 $ request ['orderId ' ] = $ orderid ;
48904940 } else if (!isset ($ params ['origClientOrderId ' ])) {
4891- throw new \Exception ('futuresCancel: either orderId or origClientOrderId must be set ' );
4941+ throw new \Exception ('futuresCancel() : either orderId or origClientOrderId must be set ' );
48924942 }
48934943 return $ this ->fapiRequest ("v1/order " , 'DELETE ' , array_merge ($ request , $ params ), true );
48944944 }
@@ -4921,7 +4971,7 @@ public function futuresCancelBatchOrders(string $symbol, $orderIdList = null, $o
49214971 // remove spaces between the ids
49224972 $ request ['origClientOrderIdList ' ] = str_replace (', ' , ', ' , json_encode ($ origClientOrderIdList ));
49234973 } else {
4924- throw new \Exception ('futuresCancelBatchOrders: either orderIdList or origClientOrderIdList must be set ' );
4974+ throw new \Exception ('futuresCancelBatchOrders() : either orderIdList or origClientOrderIdList must be set ' );
49254975 }
49264976
49274977 return $ this ->fapiRequest ("v1/batchOrders " , 'DELETE ' , array_merge ($ request , $ params ), true );
@@ -5000,7 +5050,7 @@ public function futuresOrderStatus(string $symbol, $orderId = null, $origClientO
50005050 } else if ($ origClientOrderId ) {
50015051 $ request ['origClientOrderId ' ] = $ origClientOrderId ;
50025052 } else {
5003- throw new \Exception ('futuresOrderStatus: either orderId or origClientOrderId must be set ' );
5053+ throw new \Exception ('futuresOrderStatus() : either orderId or origClientOrderId must be set ' );
50045054 }
50055055
50065056 return $ this ->fapiRequest ("v1/order " , 'GET ' , array_merge ($ request , $ params ), true );
@@ -5097,7 +5147,7 @@ public function futuresOpenOrder(string $symbol, $orderId = null, $origClientOrd
50975147 } else if ($ origClientOrderId ) {
50985148 $ request ['origClientOrderId ' ] = $ origClientOrderId ;
50995149 } else {
5100- throw new \Exception ('futuresOpenOrder: either orderId or origClientOrderId must be set ' );
5150+ throw new \Exception ('futuresOpenOrder() : either orderId or origClientOrderId must be set ' );
51015151 }
51025152
51035153 return $ this ->fapiRequest ("v1/openOrder " , 'GET ' , array_merge ($ request , $ params ), true );
@@ -5439,7 +5489,7 @@ public function futuresPositions($symbol = null, array $params = [], string $api
54395489 }
54405490
54415491 if ($ api_version !== 'v2 ' && $ api_version !== 'v3 ' ) {
5442- throw new \Exception ('futuresPositions: api_version must be either v2 or v3 ' );
5492+ throw new \Exception ('futuresPositions() : api_version must be either v2 or v3 ' );
54435493 }
54445494 return $ this ->fapiRequest ($ api_version . "/positionRisk " , 'GET ' , array_merge ($ request , $ params ), true );
54455495 }
@@ -5568,10 +5618,10 @@ public function futuresPositionMarginChangeHistory(string $symbol, $startTime =
55685618 } else if ($ addOrReduce === 'REDUCE ' || $ addOrReduce === '2 ' ) {
55695619 $ request ['addOrReduce ' ] = 2 ;
55705620 } else {
5571- throw new \Exception ('futuresPositionMarginChangeHistory: addOrReduce must be "ADD" or "REDUCE" or 1 or 2 ' );
5621+ throw new \Exception ('futuresPositionMarginChangeHistory() : addOrReduce must be "ADD" or "REDUCE" or 1 or 2 ' );
55725622 }
55735623 } else {
5574- throw new \Exception ('futuresPositionMarginChangeHistory: addOrReduce must be "ADD" or "REDUCE" or 1 or 2 ' );
5624+ throw new \Exception ('futuresPositionMarginChangeHistory() : addOrReduce must be "ADD" or "REDUCE" or 1 or 2 ' );
55755625 }
55765626 }
55775627
@@ -5597,7 +5647,7 @@ public function futuresPositionMarginChangeHistory(string $symbol, $startTime =
55975647 public function futuresBalances (array $ params = [], string $ api_version = 'v3 ' )
55985648 {
55995649 if ($ api_version !== 'v2 ' && $ api_version !== 'v3 ' ) {
5600- throw new \Exception ('futuresBalances: api_version must be either v2 or v3 ' );
5650+ throw new \Exception ('futuresBalances() : api_version must be either v2 or v3 ' );
56015651 }
56025652 return $ this ->balances ('futures ' , $ params , 'v3 ' );
56035653 }
@@ -5640,7 +5690,7 @@ public function futuresBalancesV3(array $params = [])
56405690 public function futuresAccount (array $ params = [], string $ api_version = 'v3 ' )
56415691 {
56425692 if ($ api_version !== 'v2 ' && $ api_version !== 'v3 ' ) {
5643- throw new \Exception ('futuresAccount: api_version must be either v2 or v3 ' );
5693+ throw new \Exception ('futuresAccount() : api_version must be either v2 or v3 ' );
56445694 }
56455695
56465696 return $ this ->fapiRequest ($ api_version . "/account " , "GET " , $ params , true );
@@ -6150,7 +6200,7 @@ public function convertSend(string $fromAsset, string $toAsset, $fromAmount = nu
61506200 } else if ($ toAmount ) {
61516201 $ request ['toAmount ' ] = $ toAmount ;
61526202 } else {
6153- throw new \Exception ('convertSendRequest: fromAmount or toAmount must be set ' );
6203+ throw new \Exception ('convertSendRequest() : fromAmount or toAmount must be set ' );
61546204 }
61556205 if ($ validTime ) {
61566206 $ request ['validTime ' ] = $ validTime ;
@@ -6206,7 +6256,7 @@ public function convertStatus($orderId = null, $quoteId = null, array $params =
62066256 } else if ($ quoteId ) {
62076257 $ request ['quoteId ' ] = $ quoteId ;
62086258 } else {
6209- throw new \Exception ('convertStatus: orderId or quoteId must be set ' );
6259+ throw new \Exception ('convertStatus() : orderId or quoteId must be set ' );
62106260 }
62116261 return $ this ->fapiRequest ("v1/convert/orderStatus " , 'GET ' , array_merge ($ request , $ params ), true );
62126262 }
0 commit comments