Rounding for Binance — API trading
To make a successful trade/order via Binance API with any pair rounding needs to be addressed properly. For lot size and for trading amount.
Therefore, in this article am going to show how I solve rounding.
First, we need to understand that each token has specific decimal places like 0.0001 set at Binance and therfore we need to respect those values at our end and send the right number via API or trade will be rejected.
Let say that our script gave us some price like 0.121212121. and at Binance these symbol has decimal value as 0.0001 so we need to send number as 0.1212. To say it more precise I would avoid saying that we are rounding as we are more cutting. If we round Quantity of some token upside there will be trade rejected as not enough balance and if we do it downide some balance will stay up, therefore I am not rounding but slashing ammount at exact decimal place to avoid mistakes an errors.
Lets make some rules how these should be handled with format value, step size and collecting values from our DB insert.
import mathclass Round:
def step_size_to_precision(self, ss):
return ss.find('1') - 1
def format_value(self, val, step_size_str):
precision = self.step_size_to_precision(step_size_str)
if precision > 0:
return "{:0.0{}f}".format(val, precision)
return math.floor(int(val))
def format_valueDown(self, val, step_size_str):
precision = self.step_size_to_precision(step_size_str)
if precision > 0:
return "{:0.0{}f}".format(val, precision)
return math.trunc(int(val))
def getStepSize(self, ticker):
login = DBConnection().login()
db_login = login["momentum"]["binance_misc"]
the_list2 = []
get_all_data_from_token2 = db_login.find({"_id": ticker})
for last_values_fromDb2 in get_all_data_from_token2:
the_list2.append(last_values_fromDb2)
step_size = the_list2[0]["minPrice"]
step_size2 = the_list2[0]["stepSize"]
return step_size, step_size2
Binance has all values for tokens stored at “.get_exchange_info()” see more info at official Binance Api web page.
My solution is as follows. Am connecting to Binance API and my API details are stored at client.json.
from binance.client import Client
import json
with open('...config.json') as json_file:
config = json.load(json_file)
client = Client(config["api"], config["secret"])
TokenDetails = client.get_exchange_info()
Now we have all pairs from Binance stored in variable “TokenDetails”. For further extraction and manipulation of the data am storing it to Pandas DataFrame as is easy to manipulate
Speed is not the case here that why am using DF.iterrows even am personally against such use case mainly because is slow.
All gathered data am storing to mongoDB to use it later when am using data for trading/setting orders etc.
import pandas as pd
import mongo.mongodb as mongo
exchangeName = "binance"df = pd.DataFrame(TokenDetails["symbols"])for index, ticker in df.iterrows():
for tickerRounding in ticker["filters"]:
# print(tickerRounding["filterType"])
try:
if tickerRounding["filterType"] == "LOT_SIZE":
#print(bb)
mongo.DBConnection().createTable("momentum", exchangeName + "_misc").update_one(
{"_id": ticker["symbol"]}, {
"$set": {"stepSize": tickerRounding["stepSize"]}}, upsert=True)
except:
pass
In tickerRounding we get result as: {‘filterType’: ‘LOT_SIZE’, ‘minQty’: ‘0.00100000’, ‘maxQty’: ‘922327.00000000’, ‘stepSize’: ‘0.00100000’}
Now data is stored at MongoDB and prepared for later use. That why before any trade/order we need to call it from DB and round it with getStepSize function. These is much faster than calling Binance before each trade and drasticly reduces API calls to avoid any limits.
ticker = UNIUSDT
stepsize = Round().getStepSize(ticker)
tckrPrice = float(Round().format_value(ticker, stepsize[0]))
So now we have stepsize and ticker price data sorted perfectly to use it with trading app like “Trading().SetPendingBuy(ticker, stepsize, tckrPrice)”.
1st posted at TokensQuant.com: