Search code examples
pythontradingbinance

Binance - Spot Market Profit Calculator


I have a Python method that calculates the profit after taking into account the commission structure. However, it fails to replicate the exact values from Binance trade history. For example I bought ETH/USDT using LIMIT order at a price of 2595 with a buy amount of 57.609 USDT. Then I sold using LIMIT order at a price of 2700. As per my understanding the precision value for this pair is 8 but still the calculator fails to give correct results. Below is the code I am using.

def calculate_profit_after_commission_binance(buy_price: float, buy_amount_usdt: float, sell_price: float, 
                                       order_type_buy: str = 'MARKET', order_type_sell: str = 'MARKET',
                                       fee_rate_maker: float = 0.001, fee_rate_taker: float = 0.001) -> float:
    if order_type_buy == 'MARKET':
        buy_fee_rate = fee_rate_taker
    else:
        buy_fee_rate = fee_rate_maker

    if order_type_sell == 'MARKET':
        sell_fee_rate = fee_rate_taker
    else:
        sell_fee_rate = fee_rate_maker

    # Calculate the amount of asset bought
    asset_quantity = buy_amount_usdt / buy_price
    
    # Deduct commission on the asset bought
    asset_quantity_available = asset_quantity * (1 - buy_fee_rate)
    
    # Selling commission in USDT
    sell_commission = asset_quantity_available * sell_price * sell_fee_rate

    # Profit after sell commission
    profit = asset_quantity_available * sell_price - sell_commission - buy_amount_usdt
    
    return profit

enter image description here


Solution

  • Since you can only sell up to 4 decimal place of the available asset. Below is the correct implementation. Remaining asset after 4 decimal places stays in account and can be converted to BNB.

    from decimal import Decimal, ROUND_DOWN
    
    def truncate_to_precision(value, precision=4):
        # Convert the float to Decimal
        decimal_value = Decimal(value)
        # Quantize the Decimal to the specified precision
        truncated_value = decimal_value.quantize(Decimal(f'1.{"0" * precision}'), rounding=ROUND_DOWN)
        return float(truncated_value)
    
    
    def calculate_profit_after_commission_binance(buy_price: float, buy_amount_usdt: float, sell_price: float, precision: int,
                                           order_type_buy: str = 'MARKET', order_type_sell: str = 'MARKET',
                                           fee_rate_maker: float = 0.001, fee_rate_taker: float = 0.001) -> float:
        if order_type_buy == 'MARKET':
            buy_fee_rate = fee_rate_taker
        else:
            buy_fee_rate = fee_rate_maker
    
        if order_type_sell == 'MARKET':
            sell_fee_rate = fee_rate_taker
        else:
            sell_fee_rate = fee_rate_maker
    
        # Calculate the amount of asset bought
        asset_quantity = buy_amount_usdt / buy_price
        
        # Deduct commission on the asset bought
        asset_quantity_available = asset_quantity * (1 - buy_fee_rate)
    
        asset_quantity_available_sell = truncate_to_precision(asset_quantity_available, 4)
        
        # Selling commission in USDT
        sell_commission = asset_quantity_available_sell * sell_price * sell_fee_rate
    
        # Profit after sell commission
        profit = asset_quantity_available_sell * sell_price - sell_commission - buy_amount_usdt
        
        return profit