Merge pull request #332 from gcarq/hyperopt_stoploss
Add stoploss to the hyperopt parameters
This commit is contained in:
commit
fa97a82568
@ -31,6 +31,10 @@ TOTAL_TRIES = None
|
||||
_CURRENT_TRIES = 0
|
||||
CURRENT_BEST_LOSS = 100
|
||||
|
||||
# max average trade duration in minutes
|
||||
# if eval ends with higher value, we consider it a failed eval
|
||||
MAX_ACCEPTED_TRADE_DURATION = 240
|
||||
|
||||
# this is expexted avg profit * expected trade count
|
||||
# for example 3.5%, 1100 trades, EXPECTED_MAX_PROFIT = 3.85
|
||||
EXPECTED_MAX_PROFIT = 3.85
|
||||
@ -91,6 +95,7 @@ SPACE = {
|
||||
{'type': 'stochf_cross'},
|
||||
{'type': 'ht_sine'},
|
||||
]),
|
||||
'stoploss': hp.quniform('stoploss', -30, -2, 1),
|
||||
}
|
||||
|
||||
|
||||
@ -109,11 +114,12 @@ def log_results(results):
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def calculate_loss(total_profit: float, trade_count: int):
|
||||
def calculate_loss(total_profit: float, trade_count: int, trade_duration: float):
|
||||
""" objective function, returns smaller number for more optimal results """
|
||||
trade_loss = 1 - 0.35 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.2)
|
||||
profit_loss = max(0, 1 - total_profit / EXPECTED_MAX_PROFIT)
|
||||
return trade_loss + profit_loss
|
||||
duration_loss = min(trade_duration / MAX_ACCEPTED_TRADE_DURATION, 1)
|
||||
return trade_loss + profit_loss + duration_loss
|
||||
|
||||
|
||||
def optimizer(params):
|
||||
@ -122,20 +128,21 @@ def optimizer(params):
|
||||
from freqtrade.optimize import backtesting
|
||||
backtesting.populate_buy_trend = buy_strategy_generator(params)
|
||||
|
||||
results = backtest(OPTIMIZE_CONFIG['stake_amount'], PROCESSED)
|
||||
results = backtest(OPTIMIZE_CONFIG['stake_amount'], PROCESSED, stoploss=params['stoploss'])
|
||||
result_explanation = format_results(results)
|
||||
|
||||
total_profit = results.profit_percent.sum()
|
||||
trade_count = len(results.index)
|
||||
trade_duration = results.duration.mean() * 5
|
||||
|
||||
if trade_count == 0:
|
||||
if trade_count == 0 or trade_duration > MAX_ACCEPTED_TRADE_DURATION:
|
||||
print('.', end='')
|
||||
return {
|
||||
'status': STATUS_FAIL,
|
||||
'loss': float('inf')
|
||||
}
|
||||
|
||||
loss = calculate_loss(total_profit, trade_count)
|
||||
loss = calculate_loss(total_profit, trade_count, trade_duration)
|
||||
|
||||
_CURRENT_TRIES += 1
|
||||
|
||||
|
@ -5,17 +5,23 @@ from freqtrade.optimize.hyperopt import calculate_loss, TARGET_TRADES, EXPECTED_
|
||||
|
||||
|
||||
def test_loss_calculation_prefer_correct_trade_count():
|
||||
correct = calculate_loss(1, TARGET_TRADES)
|
||||
over = calculate_loss(1, TARGET_TRADES + 100)
|
||||
under = calculate_loss(1, TARGET_TRADES - 100)
|
||||
correct = calculate_loss(1, TARGET_TRADES, 20)
|
||||
over = calculate_loss(1, TARGET_TRADES + 100, 20)
|
||||
under = calculate_loss(1, TARGET_TRADES - 100, 20)
|
||||
assert over > correct
|
||||
assert under > correct
|
||||
|
||||
|
||||
def test_loss_calculation_prefer_shorter_trades():
|
||||
shorter = calculate_loss(1, 100, 20)
|
||||
longer = calculate_loss(1, 100, 30)
|
||||
assert shorter < longer
|
||||
|
||||
|
||||
def test_loss_calculation_has_limited_profit():
|
||||
correct = calculate_loss(EXPECTED_MAX_PROFIT, TARGET_TRADES)
|
||||
over = calculate_loss(EXPECTED_MAX_PROFIT * 2, TARGET_TRADES)
|
||||
under = calculate_loss(EXPECTED_MAX_PROFIT / 2, TARGET_TRADES)
|
||||
correct = calculate_loss(EXPECTED_MAX_PROFIT, TARGET_TRADES, 20)
|
||||
over = calculate_loss(EXPECTED_MAX_PROFIT * 2, TARGET_TRADES, 20)
|
||||
under = calculate_loss(EXPECTED_MAX_PROFIT / 2, TARGET_TRADES, 20)
|
||||
assert over == correct
|
||||
assert under > correct
|
||||
|
||||
@ -93,7 +99,8 @@ def test_fmin_best_results(mocker, caplog):
|
||||
"trigger": 2,
|
||||
"uptrend_long_ema": 1,
|
||||
"uptrend_short_ema": 0,
|
||||
"uptrend_sma": 0
|
||||
"uptrend_sma": 0,
|
||||
"stoploss": -10,
|
||||
}
|
||||
|
||||
mocker.patch('freqtrade.optimize.hyperopt.MongoTrials', return_value=create_trials(mocker))
|
||||
@ -109,7 +116,8 @@ def test_fmin_best_results(mocker, caplog):
|
||||
'"adx": {\n "enabled": true,\n "value": 15.0\n },',
|
||||
'"green_candle": {\n "enabled": true\n },',
|
||||
'"mfi": {\n "enabled": false\n },',
|
||||
'"trigger": {\n "type": "ao_cross_zero"\n },'
|
||||
'"trigger": {\n "type": "ao_cross_zero"\n },',
|
||||
'"stoploss": -10.0',
|
||||
]
|
||||
|
||||
for line in exists:
|
||||
|
Loading…
Reference in New Issue
Block a user