kucoin-php-sdk icon indicating copy to clipboard operation
kucoin-php-sdk copied to clipboard

Order size increment invalid

Open mahdi4187 opened this issue 4 years ago • 8 comments

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."}

mahdi4187 avatar Oct 06 '21 09:10 mahdi4187

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).

codewc avatar Oct 09 '21 14:10 codewc

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 
}

markking79 avatar Oct 24 '22 01:10 markking79

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 avatar May 11 '23 06:05 behzadev

@behzadev do you mind to tell me on what $significance is based ?

tahola avatar May 03 '24 09:05 tahola

@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".

behzadev avatar May 03 '24 10:05 behzadev

@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 avatar May 10 '24 03:05 markking79

@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,
        ];

tahola avatar May 10 '24 03:05 tahola

@behzadev Nice! I updated the code in the earlier post to use number_format instead of round.

markking79 avatar May 12 '24 13:05 markking79