mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-01-20 14:00:38 +00:00
Merge pull request #12560 from stash86/main-stash
add more metrics on profit stat
This commit is contained in:
@@ -334,7 +334,10 @@ def calculate_expectancy(trades: pd.DataFrame) -> tuple[float, float]:
|
|||||||
|
|
||||||
|
|
||||||
def calculate_sortino(
|
def calculate_sortino(
|
||||||
trades: pd.DataFrame, min_date: datetime, max_date: datetime, starting_balance: float
|
trades: pd.DataFrame,
|
||||||
|
min_date: datetime | None,
|
||||||
|
max_date: datetime | None,
|
||||||
|
starting_balance: float,
|
||||||
) -> float:
|
) -> float:
|
||||||
"""
|
"""
|
||||||
Calculate sortino
|
Calculate sortino
|
||||||
@@ -362,7 +365,10 @@ def calculate_sortino(
|
|||||||
|
|
||||||
|
|
||||||
def calculate_sharpe(
|
def calculate_sharpe(
|
||||||
trades: pd.DataFrame, min_date: datetime, max_date: datetime, starting_balance: float
|
trades: pd.DataFrame,
|
||||||
|
min_date: datetime | None,
|
||||||
|
max_date: datetime | None,
|
||||||
|
starting_balance: float,
|
||||||
) -> float:
|
) -> float:
|
||||||
"""
|
"""
|
||||||
Calculate sharpe
|
Calculate sharpe
|
||||||
@@ -389,7 +395,10 @@ def calculate_sharpe(
|
|||||||
|
|
||||||
|
|
||||||
def calculate_calmar(
|
def calculate_calmar(
|
||||||
trades: pd.DataFrame, min_date: datetime, max_date: datetime, starting_balance: float
|
trades: pd.DataFrame,
|
||||||
|
min_date: datetime | None,
|
||||||
|
max_date: datetime | None,
|
||||||
|
starting_balance: float,
|
||||||
) -> float:
|
) -> float:
|
||||||
"""
|
"""
|
||||||
Calculate calmar
|
Calculate calmar
|
||||||
|
|||||||
@@ -157,6 +157,11 @@ class Profit(BaseModel):
|
|||||||
winrate: float
|
winrate: float
|
||||||
expectancy: float
|
expectancy: float
|
||||||
expectancy_ratio: float
|
expectancy_ratio: float
|
||||||
|
sharpe: float
|
||||||
|
sortino: float
|
||||||
|
sqn: float
|
||||||
|
calmar: float
|
||||||
|
cagr: float
|
||||||
max_drawdown: float
|
max_drawdown: float
|
||||||
max_drawdown_abs: float
|
max_drawdown_abs: float
|
||||||
max_drawdown_start: str
|
max_drawdown_start: str
|
||||||
|
|||||||
@@ -19,7 +19,16 @@ from freqtrade import __version__
|
|||||||
from freqtrade.configuration.timerange import TimeRange
|
from freqtrade.configuration.timerange import TimeRange
|
||||||
from freqtrade.constants import CANCEL_REASON, DEFAULT_DATAFRAME_COLUMNS, Config
|
from freqtrade.constants import CANCEL_REASON, DEFAULT_DATAFRAME_COLUMNS, Config
|
||||||
from freqtrade.data.history import load_data
|
from freqtrade.data.history import load_data
|
||||||
from freqtrade.data.metrics import DrawDownResult, calculate_expectancy, calculate_max_drawdown
|
from freqtrade.data.metrics import (
|
||||||
|
DrawDownResult,
|
||||||
|
calculate_cagr,
|
||||||
|
calculate_calmar,
|
||||||
|
calculate_expectancy,
|
||||||
|
calculate_max_drawdown,
|
||||||
|
calculate_sharpe,
|
||||||
|
calculate_sortino,
|
||||||
|
calculate_sqn,
|
||||||
|
)
|
||||||
from freqtrade.enums import (
|
from freqtrade.enums import (
|
||||||
CandleType,
|
CandleType,
|
||||||
ExitCheckTuple,
|
ExitCheckTuple,
|
||||||
@@ -689,6 +698,34 @@ class RPC:
|
|||||||
last_date = trades[-1].open_date_utc if trades else None
|
last_date = trades[-1].open_date_utc if trades else None
|
||||||
num = float(len(durations) or 1)
|
num = float(len(durations) or 1)
|
||||||
bot_start = KeyValueStore.get_datetime_value("bot_start_time")
|
bot_start = KeyValueStore.get_datetime_value("bot_start_time")
|
||||||
|
|
||||||
|
sharpe = calculate_sharpe(
|
||||||
|
trades=trades_df,
|
||||||
|
min_date=first_date,
|
||||||
|
max_date=last_date,
|
||||||
|
starting_balance=starting_balance,
|
||||||
|
)
|
||||||
|
sortino = calculate_sortino(
|
||||||
|
trades=trades_df,
|
||||||
|
min_date=first_date,
|
||||||
|
max_date=last_date,
|
||||||
|
starting_balance=starting_balance,
|
||||||
|
)
|
||||||
|
sqn = calculate_sqn(trades=trades_df, starting_balance=starting_balance)
|
||||||
|
calmar = calculate_calmar(
|
||||||
|
trades=trades_df,
|
||||||
|
min_date=first_date,
|
||||||
|
max_date=last_date,
|
||||||
|
starting_balance=starting_balance,
|
||||||
|
)
|
||||||
|
current_balance = self._freqtrade.wallets.get_total_stake_amount()
|
||||||
|
days_passed = max(1, (last_date - first_date).days) if first_date and last_date else 1
|
||||||
|
cagr = calculate_cagr(
|
||||||
|
starting_balance=starting_balance,
|
||||||
|
final_balance=current_balance,
|
||||||
|
days_passed=days_passed,
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"profit_closed_coin": profit_closed_coin_sum,
|
"profit_closed_coin": profit_closed_coin_sum,
|
||||||
"profit_closed_percent_mean": round(profit_closed_ratio_mean * 100, 2),
|
"profit_closed_percent_mean": round(profit_closed_ratio_mean * 100, 2),
|
||||||
@@ -725,6 +762,11 @@ class RPC:
|
|||||||
"winrate": winrate,
|
"winrate": winrate,
|
||||||
"expectancy": expectancy,
|
"expectancy": expectancy,
|
||||||
"expectancy_ratio": expectancy_ratio,
|
"expectancy_ratio": expectancy_ratio,
|
||||||
|
"sharpe": sharpe,
|
||||||
|
"sortino": sortino,
|
||||||
|
"sqn": sqn,
|
||||||
|
"calmar": calmar,
|
||||||
|
"cagr": cagr,
|
||||||
"max_drawdown": drawdown.relative_account_drawdown,
|
"max_drawdown": drawdown.relative_account_drawdown,
|
||||||
"max_drawdown_abs": drawdown.drawdown_abs,
|
"max_drawdown_abs": drawdown.drawdown_abs,
|
||||||
"max_drawdown_start": format_date(drawdown.high_date),
|
"max_drawdown_start": format_date(drawdown.high_date),
|
||||||
|
|||||||
@@ -1199,6 +1199,11 @@ def test_api_logs(botclient):
|
|||||||
"winrate": 0.0,
|
"winrate": 0.0,
|
||||||
"expectancy": -0.0033695635,
|
"expectancy": -0.0033695635,
|
||||||
"expectancy_ratio": -1.0,
|
"expectancy_ratio": -1.0,
|
||||||
|
"cagr": -0.0024567404889381805,
|
||||||
|
"calmar": -1910.497317469542,
|
||||||
|
"sharpe": -58.138247358830355,
|
||||||
|
"sortino": -58.138247358830355,
|
||||||
|
"sqn": -1.5215,
|
||||||
"trading_volume": 75.945,
|
"trading_volume": 75.945,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -1231,6 +1236,11 @@ def test_api_logs(botclient):
|
|||||||
"winrate": 1.0,
|
"winrate": 1.0,
|
||||||
"expectancy": 0.0003695635,
|
"expectancy": 0.0003695635,
|
||||||
"expectancy_ratio": 100,
|
"expectancy_ratio": 100,
|
||||||
|
"cagr": 0.0002698167695580622,
|
||||||
|
"calmar": -100.0,
|
||||||
|
"sharpe": 65.81269184917424,
|
||||||
|
"sortino": -100.0,
|
||||||
|
"sqn": 1.7224,
|
||||||
"trading_volume": 75.945,
|
"trading_volume": 75.945,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -1263,6 +1273,11 @@ def test_api_logs(botclient):
|
|||||||
"winrate": 0.5,
|
"winrate": 0.5,
|
||||||
"expectancy": -0.0027145635000000003,
|
"expectancy": -0.0027145635000000003,
|
||||||
"expectancy_ratio": -0.48612137582114445,
|
"expectancy_ratio": -0.48612137582114445,
|
||||||
|
"cagr": -0.0019796559404918757,
|
||||||
|
"calmar": -1857.4671689202785,
|
||||||
|
"sharpe": -36.14602907243071,
|
||||||
|
"sortino": -100.0,
|
||||||
|
"sqn": -0.946,
|
||||||
"trading_volume": 75.945,
|
"trading_volume": 75.945,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -1326,6 +1341,11 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, is_short, expected)
|
|||||||
"winrate": expected["winrate"],
|
"winrate": expected["winrate"],
|
||||||
"expectancy": expected["expectancy"],
|
"expectancy": expected["expectancy"],
|
||||||
"expectancy_ratio": expected["expectancy_ratio"],
|
"expectancy_ratio": expected["expectancy_ratio"],
|
||||||
|
"sharpe": expected["sharpe"],
|
||||||
|
"sortino": expected["sortino"],
|
||||||
|
"sqn": expected["sqn"],
|
||||||
|
"calmar": expected["calmar"],
|
||||||
|
"cagr": expected["cagr"],
|
||||||
"max_drawdown": ANY,
|
"max_drawdown": ANY,
|
||||||
"max_drawdown_abs": ANY,
|
"max_drawdown_abs": ANY,
|
||||||
"max_drawdown_start": ANY,
|
"max_drawdown_start": ANY,
|
||||||
|
|||||||
Reference in New Issue
Block a user