Skip to content

Commit

Permalink
3.0.0rc21
Browse files Browse the repository at this point in the history
  • Loading branch information
DogsTailFarmer committed Mar 14, 2024
1 parent 435f0e7 commit 893ba25
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 259 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## 3.0.0rc21 - 2024-03-13
### Fix
* `Analytics`: Refine unload and processing assets data

## 3.0.0rc20 - 2024-03-12
### Fix
* `cancel_order_call()`: incorrect using asyncio.wait_for()

### Update
* logging improvement
* fee settings and handling

## 3.0.0rc19 - 2024-03-11
### Update
* Replaced checking price when calculating TP vs updating price based on order book if error occurred
Expand Down
4 changes: 1 addition & 3 deletions martin_binance/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
__author__ = "Jerry Fedorenko"
__copyright__ = "Copyright © 2021 Jerry Fedorenko aka VM"
__license__ = "MIT"
__version__ = "3.0.0rc19"
__version__ = "3.0.0rc21"
__maintainer__ = "Jerry Fedorenko"
__contact__ = "https://github.com/DogsTailFarmer"

# TODO For fee not in pair calculate it for later use

from pathlib import Path
from shutil import copy

Expand Down
2 changes: 1 addition & 1 deletion martin_binance/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ async def send_request(self, _request, _request_type, **kwargs):
and 'failed to connect to all addresses' in ex.message)
or
(status_code == Status.UNKNOWN
and "'NoneType' object has no attribute 'client'" in ex.message)
and "No client exist" in ex.message)
):
self.client = None
raise UserWarning(
Expand Down
37 changes: 1 addition & 36 deletions martin_binance/db_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
__author__ = "Jerry Fedorenko"
__copyright__ = "Copyright © 2021 Jerry Fedorenko aka VM"
__license__ = "MIT"
__version__ = "2.1.3"
__version__ = "3.0.0"
__maintainer__ = "Jerry Fedorenko"
__contact__ = "https://github.com/DogsTailFarmer"

Expand Down Expand Up @@ -135,39 +135,4 @@ def save_to_db(queue_to_db) -> None:
connection_analytic.commit()
except sqlite3.Error as err:
logger.error(f"INSERT into t_orders: {err}")
elif data.get('destination') == 't_funds.active update':
cursor_analytic = connection_analytic.cursor()
try:
cursor_analytic.execute('SELECT 1 FROM t_funds\
WHERE id_exchange =:id_exchange\
AND f_currency =:f_currency\
AND s_currency =:s_currency\
AND active = 1',
{'id_exchange': data.get('ID_EXCHANGE'),
'f_currency': data.get('f_currency'),
's_currency': data.get('s_currency'),
}
)
row_active = cursor_analytic.fetchone()
cursor_analytic.close()
except sqlite3.Error as err:
cursor_analytic.close()
row_active = (2,)
logger.error(f"SELECT from t_funds: {err}")
if row_active is None:
# logger.info("save_to_db: UPDATE t_funds set active=1")
try:
connection_analytic.execute('UPDATE t_funds SET active = 1\
WHERE id=(SELECT max(id) FROM t_funds\
WHERE id_exchange=:id_exchange\
AND f_currency=:f_currency\
AND s_currency=:s_currency)',
{'id_exchange': data.get('ID_EXCHANGE'),
'f_currency': data.get('f_currency'),
's_currency': data.get('s_currency'),
}
)
connection_analytic.commit()
except sqlite3.Error as err:
logger.error(f"save_to_db: UPDATE t_funds: {err}")
connection_analytic.commit()
94 changes: 28 additions & 66 deletions martin_binance/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def __init__(self):
self.cycle_time_reverse = None # + Reverse cycle start time
self.first_run = True # -
self.grid_only_restart = None # -
self.grid_remove = None # - Flag when starting cancel grid orders
self.grid_remove = None # + Flag when starting cancel grid orders
self.grid_update_started = None # - Flag when grid update process started
self.heartbeat_counter = 0 # -
self.last_ticker_update = 0 # -
Expand Down Expand Up @@ -123,11 +123,7 @@ def __init__(self):

def init(self, check_funds: bool = True) -> None: # skipcq: PYL-W0221
self.message_log('Start Init section')
if not FEE_IN_PAIR and FEE_SECOND:
init_params_error = 'FEE_IN_PAIR and FEE_SECOND'
elif not FEE_IN_PAIR and FEE_BNB_IN_PAIR:
init_params_error = 'FEE_IN_PAIR and FEE_BNB_IN_PAIR'
elif COLLECT_ASSETS and GRID_ONLY:
if COLLECT_ASSETS and GRID_ONLY:
init_params_error = 'COLLECT_ASSETS and GRID_ONLY: one only allowed'
elif PROFIT_MAX and PROFIT_MAX < PROFIT + FEE_TAKER:
init_params_error = 'PROFIT_MAX'
Expand Down Expand Up @@ -370,16 +366,6 @@ def save_strategy_state(self, return_only=False) -> Dict[str, str]:
self.grid_update()
if self.heartbeat_counter > 150:
self.heartbeat_counter = 0
if MODE in ('T', 'TC') and not GRID_ONLY:
# Update t_funds.active set True
data_to_db = {
'ID_EXCHANGE': ID_EXCHANGE,
'f_currency': self.f_currency,
's_currency': self.s_currency,
'destination': 't_funds.active update'
}
if self.queue_to_db:
self.queue_to_db.put(data_to_db)
if self.wait_refunding_for_start or self.tp_order_hold or self.grid_hold:
self.get_buffered_funds()
if self.reverse_hold:
Expand Down Expand Up @@ -407,6 +393,7 @@ def save_strategy_state(self, return_only=False) -> Dict[str, str]:
# endregion
if MODE in ('T', 'TC'):
return {'command': json.dumps(self.command),
'grid_remove': json.dumps(self.grid_remove),
'cycle_buy': json.dumps(self.cycle_buy),
'cycle_buy_count': json.dumps(self.cycle_buy_count),
'cycle_sell_count': json.dumps(self.cycle_sell_count),
Expand Down Expand Up @@ -456,6 +443,7 @@ def restore_strategy_state(self, strategy_state: Dict[str, str] = None, restore=
self.message_log("\n".join(f"{k}\t{v}" for k, v in strategy_state.items()), log_level=logging.DEBUG)
#
self.command = json.loads(strategy_state.get('command'))
self.grid_remove = json.loads(strategy_state.get('grid_remove', 'null'))
#
self.cycle_buy = json.loads(strategy_state.get('cycle_buy'))
self.cycle_buy_count = json.loads(strategy_state.get('cycle_buy_count'))
Expand Down Expand Up @@ -525,6 +513,9 @@ def restore_strategy_state(self, strategy_state: Dict[str, str] = None, restore=
# Possible strategy states in compare with saved one
grid_open_orders_len = len(open_orders) - 1 if self.tp_order_id else 0
#
if self.grid_remove:
self.message_log("Restore, continue cancel grid orders", tlg=True)
self.cancel_grid()
if not grid_open_orders_len and self.orders_hold:
self.message_log("Restore, no grid orders, place from hold now", tlg=True)
self.place_grid_part()
Expand All @@ -534,8 +525,6 @@ def restore_strategy_state(self, strategy_state: Dict[str, str] = None, restore=
if not GRID_ONLY and self.shift_grid_threshold is None and not self.tp_order_id:
self.message_log("Restore, no TP order, replace", tlg=True)
self.place_profit_order()
#
self.message_log("Restored, go work", tlg=True)

def start(self, profit_f: Decimal = O_DEC, profit_s: Decimal = O_DEC) -> None:
self.message_log('Start')
Expand Down Expand Up @@ -569,7 +558,7 @@ def start(self, profit_f: Decimal = O_DEC, profit_s: Decimal = O_DEC) -> None:
base=False)
go_trade = fs >= init_s
if go_trade:
if FEE_IN_PAIR and FEE_MAKER:
if FEE_MAKER:
fs = self.initial_reverse_second if self.reverse else self.initial_second
_ff = ff
_fs = fs - profit_s
Expand All @@ -578,7 +567,7 @@ def start(self, profit_f: Decimal = O_DEC, profit_s: Decimal = O_DEC) -> None:
base=True)
go_trade = ff >= init_f
if go_trade:
if FEE_IN_PAIR and FEE_MAKER:
if FEE_MAKER:
ff = self.initial_reverse_first if self.reverse else self.initial_first
_ff = ff - profit_f
_fs = fs
Expand Down Expand Up @@ -939,6 +928,8 @@ def debug_output(self):
self.message_log(f"\n"
f"! =======================================\n"
f"! debug output: ver: {self.client.srv_version}: {HEAD_VERSION}+{__version__}+{msb_ver}\n"
f"! reverse: {self.reverse}\n"
f"! Cycle Buy: {self.cycle_buy}\n"
f"! deposit_first: {self.deposit_first}, deposit_second: {self.deposit_second}\n"
f"! initial_first: {self.initial_first}, initial_second: {self.initial_second}\n"
f"! initial_reverse_first: {self.initial_reverse_first},"
Expand All @@ -954,7 +945,6 @@ def debug_output(self):
f"! part_profit_first: {self.part_profit_first},"
f" part_profit_second: {self.part_profit_second}\n"
f"! command: {self.command}\n"
f"! reverse: {self.reverse}\n"
f"! Profit: {self.get_sum_profit()}\n"
f"! ======================================",
log_level=logging.DEBUG)
Expand Down Expand Up @@ -1455,7 +1445,6 @@ def set_trade_conditions(self,

def set_profit(self, tp_amount: Decimal, amount: Decimal, by_market: bool) -> Decimal:
fee = FEE_TAKER if by_market else FEE_MAKER
fee = fee if FEE_IN_PAIR else fee + FEE_MAKER
tbb = None
bbb = None
n = len(self.orders_grid) + len(self.orders_init) + len(self.orders_hold) + len(self.orders_save)
Expand Down Expand Up @@ -1577,28 +1566,14 @@ def fee_for_grid(self,
"""
Calculate trade amount with Fee for grid order for both currency
"""
message = str()
if FEE_IN_PAIR:
fee = FEE_TAKER if by_market else FEE_MAKER
if FEE_BNB_IN_PAIR:
if self.cycle_buy:
amount_first -= self.round_fee(fee, amount_first, base=True)
message = f"For grid order First - fee: {any2str(amount_first)}"
else:
amount_first += self.round_fee(fee, amount_first, base=True)
message = f"For grid order First + fee: {any2str(amount_first)}"
else:
if self.cycle_buy:
if FEE_SECOND:
amount_second += self.round_fee(fee, amount_second, base=False)
message = f"For grid order Second + fee: {any2str(amount_second)}"
else:
amount_first -= self.round_fee(fee, amount_first, base=True)
message = f"For grid order First - fee: {any2str(amount_first)}"
else:
amount_second -= self.round_fee(fee, amount_second, base=False)
message = f"For grid order Second - fee: {any2str(amount_second)}"
if print_info and message:
fee = FEE_TAKER if by_market else FEE_MAKER
if FEE_FIRST or (self.cycle_buy and not FEE_SECOND):
amount_first -= self.round_fee(fee, amount_first, base=True)
message = f"For grid order First - fee: {any2str(amount_first)}"
else:
amount_second -= self.round_fee(fee, amount_second, base=False)
message = f"For grid order Second - fee: {any2str(amount_second)}"
if print_info:
self.message_log(message, log_level=logging.DEBUG)
return self.round_truncate(amount_first, fee=True), self.round_truncate(amount_second, fee=True)

Expand All @@ -1610,28 +1585,15 @@ def fee_for_tp(self,
"""
Calculate trade amount with Fee for take profit order for both currency
"""
if FEE_IN_PAIR:
fee = FEE_TAKER if by_market else FEE_MAKER
if FEE_BNB_IN_PAIR:
if self.cycle_buy:
amount_first += self.round_fee(fee, amount_first, base=True)
log_text = f"Take profit order First + fee: {amount_first}"
else:
amount_first -= self.round_fee(fee, amount_first, base=True)
log_text = f"Take profit order First - fee: {amount_first}"
else:
if self.cycle_buy:
amount_second -= self.round_fee(fee, amount_second, base=False)
log_text = f"Take profit order Second - fee: {amount_second}"
else:
if FEE_SECOND:
amount_second += self.round_fee(fee, amount_second, base=False)
log_text = f"Take profit order Second + fee: {amount_second}"
else:
amount_first -= self.round_fee(fee, amount_first, base=True)
log_text = f"Take profit order First - fee: {amount_first}"
if log_output:
self.message_log(log_text, log_level=logging.DEBUG)
fee = FEE_TAKER if by_market else FEE_MAKER
if FEE_SECOND or (self.cycle_buy and not FEE_FIRST):
amount_second -= self.round_fee(fee, amount_second, base=False)
log_text = f"Take profit order Second - fee: {amount_second}"
else:
amount_first -= self.round_fee(fee, amount_first, base=True)
log_text = f"Take profit order First - fee: {amount_first}"
if log_output:
self.message_log(log_text, log_level=logging.DEBUG)
return self.round_truncate(amount_first, fee=True), self.round_truncate(amount_second, fee=True)

def after_filled_tp(self, one_else_grid: bool = False):
Expand Down
5 changes: 2 additions & 3 deletions martin_binance/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
EXCHANGE = ()
# Exchange setup
ID_EXCHANGE = int()
FEE_IN_PAIR = bool()
FEE_MAKER = Decimal()
FEE_TAKER = Decimal()
FEE_SECOND = bool()
FEE_BNB_IN_PAIR = bool()
FEE_FIRST = False
FEE_SECOND = False
GRID_MAX_COUNT = int()
# Trade parameter
START_ON_BUY = bool()
Expand Down
42 changes: 4 additions & 38 deletions martin_binance/service/funds_rate_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
__author__ = "Jerry Fedorenko"
__copyright__ = "Copyright © 2021 Jerry Fedorenko aka VM"
__license__ = "MIT"
__version__ = "2.0.4"
__version__ = "3.0.0"
__maintainer__ = "Jerry Fedorenko"
__contact__ = 'https://github.com/DogsTailFarmer'

from datetime import datetime

import os
import time
import sqlite3
Expand Down Expand Up @@ -158,7 +156,7 @@ def db_handler(sql_conn, _currency_rate, currency_rate_last_time):
FROM t_funds as tf LEFT JOIN t_exchange tex USING(id_exchange)\
GROUP BY tex.name, tf.id_exchange, tf.f_currency, tf.s_currency')
records = cursor.fetchall()
# Get non-traded assets
# Get assets
cursor.execute('SELECT tex.id_exchange, tex.name, ta.currency, ta.value\
FROM t_asset as ta LEFT JOIN t_exchange tex USING(id_exchange)\
WHERE ta.value > 0')
Expand Down Expand Up @@ -190,7 +188,6 @@ def db_handler(sql_conn, _currency_rate, currency_rate_last_time):
for row in records:
# print(f"row: {row}")
exchange = str(row[0])
name = names.get(exchange)
id_exchange = int(row[1])
f_currency = str(row[2])
s_currency = str(row[3])
Expand Down Expand Up @@ -281,7 +278,6 @@ def db_handler(sql_conn, _currency_rate, currency_rate_last_time):
WHERE id_exchange=:id_exchange\
AND f_currency=:f_currency\
AND s_currency=:s_currency\
AND active=1\
ORDER BY id DESC LIMIT 1',
{'id_exchange': id_exchange, 'f_currency': f_currency, 's_currency': s_currency})
if balance_row := cursor.fetchone():
Expand All @@ -291,46 +287,16 @@ def db_handler(sql_conn, _currency_rate, currency_rate_last_time):
F_BALANCE.labels(exchange, pair, VPS_NAME).set(f_balance)
S_BALANCE.labels(exchange, pair, VPS_NAME).set(s_balance)
TOTAL_BALANCE.labels(exchange, pair, VPS_NAME).set(balance)
# Balance in USD cumulative for SPOT and Funding wallets
f_balance_fw = 0.0
for i, v in enumerate(assets):
if v[0] == id_exchange and v[2] == f_currency:
f_balance_fw = v[3]
del assets[i] # skipcq: PYL-E1138
break
f_balance += f_balance_fw
f_balance_usd = -1
if _currency_rate.get(f_currency):
try:
f_balance_usd = f_balance / _currency_rate[f_currency]
except ZeroDivisionError:
f_balance_usd = -1
s_balance_fw = 0.0
for i, v in enumerate(assets):
if v[0] == id_exchange and v[2] == s_currency:
s_balance_fw = v[3]
del assets[i] # skipcq: PYL-E1138
break
s_balance += s_balance_fw
s_balance_usd = -1
if _currency_rate.get(s_currency):
try:
s_balance_usd = s_balance / _currency_rate[s_currency]
except ZeroDivisionError:
s_balance_usd = -1
# print(f"f_balance_usd: {f_balance_usd}, s_balance_usd: {s_balance_usd}")
BALANCE_USD.labels(name, exchange, f_currency, VPS_NAME).set(f_balance_usd)
BALANCE_USD.labels(name, exchange, s_currency, VPS_NAME).set(s_balance_usd)
# Cycle parameters
CYCLE_BUY.labels(exchange, pair, VPS_NAME).set(balance_row[2])
F_DEPO.labels(exchange, pair, VPS_NAME).set(balance_row[3])
S_DEPO.labels(exchange, pair, VPS_NAME).set(balance_row[4])
OVER_PRICE.labels(exchange, pair, VPS_NAME).set(balance_row[5])

for asset in assets:
if _currency_rate.get(asset[2]):
if _rate := _currency_rate.get(asset[2]):
try:
usd_amount = asset[3] / _currency_rate[asset[2]]
usd_amount = asset[3] / _rate
except ZeroDivisionError:
usd_amount = -1
if usd_amount >= 1.0:
Expand Down
Loading

0 comments on commit 893ba25

Please sign in to comment.