Binance API Copy-Trading TP/SL Orders

Good day,

Currently in the development of a copy-trading software and trying to get the TP/SL orders working.

Sending the actual orders from the master to the slave works perfectly fine,
however the issue seems to come up, when the order gets filled.

Let’s say the TP gets filled the SL stays on the slave account, even when it does automatically get removed on the master account.

Shouldn’t Binance automatically take care of the opposite level? And how to solve this?

Kind regards,

Hi,
If you’re executing the same exact orders on multiple accounts then behaviour should be the same. Can you post the code snippet you’re using to perform the orders? That will help identify your issue.

import json
import sys

from binance.client import Client
from binance.enums import TIME_IN_FORCE_GTC
from ccxt.base.decimal_to_precision import DECIMAL_PLACES  # noqa F401
from ccxt.base.decimal_to_precision import NO_PADDING  # noqa F401
from ccxt.base.decimal_to_precision import PAD_WITH_ZERO  # noqa F401
from ccxt.base.decimal_to_precision import ROUND  # noqa F401
from ccxt.base.decimal_to_precision import SIGNIFICANT_DIGITS  # noqa F401
from ccxt.base.decimal_to_precision import TICK_SIZE  # noqa F401
from ccxt.base.decimal_to_precision import TRUNCATE  # noqa F401
from ccxt.base.decimal_to_precision import decimal_to_precision  # noqa F401

from bot.models import Masters as Admin

def get_count(number):
    s = str(number)
    if '.' in s:
        return abs(s.find('.') - len(s)) - 1
    else:
        return 0

async def Trader(user, order, admin):
    leverage = int(admin.master_leverage)
    api_key = user.user_key
    api_secret = user.user_secret_key
    client = Client(
            api_key,
            api_secret
            )
    order_id = order.order_id
    origQty = order.origQty
    price = float(order.price)
    avgPrice = float(order.avgPrice)
    closePosition = order.closePosition
    cumQuote = order.cumQuote
    executedQty = order.executedQty
    # Тип Маркет лимит либо маркет
    origType = order.origType
    positionSide = order.positionSide
    priceProtect = order.priceProtect
    reduceOnly = order.reduceOnly
    side = order.side
    status = order.status
    symbol = order.symbol
    # тип маркет
    types = order.types
    stop_price = order.stop_price
    balance_percent = float(order.balance_percent)

    mes = f'Start create order\n' \
          f'Symbol {symbol}'
    print(mes)
    # информация с биржи по торговым парам
    # число на сколько нужно округлить объем для ордера
    # получаем количество знаков после запятой у ордера админа origQty_m
    # если 0 то ставим 1
    if origType == 'MARKET':
        round_size = get_count(executedQty)
    else:
        round_size = get_count(origQty)

    # шаг цены в торговой паре
    step_size = 0
    with open('data_file.json') as f:
        templates = json.load(f)

    for temp in templates:
        if temp['symbol'] == symbol:
            step_size = float(temp['stepSize'])
            break
    print(f'Round size {str(round_size)}')
    print(f'step_size {str(step_size)}')

    if types == 'MARKET':
        current_price = float(avgPrice)
    else:
        current_price = float(price)
    # Изменяем кредитном плече в валютной паре
    client.futures_change_leverage(symbol=symbol,
                                   leverage=leverage)
    if types == 'MARKET':
        # если у пользователя есть последний ордер то
        # получаем его если нет то пропускаем все
        sy = ''
        s = ''
        t = ''
        try:
            # получаем последний ордер
            user_order = client.futures_get_all_orders()[-1]
            sy = user_order['symbol']
            s = user_order['side']
            t = user_order['type']
        except:
            sy = 'BTC'
            s = ''
            t = ''
        if symbol == sy and side == s and types == t:
            print(sy + ' = There is already such an order.\n')
        else:
            # инициализируем объем покупки
            if symbol.find('USDT') >= 0:
                # получаем баланс до момента покупки
                balance_futures = client.futures_account_balance()
                balance = 0
                for bal in balance_futures:
                    if bal['asset'] == 'USDT':
                        balance = float(bal['balance']) * leverage

                # округляем и передаем в переменную
                wa = (float(balance) * float(balance_percent) / 100)
                # минимальный объем для
                # ордера
                if wa < 10:
                    wa = 11
                while True:
                    min_amount_m = float(wa) / float(current_price) // float(
                        step_size) * float(step_size)
                    if min_amount_m <= 0.001:
                        wa += 1
                    else:
                        break
                # округляем через функцию сстх апи
                quantity = float(decimal_to_precision(min_amount_m,
                                                      ROUND,
                                                      round_size,
                                                      DECIMAL_PLACES))
                print(quantity)
                try:
                    if reduceOnly:
                        client.futures_create_order(
                            symbol=symbol,
                            side=side,
                            type=types,
                            quantity=quantity,
                            reduceOnly=reduceOnly,
                        )
                    else:
                        client.futures_create_order(
                            symbol=symbol,
                            side=side,
                            type=types,
                            quantity=quantity,
                        )
                except Exception as e:
                    exc_type, exc_obj, exc_tb = sys.exc_info()
                    print(f'{e} line = {str(exc_tb.tb_lineno)}')
    else:
        try:
            print('try limit')
            # получаем последний ордер
            user_order = client.futures_get_open_orders(symbol=symbol)
            if len(user_order) > 0:
                for us_or in user_order:
                    sym = us_or['symbol']
                    ss = us_or['side']
                    ts = us_or['type']
                    if symbol == sym and side == ss and types == ts:
                        print(sym + ' = There is already such an order.\n')
                    else:
                        # инициализируем объем покупки
                        quantity = 0
                        if symbol.find('USDT') >= 0:
                            try:
                                # получаем баланс до момента покупки
                                balance_futures = client.futures_account_balance()
                                balance = 0
                                for bal in balance_futures:
                                    if bal['asset'] == 'USDT':
                                        balance = float(bal['balance']) * leverage
                                # округляем и передаем в переменную
                                wa = (float(balance) * float(
                                    balance_percent) / 100)
                                if wa < 10:
                                    wa = 11
                                # минимальный объем для ордера
                                while True:
                                    min_amount = float(wa) / float(current_price) // float(
                                        step_size) * float(step_size)
                                    if min_amount <= 0.001:
                                        wa += 1
                                    else:
                                        break

                                quantity = float(decimal_to_precision(min_amount,
                                                                      ROUND,
                                                                      round_size,
                                                                      DECIMAL_PLACES))
                                print('quantity ' + str(quantity))
                                print('round_size ' + str(min_amount))

                            except ZeroDivisionError:
                                if types == 'STOP_MARKET':
                                    print('STOP_MARKET')
                                else:
                                    print('ran out')
                        # make order
                        if types == 'LIMIT':
                            try:
                                try:
                                    # создаем ордер
                                    client.futures_create_order(
                                        symbol=symbol,
                                        side=side,
                                        type='LIMIT',
                                        timeInForce=TIME_IN_FORCE_GTC,
                                        quantity=quantity,
                                        price=price,
                                    )
                                    msg = f'Order create successful\n' \
                                          f'Symbol {symbol}\n' \
                                          f'Type {types}\n' \
                                          f'Price {price}\n' \
                                          f'QTY {quantity}'
                                    print(msg)
                                except:
                                    # создаем ордер
                                    client.futures_create_order(
                                        symbol=symbol,
                                        side=side,
                                        type='LIMIT',
                                        timeInForce=TIME_IN_FORCE_GTC,
                                        quantity=round(min_amount, 3),
                                        price=price,
                                    )
                                    msg = f'Order create successful\n' \
                                          f'Symbol {symbol}\n' \
                                          f'Type {types}\n' \
                                          f'Price {price}\n' \
                                          f'QTY {quantity}'
                                    print(msg)
                            except Exception as e:
                                msg = f'Symbol {symbol}\n' \
                                      f'Quantity {quantity}\n' \
                                      f'Price {price}'
                                print('Limit')
                                exc_type, exc_obj, exc_tb = sys.exc_info()
                                print(f'{e} line = {str(exc_tb.tb_lineno)}')
                                print(msg)
                        elif types == 'STOP_MARKET':
                            try:
                                client.futures_create_order(
                                    symbol=symbol,
                                    side=side,
                                    type=types,
                                    timeInForce=TIME_IN_FORCE_GTC,
                                    stopPrice=stop_price,
                                    closePosition=True,
                                    # reduceOnly=reduceOnly
                                )
                                msg = f'Order create successful\n' \
                                      f'Symbol {symbol}\n' \
                                      f'Type {types}\n' \
                                      f'Price {stop_price}\n' \
                                      f'QTY {quantity}'
                                print(msg)
                            except Exception as e:
                                msg = f'Symbol {symbol}\n' \
                                      f'Quantity {quantity}\n' \
                                      f'Price {price}\n' \
                                      f'StopPrice {stop_price}'
                                print('STOP_MARKET')
                                print(msg)
                                exc_type, exc_obj, exc_tb = sys.exc_info()
                                print(f'{e} line = {str(exc_tb.tb_lineno)}')
                        elif types == 'TAKE_PROFIT_MARKET':
                            try:
                                client.futures_create_order(
                                    symbol=symbol,
                                    side=side,
                                    type=types,
                                    timeInForce=TIME_IN_FORCE_GTC,
                                    stopPrice=stop_price,
                                    closePosition=True,
                                )
                                msg = f'Order create successful\n' \
                                      f'Symbol {symbol}\n' \
                                      f'Type {types}\n' \
                                      f'Price {price}\n' \
                                      f'QTY {quantity}'
                                print(msg)
                            except Exception as e:
                                msg = f'Symbol {symbol}\n' \
                                      f'Quantity {quantity}\n' \
                                      f'Price {price}'
                                print('TAKE_PROFIT_MARKET')
                                exc_type, exc_obj, exc_tb = sys.exc_info()
                                print(f'{e} line = {str(exc_tb.tb_lineno)}')
                                print(msg)
                        elif types == 'STOP_LOSS_LIMIT':
                            try:
                                client.futures_create_order(
                                    symbol=symbol,
                                    side=side,
                                    type=types,
                                    timeInForce=TIME_IN_FORCE_GTC,
                                    price=price,
                                    closePosition=True,
                                )
                                msg = f'Order create successful\n' \
                                      f'Symbol {symbol}\n' \
                                      f'Type {types}\n' \
                                      f'Price {price}\n' \
                                      f'QTY {quantity}'
                                print(msg)
                            except Exception as e:
                                msg = f'Symbol {symbol}\n' \
                                      f'Quantity {quantity}\n' \
                                      f'Price {price}'
                                print('STOP_LOSS_LIMIT')
                                exc_type, exc_obj, exc_tb = sys.exc_info()
                                print(f'{e} line = {str(exc_tb.tb_lineno)}')
                                print(msg)
                        else:
                            msg = f'Symbol {symbol}\n' \
                                  f'Quantity {quantity}\n' \
                                  f'Price {price}'
                            print(msg)
                            print('Something else')
            else:
                # инициализируем объем покупки
                quantity = 0
                if symbol.find('USDT') >= 0:
                    try:
                        # получаем баланс до момента покупки
                        balance_futures = client.futures_account_balance()
                        balance = 0
                        for bal in balance_futures:
                            if bal['asset'] == 'USDT':
                                balance = float(bal['balance']) * leverage
                        # округляем и передаем в переменную
                        wa = (float(balance) * float(
                            balance_percent) / 100)
                        if wa < 10:
                            wa = 11
                        # минимальный объем для ордера
                        while True:
                            min_amount = float(wa) / float(current_price) // float(
                                step_size) * float(step_size)
                            if min_amount <= 0.001:
                                wa += 1
                            else:
                                break

                        quantity = float(decimal_to_precision(min_amount,
                                                              ROUND,
                                                              round_size,
                                                              DECIMAL_PLACES))
                        print('quantity ' + str(quantity))
                        print('round_size ' + str(min_amount))

                    except ZeroDivisionError:
                        if types == 'STOP_MARKET':
                            print('STOP_MARKET')
                        else:
                            print('ran out')
                # make order
                if types == 'LIMIT':
                    try:
                        try:
                            # создаем ордер
                            client.futures_create_order(
                                symbol=symbol,
                                side=side,
                                type='LIMIT',
                                timeInForce=TIME_IN_FORCE_GTC,
                                quantity=quantity,
                                price=price,
                            )
                            msg = f'Order create successful\n' \
                                  f'Symbol {symbol}\n' \
                                  f'Type {types}\n' \
                                  f'Price {price}\n' \
                                  f'QTY {quantity}'
                            print(msg)
                        except:
                            # создаем ордер
                            client.futures_create_order(
                                symbol=symbol,
                                side=side,
                                type='LIMIT',
                                timeInForce=TIME_IN_FORCE_GTC,
                                quantity=round(min_amount, 3),
                                price=price,
                            )
                            msg = f'Order create successful\n' \
                                  f'Symbol {symbol}\n' \
                                  f'Type {types}\n' \
                                  f'Price {price}\n' \
                                  f'QTY {quantity}'
                            print(msg)
                    except Exception as e:
                        msg = f'Symbol {symbol}\n' \
                              f'Quantity {quantity}\n' \
                              f'Price {price}'
                        print('Limit')
                        exc_type, exc_obj, exc_tb = sys.exc_info()
                        print(f'{e} line = {str(exc_tb.tb_lineno)}')
                        print(msg)
                elif types == 'STOP_MARKET':
                    try:
                        client.futures_create_order(
                            symbol=symbol,
                            side=side,
                            type=types,
                            timeInForce=TIME_IN_FORCE_GTC,
                            stopPrice=stop_price,
                            closePosition=True,
                            # reduceOnly=reduceOnly
                        )
                        msg = f'Order create successful\n' \
                              f'Symbol {symbol}\n' \
                              f'Type {types}\n' \
                              f'Price {stop_price}\n' \
                              f'QTY {quantity}'
                        print(msg)
                    except Exception as e:
                        msg = f'Symbol {symbol}\n' \
                              f'Quantity {quantity}\n' \
                              f'Price {price}\n' \
                              f'StopPrice {stop_price}'
                        print('STOP_MARKET')
                        print(msg)
                        exc_type, exc_obj, exc_tb = sys.exc_info()
                        print(f'{e} line = {str(exc_tb.tb_lineno)}')
                elif types == 'TAKE_PROFIT_MARKET':
                    try:
                        client.futures_create_order(
                            symbol=symbol,
                            side=side,
                            type=types,
                            timeInForce=TIME_IN_FORCE_GTC,
                            stopPrice=stop_price,
                            closePosition=True,
                        )
                        msg = f'Order create successful\n' \
                              f'Symbol {symbol}\n' \
                              f'Type {types}\n' \
                              f'Price {price}\n' \
                              f'QTY {quantity}'
                        print(msg)
                    except Exception as e:
                        msg = f'Symbol {symbol}\n' \
                              f'Quantity {quantity}\n' \
                              f'Price {price}'
                        print('TAKE_PROFIT_MARKET')
                        exc_type, exc_obj, exc_tb = sys.exc_info()
                        print(f'{e} line = {str(exc_tb.tb_lineno)}')
                        print(msg)
                elif types == 'STOP_LOSS_LIMIT':
                    try:
                        client.futures_create_order(
                            symbol=symbol,
                            side=side,
                            type=types,
                            timeInForce=TIME_IN_FORCE_GTC,
                            price=price,
                            closePosition=True,
                        )
                        msg = f'Order create successful\n' \
                              f'Symbol {symbol}\n' \
                              f'Type {types}\n' \
                              f'Price {price}\n' \
                              f'QTY {quantity}'
                        print(msg)
                    except Exception as e:
                        msg = f'Symbol {symbol}\n' \
                              f'Quantity {quantity}\n' \
                              f'Price {price}'
                        print('STOP_LOSS_LIMIT')
                        exc_type, exc_obj, exc_tb = sys.exc_info()
                        print(f'{e} line = {str(exc_tb.tb_lineno)}')
                        print(msg)
                else:
                    msg = f'Symbol {symbol}\n' \
                          f'Quantity {quantity}\n' \
                          f'Price {price}'
                    print(msg)
                    print('Something else')

        except Exception as e:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            print(f'{e} line = {str(exc_tb.tb_lineno)}')

This is the full cuntion taking care of the orders.

1 Like