@Dzonke

Почему ccxt.kucoin выдаёт ошибку: kucoin price of BTC/EUR must be greater than minimum price precision of 0.01?

есть код. Он работает хорошо в связке с ETH/EUR но если надо поставить его выполнение на BTC/EUR то я получаю ошибку:
Placing order: BTC/EUR buy 25567.73 0.00226
Failed to place order: kucoin price of BTC/EUR must be greater than minimum price precision of 0.01

C чем может быть связано? Шаг выставлен, округление также

Сам код:
import ccxt
import time
import telebot
import threading

api_key = 'key'
api_secret = 'secret'
api_passphrase = 'passphrase'

kucoin = ccxt.kucoin({
    'apiKey': api_key,
    'secret': api_secret,
    'password': api_passphrase,
    'rateLimit': 2000,
    'enableRateLimit': True,
})

bot_token = 'bot_token'
bot = telebot.TeleBot(bot_token)

active_pairs = {'BTC/EUR': False, 'ETH/EUR': False}

def currentSettings(message):
    global active_pairs
    bot.send_message(message.chat.id, """Текущие настройки:
    BTC/EUR: {}
    ETH/EUR: {}
    """.format(active_pairs['BTC/EUR'], active_pairs['ETH/EUR']))


@bot.message_handler(commands=['on_all'])
def on_all(message):
    global active_pairs
    active_pairs = {'BTC/EUR': True, 'ETH/EUR': True}
    bot.send_message(message.chat.id, "Все пары включены.")
    currentSettings(message)

@bot.message_handler(commands=['off_all'])
def off_all(message):
    global active_pairs
    active_pairs = {'BTC/EUR': False, 'ETH/EUR': False}
    bot.send_message(message.chat.id, "Все пары выключены.")
    currentSettings(message)

@bot.message_handler(commands=['on_btc'])
def on_btc(message):
    global active_pairs
    active_pairs['BTC/EUR'] = True
    bot.send_message(message.chat.id, "Торговля BTC включена.")
    currentSettings(message)

@bot.message_handler(commands=['off_btc'])
def off_btc(message):
    global active_pairs
    active_pairs['BTC/EUR'] = False
    bot.send_message(message.chat.id, "Торговля BTC выключена.")
    currentSettings(message)

@bot.message_handler(commands=['on_eth'])
def on_eth(message):
    global active_pairs
    active_pairs['ETH/EUR'] = True
    bot.send_message(message.chat.id, "Торговля ETH включена.")
    currentSettings(message)

@bot.message_handler(commands=['off_eth'])
def off_eth(message):
    global active_pairs
    active_pairs['ETH/EUR'] = False
    bot.send_message(message.chat.id, "Торговля ETH выключена.")
    currentSettings(message)

@bot.message_handler(commands=['start'])
def start(message):
    global chat_id
    chat_id = message.chat.id
    bot.send_message(chat_id, """Бот запущен.""")
    bot.send_message(chat_id, """Доступные команды:
    /on_all - включить торговлю на всех парах
    /off_all - выключить торговлю на всех парах
    /on_btc - включить торговлю на паре BTC/EUR
    /off_btc - выключить торговлю на паре BTC/EUR
    /on_eth - включить торговлю на паре ETH/EUR
    /off_eth - выключить торговлю на паре ETH/EUR
    """)
    currentSettings(message)
        
def get_price_step(pair):
    try:
        market_info = kucoin.load_markets()
        return float(market_info[pair]['info']['priceIncrement'])
    except Exception as e:
        print(f"Failed to fetch price step: {e}")
        return None

def round_price_to_step(price, step):
    return round(price / step) * step

def get_account_balance(currency):
    try:
        balances = kucoin.fetch_balance()
        if(currency not in balances['free']):
            return 0

        return balances['free'][currency]
    except Exception as e:
        print(f"Failed to fetch account balance: {e}")
        return 0

def fetch_order_book(pair):
    try:
        return kucoin.fetch_order_book(pair)
    except Exception as e:
        print(f"Failed to fetch order book: {e}")
        return None

def calculate_order_price(pair, side, threshold):
    order_book = fetch_order_book(pair)
    if not order_book:
        return None

    orders = order_book['bids'] if side == 'buy' else order_book['asks']
    best_price = orders[0][0]
    lowest_sell_price = order_book['asks'][0][0]

    if side == 'buy':
        if best_price >= lowest_sell_price * (1 - threshold):
            target_price = best_price
        else:
            target_price = lowest_sell_price * (1 - threshold)
            for price, _ in orders:
                if price < target_price:
                    target_price = price
                    break

    price_step = get_price_step(pair)
    if not price_step:
        return None

    rounded_price = round_price_to_step(target_price, price_step)

    return rounded_price
    
def place_order(pair, side, price, size):
    try:
        print(f"Placing order: {pair} {side} {price} {size}")
        return kucoin.create_limit_order(pair, side, price, size)
    except Exception as e:
        print(f"Failed to place order: {e}")
        return None

def cancel_order(order_id):
    try:
        return kucoin.cancel_order(order_id)
    except Exception as e:
        print(f"Failed to cancel order: {e}")

def trade(pair, side, threshold, balance_ratio):
    eur_balance = get_account_balance('EUR')

    if eur_balance == 0:
        return print("No EUR balance")

    trade_balance = eur_balance * balance_ratio

    best_price = calculate_order_price(pair, side, threshold)
    if not best_price:
        return

    size = trade_balance / best_price
    size = round(size, 6)  # Round size to the correct precision

    open_orders = kucoin.fetch_open_orders(pair)
    for order in open_orders:
        cancel_order(order['id'])

    try:
        place_order(pair, side, round(best_price, 2), size)
        print(f"Placed {side} order for {pair} at price {best_price} with size {size}")
    except Exception as e:
        pass
    
def main():
    while True:
        for pair, threshold, balance_ratio in [('BTC/EUR', 0.02, 0.5), ('ETH/EUR', 0.015, 0.5)]:
            if active_pairs[pair]:
                trade(pair, 'buy', threshold, balance_ratio)
        time.sleep(1)

if __name__ == "__main__":
    main_thread = threading.Thread(target=main)
    main_thread.start()
    bot.polling(none_stop=True)
  • Вопрос задан
  • 93 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы