Files
hummingbot-dashboard/quants_lab/backtesting/backtesting.py
2023-06-23 20:42:36 +01:00

61 lines
2.4 KiB
Python

from typing import Callable
import pandas as pd
from quants_lab.backtesting.backtesting_analysis import BacktestingAnalysis
from quants_lab.labeling.triple_barrier_method import triple_barrier_method
class Backtesting:
def __init__(self, candles_df):
self.candles_df = candles_df
def run_backtesting(self,
strategy: Callable,
order_amount, leverage, initial_portfolio,
take_profit_multiplier, stop_loss_multiplier, time_limit,
std_span, taker_fee=0.0003, maker_fee=0.00012):
df = strategy(self.candles_df.copy())
df = triple_barrier_method(
df=df,
std_span=std_span,
tp=take_profit_multiplier,
sl=stop_loss_multiplier,
tl=time_limit,
trade_cost=taker_fee * 2,
max_executors=1,
)
backtesting_analysis = self.get_backtest_analysis(
df=df,
maker_fee=maker_fee,
taker_fee=taker_fee,
order_amount=order_amount,
leverage=leverage,
initial_portfolio=initial_portfolio,
)
return backtesting_analysis
@staticmethod
def get_backtest_analysis(
df,
order_amount=15,
initial_portfolio=700,
leverage=20,
maker_fee=0.00012,
taker_fee=0.0003,
):
# Set starting params
first_row = df.iloc[0].tolist()
first_row.extend([0, 0, 0, 0, 0, initial_portfolio])
active_signals = df[df["active_signal"] == 1].copy()
active_signals.loc[:, "amount"] = order_amount
active_signals.loc[:, "margin_used"] = order_amount / leverage
active_signals.loc[:, "fee_pct"] = active_signals["close_type"].apply(lambda x: maker_fee + taker_fee if x == "tp" else taker_fee * 2)
active_signals.loc[:, "fee_usd"] = active_signals["fee_pct"] * active_signals["amount"]
active_signals.loc[:, "ret_usd"] = active_signals.apply(lambda x: (x["ret"] - x["fee_pct"]) * x["amount"], axis=1)
active_signals.loc[:, "current_portfolio"] = initial_portfolio + active_signals["ret_usd"].cumsum()
active_signals.loc[:, "current_portfolio"].fillna(method='ffill', inplace=True)
positions = pd.concat([pd.DataFrame([first_row], columns=active_signals.columns), active_signals])
return positions.reset_index(drop=True)