revise docs, update dp method docstring

This commit is contained in:
Timothy Pogue
2022-09-21 15:50:11 -06:00
parent 366c6c24d8
commit 0811bca8b4
5 changed files with 137 additions and 147 deletions

View File

@@ -460,147 +460,3 @@ The correct configuration for this case is `http://localhost:8080` - the main pa
!!! Note
We strongly recommend to also set `jwt_secret_key` to something random and known only to yourself to avoid unauthorized access to your bot.
## External Signals API
FreqTrade provides a mechanism whereby a leader instance may provide analyzed dataframes to a subscriber/follower instance (or instances) using websockets.
Run a bot in Leader mode to broadcast any populated indicators in the dataframes for each pair to bots running in Follower mode. This allows the reuse of computed indicators in multiple bots without needing to compute them multiple times.
### Leader configuration
Enable the leader websocket api by adding `enable_message_ws` to your `api_server` section and setting it to `true`, and providing an api token with `ws_token`. See [Security](#security) above for advice on token generation.
!!! Note
We strongly recommend to also set `ws_token` to something random and known only to yourself to avoid unauthorized access to your bot.
```jsonc
{
//...
"api_server": {
//...
"enable_message_ws": true,
"ws_token": "mysecretapitoken"
//...
}
//...
}
```
The leader instance will listen for incoming reqests on the port configured by `api_server.listen_port` to forward its analyzed dataframes for each pair in its active whitelist calculated in its `populate_indicators()`.
### Follower configuration
Enable subscribing to a leader instance by adding the `external_message_consumer` section to the follower's config file.
```jsonc
{
//...
"external_message_consumer": {
"enabled": true,
"producers": [
{
"name": "default",
"host": "127.0.0.1",
"port": 8080,
"ws_token": "mysecretapitoken"
}
],
"reply_timeout": 10,
"ping_timeout": 5,
"sleep_time": 5,
"message_size_limit": 8, // in MB, default=8
"remove_entry_exit_signals": false
}
//...
}
```
Instead of (or as well as) calculating indicators in `populate_indicators()` the follower instance opens a websocket connection to a leader instance (or multiple leader instances in advanced configurations) and requests the leader's most recently analyzed dataframes for each pair in the active whitelist.
A follower instance will then have a full copy of the analyzed dataframes without the need to calculate them itself.
### Example - Leader Strategy
A simple strategy with multiple indicators. No special considerations are required in the strategy itself, only in the configuration file to enable websocket listening.
```py
class LeaderStrategy(IStrategy):
#...
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Calculate indicators in the standard freqtrade way which can then be broadcast to other instances
"""
dataframe['rsi'] = ta.RSI(dataframe)
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
dataframe['bb_lowerband'] = bollinger['lower']
dataframe['bb_middleband'] = bollinger['mid']
dataframe['bb_upperband'] = bollinger['upper']
dataframe['tema'] = ta.TEMA(dataframe, timeperiod=9)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Populates the entry signal for the given dataframe
"""
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi'], self.buy_rsi.value)) &
(dataframe['tema'] <= dataframe['bb_middleband']) &
(dataframe['tema'] > dataframe['tema'].shift(1)) &
(dataframe['volume'] > 0)
),
'enter_long'] = 1
return dataframe
```
### Example - Follower Strategy
A logically equivalent strategy which calculates no indicators itself, but will have the same analyzed dataframes to make trading decisions from as the leader. In this example the follower has the same entry criteria, however this is not necessary. The follower may use different logic to enter/exit trades.
```py
class FollowerStrategy(IStrategy):
#...
process_only_new_candles = False # required for followers
_columns_to_expect = ['rsi_default', 'tema_default', 'bb_middleband_default']
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Use the websocket api to get pre-populated indicators from another FreqTrade instance.
Use `self.dp.get_external_df(pair)` to get the dataframe
"""
pair = metadata['pair']
timeframe = self.timeframe
leader_dataframe, _ = self.dp.get_external_df(pair)
if not leader_dataframe.empty:
merged_dataframe = merge_informative_pair(dataframe, leader_dataframe,
timeframe, timeframe,
append_timeframe=False,
suffix="default")
return merged_dataframe
else:
dataframe[self._columns_to_expect] = 0
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Populates the entry signal for the given dataframe
"""
# Use the dataframe columns as if we calculated them ourselves
dataframe.loc[
(
(qtpylib.crossed_above(dataframe['rsi_default'], self.buy_rsi.value)) &
(dataframe['tema_default'] <= dataframe['bb_middleband_default']) &
(dataframe['tema_default'] > dataframe['tema_default'].shift(1)) &
(dataframe['volume'] > 0)
),
'enter_long'] = 1
return dataframe
```