improve example strat so that it has dynamic buy and sell logic according to original prediction
This commit is contained in:
parent
4eb29c8810
commit
ce365eb9e3
3
.gitignore
vendored
3
.gitignore
vendored
@ -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
|
||||||
|
93
config_examples/config_freqai_futures.example.json
Normal file
93
config_examples/config_freqai_futures.example.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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"
|
||||||
}
|
}
|
||||||
},
|
},
|
@ -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:
|
||||||
|
|
||||||
|
@ -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'
|
||||||
|
Loading…
Reference in New Issue
Block a user