Skip to content

Commit

Permalink
1.3.1-1
Browse files Browse the repository at this point in the history
  • Loading branch information
DogsTailFarmer committed Jun 22, 2023
1 parent b0e1369 commit 4644a5e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 49 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
## v1.3.1-1 2023-06-xx
## v1.3.1-1 2023-06-22
### Fix
* BACKTEST "S" mode: Restore an TP from a saved state, was missing

### Added for new features
* BACKTEST "S" mode: add progress bar
* BACKTEST "S" mode: supress logging

## v1.3.1 2023-06-21
### Update
* Up requirements for exchanges-wrapper to 1.3.1
Expand Down
2 changes: 1 addition & 1 deletion martin_binance/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
__author__ = "Jerry Fedorenko"
__copyright__ = "Copyright © 2021 Jerry Fedorenko aka VM"
__license__ = "MIT"
__version__ = "1.3.1-1b0"
__version__ = "1.3.1-1"
__maintainer__ = "Jerry Fedorenko"
__contact__ = "https://github.com/DogsTailFarmer"

Expand Down
56 changes: 21 additions & 35 deletions martin_binance/executor.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__ = "1.3.1"
__version__ = "1.3.1-1"
__maintainer__ = "Jerry Fedorenko"
__contact__ = 'https://github.com/DogsTailFarmer'
##################################################################
Expand Down Expand Up @@ -473,7 +473,7 @@ def f2d(_f: float) -> Decimal:
return Decimal(str(_f))


def solve(fn, value: Decimal, x: Decimal, max_err: Decimal, max_tries=50, **kwargs) -> Decimal:
def solve(fn, value: Decimal, x: Decimal, max_err: Decimal, max_tries=50, **kwargs) -> ():
"""
Numerical solution of the equation, value = fn(x)
:param fn: Function
Expand All @@ -498,8 +498,7 @@ def dx(_fn, _x, _delta, **_kwargs):
err = fn(x, **kwargs) - value
# print(f"tries: {tries}, x: {x}, fn: {fn(x, **kwargs)}, err: {err}")
if err >= 0 and abs(err) <= max_err:
print(f"In {tries} attempts the best solution was found!", )
return x
return x, f"In {tries} attempts the best solution was found!"
correction = (delta * tries) if err < 0 and _err.count(err) else 0
if err >= 0:
solves.append((err, x))
Expand All @@ -514,15 +513,12 @@ def dx(_fn, _x, _delta, **_kwargs):
# print(f"tries: {tries}, delta: {delta}, correction: {correction}, slope: {slope}")
if (_err.count(err) or tries > max_tries) and len(solves) > 5:
solves.sort(key=lambda a: (a[0], a[1]), reverse=False)
print('Solve return the best of the right value ;-)')
# print("\n".join(f"delta: {k}\t result: {v}" for k, v in solves))
return solves[0][1]
return solves[0][1], 'Solve return the best of the right value ;-)'
if tries > max_tries * 2:
break
_err.append(err)
print('Oops. No solution found')
print("\n".join(f"delta: {k}\tresult: {v}" for k, v in solves))
return f2d(0)
return f2d(0), "\n".join(f"delta: {k}\tresult: {v}" for k, v in solves)


class Orders:
Expand Down Expand Up @@ -890,7 +886,6 @@ def init(self, check_funds: bool = True) -> None: # skipcq: PYL-W0221

@staticmethod
def get_strategy_config() -> StrategyConfig:
print('Get config')
s = StrategyConfig()
s.required_data_updates = {StrategyConfig.ORDER_BOOK,
StrategyConfig.FUNDS,
Expand Down Expand Up @@ -1432,9 +1427,6 @@ def restore_strategy_state(self, strategy_state: Dict[str, str] = None) -> None:

def start(self, profit_f: Decimal = f2d(0), profit_s: Decimal = f2d(0)) -> None:
self.message_log('Start')

print(self.account.funds.get_funds())

if self.command == 'stopped':
self.message_log('Strategy stopped, waiting manual action')
return
Expand Down Expand Up @@ -1555,8 +1547,7 @@ def start(self, profit_f: Decimal = f2d(0), profit_s: Decimal = f2d(0)) -> None:
self.start_collect = 1
self.message_log('Stop, waiting manual action', tlg=True)
else:
n = gc.collect(generation=2)
print('Number of unreachable objects collected by GC:', n)
self.message_log(f"Number of unreachable objects collected by GC: {gc.collect(generation=2)}")
self.message_log(f"Initial first: {ff}, second: {fs}", color=Style.B_WHITE)
self.restart = None
# Init variable
Expand Down Expand Up @@ -1603,20 +1594,20 @@ def stop(self) -> None:
's_currency': self.s_currency})
self.connection_analytic.commit()
except sqlite3.Error as err:
print(f"DELETE from t_order: {err}")
self.message_log(f"DELETE from t_order: {err}")
self.connection_analytic.close()
self.connection_analytic = None

def suspend(self) -> None:
print('Suspend')
self.message_log('Suspend')
self.queue_to_db.put({'stop_signal': True})
self.queue_to_tlg.put(STOP_TLG)
self.connection_analytic.commit()
self.connection_analytic.close()
self.connection_analytic = None

def unsuspend(self) -> None:
print('Unsuspend')
self.message_log('Unsuspend')
self.start_process()

def init_warning(self, _amount_first_grid: Decimal):
Expand Down Expand Up @@ -1688,15 +1679,15 @@ def message_log(self, msg: str, log_level=LogLevel.INFO, tlg=False, color=Style.
color_msg = color+msg+Style.RESET if color else msg
if log_level not in LOG_LEVEL_NO_PRINT:
if MODE in ('T', 'TC'):
local_time = datetime.now().strftime('%d/%m %H:%M:%S')
print(f"{datetime.now().strftime('%d/%m %H:%M:%S')} {color_msg}")
else:
local_time = datetime.fromtimestamp(self.local_time()).strftime('%H:%M:%S.%f')
print(f"{local_time} {color_msg}")
write_log(log_level, msg)
if MODE in ('T', 'TC') and tlg and self.queue_to_tlg:
msg = self.tlg_header + msg
self.status_time = self.local_time()
self.queue_to_tlg.put(msg)
tqdm.write(f"{datetime.fromtimestamp(self.local_time()).strftime('%H:%M:%S.%f')} {color_msg}")
if MODE in ('T', 'TC'):
write_log(log_level, msg)
if tlg and self.queue_to_tlg:
msg = self.tlg_header + msg
self.status_time = self.local_time()
self.queue_to_tlg.put(msg)

##############################################################
# Technical analysis
Expand Down Expand Up @@ -2447,7 +2438,8 @@ def calc_over_price(self,
'amount_first_grid': amount_first_grid,
'min_delta': min_delta,
'amount_min': amount_min}
over_price = solve(self.calc_grid, reverse_target_amount, over_price_coarse, max_err, **params)
over_price, msg = solve(self.calc_grid, reverse_target_amount, over_price_coarse, max_err, **params)
self.message_log(msg)
if over_price == 0:
self.message_log("Can't calculate over price for reverse cycle,"
" use previous or over_price_coarse * 3", log_level=LogLevel.ERROR)
Expand All @@ -2465,13 +2457,13 @@ def start_process(self):
self.pr_db = Thread(target=save_to_db, args=(self.queue_to_db,))
self.pr_tlg = Thread(target=telegram, args=(self.queue_to_tlg, self.tlg_header.split('.')[0],))
if not self.pr_db.is_alive():
print('Start process for .db save')
self.message_log('Start process for .db save')
try:
self.pr_db.start()
except AssertionError as error:
self.message_log(str(error), log_level=LogLevel.ERROR, color=Style.B_RED)
if not self.pr_tlg.is_alive():
print('Start process for Telegram')
self.message_log('Start process for Telegram')
try:
self.pr_tlg.start()
except AssertionError as error:
Expand Down Expand Up @@ -2940,9 +2932,6 @@ def cancel_grid(self, cancel_all=False):
"""
if self.grid_remove is None:
self.message_log("cancel_grid: Started", log_level=LogLevel.DEBUG)

print(self.account.funds.get_funds())

self.grid_remove = True
if self.grid_remove:
# Temporary save and clear hold orders avoid placing them
Expand All @@ -2964,9 +2953,6 @@ def cancel_grid(self, cancel_all=False):
self.cancel_order(_id)
elif self.grid_remove:
self.message_log("cancel_grid: Ended", log_level=LogLevel.DEBUG)

print(self.account.funds.get_funds())

self.grid_remove = None
self.order_q_placed = None
sum_amount = self.orders_save.sum_amount(self.cycle_buy) if self.grid_update_started else Decimal('0.0')
Expand Down
17 changes: 6 additions & 11 deletions martin_binance/margin_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from decimal import Decimal
from pathlib import Path
from datetime import datetime, timedelta
from tqdm import tqdm

# noinspection PyPackageRequirements
import grpc
Expand Down Expand Up @@ -958,7 +959,7 @@ async def on_klines_update(_klines: {str: StrategyBase.Klines}):
async def aiter_candles(ds: pd.Series, _klines: {str: StrategyBase.Klines}, _i: str):
async for row in loop_ds(ds):
_klines.get(_i).refresh(json.loads(row))
print(f"Backtest candles *** {_i} *** timeSeries ended")
StrategyBase.strategy.message_log(f"Backtest candles *** {_i} *** timeSeries ended")


async def buffered_funds(print_info: bool = True):
Expand Down Expand Up @@ -1498,6 +1499,7 @@ async def on_ticker_update():
logger.warning(f"Exception on WSS, on_ticker_update loop closed: {ex}")
cls.wss_fire_up = True
else:
pbar = tqdm(total=cls.backtest['ticker'].count())
async for row in loop_ds(cls.backtest['ticker'], tik=True):
cls.delay_ordering_s = row.pop('delay', 0)
cls.ticker = row
Expand All @@ -1506,6 +1508,8 @@ async def on_ticker_update():
for _res in res:
on_order_update_handler(cls, _res)
await on_funds_update()
pbar.update()
pbar.close()
cls.strategy.message_log("Backtest *** ticker *** timeSeries ended")
back_test_handler(cls)

Expand Down Expand Up @@ -1574,7 +1578,7 @@ async def on_order_book_update():
async for row in loop_ds(cls.backtest['order_book']):
cls.order_book = row
cls.strategy.on_new_order_book(OrderBook(cls.order_book))
print("Backtest *** order_book *** timeSeries ended")
cls.strategy.message_log("Backtest *** order_book *** timeSeries ended")


def load_file(name: Path) -> {}:
Expand Down Expand Up @@ -1680,13 +1684,7 @@ def restore_state_before_backtesting(cls):
cls.strategy.initial_second = cls.strategy.deposit_second
else:
cls.strategy.initial_first = cls.strategy.deposit_first

print(f"MW: init {cls.strategy.account.funds.get_funds()}")

cls.strategy.account.restore_state(cls.symbol, cls.start_time_ms, orders)

print(f"MW: restore grid {cls.strategy.account.funds.get_funds()}")

cls.strategy.last_shift_time = json.loads(saved_state.get('last_shift_time')) or cls.strategy.local_time()
cls.strategy.order_q = json.loads(saved_state.get('order_q'))
cls.strategy.orders_grid.restore(json.loads(saved_state.get('orders')))
Expand Down Expand Up @@ -1722,9 +1720,6 @@ def restore_state_before_backtesting(cls):
tp_order,
tp=(cls.strategy.sum_amount_first, cls.strategy.sum_amount_second)
)

print(f"MW restore TP: {cls.strategy.account.funds.get_funds()}")

cls.strategy.start_collect = True


Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ dependencies = [
"future==0.18.3",
"inquirer==3.1.3",
"scikit-learn==1.2.2",
"tqdm==4.65.0",
]

[tool.flit.module]
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ pandas==2.0.2
dash==2.10.2
future==0.18.3
inquirer==3.1.3
scikit-learn==1.2.2
scikit-learn==1.2.2
tqdm==4.65.0

0 comments on commit 4644a5e

Please sign in to comment.