这个分支貌似没有太大优化空间, 或者回头换grok

This commit is contained in:
zhangkun9038@dingtalk.com 2025-05-28 09:54:51 +00:00
parent 021c0ab8db
commit 3b5e518d7d
15 changed files with 8354 additions and 672 deletions

8302
ccxt/async_support/okx.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -60,49 +60,6 @@
"method": "StaticPairList"
}
],
"freqai": {
"enabled": true,
"data_kitchen": {
"fillna": "ffill",
"feature_parameters": {
"DI_threshold": 0.9,
"weight_factor": 0.9
}
},
"freqaimodel": "XGBoostRegressor",
"purge_old_models": 2,
"identifier": "test175",
"train_period_days": 30,
"backtest_period_days": 10,
"live_retrain_hours": 0,
"feature_selection": {
"method": "recursive_elimination",
"threshold": 0.01
},
"feature_parameters": {
"include_timeframes": ["5m", "1h"],
"include_corr_pairlist": ["BTC/USDT"],
"label_period_candles": 10,
"use_SVM_to_remove_outliers": true,
"principal_component_analysis": true
},
"model": "XGBoostRegressor",
"data_split_parameters": {
"test_size": 0.2,
"shuffle": true,
"random_state": 42
},
"model_training_parameters": {
"n_estimators": 200,
"learning_rate": 0.05,
"max_depth": 5,
"subsample": 0.8,
"colsample_bytree": 0.8,
"objective": "reg:squarederror",
"eval_metric": "rmse",
"early_stopping_rounds": 50
}
},
"api_server": {
"enabled": true,
"listen_ip_address": "0.0.0.0",

View File

@ -11,38 +11,9 @@
},
"pair_whitelist": ["OKB/USDT", "SOL/USDT"]
},
"pairlists": [
{
"method": "StaticPairList"
}
],
"timeframe": "15m",
"strategy": "NostalgiaForInfinityV8",
"freqai": {
"enabled": true,
"freqaimodel": "LightGBMRegressor",
"train_period_days": 7,
"backtest_period_days": 0.2,
"feature_parameters": {
"include_timeframes": ["15m"],
"include_corr_pairlist": ["OKB/USDT", "SOL/USDT"],
"label_period_candles": 4,
"include_shifted_candles": 0,
"indicator_periods_candles": [5, 10, 20],
"include_default_features": ["close", "open", "high", "low", "volume", "rsi", "ema", "sma"],
"DI_threshold": 0.3
},
"data_split_parameters": {
"test_size": 0.2,
"shuffle": false
},
"model_training_parameters": {
"n_estimators": 100,
"learning_rate": 0.1,
"num_leaves": 15,
"verbose": -1
}
},
"order_types": {
"entry": "market",
"exit": "market",

View File

@ -1,133 +0,0 @@
{
"$schema": "https://schema.freqtrade.io/schema.json",
"trading_mode": "spot",
"margin_mode": "isolated",
"max_open_trades": 4,
"stake_currency": "USDT",
"stake_amount": 150,
"startup_candle_count": 30,
"tradable_balance_ratio": 1,
"fiat_display_currency": "USD",
"dry_run": true,
"identifier": "demo1",
"timeframe": "5m",
"dry_run_wallet": 1000,
"cancel_open_orders_on_exit": true,
"stoploss": -0.05,
"unfilledtimeout": {
"entry": 5,
"exit": 15
},
"exchange": {
"name": "okx",
"key": "eca767d4-fda5-4a1b-bb28-49ae18093307",
"secret": "8CA3628A556ED137977DB298D37BC7F3",
"enable_ws": false,
"ccxt_config": {
"enableRateLimit": true,
"rateLimit": 500,
"options": {
"defaultType": "spot"
}
},
"ccxt_async_config": {
"enableRateLimit": true,
"rateLimit": 500,
"timeout": 20000
},
"pair_whitelist": [
"OKB/USDT",
"BTC/USDT",
"SOL/USDT",
"DOT/USDT",
"TON/USDT",
"ETH/USDT",
],
"pair_blacklist": []
},
"freqai": {
"enabled": true,
"identifier": "test175",
"freqaimodel": "XGBoostRegressor",
"model_path": "/freqtrade/user_data/models",
"save_backtesting_prediction": true,
"save_backtest_models": true,
"backtest_period_days": 30,
"purge_old_models": true,
"load_trained_model": true,
"train_period_days": 90,
"backtest_period_days": 10,
"live_retrain_hours": 0,
"include_predictions_in_final_dataframe": true,
"data_kitchen": {
"fillna": "ffill",
"feature_parameters": {
"DI_threshold": 0.5,
"weight_factor": 0.9
}
},
"feature_parameters": {
"include_timeframes": ["5m", "15m", "1h"],
"include_corr_pairlist": ["BTC/USDT", "ETH/USDT"],
"label_period_candles": 12,
"include_shifted_candles": 3,
"indicator_periods_candles": [10, 20, 50],
"plot_feature_importances": 1,
"feature_selection": {
"method": "none"
}
},
"data_split_parameters": {
"test_size": 0.2,
"shuffle": false
},
"model_training_parameters": {
"n_estimators": 200,
"learning_rate": 0.05,
"max_depth": 6,
"subsample": 0.8,
"colsample_bytree": 0.8
},
},
"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"
}
],
"api_server": {
"enabled": true,
"listen_ip_address": "0.0.0.0",
"listen_port": 8080,
"verbosity": "error",
"enable_openapi": false,
"jwt_secret_key": "6a599ab046dbb419014807dffd7b8823bfa7e5df56b17d545485deb87331b4ca",
"ws_token": "6O5pBDiRigiZrmIsofaE2rkKMJtf9h8zVQ",
"CORS_origins": [],
"username": "freqAdmin",
"password": "admin"
},
"use_exit_signal": true,
"bot_name": "freqtrade",
"initial_state": "running",
"force_entry_enable": false,
"internals": {
"process_throttle_secs": 5,
"heartbeat_interval": 20,
"loglevel": "DEBUG"
}
}

View File

@ -8,7 +8,7 @@
"tradable_balance_ratio": 1,
"fiat_display_currency": "USD",
"dry_run": true,
"timeframe": "3m",
"timeframe": "5m",
"dry_run_wallet": 1000,
"cancel_open_orders_on_exit": true,
"stoploss": -0.085,
@ -87,7 +87,7 @@
},
"feature_parameters": {
"include_timeframes": [
"3m",
"5m",
"15m",
"1h"
],
@ -99,7 +99,7 @@
"include_shifted_candles": 5,
"DI_threshold": 0.7,
"weight_factor": 0.9,
"principal_component_analysis": false,
"principal_component_analysis": true,
"use_SVM_to_remove_outliers": true,
"plot_feature_importances": 10,
"indicator_periods_candles": [
@ -109,13 +109,15 @@
]
},
"data_split_parameters": {
"test_size": 0.2
"test_size": 0.2,
"shuffle": false,
},
"model_training_parameters": {
"n_estimators": 100,
"learning_rate": 0.05,
"num_leaves": 31,
"max_depth": 5,
"num_leaves": 31
"verbose": 1
}
},
"api_server": {

View File

@ -1,121 +0,0 @@
{
"strategy": "TheForceFreqaiStrategy",
"timeframe": "3m",
"exchange": {
"name": "okx",
"ccxt_config": {
"enableRateLimit": true,
"rateLimit": 500,
"options": {"defaultType": "spot"},
"timeout": 20000
},
"pair_whitelist": [
"OKB/USDT"
],
"fee": 0.0008
},
"pair_whitelist": ["OKB/USDT"],
"stake_currency": "USDT",
"stake_amount": 150,
"stoploss": -0.15,
"minimal_roi": {
"0": 0.05,
"60": 0.03,
"120": 0.01
},
"startup_candle_count": 200,
"max_open_trades": 4,
"use_exit_signal": true,
"unfilledtimeout": {
"entry": 5,
"exit": 15,
"unit": "minutes"
},
"export": "trades",
"cache": "none",
"loglevel": "DEBUG",
"verbosity": 2,
"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": {
"enabled": true,
"identifier": "TheForceV7_FreqAI",
"save_backtest_models": true,
"live_retrain": false,
"purge_old_models": true,
"fit_live_predictions_candles": 50,
"force_train": true,
"verbose": 2,
"train_period_days": 60,
"backtest_period_days": 14,
"feature_parameters": {
"include_timeframes": ["3m", "15m"],
"label_period_candles": 12,
"include_shifted_candles": 2,
"include_corr_pairlist": [],
"include_shifted_candles": 5,
"DI_threshold": 1.5,
"indicator_periods_candles": [10, 20, 50],
"include_default_features": [
"open", "high", "low", "close", "volume",
"sma", "ema", "rsi", "macd", "bollinger_bands"
],
"use_SVM_to_remove_outliers": true,
"plot_feature_importances": 10,
"feature_selection": {
"method": "variance_threshold",
"threshold": 0.01
}
},
"data_split_parameters": {
"test_size": 0.2,
"shuffle": false
},
"model_training_parameters": {
"n_estimators": 200,
"learning_rate": 0.05,
"max_depth": 6,
"subsample": 0.8,
"colsample_bytree": 0.8
}
},
"stake_currency": "USDT",
"stake_amount": 150,
"stoploss": -0.15,
"minimal_roi": {
"0": 0.05,
"60": 0.03,
"120": 0.01
},
"startup_candle_count": 100,
"max_open_trades": 4,
"use_exit_signal": true,
"unfilledtimeout": {
"entry": 5,
"exit": 15,
"unit": "minutes"
},
"export": "trades",
"cache": "none",
"loglevel": "DEBUG",
"verbosity": 2
}

View File

@ -1,97 +0,0 @@
{
"$schema": "https://schema.freqtrade.io/schema.json",
"trading_mode": "spot",
"margin_mode": "isolated",
"max_open_trades": 3,
"stake_amount": 15,
"unfilledtimeout": {
"entry": 10,
"exit": 20
},
"entry_pricing": {
"price_side": "same",
"use_order_book": true,
"order_book_top": 1
},
"exit_pricing": {
"price_side": "other",
"use_order_book": true,
"order_book_top": 1
},
"stake_currency": "USDT",
"trailing_stop": false,
"use_custom_stoploss": true,
"startup_candle_count": 200,
"tradable_balance_ratio": 0.25,
"fiat_display_currency": "USD",
"dry_run": false,
"identifier": "demo1",
"timeframe": "5m",
"dry_run_wallet": 1000,
"cancel_open_orders_on_exit": true,
"stoploss": -0.061,
"roi": {},
"trailing": {
"trailing_stop": false,
"trailing_stop_positive": null,
"trailing_stop_positive_offset": 0.0,
"trailing_only_offset_is_reached": false
},
"max_open_trades": 3,
"buy": {
"adx_buy": 25,
"atr_ratio": 0.005
},
"sell": {
"ema_fast_period": 7,
"rsi_sell": 60
},
"exchange": {
"name": "okx",
"key": "314e75b0-1113-47e8-ad01-1fca7e3c0496",
"secret": "9C8B170390F46EA6FB87592AD46F5A34",
"password": "nekFoylf:Om0",
"enable_ws": false,
"ccxt_config": {
"enableRateLimit": true,
"rateLimit": 500,
"options": {
"defaultType": "spot"
}
},
"ccxt_async_config": {
"enableRateLimit": true,
"rateLimit": 3000,
"timeout": 20000
},
"pair_whitelist": ["BTC/USDT", "ETH/USDT", "SOL/USDT", "DOT/USDT", "OKB/USDT", "TON/USDT"],
"pair_blacklist": []
},
"pairlists": [
{
"method": "StaticPairList"
}
],
"api_server": {
"enabled": true,
"listen_ip_address": "0.0.0.0",
"listen_port": 8080,
"verbosity": "error",
"enable_openapi": false,
"jwt_secret_key": "6a599ab046dbb419014807dffd7b8823bfa7e5df56b17d545485deb87331b4ca",
"ws_token": "6O5pBDiRigiZrmIsofaE2rkKMJtf9h8zVQ",
"CORS_origins": [],
"username": "freqAdmin",
"password": "admin"
},
"use_exit_signal": true,
"bot_name": "freqtrade",
"initial_state": "running",
"force_entry_enable": false,
"internals": {
"process_throttle_secs": 5,
"heartbeat_interval": 20,
"loglevel": "INFO"
},
"config_files": ["config_examples/theforcev7.json"]
}

View File

@ -23,6 +23,7 @@ services:
- "./config_examples:/freqtrade/config_examples"
- "./freqtrade/templates:/freqtrade/templates"
- "./freqtrade/exchange/:/freqtrade/exchange"
- "./ccxt/async_support/okx.py:/home/ftuser/.local/lib/python3.12/site-packages/ccxt/async_support/okx.py"
# Expose api on port 8080 (localhost only)
# Please read the https://www.freqtrade.io/en/stable/rest-api/ documentation
# for more information.

View File

@ -1,32 +0,0 @@
{
"strategy_name": "TheForceV7",
"params": {
"max_open_trades": {
"max_open_trades": 4
},
"buy": {
"buy_rsi": 45.2500884290867
},
"sell": {
"sell_rsi": 75.2500884290867
},
"protection": {},
"roi": {
"0": 0.20400000000000001,
"18": 0.07100000000000001,
"47": 0.03,
"102": 0
},
"stoploss": {
"stoploss": -0.07
},
"trailing": {
"trailing_stop": true,
"trailing_stop_positive": 0.237,
"trailing_stop_positive_offset": 0.267,
"trailing_only_offset_is_reached": false
}
},
"ft_stratparam_v": 1,
"export_time": "2025-05-17 11:42:41.193338+00:00"
}

View File

@ -1,200 +0,0 @@
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
from typing import Dict, List, Optional, Union
from freqtrade.persistence import Trade
from freqtrade.strategy import CategoricalParameter, DecimalParameter, IntParameter
from datetime import datetime, timezone
class TheForceV7(IStrategy):
# 基础参数
timeframe = '5m'
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = False
# # Hyperopt 参数
# stoploss = DecimalParameter(
# low=-0.3, high=-0.1, default=-0.233, decimals=3, space='`stoploss'
# )
# profit_threshold_multiplier = DecimalParameter(
# low=0.1, high=1.0, default=0.5, decimals=3, space='stoploss'
# )
# trailing_stop_multiplier = DecimalParameter(
# low=0.5, high=3.0, default=1.5, decimals=3, space='stoploss'
# )
# Hyperopt 参数
stoploss = DecimalParameter(low=-0.3, high=-0.1, default=-0.233, decimals=3, space='stoploss')
profit_threshold_multiplier = DecimalParameter(low=0.2, high=1.0, default=0.5, decimals=3, space='stoploss') # 扩大范围
trailing_stop_multiplier = DecimalParameter(low=0.8, high=3.0, default=1.5, decimals=3, space='stoploss') # 扩大范围
# Hyperopt 参数
stoploss = DecimalParameter(-0.3, -0.05, default=-0.15, decimals=3, space='stoploss')
profit_threshold_multiplier = DecimalParameter(0.8, 3.0, default=1.5, decimals=3, space='stoploss')
trailing_stop_multiplier = DecimalParameter(1.5, 6.0, default=3.0, decimals=3, space='stoploss')
adx_buy = DecimalParameter(15, 35, default=25, decimals=0, space='buy')
atr_ratio = DecimalParameter(0.002, 0.01, default=0.005, decimals=3, space='buy')
rsi_sell = DecimalParameter(50, 70, default=60, decimals=0, space='sell')
ema_fast_period = IntParameter(3, 10, default=7, space='sell')
@property
def protections(self):
return [
{
"method": "CooldownPeriod",
"stop_duration_candles": 5 # 卖出后禁止再次买入的K线数
},
{
"method": "MaxDrawdown",
"lookback_period_candles": 48,
"trade_limit": 20,
"stop_duration_candles": 4,
"max_allowed_drawdown": 0.2 # 最大允许回撤 20%
},
{
"method": "StoplossGuard",
"lookback_period_candles": 24,
"trade_limit": 4, # 在 lookback 内最多触发几次止损
"stop_duration_candles": 2, # 锁定多少根 K 线
"only_per_pair": False # 是否按币种统计
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 6,
"trade_limit": 2,
"stop_duration_candles": 60,
"required_profit": 0.02
},
{
"method": "LowProfitPairs",
"lookback_period_candles": 24,
"trade_limit": 4,
"stop_duration_candles": 2,
"required_profit": 0.01
}
]
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Calculate ATR (14-period, consistent with your code)
# Store the latest ATR in metadata for the pair
dataframe['ema200c'] = ta.EMA(dataframe['close'], timeperiod=200)
dataframe['ema50c'] = ta.EMA(dataframe['close'], timeperiod=50)
dataframe['ema20c'] = ta.EMA(dataframe['close'], timeperiod=20)
dataframe['rsi7'] = ta.RSI(dataframe['close'], timeperiod=7)
macd = ta.MACD(dataframe['close'])
dataframe['macd'] = macd[0]
dataframe['macdsignal'] = macd[1]
stoch = ta.STOCH(dataframe['high'], dataframe['low'], dataframe['close'], fastk_period=14, slowk_period=3, slowd_period=3)
dataframe['slowk'] = stoch[0]
dataframe['slowd'] = stoch[1]
dataframe['volvar'] = dataframe['volume'].rolling(window=20).mean()
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=14)
for period in [self.ema_fast_period.value, 21, 50]:
dataframe[f'ema_{period}'] = ta.EMA(dataframe, timeperiod=period)
metadata['latest_atr'] = dataframe['atr'].iloc[-1]
metadata['latest_adx'] = dataframe['adx'].iloc[-1]
return dataframe
def crossover(self, series1: DataFrame, series2: DataFrame) -> DataFrame:
"""Detects when series1 crosses above series2."""
return (series1 > series2) & (series1.shift(1) <= series2.shift(1))
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(dataframe['close'] > dataframe['ema200c']) & # Relaxed trend
(dataframe['close'] > dataframe['ema50c']) & # Short-term trend
(dataframe['rsi7'] < 50) & # Relaxed RSI
(dataframe['macd'] > 0) & # Relaxed MACD
(dataframe['volume'] > dataframe['volvar'] * 0.5) & # Relaxed volume
(dataframe['adx'] > 21), # Trend strength
'enter_long'
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe.loc[
(
(dataframe['slowk'] > 65) | (dataframe['slowd'] > 65) | # Relaxed STOCH
(dataframe['rsi7'] > 70) # Overbought
) &
(dataframe['close'] < dataframe['ema20c']) & # Trend reversal
(self.crossover(dataframe['macdsignal'], dataframe['macd'])) & # Custom crossover
(dataframe['macd'] < 0), # Downtrend
'exit_long'
] = 1
return dataframe
def custom_stoploss(self, pair: str, trade: Trade, current_time: datetime, current_rate: float, current_profit: float, after_fill: bool, **kwargs) -> Optional[float]:
atr = kwargs.get('metadata', {}).get('latest_atr', 0.01 * current_rate)
adx = kwargs.get('metadata', {}).get('latest_adx', 0)
atr_percent = atr / current_rate
profit_threshold = float(self.profit_threshold_multiplier.value) * atr_percent
trailing_stop_distance = float(self.trailing_stop_multiplier.value) * atr_percent
# Ensure both datetimes are timezone-aware
if trade.open_date.tzinfo is None:
trade_open_date = trade.open_date.replace(tzinfo=timezone.utc)
else:
trade_open_date = trade.open_date
trade_duration = (current_time - trade_open_date).total_seconds() / 3600
# 动态调整
if trade_duration < 3: # 3小时内放宽
profit_threshold *= 1.5 # 提高触发门槛
trailing_stop_distance *= 1.5 # 放宽止损距离
if adx > 35: # 强趋势
trailing_stop_distance *= 0.5 # 紧跟趋势
elif adx < 20: # 震荡市场
trailing_stop_distance *= 2.0 # 放宽止损
# ATR 追踪止损
if adx > 35 and after_fill and current_profit > profit_threshold:
return -trailing_stop_distance
# 固定止损
elif trade_duration > 1.5 or adx < 20 or current_profit < -0.015: # 1.5小时,震荡,亏损>1.5%
return float(self.stoploss)
return -0.05 # 默认止损收紧
@staticmethod
def hyperopt_loss_function(results: DataFrame, trade_count: int, min_date: datetime, max_date: datetime, config: Dict, processed: Dict[str, DataFrame], *args, **kwargs) -> float:
total_profit = results['profit_abs'].sum()
win_rate = len(results[results['profit_abs'] > 0]) / trade_count if trade_count > 0 else 0
avg_duration = results['trade_duration'].mean() / 60 # 分钟
loss = -total_profit * win_rate * (1 / (avg_duration + 1))
return loss
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
proposed_stake: float, min_stake: float, max_stake: float,
leverage: float, entry_tag: Optional[str], side: str,
**kwargs) -> float:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
if dataframe.empty:
return proposed_stake
atr = ta.ATR(dataframe, timeperiod=28).iloc[-1]
price_std = dataframe['close'].std()
combined_volatility = atr + price_std
base_stake = self.wallets.get_total_stake_amount() * 0.0333 # 3.33% risk
base_stake = min(base_stake, 50.0) # Cap at 50 USDT
risk_factor = 1.0
if combined_volatility > current_rate * 0.03: # High volatility
risk_factor = 0.3 if pair in ['SOL/USDT', 'OKB/USDT'] else 0.5
elif combined_volatility < current_rate * 0.01: # Low volatility
risk_factor = 1.2 if pair in ['BTC/USDT', 'ETH/USDT'] else 1.0
return base_stake * risk_factor

View File

@ -15,7 +15,7 @@ class FreqaiPrimer(IStrategy):
15: 0.007,
60: 0
}
stoploss = -0.263
stoploss = -0.085
trailing_stop = True
trailing_stop_positive = 0.324
trailing_stop_positive_offset = 0.411
@ -31,7 +31,7 @@ class FreqaiPrimer(IStrategy):
roi_0 = DecimalParameter(low=0.01, high=0.2, default=0.135, space="roi", optimize=True, load=True)
roi_15 = DecimalParameter(low=0.005, high=0.1, default=0.052, space="roi", optimize=True, load=True)
roi_30 = DecimalParameter(low=0.001, high=0.05, default=0.007, space="roi", optimize=True, load=True)
stoploss_param = DecimalParameter(low=-0.35, high=-0.1, default=-0.263, space="stoploss", optimize=True, load=True)
stoploss_param = DecimalParameter(low=-0.15, high=-0.05, default=-0.075, space="stoploss", optimize=True, load=True)
trailing_stop_positive_param = DecimalParameter(low=0.1, high=0.5, default=0.324, space="trailing", optimize=True, load=True)
trailing_stop_positive_offset_param = DecimalParameter(low=0.2, high=0.6, default=0.411, space="trailing", optimize=True, load=True)
@ -64,7 +64,26 @@ class FreqaiPrimer(IStrategy):
"&-roi_0": {"&-roi_0": {"color": "orange"}},
"do_predict": {"do_predict": {"color": "brown"}},
},
}
},
protections = [
{
"name": "CooldownPeriod",
"stop_duration": 60, # 单位:分钟
"trade_limit": 1,
"only_per_pair": False
},
{
"name": "StoplossGuard",
"lookback_period": 60, # 查看过去 60 分钟内
"trade_limit": 2, # 最多允许触发 2 次止损
"stop_duration": 30 # 如果超过限制,暂停交易 30 分钟
},
{
"name": "LowProfit",
"lookback_period": 20,
"required_profit": 0.01 # 要求至少盈利 1%
}
]
def feature_engineering_expand_all(self, dataframe: DataFrame, period: int, metadata: dict, **kwargs) -> DataFrame:
dataframe["%-rsi-period"] = ta.RSI(dataframe, timeperiod=period)
@ -277,3 +296,12 @@ class FreqaiPrimer(IStrategy):
except Exception as e:
logger.error(f"确认 {pair} 交易时出错:{str(e)}")
return False
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime, current_rate: float, **kwargs) -> float:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1]
# 如果市场波动率高,收紧止损
if last_candle["%-volatility"] > 0.05:
return -0.05 # 更严格止损
return -0.08 # 默认止损

View File

@ -37,7 +37,8 @@ hyperopt_config="${STRATEGY_NAME%.py}.json"
echo "docker-compose run --rm freqtrade backtesting \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--freqaimodel LightGBMRegressor \
--freqaimodel LightGBMRegressorMultiTarget \
--enable-protections \
--config /freqtrade/config_examples/$CONFIG_FILE \
--strategy-path /freqtrade/templates \
--strategy $STRATEGY_NAME \
@ -47,7 +48,8 @@ echo "docker-compose run --rm freqtrade backtesting \
docker-compose run --rm freqtrade backtesting \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--freqaimodel LightGBMRegressor \
--freqaimodel LightGBMRegressorMultiTarget \
--enable-protections \
--config /freqtrade/config_examples/$CONFIG_FILE \
--strategy-path /freqtrade/templates \
--strategy $STRATEGY_NAME \

View File

@ -73,7 +73,7 @@ GIT_COMMIT_SHORT=$(git rev-parse HEAD | cut -c 1-8)
echo "docker-compose run -d --rm --name freqtrade-dryrun-${GIT_COMMIT_SHORT} -p 8080:8080 freqtrade trade \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite \
--freqaimodel LightGBMRegressor \
--freqaimodel LightGBMRegressorMultiTarget \
--config /freqtrade/config_examples/$CONFIG_FILE \
--strategy $STRATEGY_NAME \
--fee 0.0008 \
@ -82,7 +82,7 @@ echo "docker-compose run -d --rm --name freqtrade-dryrun-${GIT_COMMIT_SHORT} -p
docker-compose run -d --rm --name freqtrade-dryrun-${GIT_COMMIT_SHORT} -p 8080:8080 freqtrade trade \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite \
--freqaimodel LightGBMRegressor \
--freqaimodel LightGBMRegressorMultiTarget \
--config /freqtrade/config_examples/$CONFIG_FILE \
--strategy $STRATEGY_NAME \
--fee 0.0008 \

View File

@ -34,7 +34,8 @@ rm -fr ./user_data/dryrun_results/*
#docker-compose -f docker-compose_backtest.yml run --rm freqtrade >output.log 2>&1
echo "docker-compose run --rm freqtrade hyperopt \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--freqaimodel LightGBMRegressor \
--freqaimodel LightGBMRegressorMultiTarget \
--enable-protections \
--strategy $STRATEGY_NAME \
--config /freqtrade/config_examples/$CONFIG_FILE \
--strategy-path /freqtrade/templates \
@ -45,7 +46,8 @@ echo "docker-compose run --rm freqtrade hyperopt \
--fee 0.0016"
docker-compose run --rm freqtrade hyperopt \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--freqaimodel LightGBMRegressor \
--freqaimodel LightoGBMRegressorMultiTarget \
--enable-protections \
--strategy $STRATEGY_NAME \
--config /freqtrade/config_examples/$CONFIG_FILE \
--strategy-path /freqtrade/templates \

View File

@ -73,7 +73,7 @@ GIT_COMMIT_SHORT=$(git rev-parse HEAD | cut -c 1-8)
echo "docker-compose run -d --rm --name freqtrade-dryrun-${GIT_COMMIT_SHORT} -p 8080:8080 freqtrade trade \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite \
--freqaimodel LightGBMRegressor \
--freqaimodel LightGBMRegressorMultiTarget \
--fee 0.0008
--config /freqtrade/config_examples/$CONFIG_FILE \
--strategy $STRATEGY_NAME \
@ -82,7 +82,7 @@ echo "docker-compose run -d --rm --name freqtrade-dryrun-${GIT_COMMIT_SHORT} -p
docker-compose run -d --rm --name freqtrade-dryrun-${GIT_COMMIT_SHORT} -p 8080:8080 freqtrade trade \
--logfile /freqtrade/user_data/logs/freqtrade.log \
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite \
--freqaimodel LightGBMRegressor \
--freqaimodel LightGBMRegressorMultiTarget \
--fee 0.0008 \
--config /freqtrade/config_examples/$CONFIG_FILE \
--strategy $STRATEGY_NAME \