From d5993db064bcbd5fd1c83163e68d3e26a6af31c2 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Wed, 3 Mar 2021 14:59:55 +0100 Subject: [PATCH 01/16] refactor(docs/strategy-customization): change variable name for better readability `cust_info` -> `custom_info` --- docs/strategy-customization.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index fdc95a3c1..6eaafa15c 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -311,18 +311,18 @@ The name of the variable can be chosen at will, but should be prefixed with `cus ```python class AwesomeStrategy(IStrategy): # Create custom dictionary - cust_info = {} + custom_info = {} def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # Check if the entry already exists - if not metadata["pair"] in self.cust_info: + if not metadata["pair"] in self.custom_info: # Create empty entry for this pair - self.cust_info[metadata["pair"]] = {} + self.custom_info[metadata["pair"]] = {} - if "crosstime" in self.cust_info[metadata["pair"]]: - self.cust_info[metadata["pair"]]["crosstime"] += 1 + if "crosstime" in self.custom_info[metadata["pair"]]: + self.custom_info[metadata["pair"]]["crosstime"] += 1 else: - self.cust_info[metadata["pair"]]["crosstime"] = 1 + self.custom_info[metadata["pair"]]["crosstime"] = 1 ``` !!! Warning From 5cf3194fab8b026d204f8992aa0ad76c18c8bcb5 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Wed, 3 Mar 2021 15:03:44 +0100 Subject: [PATCH 02/16] chore(docs/strategy-customization): clean up left over trailing whitespaces --- docs/strategy-advanced.md | 2 +- docs/strategy-customization.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index dcd340fd1..2fe29d431 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -142,7 +142,7 @@ class AwesomeStrategy(IStrategy): return -1 # return a value bigger than the inital stoploss to keep using the inital stoploss # After reaching the desired offset, allow the stoploss to trail by half the profit - desired_stoploss = current_profit / 2 + desired_stoploss = current_profit / 2 # Use a minimum of 2.5% and a maximum of 5% return max(min(desired_stoploss, 0.05), 0.025) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 6eaafa15c..983a5f60a 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -399,7 +399,7 @@ if self.dp: ### *current_whitelist()* -Imagine you've developed a strategy that trades the `5m` timeframe using signals generated from a `1d` timeframe on the top 10 volume pairs by volume. +Imagine you've developed a strategy that trades the `5m` timeframe using signals generated from a `1d` timeframe on the top 10 volume pairs by volume. The strategy might look something like this: @@ -418,7 +418,7 @@ This is where calling `self.dp.current_whitelist()` comes in handy. pairs = self.dp.current_whitelist() # Assign tf to each pair so they can be downloaded and cached for strategy. informative_pairs = [(pair, '1d') for pair in pairs] - return informative_pairs + return informative_pairs ``` ### *get_pair_dataframe(pair, timeframe)* @@ -583,7 +583,7 @@ All columns of the informative dataframe will be available on the returning data ``` python 'date', 'open', 'high', 'low', 'close', 'rsi' # from the original dataframe - 'date_1h', 'open_1h', 'high_1h', 'low_1h', 'close_1h', 'rsi_1h' # from the informative dataframe + 'date_1h', 'open_1h', 'high_1h', 'low_1h', 'close_1h', 'rsi_1h' # from the informative dataframe ``` ??? Example "Custom implementation" From cc4e84bb7009330031dfd0aadc8b2db9a1d13b49 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Wed, 3 Mar 2021 15:04:18 +0100 Subject: [PATCH 03/16] feature(docs/strategy-customization): add example how to store indicator with DatetimeIndex into custom_info --- docs/strategy-customization.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 983a5f60a..0b09e073f 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -333,6 +333,22 @@ class AwesomeStrategy(IStrategy): *** +#### Storing custom information using DatetimeIndex from `dataframe` + +Imagine you need to store an indicator like `ATR` or `RSI` into `custom_info`. To use this in a meaningful way, you will not only need the raw data of the indicator, but probably also need to keep the right timestamps. + +class AwesomeStrategy(IStrategy): + # Create custom dictionary + custom_info = {} + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + # add indicator mapped to correct DatetimeIndex to custom_info + # using "ATR" here as example + self.custom_info[metadata['pair']] = dataframe[['date', 'atr']].copy().set_index('date') + return dataframe + +See: (custom_stoploss example)[WIP] for how to access it + ## Additional data (informative_pairs) ### Get data for non-tradeable pairs From c5900bbd384e3d3c22a5bc717dfddb47dc13c6a4 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Wed, 3 Mar 2021 15:16:27 +0100 Subject: [PATCH 04/16] feature(docs/strategy-customization): add example "Custom stoploss using an indicator from dataframe" --- docs/strategy-advanced.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 2fe29d431..0cd4d1be0 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -179,6 +179,35 @@ class AwesomeStrategy(IStrategy): return (-0.07 + current_profit) return 1 ``` +#### Custom stoploss using an indicator from dataframe example + +Imagine you want to use `custom_stoploss()` to use a trailing indicator like e.g. "ATR" + +See: (Storing custom information using DatetimeIndex from `dataframe` +)[WIP] on how to store the indicator into `custom_info` + +``` python +from freqtrade.persistence import Trade + +class AwesomeStrategy(IStrategy): + + # ... populate_* methods + + use_custom_stoploss = True + + def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, + current_rate: float, current_profit: float, **kwargs) -> float: + + result = 1 + if self.custom_info[pair] is not None and trade is not None: + atr = self.custom_info[pair].loc[current_time]['atr'] + if (atr is not None): + # new stoploss relative to current_rate + new_stoploss = (current_rate-atr)/current_rate + # turn into relative negative offset required by `custom_stoploss` return implementation + result = new_stoploss - 1 + return result +``` --- From 32f35fcd904f44b8a96e23d726da1e5f1e5484b3 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Wed, 3 Mar 2021 21:26:21 +0100 Subject: [PATCH 05/16] fix(docs/strategy-customization): "custom_stoploss indicator" example need to check for RUN_MODE --- docs/strategy-advanced.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 0cd4d1be0..8c730b3df 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -188,6 +188,7 @@ See: (Storing custom information using DatetimeIndex from `dataframe` ``` python from freqtrade.persistence import Trade +from freqtrade.state import RunMode class AwesomeStrategy(IStrategy): @@ -200,12 +201,23 @@ class AwesomeStrategy(IStrategy): result = 1 if self.custom_info[pair] is not None and trade is not None: - atr = self.custom_info[pair].loc[current_time]['atr'] - if (atr is not None): + # using current_time directly (like below) will only work in backtesting. + # so check "runmode" to make sure that it's only used in backtesting + if(self.dp.runmode == RunMode.BACKTEST): + relative_sl = self.custom_info[pair].loc[current_time]['atr] + # in live / dry-run, it'll be really the current time + else: + # but we can just use the last entry to get the current value + relative_sl = self.custom_info[pair]['atr].iloc[ -1 ] + + if (relative_sl is not None): + print("Custom SL: {}".format(relative_sl)) # new stoploss relative to current_rate - new_stoploss = (current_rate-atr)/current_rate + new_stoploss = (current_rate-relative_sl)/current_rate # turn into relative negative offset required by `custom_stoploss` return implementation result = new_stoploss - 1 + + print("Result: {}".format(result)) return result ``` From d05acc30fa2819fe9ca03c224b62d3b46cae86fe Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Wed, 3 Mar 2021 22:10:08 +0100 Subject: [PATCH 06/16] fix(docs/strategy-customization): remove superflous `prints` from example code --- docs/strategy-advanced.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 8c730b3df..504b7270e 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -211,13 +211,11 @@ class AwesomeStrategy(IStrategy): relative_sl = self.custom_info[pair]['atr].iloc[ -1 ] if (relative_sl is not None): - print("Custom SL: {}".format(relative_sl)) # new stoploss relative to current_rate new_stoploss = (current_rate-relative_sl)/current_rate # turn into relative negative offset required by `custom_stoploss` return implementation result = new_stoploss - 1 - print("Result: {}".format(result)) return result ``` From b52698197b469d7739076b2c538f7c216f27cc8e Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Thu, 4 Mar 2021 14:44:51 +0100 Subject: [PATCH 07/16] refactor(docs/strategy-advanced): extract "Storing information" section from `strategy-customization.md` --- docs/strategy-advanced.md | 47 ++++++++++++++++++++++++++++++++++ docs/strategy-customization.md | 47 ---------------------------------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 504b7270e..2cd411078 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -11,6 +11,53 @@ If you're just getting started, please be familiar with the methods described in !!! Tip You can get a strategy template containing all below methods by running `freqtrade new-strategy --strategy MyAwesomeStrategy --template advanced` +## Storing information + +Storing information can be accomplished by creating a new dictionary within the strategy class. + +The name of the variable can be chosen at will, but should be prefixed with `cust_` to avoid naming collisions with predefined strategy variables. + +```python +class AwesomeStrategy(IStrategy): + # Create custom dictionary + custom_info = {} + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + # Check if the entry already exists + if not metadata["pair"] in self.custom_info: + # Create empty entry for this pair + self.custom_info[metadata["pair"]] = {} + + if "crosstime" in self.custom_info[metadata["pair"]]: + self.custom_info[metadata["pair"]]["crosstime"] += 1 + else: + self.custom_info[metadata["pair"]]["crosstime"] = 1 +``` + +!!! Warning + The data is not persisted after a bot-restart (or config-reload). Also, the amount of data should be kept smallish (no DataFrames and such), otherwise the bot will start to consume a lot of memory and eventually run out of memory and crash. + +!!! Note + If the data is pair-specific, make sure to use pair as one of the keys in the dictionary. + +*** + +### Storing custom information using DatetimeIndex from `dataframe` + +Imagine you need to store an indicator like `ATR` or `RSI` into `custom_info`. To use this in a meaningful way, you will not only need the raw data of the indicator, but probably also need to keep the right timestamps. + +class AwesomeStrategy(IStrategy): + # Create custom dictionary + custom_info = {} + + def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + # add indicator mapped to correct DatetimeIndex to custom_info + # using "ATR" here as example + self.custom_info[metadata['pair']] = dataframe[['date', 'atr']].copy().set_index('date') + return dataframe + +See `custom_stoploss` examples below on how to access the saved dataframe columns + ## Custom stoploss A stoploss can only ever move upwards - so if you set it to an absolute profit of 2%, you can never move it below this price. diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index 0b09e073f..a66be013e 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -302,53 +302,6 @@ Currently this is `pair`, which can be accessed using `metadata['pair']` - and w The Metadata-dict should not be modified and does not persist information across multiple calls. Instead, have a look at the section [Storing information](#Storing-information) -### Storing information - -Storing information can be accomplished by creating a new dictionary within the strategy class. - -The name of the variable can be chosen at will, but should be prefixed with `cust_` to avoid naming collisions with predefined strategy variables. - -```python -class AwesomeStrategy(IStrategy): - # Create custom dictionary - custom_info = {} - - def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - # Check if the entry already exists - if not metadata["pair"] in self.custom_info: - # Create empty entry for this pair - self.custom_info[metadata["pair"]] = {} - - if "crosstime" in self.custom_info[metadata["pair"]]: - self.custom_info[metadata["pair"]]["crosstime"] += 1 - else: - self.custom_info[metadata["pair"]]["crosstime"] = 1 -``` - -!!! Warning - The data is not persisted after a bot-restart (or config-reload). Also, the amount of data should be kept smallish (no DataFrames and such), otherwise the bot will start to consume a lot of memory and eventually run out of memory and crash. - -!!! Note - If the data is pair-specific, make sure to use pair as one of the keys in the dictionary. - -*** - -#### Storing custom information using DatetimeIndex from `dataframe` - -Imagine you need to store an indicator like `ATR` or `RSI` into `custom_info`. To use this in a meaningful way, you will not only need the raw data of the indicator, but probably also need to keep the right timestamps. - -class AwesomeStrategy(IStrategy): - # Create custom dictionary - custom_info = {} - - def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - # add indicator mapped to correct DatetimeIndex to custom_info - # using "ATR" here as example - self.custom_info[metadata['pair']] = dataframe[['date', 'atr']].copy().set_index('date') - return dataframe - -See: (custom_stoploss example)[WIP] for how to access it - ## Additional data (informative_pairs) ### Get data for non-tradeable pairs From 4064f856d1b47d68dbd1d40aa09cbb47c342720c Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Thu, 4 Mar 2021 14:50:04 +0100 Subject: [PATCH 08/16] fix(docs/strategy-customization): add "hyperopt" to runmode check for custom_info in custom_stoploss example --- docs/strategy-advanced.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 2cd411078..f230a2371 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -249,8 +249,8 @@ class AwesomeStrategy(IStrategy): result = 1 if self.custom_info[pair] is not None and trade is not None: # using current_time directly (like below) will only work in backtesting. - # so check "runmode" to make sure that it's only used in backtesting - if(self.dp.runmode == RunMode.BACKTEST): + # so check "runmode" to make sure that it's only used in backtesting/hyperopt + if self.dp and self.dp.runmode.value in ('backtest', 'hyperopt'): relative_sl = self.custom_info[pair].loc[current_time]['atr] # in live / dry-run, it'll be really the current time else: From 1a02a146a1e1023fba4f040e88eec3d9b8ace32a Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Thu, 4 Mar 2021 14:59:08 +0100 Subject: [PATCH 09/16] feature(docs/strategy-advanced/custom_info-storage/example): add ATR column calculation --- docs/strategy-advanced.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index f230a2371..81ba24a67 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -46,15 +46,19 @@ class AwesomeStrategy(IStrategy): Imagine you need to store an indicator like `ATR` or `RSI` into `custom_info`. To use this in a meaningful way, you will not only need the raw data of the indicator, but probably also need to keep the right timestamps. +```python +import talib.abstract as ta class AwesomeStrategy(IStrategy): # Create custom dictionary custom_info = {} def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: - # add indicator mapped to correct DatetimeIndex to custom_info # using "ATR" here as example + dataframe['atr'] = ta.ATR(dataframe) + # add indicator mapped to correct DatetimeIndex to custom_info self.custom_info[metadata['pair']] = dataframe[['date', 'atr']].copy().set_index('date') return dataframe +``` See `custom_stoploss` examples below on how to access the saved dataframe columns From 22a558e33120a9e16a29c53b4f00ee268e30d7fe Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Thu, 4 Mar 2021 15:01:21 +0100 Subject: [PATCH 10/16] fix(docs/strategy-advanced): fix link to custom_info storage --- docs/strategy-advanced.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 81ba24a67..d685662eb 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -234,8 +234,7 @@ class AwesomeStrategy(IStrategy): Imagine you want to use `custom_stoploss()` to use a trailing indicator like e.g. "ATR" -See: (Storing custom information using DatetimeIndex from `dataframe` -)[WIP] on how to store the indicator into `custom_info` +See: "Storing custom information using DatetimeIndex from `dataframe`" example above) on how to store the indicator into `custom_info` ``` python from freqtrade.persistence import Trade From a6ef354a5fc5c289aee14ace1881055471370a10 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Thu, 4 Mar 2021 18:52:23 +0100 Subject: [PATCH 11/16] fix(docs/strategy-advanced): use `get_analyzed_dataframe()` instead of `custom_info.iloc` --- docs/strategy-advanced.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index d685662eb..42ffaa423 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -257,8 +257,11 @@ class AwesomeStrategy(IStrategy): relative_sl = self.custom_info[pair].loc[current_time]['atr] # in live / dry-run, it'll be really the current time else: + # but we can just use the last entry from an already analyzed dataframe instead + dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=pair, + timeframe=self.timeframe) # but we can just use the last entry to get the current value - relative_sl = self.custom_info[pair]['atr].iloc[ -1 ] + relative_sl = dataframe['atr'].iat[-1] if (relative_sl is not None): # new stoploss relative to current_rate From c56b9cd75172ef43d3de33814fd79c3c1f1a3ec1 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Thu, 4 Mar 2021 18:50:48 +0100 Subject: [PATCH 12/16] fix(docs/strategy-advanced): add warnings --- docs/strategy-advanced.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 42ffaa423..4cc1adb49 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -60,6 +60,12 @@ class AwesomeStrategy(IStrategy): return dataframe ``` +!!! Warning + The data is not persisted after a bot-restart (or config-reload). Also, the amount of data should be kept smallish (no DataFrames and such), otherwise the bot will start to consume a lot of memory and eventually run out of memory and crash. + +!!! Note + If the data is pair-specific, make sure to use pair as one of the keys in the dictionary. + See `custom_stoploss` examples below on how to access the saved dataframe columns ## Custom stoploss @@ -236,6 +242,11 @@ Imagine you want to use `custom_stoploss()` to use a trailing indicator like e.g See: "Storing custom information using DatetimeIndex from `dataframe`" example above) on how to store the indicator into `custom_info` +!!! Warning + only use .iat[-1] in live mode, not in backtesting/hyperopt + otherwise you will look into the future + see: https://www.freqtrade.io/en/latest/strategy-customization/#common-mistakes-when-developing-strategies + ``` python from freqtrade.persistence import Trade from freqtrade.state import RunMode @@ -260,7 +271,10 @@ class AwesomeStrategy(IStrategy): # but we can just use the last entry from an already analyzed dataframe instead dataframe, last_updated = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe) - # but we can just use the last entry to get the current value + # WARNING + # only use .iat[-1] in live mode, not in backtesting/hyperopt + # otherwise you will look into the future + # see: https://www.freqtrade.io/en/latest/strategy-customization/#common-mistakes-when-developing-strategies relative_sl = dataframe['atr'].iat[-1] if (relative_sl is not None): From 900deb663a282b5e234993e6b9b36ccc5a4df487 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Thu, 4 Mar 2021 19:58:43 +0100 Subject: [PATCH 13/16] fix(docs/strategy-advanced/custom_stoploss/example): check if "pair" exists in "custom_info" before requesting --- docs/strategy-advanced.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 4cc1adb49..c166f87fb 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -261,7 +261,7 @@ class AwesomeStrategy(IStrategy): current_rate: float, current_profit: float, **kwargs) -> float: result = 1 - if self.custom_info[pair] is not None and trade is not None: + if self.custom_info and pair in self.custom_info and trade: # using current_time directly (like below) will only work in backtesting. # so check "runmode" to make sure that it's only used in backtesting/hyperopt if self.dp and self.dp.runmode.value in ('backtest', 'hyperopt'): From 1304918a29de43e34b207b21a6f9b3b92bd79023 Mon Sep 17 00:00:00 2001 From: Joe Schr Date: Thu, 4 Mar 2021 19:59:57 +0100 Subject: [PATCH 14/16] fix(docs/strategy-advanced/custom_info-storage/example): only add to "custom_info" in backtesting and hyperopt --- docs/strategy-advanced.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index c166f87fb..5c7ae83bc 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -55,8 +55,9 @@ class AwesomeStrategy(IStrategy): def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame: # using "ATR" here as example dataframe['atr'] = ta.ATR(dataframe) - # add indicator mapped to correct DatetimeIndex to custom_info - self.custom_info[metadata['pair']] = dataframe[['date', 'atr']].copy().set_index('date') + if self.dp.runmode.value in ('backtest', 'hyperopt'): + # add indicator mapped to correct DatetimeIndex to custom_info + self.custom_info[metadata['pair']] = dataframe[['date', 'atr']].copy().set_index('date') return dataframe ``` From 161a4656d5769ac3942fc2f1ec96d971bf224494 Mon Sep 17 00:00:00 2001 From: JoeSchr Date: Thu, 4 Mar 2021 20:05:21 +0100 Subject: [PATCH 15/16] Update docs/strategy-advanced.md Co-authored-by: Matthias --- docs/strategy-advanced.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/strategy-advanced.md b/docs/strategy-advanced.md index 5c7ae83bc..56061365e 100644 --- a/docs/strategy-advanced.md +++ b/docs/strategy-advanced.md @@ -246,7 +246,7 @@ See: "Storing custom information using DatetimeIndex from `dataframe`" example a !!! Warning only use .iat[-1] in live mode, not in backtesting/hyperopt otherwise you will look into the future - see: https://www.freqtrade.io/en/latest/strategy-customization/#common-mistakes-when-developing-strategies + see [Common mistakes when developing strategies](strategy-customization.md#common-mistakes-when-developing-strategies) for more info. ``` python from freqtrade.persistence import Trade From dfeafc22044b169c99c39436ac9679ea31211afc Mon Sep 17 00:00:00 2001 From: JoeSchr Date: Thu, 4 Mar 2021 20:05:27 +0100 Subject: [PATCH 16/16] Update docs/strategy-customization.md Co-authored-by: Matthias --- docs/strategy-customization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/strategy-customization.md b/docs/strategy-customization.md index a66be013e..aebc51509 100644 --- a/docs/strategy-customization.md +++ b/docs/strategy-customization.md @@ -300,7 +300,7 @@ The metadata-dict (available for `populate_buy_trend`, `populate_sell_trend`, `p Currently this is `pair`, which can be accessed using `metadata['pair']` - and will return a pair in the format `XRP/BTC`. The Metadata-dict should not be modified and does not persist information across multiple calls. -Instead, have a look at the section [Storing information](#Storing-information) +Instead, have a look at the section [Storing information](strategy-advanced.md#Storing-information) ## Additional data (informative_pairs)