Skip to content

Commit

Permalink
Merge pull request idkravitz#9 from bobwng/auto-adjust-bnb-balance-tn…
Browse files Browse the repository at this point in the history
…twist

Auto adjust BNB balance
  • Loading branch information
tntwist authored Jul 18, 2021
2 parents be4c209 + 7f3eea9 commit 44d45b8
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
4 changes: 3 additions & 1 deletion .user.cfg.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ trade_fee=auto
price_type=orderbook
accept_losses=false
max_idle_hours=72
ratio_adjust_weight=500
ratio_adjust_weight=500
auto_adjust_bnb_balance=false
auto_adjust_bnb_balance_rate=3
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ Create a .cfg file named `user.cfg` based off `.user.cfg.example`, then add your
- **accept_losses** - Needs to be set to true for highly risky and gamling strategies. Otherwise the bot wont start.
- **max_idle_hours** - Controls the amount of hours for reseting the ratios when the bot has not traded (only used in db_reset strategy)
- **ratio_adjust_weight** - Controls the weight of the cumulative moving ratio avarage in the ratio_adjust strategy (only used in ratio_adjust strategy)
- **auto_adjust_bnb_balance** - Controls the bot to auto buy BNB while there is no enough BNB balance in your account, to get the benifits of using BNB to pay the commisions. Default is false. Effective if you have enabled to [use BNB to pay for any fees on the Binance platform](https://www.binance.com/en/support/faq/115000583311-Using-BNB-to-Pay-for-Fees), reade more information [here](#paying-fees-with-bnb).
- **auto_adjust_bnb_balance_rate** - The multiplying power of buying quantity of BNB compares to evaluated comission of the coming order, effective only if auto_adjust_bnb_balance is true. Default value is 3.

#### Environment Variables

Expand All @@ -91,6 +93,8 @@ BUY_TIMEOUT: 0
SELL_TIMEOUT: 0
BUY_ORDER_TYPE: limit
SELL_ORDER_TYPE: market
AUTO_ADJUST_BNB_BALANCE: false
AUTO_ADJUST_BNB_BALANCE_RATE: 3
```

### Paying Fees with BNB
Expand Down
56 changes: 54 additions & 2 deletions binance_trade_bot/binance_api_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ def get_alt_tick(self, origin_symbol: str, target_symbol: str):
def get_min_notional(self, origin_symbol: str, target_symbol: str):
return float(self.get_symbol_filter(origin_symbol, target_symbol, "MIN_NOTIONAL")["minNotional"])

@cached(cache=TTLCache(maxsize=2000, ttl=43200))
def get_min_qty(self, origin_symbol: str, target_symbol: str):
return float(self.get_symbol_filter(origin_symbol, target_symbol, "LOT_SIZE")["minQty"])

def _wait_for_order(
self, order_id, origin_symbol: str, target_symbol: str
) -> Optional[BinanceOrder]: # pylint: disable=unsubscriptable-object
Expand Down Expand Up @@ -406,6 +410,48 @@ def _should_cancel_order(self, order_status):

return False

def _adjust_bnb_balance(self, origin_coin: Coin, target_coin: Coin):
if not self.get_using_bnb_for_fees():
# No need to adjust bnb balance if not using bnb for fees
return

base_fee = self.get_trade_fees()[origin_coin + target_coin]

# The discount is only applied if we have enough BNB to cover the fee
amount_trading = self._buy_quantity(origin_coin.symbol, target_coin.symbol)

fee_amount = amount_trading * base_fee * 0.75
if origin_coin.symbol == "BNB":
fee_amount_bnb = fee_amount
else:
origin_price = self.get_ticker_price(origin_coin.symbol + "BNB")
if origin_price is None:
return
fee_amount_bnb = fee_amount * origin_price

bnb_balance = self.get_currency_balance("BNB")

if bnb_balance >= fee_amount_bnb:
# No need to buy more bnb
return

min_qty = self.get_min_qty("BNB", target_coin.symbol)
alt_tick = self.get_alt_tick("BNB", target_coin.symbol)
# Default value of AUTO_ADJUST_BNB_BALANCE_RATE is 3, means trying to buy 3x BNB compare to the commision needed by the coming order.
# Put "3x" as default since: 1. buy commision, 2. sell commision, 3. buffer, since selling price may rise and then needs more comission.
fee_amount_bnb_ceil = math.ceil((fee_amount_bnb * self.config.AUTO_ADJUST_BNB_BALANCE_RATE - bnb_balance) * 10 ** alt_tick) / float(10 ** alt_tick)

min_notional = self.get_min_notional("BNB", target_coin.symbol)
bnb_price = self.get_ticker_price("BNB" + target_coin.symbol)
# multiply 1.01 considering that market price is changing
min_qty_for_min_notinal = math.ceil((min_notional / bnb_price) * 1.01 * 10 ** alt_tick) / float(10 ** alt_tick)

buy_quantity = max(min_qty, fee_amount_bnb_ceil, min_qty_for_min_notinal)

self.logger.info(f"Needed/available BNB balance: {fee_amount_bnb}/{bnb_balance}, buy quantity: {buy_quantity}...")

self.retry(self._buy_alt, Coin("BNB"), target_coin, bnb_price, buy_quantity)

def buy_alt(self, origin_coin: Coin, target_coin: Coin, buy_price: float) -> BinanceOrder:
return self.retry(self._buy_alt, origin_coin, target_coin, buy_price)

Expand All @@ -422,10 +468,13 @@ def _buy_quantity(
def float_as_decimal_str(num: float):
return f"{num:0.08f}".rstrip("0").rstrip(".") # remove trailing zeroes too

def _buy_alt(self, origin_coin: Coin, target_coin: Coin, buy_price: float): # pylint: disable=too-many-locals
def _buy_alt(self, origin_coin: Coin, target_coin: Coin, buy_price: float, buy_quantity: float=None): # pylint: disable=too-many-locals
"""
Buy altcoin
"""
if self.config.AUTO_ADJUST_BNB_BALANCE and origin_coin.symbol != "BNB":
self._adjust_bnb_balance(origin_coin, target_coin)

origin_symbol = origin_coin.symbol
target_symbol = target_coin.symbol

Expand All @@ -443,7 +492,10 @@ def _buy_alt(self, origin_coin: Coin, target_coin: Coin, buy_price: float): # p
#from_coin_price = min(buy_price, from_coin_price)
trade_log = self.db.start_trade_log(origin_coin, target_coin, False)

order_quantity = self._buy_quantity(origin_symbol, target_symbol, target_balance, from_coin_price)
if buy_quantity is None:
order_quantity = self._buy_quantity(origin_symbol, target_symbol, target_balance, from_coin_price)
else:
order_quantity = buy_quantity
self.logger.info(f"BUY QTY {order_quantity} of <{origin_symbol}>")

# Try to buy until successful
Expand Down
11 changes: 10 additions & 1 deletion binance_trade_bot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ def __init__(self):
"price_type": self.PRICE_TYPE_ORDERBOOK,
"accept_losses": "false",
"max_idle_hours": "3",
"ratio_adjust_weight":"100"
"ratio_adjust_weight":"100",
"auto_adjust_bnb_balance": "false",
"auto_adjust_bnb_balance_rate": "3",
}

if not os.path.exists(CFG_FL_NAME):
Expand Down Expand Up @@ -148,3 +150,10 @@ def __init__(self):
self.ACCEPT_LOSSES = accept_losses_str == 'true' or accept_losses_str == 'True'

self.MAX_IDLE_HOURS = os.environ.get("MAX_IDLE_HOURS") or config.get(USER_CFG_SECTION, "max_idle_hours")

auto_adjust_bnb_balance_str = os.environ.get("AUTO_ADJUST_BNB_BALANCE") or config.get(USER_CFG_SECTION, "auto_adjust_bnb_balance")
self.AUTO_ADJUST_BNB_BALANCE = str(auto_adjust_bnb_balance_str).lower() == "true"

self.AUTO_ADJUST_BNB_BALANCE_RATE = float(
os.environ.get("AUTO_ADJUST_BNB_BALANCE_RATE") or config.get(USER_CFG_SECTION, "auto_adjust_bnb_balance_rate")
)

0 comments on commit 44d45b8

Please sign in to comment.