Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
quantfreedom committed Jul 5, 2024
1 parent 1c5fa2a commit 11bdbcc
Show file tree
Hide file tree
Showing 25 changed files with 583 additions and 6,084 deletions.
4,942 changes: 0 additions & 4,942 deletions poetry.lock

This file was deleted.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ mysql-connector-python = { version = "8.4.0", optional = true }
pyjwt = {version = "2.8.0", optional = true}
uvicorn = { version = "0.30.0", optional = true}

griffe = { version = "0.45.2", optional = true }
griffe = { version = "0.47.0", optional = true }
mkdocs = { version = "1.6.0", optional = true }
mkdocs-gen-files = { version = "0.5.0", optional = true }
mkdocs-literate-nav = {version = "0.6.1", optional = true}
Expand Down
16 changes: 10 additions & 6 deletions quantfreedom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@
from quantfreedom.helpers.utils import pretty_qf, pretty_qf_string
from quantfreedom.helpers.helper_funcs import dl_ex_candles, all_backtest_stats, symbol_bt_df
from quantfreedom.helpers.custom_logger import set_loggers
from quantfreedom.core.enums import FootprintCandlesTuple
from quantfreedom.core.enums import FootprintCandlesTuple, DynamicOrderSettings, CandleBodyType
from quantfreedom.backtesters import or_backtest
from quantfreedom.core.strategy import Strategy


__all__ = [
"pretty_qf",
"dl_ex_candles",
"pretty_qf_string",
"all_backtest_stats",
"set_loggers",
"CandleBodyType",
"dl_ex_candles",
"DynamicOrderSettings",
"FootprintCandlesTuple",
"or_backtest",
"symbol_bt_df"
"pretty_qf",
"pretty_qf_string",
"set_loggers",
"Strategy",
"symbol_bt_df",
]

load_figure_template("darkly")
Expand Down
149 changes: 70 additions & 79 deletions quantfreedom/backtesters/bt_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
or_dt,
)

from quantfreedom.order_handler.grid_order_handler import GridOrderHandler, GridStopLoss, GridLeverage
from quantfreedom.order_handler.grid_order_handler import *

logger = getLogger()

Expand Down Expand Up @@ -63,68 +63,75 @@ def grid_backtest(
for bar_index in range(1, closing_prices.size):
try:
if position_size > 0: # in a long position
current_candle = CurrentFootprintCandleTuple(
open_timestamp=candles.candle_open_timestamps[bar_index],
open_price=candles.candle_open_prices[bar_index],
high_price=candles.candle_high_prices[bar_index],
low_price=candles.candle_low_prices[bar_index],
close_price=candles.candle_close_prices[bar_index],

current_candle = grid_order_handler.helpers.get_current_candle(
bar_index=bar_index,
candles=candles,
)
grid_order_handler.pnl_calc = grid_order_handler.long_pnl_calc

grid_order_handler.obj_stop_loss.get_sl_hit = GridStopLoss.long_sl_hit_bool
grid_order_handler.check_stop_loss_hit(current_candle=current_candle)
pnl_exec = GridDPExecLong.long_pnl_exec

grid_order_handler.check_stop_loss_hit(
current_candle=current_candle,
sl_hit_exec=GridSLExecLong.long_sl_hit_exec,
)

grid_order_handler.obj_leverage.liq_hit_bool = GridLeverage.long_liq_hit_bool
grid_order_handler.check_liq_hit(current_candle=current_candle)
grid_order_handler.check_liq_hit(
current_candle=current_candle,
liq_hit_bool_exec=GridLevExecLong.long_liq_hit_bool_exec,
)

elif position_size < 0:
current_candle = CurrentFootprintCandleTuple(
open_timestamp=candles.candle_open_timestamps[bar_index],
open_price=candles.candle_open_prices[bar_index],
high_price=candles.candle_high_prices[bar_index],
low_price=candles.candle_low_prices[bar_index],
close_price=candles.candle_close_prices[bar_index],

current_candle = grid_order_handler.helpers.get_current_candle(
bar_index=bar_index,
candles=candles,
)
grid_order_handler.pnl_calc = grid_order_handler.short_pnl_calc

grid_order_handler.obj_stop_loss.get_sl_hit = GridStopLoss.short_sl_hit_bool
grid_order_handler.check_stop_loss_hit(current_candle=current_candle)
pnl_exec = GridDPExecShort.short_pnl_exec

grid_order_handler.obj_leverage.liq_hit_bool = GridLeverage.short_liq_hit_bool
grid_order_handler.check_liq_hit(current_candle=current_candle)
grid_order_handler.check_stop_loss_hit(
current_candle=current_candle,
sl_hit_exec=GridSLExecShort.short_sl_hit_exec,
)

except DecreasePosition as e:
grid_order_handler.check_liq_hit(
current_candle=current_candle,
liq_hit_bool_exec=GridLevExecShort.short_liq_hit_bool_exec,
)

except DecreasePosition as dp:
(
equity,
fees_paid,
realized_pnl,
) = grid_order_handler.calculate_decrease_position(
cur_datetime=candles.candle_open_datetimes[bar_index],
exit_fee_pct=e.exit_fee_pct,
exit_price=e.exit_price,
order_status=e.order_status,
market_fee_pct=exchange_settings_tuple.market_fee_pct,
exit_price=dp.exit_price,
equity=grid_order_handler.equity,
order_status=dp.order_status,
pnl_exec=pnl_exec,
)
logger.debug(f"Filling or for decrease postiion {OrderStatus._fields[e.order_status]}")

grid_order_handler.fill_or_exit_move(
grid_order_handler.helpers.fill_order_record_exit(
bar_index=bar_index,
set_idx=0,
order_records=order_records[or_filled],
order_status=e.order_status,
order_status=dp.order_status,
timestamp=current_candle.open_timestamp,
equity=equity,
exit_price=e.exit_price,
fees_paid=fees_paid,
realized_pnl=realized_pnl,
sl_price=dp.sl_price,
liq_price=dp.liq_price,
)

or_filled += 1
logger.debug(f"Filled decrease postiion order records for {OrderStatus._fields[e.order_status]}")
logger.debug(f"Filled decrease postiion order records for {OrderStatus._fields[dp.order_status]}")

grid_order_handler.set_order_variables(equity=equity)
grid_order_handler.helpers.reset_grid_order_variables(
equity=equity,
)
logger.debug("reset order variables")
try:
if low_prices[bar_index] <= buy_order:
Expand All @@ -134,66 +141,50 @@ def grid_backtest(
buy_signals[bar_index] = buy_order
if position_size >= 0:
# adding to long position
grid_order_handler.obj_leverage.get_bankruptcy_price = GridLeverage.long_get_bankruptcy_price
grid_order_handler.obj_leverage.get_liq_price = GridLeverage.long_get_liq_price
get_bankruptcy_price_exec = GridLevExecLong.long_get_bankruptcy_price_exec
get_liq_price_exec = GridLevExecLong.long_get_liq_price_exec

try:
average_entry = (position_size + order_size) / (
(position_size / average_entry) + (order_size / buy_order)
)
ae_buy_array[bar_index] = average_entry
except ZeroDivisionError:
average_entry = buy_order
ae_buy_array[bar_index] = average_entry
average_entry = grid_order_handler.calculate_increase_position(
order_size=order_size,
entry_price=buy_order,
)
ae_buy_array[bar_index] = average_entry

elif temp_pos_size >= 0 and position_size <= 0:
# switch from short to long
grid_order_handler.obj_leverage.get_bankruptcy_price = GridLeverage.long_get_bankruptcy_price
grid_order_handler.obj_leverage.get_liq_price = GridLeverage.long_get_liq_price
grid_order_handler.pnl_calc = grid_order_handler.short_pnl_calc

grid_order_handler.calculate_decrease_position(
get_bankruptcy_price_exec = GridLevExecLong.long_get_bankruptcy_price_exec
get_liq_price_exec = GridLevExecLong.long_get_liq_price_exec

(
equity,
fees_paid,
realized_pnl,
) = grid_order_handler.calculate_decrease_position(
cur_datetime=candles.candle_open_datetimes[bar_index],
exit_price=buy_order,
equity=equity,
)
grid_order_handler.fill_or_exit_move(
bar_index=bar_index,
set_idx=0,
order_records=order_records[or_filled],
order_status=e.order_status,
timestamp=current_candle.open_timestamp,
equity=equity,
exit_price=e.exit_price,
fees_paid=fees_paid,
realized_pnl=realized_pnl,
order_status=OrderStatus.TakeProfitFilled,
pnl_exec=GridDPExecShort.short_pnl_exec,
)

average_entry = buy_order
ae_buy_array[bar_index] = average_entry

elif temp_pos_size < 0:
# tp on short

grid_order_handler.obj_leverage.get_bankruptcy_price = GridLeverage.short_get_bankruptcy_price
grid_order_handler.obj_leverage.get_liq_price = GridLeverage.short_get_liq_price
grid_order_handler.pnl_calc = grid_order_handler.short_pnl_calc

grid_order_handler.calculate_decrease_position(
get_bankruptcy_price_exec = GridLevExecShort.short_get_bankruptcy_price_exec
get_liq_price_exec = GridLevExecShort.short_get_liq_price_exec

(
equity,
fees_paid,
realized_pnl,
) = grid_order_handler.calculate_decrease_position(
cur_datetime=candles.candle_open_datetimes[bar_index],
exit_price=buy_order,
equity=equity,
)
grid_order_handler.fill_or_exit_move(
bar_index=bar_index,
set_idx=0,
order_records=order_records[or_filled],
order_status=e.order_status,
timestamp=current_candle.open_timestamp,
equity=equity,
exit_price=e.exit_price,
fees_paid=fees_paid,
realized_pnl=realized_pnl,
order_status=OrderStatus.TakeProfitFilled,
pnl_exec=GridDPExecShort.short_pnl_exec,
)

position_size = temp_pos_size
Expand All @@ -203,7 +194,7 @@ def grid_backtest(
cash_borrowed,
cash_used,
liq_price,
) = grid_order_handler.obj_leverage.calc_liq_price(
) = grid_order_handler.leverage_class.calculate_liquidation_price(
average_entry=average_entry,
leverage=leverage,
og_available_balance=avaliable_balance,
Expand All @@ -212,7 +203,7 @@ def grid_backtest(
position_size_asset=average_entry / position_size,
position_size_usd=position_size,
)

grid_order_handler.fill_or_entry(
bar_index=bar_index + 1,
set_idx=0,
Expand Down
8 changes: 4 additions & 4 deletions quantfreedom/backtesters/bt_multi_bt.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ def run_df_backtest(
# set_loggers(log_folder=strategy.log_folder)

starting_equity = strategy.static_os_tuple.starting_equity

order = OrderHandler(
long_short=strategy.long_short,
long_short=strategy.get_long_or_short(),
static_os_tuple=strategy.static_os_tuple,
exchange_settings_tuple=strategy.exchange_settings_tuple,
)
Expand Down Expand Up @@ -135,7 +135,7 @@ def multiprocess_backtest(
for set_idx in range(range_start, range_end, step_by):
logger.debug(set_idx)

strategy.set_cur_ind_tuple(
strategy.set_cur_ind_set_tuple(
set_idx=set_idx,
)

Expand Down Expand Up @@ -424,7 +424,7 @@ def or_backtest(

set_idx = strategy.get_settings_index(set_idx=set_idx)

strategy.set_cur_ind_tuple(
strategy.set_cur_ind_set_tuple(
set_idx=set_idx,
)

Expand Down
6 changes: 4 additions & 2 deletions quantfreedom/backtesters/bt_or_bt.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,17 @@ def or_backtest(

starting_equity = strategy.static_os_tuple.starting_equity



order = OrderHandler(
exchange_settings_tuple=strategy.exchange_settings_tuple,
long_short=strategy.long_short,
long_short=strategy.get_long_or_short(),
static_os_tuple=strategy.static_os_tuple,
)

set_idx = strategy.get_settings_index(set_idx=set_idx)

strategy.set_cur_ind_tuple(
strategy.set_cur_ind_set_tuple(
set_idx=set_idx,
)

Expand Down
16 changes: 10 additions & 6 deletions quantfreedom/core/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,19 @@ def __init__(
class DecreasePosition(Exception):
def __init__(
self,
order_status: OrderStatus = None, # type: ignore
exit_price: Optional[float] = None,
exit_fee_pct: Optional[float] = None,
msg: str = None,
exit_fee_pct: Optional[float] = np.nan,
exit_price: Optional[float] = np.nan,
liq_price: Optional[float] = np.nan,
msg: Optional[str] = None,
order_status: Optional[OrderStatus] = None, # type: ignore
sl_price: Optional[float] = np.nan,
):
self.order_status = order_status
self.exit_price = exit_price
self.exit_fee_pct = exit_fee_pct
self.exit_price = exit_price
self.liq_price = liq_price
self.msg = msg
self.order_status = order_status
self.sl_price = sl_price


order_settings_array_dt = np.dtype(
Expand Down
9 changes: 7 additions & 2 deletions quantfreedom/core/strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class IndicatorSettings(NamedTuple):
class Strategy:
backtest_settings_tuple: BacktestSettings
cur_dos_tuple: DynamicOrderSettings
cur_ind_set_tuple: IndicatorSettings
entries: np.ndarray
exchange_settings_tuple: ExchangeSettings
exit_prices: np.ndarray
Expand All @@ -31,6 +30,7 @@ class Strategy:
total_filtered_settings: int = 0
total_indicator_settings: int = 0
total_order_settings: int = 0
cur_ind_set_tuple: IndicatorSettings

def get_ind_set_dos_cart_product(
self,
Expand Down Expand Up @@ -206,7 +206,7 @@ def get_og_ind_set_tuple(
) -> IndicatorSettings:
pass

def set_cur_ind_tuple(
def set_cur_ind_set_tuple(
self,
set_idx: int,
):
Expand Down Expand Up @@ -346,3 +346,8 @@ def get_strategy_plot_filename(
candles: FootprintCandlesTuple,
):
pass

def get_long_or_short(
self,
):
pass
Loading

0 comments on commit 11bdbcc

Please sign in to comment.