improve example strat so that it has dynamic buy and sell logic according to original prediction

This commit is contained in:
robcaulk 2022-05-29 14:45:46 +02:00
parent 4eb29c8810
commit ce365eb9e3
5 changed files with 189 additions and 23 deletions

3
.gitignore vendored
View File

@ -109,4 +109,5 @@ target/
!config_examples/config_ftx.example.json !config_examples/config_ftx.example.json
!config_examples/config_full.example.json !config_examples/config_full.example.json
!config_examples/config_kraken.example.json !config_examples/config_kraken.example.json
!config_examples/config_freqai.example.json !config_examples/config_freqai_futures.example.json
!config_examples/config_freqai_spot.example.json

View File

@ -0,0 +1,93 @@
{
"trading_mode": "futures",
"margin_mode": "isolated",
"max_open_trades": 5,
"stake_currency": "USDT",
"stake_amount": 200,
"tradable_balance_ratio": 1,
"fiat_display_currency": "USD",
"dry_run": true,
"timeframe": "3m",
"dry_run_wallet": 1000,
"cancel_open_orders_on_exit": true,
"unfilledtimeout": {
"entry": 10,
"exit": 30
},
"exchange": {
"name": "okx",
"key": "",
"secret": "",
"ccxt_config": {
"enableRateLimit": true
},
"ccxt_async_config": {
"enableRateLimit": true,
"rateLimit": 200
},
"pair_whitelist": [
"AGLD/USDT:USDT",
"1INCH/USDT:USDT",
"AAVE/USDT:USDT",
"ALGO/USDT:USDT",
"ALPHA/USDT:USDT",
"API3/USDT:USDT",
"AVAX/USDT:USDT",
"AXS/USDT:USDT",
"BCH/USDT:USDT"
],
"pair_blacklist": []
},
"entry_pricing": {
"price_side": "same",
"use_order_book": true,
"order_book_top": 1,
"price_last_balance": 0.0,
"check_depth_of_market": {
"enabled": false,
"bids_to_ask_delta": 1
}
},
"exit_pricing": {
"price_side": "other",
"use_order_book": true,
"order_book_top": 1
},
"pairlists": [
{
"method": "StaticPairList"
}
],
"freqai": {
"timeframes": [
"3m",
"15m",
"1h"
],
"train_period": 20,
"backtest_period": 2,
"identifier": "example",
"live_trained_timestamp": 0,
"corr_pairlist": [
"BTC/USDT:USDT",
"ETH/USDT:USDT"
],
"feature_parameters": {
"period": 20,
"shift": 2,
"DI_threshold": 0,
"weight_factor": 0.9,
"principal_component_analysis": false,
"use_SVM_to_remove_outliers": true,
"stratify": 0
},
"data_split_parameters": {
"test_size": 0.33,
"random_state": 1
},
"model_training_parameters": {
"n_estimators": 1000,
"task_type": "CPU"
}
}
}

View File

@ -6,7 +6,7 @@
"fiat_display_currency": "USD", "fiat_display_currency": "USD",
"dry_run": true, "dry_run": true,
"timeframe": "5m", "timeframe": "5m",
"dry_run_wallet": 1000, "dry_run_wallet": 4000,
"cancel_open_orders_on_exit": true, "cancel_open_orders_on_exit": true,
"unfilledtimeout": { "unfilledtimeout": {
"entry": 10, "entry": 10,
@ -51,7 +51,8 @@
"freqai": { "freqai": {
"timeframes": [ "timeframes": [
"5m", "5m",
"15m" "15m",
"4h"
], ],
"train_period": 30, "train_period": 30,
"backtest_period": 7, "backtest_period": 7,
@ -60,16 +61,18 @@
"corr_pairlist": [ "corr_pairlist": [
"BTC/USDT", "BTC/USDT",
"ETH/USDT", "ETH/USDT",
"DOT/USDT" "DOT/USDT",
"MATIC/USDT",
"SOL/USDT"
], ],
"feature_parameters": { "feature_parameters": {
"period": 24, "period": 20,
"shift": 1, "shift": 1,
"DI_threshold": 0, "DI_threshold": 0,
"weight_factor": 0.9, "weight_factor": 0.9,
"principal_component_analysis": false, "principal_component_analysis": false,
"use_SVM_to_remove_outliers": true, "use_SVM_to_remove_outliers": false,
"stratify": 3 "stratify": 0
}, },
"data_split_parameters": { "data_split_parameters": {
"test_size": 0.33, "test_size": 0.33,
@ -77,8 +80,6 @@
}, },
"model_training_parameters": { "model_training_parameters": {
"n_estimators": 1000, "n_estimators": 1000,
"random_state": 1,
"learning_rate": 0.1,
"task_type": "CPU" "task_type": "CPU"
} }
}, },

View File

@ -56,6 +56,7 @@ class IFreqaiModel(ABC):
self.set_full_path() self.set_full_path()
self.data_drawer = FreqaiDataDrawer(Path(self.full_path), self.data_drawer = FreqaiDataDrawer(Path(self.full_path),
self.config['exchange']['pair_whitelist']) self.config['exchange']['pair_whitelist'])
self.lock = threading.Lock()
def assert_config(self, config: Dict[str, Any]) -> None: def assert_config(self, config: Dict[str, Any]) -> None:

View File

@ -7,8 +7,10 @@ import talib.abstract as ta
from pandas import DataFrame from pandas import DataFrame
from technical import qtpylib from technical import qtpylib
from freqtrade.exchange import timeframe_to_prev_date
from freqtrade.freqai.strategy_bridge import CustomModel from freqtrade.freqai.strategy_bridge import CustomModel
from freqtrade.strategy import merge_informative_pair from freqtrade.persistence import Trade
from freqtrade.strategy import DecimalParameter, IntParameter, merge_informative_pair
from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.interface import IStrategy
@ -46,6 +48,11 @@ class FreqaiExampleStrategy(IStrategy):
stoploss = -0.05 stoploss = -0.05
use_sell_signal = True use_sell_signal = True
startup_candle_count: int = 300 startup_candle_count: int = 300
can_short = False
linear_roi_offset = DecimalParameter(0.00, 0.02, default=0.005, space='sell',
optimize=False, load=True)
max_roi_time_long = IntParameter(0, 800, default=400, space='sell', optimize=False, load=True)
def informative_pairs(self): def informative_pairs(self):
whitelist_pairs = self.dp.current_whitelist() whitelist_pairs = self.dp.current_whitelist()
@ -182,25 +189,88 @@ class FreqaiExampleStrategy(IStrategy):
dataframe["sell_roi"] = dataframe["target_mean"] - dataframe["target_std"] dataframe["sell_roi"] = dataframe["target_mean"] - dataframe["target_std"]
return dataframe return dataframe
def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_entry_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
buy_conditions = [ enter_long_conditions = [
(dataframe["prediction"] > dataframe["target_roi"]) & (dataframe["do_predict"] == 1) df['do_predict'] == 1,
df['prediction'] > df["target_roi"]
] ]
if buy_conditions: if enter_long_conditions:
dataframe.loc[reduce(lambda x, y: x | y, buy_conditions), "buy"] = 1 df.loc[reduce(lambda x, y: x & y,
enter_long_conditions), ["enter_long", "enter_tag"]] = (1, 'long')
return dataframe enter_short_conditions = [
df['do_predict'] == 1,
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: df['prediction'] < df["sell_roi"]
sell_conditions = [
(dataframe["do_predict"] <= 0)
] ]
if sell_conditions:
dataframe.loc[reduce(lambda x, y: x | y, sell_conditions), "sell"] = 1
return dataframe if enter_short_conditions:
df.loc[reduce(lambda x, y: x & y,
enter_short_conditions), ["enter_short", "enter_tag"]] = (1, 'short')
return df
def populate_exit_trend(self, df: DataFrame, metadata: dict) -> DataFrame:
exit_long_conditions = [
df['do_predict'] == 1,
df['prediction'] < df['sell_roi'] * 0.25
]
if exit_long_conditions:
df.loc[reduce(lambda x, y: x & y, exit_long_conditions), "exit_long"] = 1
exit_short_conditions = [
df['do_predict'] == 1,
df['prediction'] > df['target_roi'] * 0.25
]
if exit_short_conditions:
df.loc[reduce(lambda x, y: x & y, exit_short_conditions), "exit_short"] = 1
return df
def get_ticker_indicator(self): def get_ticker_indicator(self):
return int(self.config["timeframe"][:-1]) return int(self.config["timeframe"][:-1])
def custom_exit(self, pair: str, trade: Trade, current_time, current_rate,
current_profit, **kwargs):
dataframe, _ = self.dp.get_analyzed_dataframe(pair=pair, timeframe=self.timeframe)
trade_date = timeframe_to_prev_date(self.config['timeframe'], trade.open_date_utc)
trade_candle = dataframe.loc[(dataframe['date'] == trade_date)]
if trade_candle.empty:
return None
trade_candle = trade_candle.squeeze()
pair_dict = self.model.bridge.data_drawer.pair_dict
entry_tag = trade.enter_tag
if 'prediction' + entry_tag not in pair_dict[pair]:
with self.model.bridge.lock:
self.model.bridge.data_drawer.pair_dict[pair][
'prediction' + entry_tag] = abs(trade_candle['prediction'])
self.model.bridge.data_drawer.save_drawer_to_disk()
else:
if pair_dict[pair]['prediction' + entry_tag] > 0:
roi_price = abs(trade_candle['prediction' + entry_tag])
else:
with self.model.bridge.lock:
self.model.bridge.data_drawer.pair_dict[pair][
'prediction' + entry_tag] = abs(trade_candle['prediction'])
self.model.bridge.data_drawer.save_drawer_to_disk()
roi_price = abs(trade_candle['prediction'])
roi_time = self.max_roi_time_long.value
roi_decay = roi_price * (1 - ((current_time - trade.open_date_utc).seconds) /
(roi_time * 60))
if roi_decay < 0:
roi_decay = self.linear_roi_offset.value
else:
roi_decay += self.linear_roi_offset.value
if current_profit > roi_price: # roi_decay:
with self.model.bridge.lock:
self.model.bridge.data_drawer.pair_dict[pair]['prediction' + entry_tag] = 0
self.model.bridge.data_drawer.save_drawer_to_disk()
return 'roi_custom_win'