kucoin-php-sdk
kucoin-php-sdk copied to clipboard
Order size increment invalid
may size = 0.693
[API]Failure: api code is NOT 200000, POST /api/v1/orders with body={"clientOid":"615d681b3f8c44.66488972","side":"buy","symbol":"SOL-USDT","type":"market","size":0.6930000000000001}, respond code=400100 message="Order size increment invalid." body={"code":"400100","msg":"Order size increment invalid."}
may size = 0.693
[API]Failure: api code is NOT 200000, POST /api/v1/orders with body={"clientOid":"615d681b3f8c44.66488972","side":"buy","symbol":"SOL-USDT","type":"market","size":0.6930000000000001}, respond code=400100 message="Order size increment invalid." body={"code":"400100","msg":"Order size increment invalid."}
Hi,
The spot and futures of KuCoin exchange have restrictions on placing orders
spot: https://docs.kucoin.center/#get-symbols-list
futures: https://docs.kucoin.center/futures/#get-order-info-of-the-contract
For example, for placing a spot order: The baseMinSize and baseMaxSize fields define the min and max order size. The priceIncrement field specifies the min order price as well as the price increment.This also applies to quote currency. The order price must be a positive integer multiple of this priceIncrement (i.e. if the increment is 0.01, the 0.001 and 0.021 order prices would be rejected).
I'm sure others will run into this issue. It's not an issue with this repo, but something that KuCoin requires. Here is code that should help people. Or at least get them closer to solving the issue. I've used the following code for many months and appears to be working.
$coin = 'BTC-USDT'; // coin you want to buy
$canBuyFor = 30000; // price per coin
$amountToSpend = 10; // you want to buy 10 USDT worth of BTC
$priceInc = 0;
$sizeInc = 0;
$tickers = $Symbol->getList();
foreach ($tickers as $ticker) {
if ($ticker['symbol'] == $coin) {
$priceInc = $ticker['priceIncrement'];
$sizeInc = $ticker['baseIncrement'];
break;
}
}
$buySize = $amountToSpend / $canBuyFor;
$priceDecimalPlaces = strlen(substr(strrchr($priceInc, "."), 1));
$sizeDecimalPlaces = strlen(substr(strrchr($sizeInc, "."), 1));
$priceForOrder = roundNumberDown($canBuyFor, $priceDecimalPlaces);
$sizeForOrder = roundNumberDown($buySize, $sizeDecimalPlaces);
$priceForOrder = strval($priceForOrder);
$sizeForOrder = strval($sizeForOrder);
// order now....
$orderClass = new Order($auth);
$order = [
'type' => 'limit',
'side' => 'buy',
'symbol' => $coin,
'price' => $priceForOrder,
'size' => $sizeForOrder,
];
function roundNumberDown($number, $significance = 2)
{
$multiplier = 1;
for ($i = 0; $i < $significance; $i++)
$multiplier *= 10;
$number = intval($number * $multiplier) / $multiplier;
//return round($number, $significance);
return number_format($number, $significance, '.', ''); // bug fix by @behzadev
}
the roundNumberDown function above, returns scientific notations for very small numbers like BTC Satoshi which is 1 * 10^(-8), for example it returns "1.0E-8" for "0.00000001". make sure to take care of that as well.
to fix that, I'm using number_format instead of round:
return number_format($number, $significance, '.', '');
@behzadev do you mind to tell me on what $significance is based ?
@tahola it's the number of decimal places you want to consider based on the pair, for example for XXX-USDT, priceIncrement might be 0.001, then the decimal places ($significance) is 3. so before using that function you need another function to get decimal places of that priceIncrement, and make sure your function also takes care of getting decimal places for scientific notation numbers such as "1.0E-8".
@tahola Have you been able to test out your fix on a few buys? I use number_format () mostly in programming and can't help but think there was some odd reason I used round() but can't remember now. Sadly I don't use Kucoin anymore since I am in the USA.
@markking79 yes thank you, I took your code as a base and modified the first line.
$buySize = $quote_size / $limit_price;
$priceDecimalPlaces = strlen(substr(strrchr($priceIncrement, "."), 1));
$sizeDecimalPlaces = strlen(substr(strrchr($baseIncrement, "."), 1));
$priceForOrder = \App\Models\Kucoin::roundNumberDown($limit_price, $priceDecimalPlaces);
$sizeForOrder = \App\Models\Kucoin::roundNumberDown($buySize, $sizeDecimalPlaces);
$priceForOrder = strval($priceForOrder);
$sizeForOrder = strval($sizeForOrder);
$orderApi = new Order($auth);
$params = [
'clientOid' => uniqid(),
'side' => $side,
'symbol' => $base . '-' . $quote,
'type' => 'limit',
'price' => (string) $priceForOrder,
'size' => $sizeForOrder,
];
@behzadev Nice! I updated the code in the earlier post to use number_format instead of round.