Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds proper sell rounding to avoid LOT errors #79

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ __*__

# IDE settings
.vscode
.idea
55 changes: 36 additions & 19 deletions Binance Detect Moonings.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@

# Needed for colorful console output Install with: python3 -m pip install colorama (Mac/Linux) or pip install colorama (PC)
from colorama import init

init()

# needed for the binance API / websockets / Exception handling
from binance.client import Client
from binance.exceptions import BinanceAPIException

# needed to round to step size
from binance.helpers import round_step_size

# used for dates
from datetime import date, datetime, timedelta
import time
Expand All @@ -54,7 +58,6 @@
load_correct_creds
)


# for colourful logging to the console
class txcolors:
BUY = '\033[92m'
Expand All @@ -64,7 +67,6 @@ class txcolors:
DIM = '\033[2m\033[35m'
DEFAULT = '\033[39m'


# tracks profit/loss each session
global session_profit
session_profit = 0
Expand Down Expand Up @@ -103,11 +105,12 @@ def get_price(add_to_historical=True):
for coin in prices:

if CUSTOM_LIST:
if any(item + PAIR_WITH == coin['symbol'] for item in tickers) and all(item not in coin['symbol'] for item in FIATS):
initial_price[coin['symbol']] = { 'price': coin['price'], 'time': datetime.now()}
if any(item + PAIR_WITH == coin['symbol'] for item in tickers) and all(
item not in coin['symbol'] for item in FIATS):
initial_price[coin['symbol']] = {'price': coin['price'], 'time': datetime.now()}
else:
if PAIR_WITH in coin['symbol'] and all(item not in coin['symbol'] for item in FIATS):
initial_price[coin['symbol']] = { 'price': coin['price'], 'time': datetime.now()}
initial_price[coin['symbol']] = {'price': coin['price'], 'time': datetime.now()}

if add_to_historical:
hsp_head += 1
Expand All @@ -134,7 +137,7 @@ def wait_for_price():
coins_unchanged = 0

pause_bot()

if historical_prices[hsp_head]['BNB' + PAIR_WITH]['time'] > datetime.now() - timedelta(minutes=float(TIME_DIFFERENCE / RECHECK_INTERVAL)):

# sleep for exactly the amount of time required
Expand Down Expand Up @@ -297,7 +300,6 @@ def buy():
# only buy if the there are no active trades on the coin
if coin not in coins_bought:
print(f"{txcolors.BUY}Preparing to buy {volume[coin]} {coin}{txcolors.DEFAULT}")

if TEST_MODE:
orders[coin] = [{
'symbol': coin,
Expand All @@ -314,10 +316,10 @@ def buy():
# try to create a real order if the test orders did not raise an exception
try:
buy_limit = client.create_order(
symbol = coin,
side = 'BUY',
type = 'MARKET',
quantity = volume[coin]
symbol=coin,
side='BUY',
type='MARKET',
quantity=volume[coin]
)

# error handling here in case position cannot be placed
Expand Down Expand Up @@ -360,9 +362,15 @@ def sell_coins():

for coin in list(coins_bought):
# define stop loss and take profit
TP = float(coins_bought[coin]['bought_at']) + (float(coins_bought[coin]['bought_at']) * coins_bought[coin]['take_profit']) / 100
SL = float(coins_bought[coin]['bought_at']) + (float(coins_bought[coin]['bought_at']) * coins_bought[coin]['stop_loss']) / 100

try:
TP = float(coins_bought[coin]['bought_at']) + (
float(coins_bought[coin]['bought_at']) * coins_bought[coin]['take_profit']) / 100
SL = float(coins_bought[coin]['bought_at']) + (
float(coins_bought[coin]['bought_at']) * coins_bought[coin]['stop_loss']) / 100
# When an older version of the script is being executed
except KeyError:
TP = float(coins_bought[coin]['bought_at']) + (float(coins_bought[coin]['bought_at'])) / 100
SL = float(coins_bought[coin]['bought_at']) + (float(coins_bought[coin]['bought_at'])) / 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't be a good idea to put coins_bought[coin]['bought_at'] into a variable to avoid repeating it too much?
Code might be cleaner


LastPrice = float(last_price[coin]['price'])
BuyPrice = float(coins_bought[coin]['bought_at'])
Expand All @@ -383,14 +391,20 @@ def sell_coins():

# try to create a real order
try:
try:
rounded_amount = round_step_size(coins_bought[coin]['volume'], coins_bought[coin]['step_size'])
except Exception:
tick_size = float(next(
filter(lambda f: f['filterType'] == 'LOT_SIZE', client.get_symbol_info(coin)['filters'])
)['stepSize'])
Comment on lines +395 to +397
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line seems to be too long. Is there any way to make it more readable? (I really don't know)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't tested this yet, will it leave crypto dust for people using BNB for fees?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it will leave crypto dust which can be changed into BNB afterward.

rounded_amount = round_step_size(coins_bought[coin]['volume'], tick_size)

if not TEST_MODE:
sell_coins_limit = client.create_order(
symbol = coin,
side = 'SELL',
type = 'MARKET',
quantity = coins_bought[coin]['volume']

quantity = rounded_amount
)

# error handling here in case position cannot be placed
Expand Down Expand Up @@ -425,7 +439,9 @@ def update_portfolio(orders, last_price, volume):
'''add every coin bought to our portfolio for tracking/selling later'''
if DEBUG: print(orders)
for coin in orders:

coin_step_size = float(next(
filter(lambda f: f['filterType'] == 'LOT_SIZE', client.get_symbol_info(orders[coin][0]['symbol'])['filters'])
)['stepSize'])
coins_bought[coin] = {
'symbol': orders[coin][0]['symbol'],
'orderid': orders[coin][0]['orderId'],
Expand All @@ -434,7 +450,8 @@ def update_portfolio(orders, last_price, volume):
'volume': volume[coin],
'stop_loss': -STOP_LOSS,
'take_profit': TAKE_PROFIT,
}
'step_size': coin_step_size,
}

# save the coins in a json file in the same directory
with open(coins_bought_file_path, 'w') as file:
Expand All @@ -454,7 +471,7 @@ def remove_from_portfolio(coins_sold):

def write_log(logline):
timestamp = datetime.now().strftime("%d/%m %H:%M:%S")
with open(LOG_FILE,'a+') as f:
with open(LOG_FILE, 'a+') as f:
f.write(timestamp + ' ' + logline + '\n')

if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
python-binance==0.7.9
python-binance==1.0.10
colorama==0.4.4
PyYAML==5.4.1
tradingview-ta==3.2.3