Add market Change

closes #2524 and #3518
This commit is contained in:
Matthias 2020-06-25 20:39:55 +02:00
parent cf044d166e
commit 5fce7f3b22
3 changed files with 37 additions and 4 deletions

View File

@ -168,6 +168,26 @@ def extract_trades_of_period(dataframe: pd.DataFrame, trades: pd.DataFrame,
return trades return trades
def calculate_market_change(data: Dict[str, pd.DataFrame], column: str = "close") -> float:
"""
Calculate market change based on "column".
Calculation is done by taking the first non-null and the last non-null element of each column
and calculating the pctchange as "(last - first) / first".
Then the results per pair are combined as mean.
:param data: Dict of Dataframes, dict key should be pair.
:param column: Column in the original dataframes to use
:return:
"""
tmp_means = []
for pair, df in data.items():
start = df[column].dropna().iloc[0]
end = df[column].dropna().iloc[-1]
tmp_means.append((end - start) / start)
return np.mean(tmp_means)
def combine_dataframes_with_mean(data: Dict[str, pd.DataFrame], def combine_dataframes_with_mean(data: Dict[str, pd.DataFrame],
column: str = "close") -> pd.DataFrame: column: str = "close") -> pd.DataFrame:
""" """

View File

@ -8,7 +8,7 @@ from pandas import DataFrame
from tabulate import tabulate from tabulate import tabulate
from freqtrade.constants import DATETIME_PRINT_FORMAT from freqtrade.constants import DATETIME_PRINT_FORMAT
from freqtrade.data.btanalysis import calculate_max_drawdown from freqtrade.data.btanalysis import calculate_max_drawdown, calculate_market_change
from freqtrade.misc import file_dump_json from freqtrade.misc import file_dump_json
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -208,6 +208,8 @@ def generate_backtest_stats(config: Dict, btdata: Dict[str, DataFrame],
stake_currency = config['stake_currency'] stake_currency = config['stake_currency']
max_open_trades = config['max_open_trades'] max_open_trades = config['max_open_trades']
result: Dict[str, Any] = {'strategy': {}} result: Dict[str, Any] = {'strategy': {}}
market_change = calculate_market_change(btdata, 'close')
for strategy, results in all_results.items(): for strategy, results in all_results.items():
pair_results = generate_pair_metrics(btdata, stake_currency=stake_currency, pair_results = generate_pair_metrics(btdata, stake_currency=stake_currency,
@ -232,7 +234,8 @@ def generate_backtest_stats(config: Dict, btdata: Dict[str, DataFrame],
'backtest_end': max_date.datetime, 'backtest_end': max_date.datetime,
'backtest_end_ts': max_date.timestamp, 'backtest_end_ts': max_date.timestamp,
'backtest_days': backtest_days, 'backtest_days': backtest_days,
'trades_per_day': round(len(results) / backtest_days, 2) if backtest_days > 0 else None 'trades_per_day': round(len(results) / backtest_days, 2) if backtest_days > 0 else None,
'market_change': market_change,
} }
result['strategy'][strategy] = strat_stats result['strategy'][strategy] = strat_stats
@ -348,11 +351,12 @@ def text_table_add_metrics(strategy_results: Dict) -> str:
('Max Drawdown', f"{round(strategy_results['max_drawdown'] * 100, 2)}%"), ('Max Drawdown', f"{round(strategy_results['max_drawdown'] * 100, 2)}%"),
('Drawdown Start', strategy_results['drawdown_start'].strftime(DATETIME_PRINT_FORMAT)), ('Drawdown Start', strategy_results['drawdown_start'].strftime(DATETIME_PRINT_FORMAT)),
('Drawdown End', strategy_results['drawdown_end'].strftime(DATETIME_PRINT_FORMAT)), ('Drawdown End', strategy_results['drawdown_end'].strftime(DATETIME_PRINT_FORMAT)),
('Market change', f"{round(strategy_results['market_change'] * 100, 2)}%"),
] ]
return tabulate(metrics, headers=["Metric", "Value"], tablefmt="orgtbl") return tabulate(metrics, headers=["Metric", "Value"], tablefmt="orgtbl")
else: else:
return return ''
def show_backtest_results(config: Dict, backtest_stats: Dict): def show_backtest_results(config: Dict, backtest_stats: Dict):

View File

@ -8,6 +8,7 @@ from pandas import DataFrame, DateOffset, Timestamp, to_datetime
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.data.btanalysis import (BT_DATA_COLUMNS, from freqtrade.data.btanalysis import (BT_DATA_COLUMNS,
analyze_trade_parallelism, analyze_trade_parallelism,
calculate_market_change,
calculate_max_drawdown, calculate_max_drawdown,
combine_dataframes_with_mean, combine_dataframes_with_mean,
create_cum_profit, create_cum_profit,
@ -135,6 +136,14 @@ def test_load_trades(default_conf, mocker):
assert bt_mock.call_count == 0 assert bt_mock.call_count == 0
def test_calculate_market_change(testdatadir):
pairs = ["ETH/BTC", "ADA/BTC"]
data = load_data(datadir=testdatadir, pairs=pairs, timeframe='5m')
result = calculate_market_change(data)
assert isinstance(result, float)
assert pytest.approx(result) == 0.00955514
def test_combine_dataframes_with_mean(testdatadir): def test_combine_dataframes_with_mean(testdatadir):
pairs = ["ETH/BTC", "ADA/BTC"] pairs = ["ETH/BTC", "ADA/BTC"]
data = load_data(datadir=testdatadir, pairs=pairs, timeframe='5m') data = load_data(datadir=testdatadir, pairs=pairs, timeframe='5m')