Merge remote-tracking branch 'origin/bt-metrics' into bt-metrics

This commit is contained in:
Stefano Ariestasia 2023-09-29 14:19:37 +09:00
commit 2e7b5e2be9
3 changed files with 16 additions and 19 deletions

View File

@ -47,10 +47,6 @@ optional arguments:
be checked. Default : `199 399 499 999 1999`.
```
### Summary
Checks a given strategy for recursive formula issue via `recursive-analysis`.
### Why are odd-numbered default startup candles used?
The default value for startup candles are odd numbers. When the bot fetches candle data from the exchange's API, the last candle is the one being checked by the bot and the rest of the data are the "startup candles".
@ -64,8 +60,8 @@ Please note that this candle limit may be changed in the future by the exchanges
### How does the command work?
- Firstly an initial indicator calculation is carried out using the supplied timerange to generate a benchmark for indicator values.
- After setting the benchmark it will then carry out additional runs for each different startup candle count.
- It will then compare the indicator values at the last candle rows and report the differences in a table.
- After setting the benchmark it will then carry out additional runs for each of the different startup candle count values.
- The command will then compare the indicator values at the last candle rows and report the differences in a table.
## Understanding the recursive-analysis output
@ -89,5 +85,5 @@ As such, aiming for absolute zero variance (shown by `-` value) might not be the
## Caveats
- `recursive-analysis` will only calculate and compare the indicator values at the last row. The output table reports the percentage differences between the different startup candle count calculations and the original benchmark calculation. Whether it has any actual impact on your entries and exits is not included.
- The ideal scenario is that indicators will have no variance (or at least very close to 0%) despite the startup candle being varied. In reality, indicators such as EMA are using a recursive formula to calculate indicator values, so the goal is not necessarily to have zero percentage variance, but to have the variance low enough (and the `startup_candle_count` high enough) that the recursion inherent in the indicator will not have any real impact on trading decisions.
- `recursive-analysis` will only run calculations on `populate_indicators` and `@informative` decorator(s). If you put any indicator calculation on `populate_entry_trend` or `populate_exit_trend`, it won't be calculated
- The ideal scenario is that indicators will have no variance (or at least very close to 0%) despite the startup candle being varied. In reality, indicators such as EMA are using a recursive formula to calculate indicator values, so the goal is not necessarily to have zero percentage variance, but to have the variance low enough (and therefore `startup_candle_count` high enough) that the recursion inherent in the indicator will not have any real impact on trading decisions.
- `recursive-analysis` will only run calculations on `populate_indicators` and `@informative` decorator(s). If you put any indicator calculation on `populate_entry_trend` or `populate_exit_trend`, it won't be calculated.

View File

@ -179,11 +179,10 @@ def test_recursive_biased_strategy(recursive_conf, mocker, caplog, scenario) ->
if scenario == "bias2":
assert log_has_re("=> found lookahead in indicator rsi", caplog)
else:
diff_pct = abs(float(instance.dict_recursive['rsi'][100].replace("%", "")))
# check non-biased strategy
if scenario == "no_bias":
assert diff_pct < 0.01
# check biased strategy
elif scenario == "bias1":
assert diff_pct >= 0.01
diff_pct = abs(float(instance.dict_recursive['rsi'][100].replace("%", "")))
# check non-biased strategy
if scenario == "no_bias":
assert diff_pct < 0.01
# check biased strategy
elif scenario in ("bias1", "bias2"):
assert diff_pct >= 0.01

View File

@ -28,10 +28,12 @@ class strategy_test_v3_recursive_issue(IStrategy):
# bias is introduced here
if self.scenario.value == 'no_bias':
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
elif self.scenario.value == 'bias1':
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=50)
else:
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=50).shift(-1)
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=50)
if self.scenario.value == 'bias2':
# Has both bias1 and bias2
dataframe['rsi_lookahead'] = ta.RSI(dataframe, timeperiod=50).shift(-1)
return dataframe