not work NostalgiaV8

This commit is contained in:
zhangkun9038@dingtalk.com 2025-05-07 16:56:25 +08:00
parent 17199e9a44
commit 62b9fed359
14 changed files with 987 additions and 9 deletions

1
.gitignore vendored
View File

@ -1,5 +1,4 @@
# Freqtrade rules
config*.json
*.sqlite
*.sqlite-shm
*.sqlite-wal

View File

@ -0,0 +1,59 @@
{
"exchange": {
"name": "okx",
"key": "your_api_key",
"secret": "your_api_secret",
"ccxt_config": {
"enableRateLimit": true,
"defaultType": "spot",
"rateLimit": 2000,
"timeout": 30000
},
"pair_whitelist": ["OKB/USDT", "SOL/USDT"]
},
"pairlists": [
{
"method": "StaticPairList"
}
],
"timeframe": "3m",
"strategy": "",
"order_types": {
"entry": "market",
"exit": "market",
"stoploss": "limit",
"stoploss_on_exchange": false
},
"order_time_in_force": {
"entry": "gtc",
"exit": "gtc"
},
"entry_pricing": {
"price_side": "other",
"use_order_book": false,
"price_last_balance": 0.0
},
"exit_pricing": {
"price_side": "other",
"use_order_book": false
},
"use_exit_signal": true,
"exit_profit_only": false,
"ignore_roi_if_entry_signal": false,
"stoploss": -0.05,
"minimal_roi": {
"0": 0.06,
"30": 0.04,
"60": 0.02,
"120": 0
},
"stake_currency": "USDT",
"stake_amount": 150,
"max_open_trades": 4,
"unfilledtimeout": {
"entry": 5,
"exit": 15,
"unit": "minutes"
},
"fee": 0.0008
}

View File

@ -0,0 +1,84 @@
{
"exchange": {
"name": "okx",
"key": "your_api_key",
"secret": "your_api_secret",
"ccxt_config": {
"enableRateLimit": true,
"defaultType": "spot",
"rateLimit": 2000,
"timeout": 30000
},
"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",
"stoploss": "limit",
"stoploss_on_exchange": false
},
"order_time_in_force": {
"entry": "gtc",
"exit": "gtc"
},
"entry_pricing": {
"price_side": "other",
"use_order_book": false,
"price_last_balance": 0.0
},
"exit_pricing": {
"price_side": "other",
"use_order_book": false
},
"use_exit_signal": true,
"exit_profit_only": false,
"ignore_roi_if_entry_signal": false,
"stoploss": -0.05,
"minimal_roi": {
"0": 0.06,
"30": 0.04,
"60": 0.02,
"120": 0
},
"stake_currency": "USDT",
"stake_amount": 150,
"max_open_trades": 4,
"unfilledtimeout": {
"entry": 5,
"exit": 15,
"unit": "minutes"
},
"fee": 0.0008
}

View File

@ -0,0 +1,127 @@
{
"$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,
"timeframe": "3m",
"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"
],
"pair_blacklist": []
},
"entry_pricing": {
"price_side": "other",
"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": "test175",
"freqaimodel": "XGBoostRegressor",
"model_path": "/freqtrade/user_data/models",
"save_backtesting_prediction": true,
"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,
"random_state": 42
},
"model_training_parameters": {
"n_estimators": 200,
"learning_rate": 0.05,
"max_depth": 6,
"subsample": 0.8,
"colsample_bytree": 0.8,
"reg_alpha": 0.1,
"reg_lambda": 1.0
},
},
"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"
},
"bot_name": "freqtrade",
"initial_state": "running",
"force_entry_enable": false,
"internals": {
"process_throttle_secs": 5,
"heartbeat_interval": 20,
"loglevel": "DEBUG"
}
}

View File

@ -30,12 +30,22 @@ services:
# Default command used when running `docker compose up`
# --freqaimodel XGBoostRegressor
command: >
trade
--logfile /freqtrade/user_data/logs/freqtrade.log
--db-url sqlite:////freqtrade/user_data/tradesv3.sqlite
--freqaimodel LightGBMRegressor
--config /freqtrade/config_examples/config_freqai.okx.json
--strategy FreqaiExampleStrategy
--strategy-path /freqtrade/templates
# command: >
# trade
# --logfile /freqtrade/user_data/logs/freqtrade.log
# --db-url sqlite:////freqtrade/user_data/tradesv3.sqlite
# --freqaimodel LightGBMRegressor
# --config /freqtrade/config_examples/config_freqai.okx.json
# --strategy FreqaiExampleStrategy
# --strategy-path /freqtrade/templates
command: >
backtesting
--logfile /freqtrade/user_data/logs/freqtrade.log
--config /freqtrade/config_examples/config_adsf.json
--strategy-path /freqtrade/templates
--freqaimodel LightGBMRegressor
--strategy NostalgiaForInfinityV8
--timerange 20250401-20250415
--fee 0.0008
--cache none

7
filter.py Normal file
View File

@ -0,0 +1,7 @@
with open('output.log', 'r') as input_file, open('output_filted.log', 'w') as output_file:
for line in input_file:
if "validation_0" in line:
if "[99]" in line:
output_file.write(line)
else:
output_file.write(line)

View File

@ -0,0 +1,248 @@
import numpy as np
import pandas as pd
pd.options.mode.chained_assignment = None
from pandas import DataFrame
from freqtrade.strategy import IStrategy
from freqtrade.strategy import IntParameter
import logging
from functools import reduce
import datetime
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
logger = logging.getLogger(__name__)
class NostalgiaForInfinityV8(IStrategy):
INTERFACE_VERSION = 3
minimal_roi = {
"0": 0.06,
"30": 0.04,
"60": 0.02,
"120": 0
}
stoploss = -0.05
use_custom_stoploss = True
trailing_stop = False
timeframe = '15m'
process_only_new_candles = True
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = False
startup_candle_count: int = 146
can_short = False
order_types = {
'entry': 'market',
'exit': 'market',
'stoploss': 'limit',
'stoploss_on_exchange': False
}
order_time_in_force = {
'entry': 'gtc',
'exit': 'gtc'
}
buy_rsi = IntParameter(low=20, high=60, default=50, space="buy", optimize=True)
sell_rsi = IntParameter(low=50, high=80, default=55, space="sell", optimize=True)
buy_volume_factor = IntParameter(low=1, high=5, default=2, space="buy", optimize=True)
freqai_info = {
"model": "XGBoostRegressor",
"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"]
},
"data_split_parameters": {
"test_size": 0.2,
"shuffle": False
},
"model_training_parameters": {
"n_estimators": 100,
"learning_rate": 0.1,
"num_leaves": 15,
"n_jobs": 4,
"verbosity": -1
}
}
plot_config = {
'main_plot': {
'ema6': {'color': 'blue'},
'ema24': {'color': 'red'},
'sma32': {'color': 'green'},
'sma64': {'color': 'purple'},
},
'subplots': {
"RSI": {'rsi': {'color': 'blue'}, 'buy_rsi_pred': {'color': 'orange'}}
}
}
def detect_pivot_low(self, series: pd.Series, left: int, right: int) -> pd.Series:
pivots = pd.Series(False, index=series.index)
for i in range(left, len(series) - right):
if (series[i] < series[i - left:i]).all() and (series[i] < series[i + 1:i + right + 1]).all():
pivots.iloc[i] = True
return pivots
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
if dataframe.empty:
logger.warning(f"Empty dataframe for {metadata['pair']}, skipping indicators")
return dataframe
informative = dataframe.copy()
# Momentum Indicators
informative['rsi'] = ta.RSI(informative, timeperiod=14)
# EMA and SMA
informative['ema6'] = ta.EMA(informative, timeperiod=6)
informative['ema24'] = ta.EMA(informative, timeperiod=24)
informative['sma32'] = ta.SMA(informative, timeperiod=32)
informative['sma64'] = ta.SMA(informative, timeperiod=64)
# ATR for dynamic stoploss
informative['atr'] = ta.ATR(informative, timeperiod=14)
# Volume
informative['volume_mean'] = informative['volume'].rolling(20).mean()
# RSI Divergence using custom pivot detection
informative['price_pivot_low'] = self.detect_pivot_low(informative['close'], left=3, right=3)
informative['rsi_pivot_low'] = self.detect_pivot_low(informative['rsi'], left=3, right=3)
informative['bullish_divergence'] = (informative['price_pivot_low'] == True) & (informative['rsi_pivot_low'] != True)
# 设置 FreqAI 标签
informative = self.set_freqai_targets(informative)
# 启动 FreqAI
try:
informative = self.freqai.start(informative, metadata, self)
logger.info(f"FreqAI features for {metadata['pair']}: {informative.columns.tolist()}")
except Exception as e:
logger.error(f"FreqAI failed for {metadata['pair']}: {str(e)}")
informative['buy_rsi_pred'] = informative['rsi']
informative['do_predict'] = 0
logger.info(f"Indicators for {metadata['pair']} at {informative['date'].iloc[-1]}: "
f"RSI={informative['rsi'].iloc[-1]:.2f}, "
f"buy_rsi_pred={informative['buy_rsi_pred'].iloc[-1] if 'buy_rsi_pred' in informative else 'N/A'}, "
f"do_predict={informative['do_predict'].iloc[-1]}, "
f"EMA6={informative['ema6'].iloc[-1]:.2f}, "
f"EMA24={informative['ema24'].iloc[-1]:.2f}, "
f"Bullish_Divergence={informative['bullish_divergence'].iloc[-1]}")
return informative
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
if dataframe.empty:
logger.warning(f"Empty dataframe for {metadata['pair']}, skipping indicators")
return dataframe
informative = dataframe.copy()
# Momentum Indicators
informative['rsi'] = ta.RSI(informative, timeperiod=14)
# EMA and SMA
informative['ema6'] = ta.EMA(informative, timeperiod=6)
informative['ema24'] = ta.EMA(informative, timeperiod=24)
informative['sma32'] = ta.SMA(informative, timeperiod=32)
informative['sma64'] = ta.SMA(informative, timeperiod=64)
# ATR for dynamic stoploss
informative['atr'] = ta.ATR(informative, timeperiod=14)
# Volume
informative['volume_mean'] = informative['volume'].rolling(20).mean()
# RSI Divergence using custom pivot detection
informative['price_pivot_low'] = self.detect_pivot_low(informative['close'], left=3, right=3)
informative['rsi_pivot_low'] = self.detect_pivot_low(informative['rsi'], left=3, right=3)
informative['bullish_divergence'] = (informative['price_pivot_low'] == True) & (informative['rsi_pivot_low'] != True)
# 设置 FreqAI 标签(✅ 已修复:删除了非法标记)
informative = self.set_freqai_targets(informative, metadata)
# 启动 FreqAI
try:
informative = self.freqai.start(informative, metadata, self)
logger.info(f"FreqAI features for {metadata['pair']}: {informative.columns.tolist()}")
except Exception as e:
logger.error(f"FreqAI failed for {metadata['pair']}: {str(e)}")
informative['buy_rsi_pred'] = informative['rsi']
informative['do_predict'] = 0
logger.info(f"Indicators for {metadata['pair']} at {informative['date'].iloc[-1]}: "
f"RSI={informative['rsi'].iloc[-1]:.2f}, "
f"buy_rsi_pred={informative['buy_rsi_pred'].iloc[-1] if 'buy_rsi_pred' in informative else 'N/A'}, "
f"do_predict={informative['do_predict'].iloc[-1]}, "
f"EMA6={informative['ema6'].iloc[-1]:.2f}, "
f"EMA24={informative['ema24'].iloc[-1]:.2f}, "
f"Bullish_Divergence={informative['bullish_divergence'].iloc[-1]}")
return informative
def set_freqai_targets(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
label_period = self.freqai_info["feature_parameters"]["label_period_candles"]
dataframe['label'] = (
(dataframe['close'].shift(-label_period) / dataframe['close']) - 1
) * 100 # 百分比变化
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
if dataframe.empty:
logger.warning(f"Empty dataframe for {metadata['pair']}, skipping exit trend")
return dataframe
exit_long_conditions = [
dataframe['rsi'] > self.sell_rsi.value,
dataframe['ema6'] < dataframe['ema24'],
dataframe['volume'] > 0
]
dataframe.loc[
reduce(lambda x, y: x & y, exit_long_conditions),
'exit_long'
] = 1
return dataframe
def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
if dataframe.empty:
logger.warning(f"Empty dataframe for {pair} in custom_stoploss")
return self.stoploss
last_candle = dataframe.iloc[-1].squeeze()
atr_stoploss = last_candle['close'] - 1.5 * last_candle['atr']
if atr_stoploss < current_rate:
return (atr_stoploss / current_rate) - 1
return self.stoploss
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
if dataframe.empty:
logger.warning(f"Empty dataframe for {metadata['pair']}, skipping entry trend")
return dataframe
# 示例买入条件:
conditions = [
dataframe['rsi'] < self.buy_rsi.value,
dataframe['ema6'] > dataframe['ema24'],
dataframe['volume'] > 0,
dataframe['bullish_divergence'] == True,
dataframe['do_predict'] == 1,
dataframe['rsi'] < dataframe['buy_rsi_pred']
]
dataframe.loc[
reduce(lambda x, y: x & y, conditions),
'enter_long'
] = 1
return dataframe

View File

@ -0,0 +1,69 @@
from functools import reduce
from pandas import DataFrame
from freqtrade.strategy import IStrategy
import talib.abstract as ta
from freqtrade.strategy.interface import IStrategy
class TrendFollowingStrategy(IStrategy):
INTERFACE_VERSION: int = 3
# ROI table:
minimal_roi = {"0": 0.15, "30": 0.1, "60": 0.05}
# minimal_roi = {"0": 1}
# Stoploss:
stoploss = -0.265
# Trailing stop:
trailing_stop = True
trailing_stop_positive = 0.05
trailing_stop_positive_offset = 0.1
trailing_only_offset_is_reached = False
can_short=False
timeframe = "5m"
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Calculate OBV
dataframe['obv'] = ta.OBV(dataframe['close'], dataframe['volume'])
# Add your trend following indicators here
dataframe['trend'] = dataframe['close'].ewm(span=20, adjust=False).mean()
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Add your trend following buy signals here
dataframe.loc[
(dataframe['close'] > dataframe['trend']) &
(dataframe['close'].shift(1) <= dataframe['trend'].shift(1)) &
(dataframe['obv'] > dataframe['obv'].shift(1)),
'enter_long'] = 1
# Add your trend following sell signals here
dataframe.loc[
(dataframe['close'] < dataframe['trend']) &
(dataframe['close'].shift(1) >= dataframe['trend'].shift(1)) &
(dataframe['obv'] < dataframe['obv'].shift(1)),
'enter_short'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Add your trend following exit signals for long positions here
dataframe.loc[
(dataframe['close'] < dataframe['trend']) &
(dataframe['close'].shift(1) >= dataframe['trend'].shift(1)) &
(dataframe['obv'] > dataframe['obv'].shift(1)),
'exit_long'] = 1
# Add your trend following exit signals for short positions here
dataframe.loc[
(dataframe['close'] > dataframe['trend']) &
(dataframe['close'].shift(1) <= dataframe['trend'].shift(1)) &
(dataframe['obv'] < dataframe['obv'].shift(1)),
'exit_short'] = 1
return dataframe

View File

@ -0,0 +1,85 @@
> 请把当前策略的运行逻辑进行梳理和讲解
我来为您梳理和讲解这个策略的运行逻辑。这是一个基于 FreqAI 的机器学习交易策略,主要使用 RSI 指标和机器学习模型进行交易决策。以下是策略的主要逻辑:
### 1. 策略配置
```python
minimal_roi = {
"0": 0.02,
"7": 0.01,
"13": 0.005,
"60": 0
}
stoploss = 0.0
trailing_stop = True
```
- 设置了静态的 ROI 目标
- 启用了追踪止损
### 2. 特征工程
策略通过多个方法构建特征:
- `feature_engineering_expand_all`: 计算 RSI 和布林带宽度
- `feature_engineering_expand_basic`: 计算价格变化百分比
- `feature_engineering_standard`: 计算波动率和时间特征
### 3. 目标变量设置
`set_freqai_targets` 方法中:
- 使用未来 `label_period_candles` 周期的 RSI 值作为目标变量
- 计算并标准化波动率特征
### 4. 指标计算
`populate_indicators` 方法中计算了多个技术指标:
- RSI
- 波动率
- TEMA三重指数移动平均线
- 布林带下轨
- 未来价格方向up_or_down
### 5. 机器学习模型
使用 LightGBM 回归模型:
```python
freqai_info = {
"model": "LightGBMRegressor",
"feature_parameters": {...},
"data_split_parameters": {...},
"model_training_parameters": {...}
}
```
- 模型预测买入和卖出的 RSI 值
- 使用 SOL/USDT 作为相关交易对
### 6. 入场逻辑
`populate_entry_trend` 方法中:
- 当实际 RSI 上穿预测的买入 RSI 时
- TEMA 指标向上
- 交易量大于 0
- 模型预测结果为 1
- 未来价格方向为上涨
### 7. 出场逻辑
`populate_exit_trend` 方法中:
- 当实际 RSI 上穿预测的卖出 RSI 时
- 或价格下跌超过 2%
- 或价格跌破布林带下轨
- 或持有时间超过 1 天
### 8. 交易确认
`confirm_trade_entry` 方法:
- 检查当前价格是否在可接受范围内
- 记录交易确认信息
### 策略特点
1. 机器学习驱动:使用 LightGBM 模型预测 RSI 值
2. 多特征融合:结合技术指标、波动率和时间特征
3. 风险控制:设置了 ROI 目标和追踪止损
4. 动态调整:通过机器学习模型动态调整交易信号
### 运行流程
1. 数据准备:获取历史数据,计算技术指标
2. 特征工程:构建机器学习特征
3. 模型训练:使用历史数据训练 LightGBM 模型
4. 信号生成:根据模型预测结果生成交易信号
5. 交易执行:根据入场和出场逻辑执行交易
6. 风险控制:根据 ROI 和止损规则管理仓位
这个策略结合了传统技术分析和机器学习方法,通过模型预测来增强交易信号的准确性,同时保持了严格的风险控制机制。

View File

@ -0,0 +1 @@

View File

130
freqtrade/templates/sma.py Normal file
View File

@ -0,0 +1,130 @@
# pragma pylint: disable=missing-docstring, invalid-name, pointless-string-statement
# flake8: noqa: F401
# isort: skip_file
# --- Do not remove these libs ---
from functools import reduce
import numpy as np # noqa
import pandas as pd # noqa
from pandas import DataFrame
from freqtrade.strategy import (
BooleanParameter,
CategoricalParameter,
DecimalParameter,
IStrategy,
IntParameter,
)
# --------------------------------
# Add your lib to import here
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
# This class is a sample. Feel free to customize it.
class FAdxSmaStrategy(IStrategy):
INTERFACE_VERSION = 3
timeframe = "1h"
# Minimal ROI designed for the strategy.
# This attribute will be overridden if the config file contains "minimal_roi".
minimal_roi = {"60": 0.075, "30": 0.1, "0": 0.05}
# minimal_roi = {"0": 1}
stoploss = -0.05
can_short = False
# Trailing stoploss
trailing_stop = False
# trailing_only_offset_is_reached = False
# trailing_stop_positive = 0.01
# trailing_stop_positive_offset = 0.0 # Disabled / not configured
# Run "populate_indicators()" only for new candle.
process_only_new_candles = True
# Number of candles the strategy requires before producing valid signals
startup_candle_count: int = 14
# Hyperoptable parameters
# Define the guards spaces
pos_entry_adx = DecimalParameter(15, 40, decimals=1, default=30.0, space="buy")
pos_exit_adx = DecimalParameter(15, 40, decimals=1, default=30.0, space="sell")
# Define the parameter spaces
adx_period = IntParameter(4, 24, default=14)
sma_short_period = IntParameter(4, 24, default=12)
sma_long_period = IntParameter(12, 175, default=48)
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Calculate all adx values
for val in self.adx_period.range:
dataframe[f"adx_{val}"] = ta.ADX(dataframe, timeperiod=val)
# Calculate all sma_short values
for val in self.sma_short_period.range:
dataframe[f"sma_short_{val}"] = ta.SMA(dataframe, timeperiod=val)
# Calculate all sma_long values
for val in self.sma_long_period.range:
dataframe[f"sma_long_{val}"] = ta.SMA(dataframe, timeperiod=val)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions_long = []
conditions_short = []
# GUARDS AND TRIGGERS
conditions_long.append(
dataframe[f"adx_{self.adx_period.value}"] > self.pos_entry_adx.value
)
conditions_short.append(
dataframe[f"adx_{self.adx_period.value}"] > self.pos_entry_adx.value
)
conditions_long.append(
qtpylib.crossed_above(
dataframe[f"sma_short_{self.sma_short_period.value}"],
dataframe[f"sma_long_{self.sma_long_period.value}"],
)
)
conditions_short.append(
qtpylib.crossed_below(
dataframe[f"sma_short_{self.sma_short_period.value}"],
dataframe[f"sma_long_{self.sma_long_period.value}"],
)
)
dataframe.loc[
reduce(lambda x, y: x & y, conditions_long),
"enter_long",
] = 1
dataframe.loc[
reduce(lambda x, y: x & y, conditions_short),
"enter_short",
] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
conditions_close = []
conditions_close.append(
dataframe[f"adx_{self.adx_period.value}"] < self.pos_entry_adx.value
)
dataframe.loc[
reduce(lambda x, y: x & y, conditions_close),
"exit_long",
] = 1
dataframe.loc[
reduce(lambda x, y: x & y, conditions_close),
"exit_short",
] = 1
return dataframe

30
run.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash
rm -rf user_data/models/*
rm -rf ./freqtrade/user_data/data/backtest_results/*
docker-compose run --rm freqtrade >output.log 2>&1
sed -i 's/\x1B\[[0-9;]*m//g' output.log
python3 filter.py
rm ./result/* -fr
mv ./user_data/backtest_results/* ./result/
cd ./result
# 查找当前目录下的所有 zip 文件
zip_files=(*.zip)
# 检查是否只有一个 zip 文件
if [ ${#zip_files[@]} -eq 1 ]; then
# 解压缩该 zip 文件到当前目录
unzip "${zip_files[0]}"
rm *.zip
rm *.feather
else
echo "当前目录下没有 zip 文件或者有多个 zip 文件,无法操作。"
fi
cd -
sed -i 's/\x1B\[[0-9;]*m//g' output.log
python3 filter.py
cp output_filted.log result/ -f

View File

@ -0,0 +1,129 @@
{
/* Single-line C-style comment */
"max_open_trades": 3,
/*
* Multi-line C-style comment
*/
"stake_currency": "BTC",
"stake_amount": 0.05,
"fiat_display_currency": "USD", // C++-style comment
"amount_reserve_percent": 0.05, // And more, tabs before this comment
"dry_run": false,
"timeframe": "5m",
"trailing_stop": false,
"trailing_stop_positive": 0.005,
"trailing_stop_positive_offset": 0.0051,
"trailing_only_offset_is_reached": false,
"minimal_roi": {
"40": 0.0,
"30": 0.01,
"20": 0.02,
"0": 0.04
},
"stoploss": -0.10,
"unfilledtimeout": {
"buy": 10,
"sell": 30, // Trailing comma should also be accepted now
},
"bid_strategy": {
"use_order_book": false,
"ask_last_balance": 0.0,
"order_book_top": 1,
"check_depth_of_market": {
"enabled": false,
"bids_to_ask_delta": 1
}
},
"ask_strategy": {
"use_order_book": false,
"order_book_min": 1,
"order_book_max": 9
},
"order_types": {
"buy": "limit",
"sell": "limit",
"stoploss": "market",
"stoploss_on_exchange": false,
"stoploss_on_exchange_interval": 60
},
"order_time_in_force": {
"buy": "gtc",
"sell": "gtc"
},
"pairlist": {
"method": "VolumePairList",
"config": {
"number_assets": 20,
"sort_key": "quoteVolume",
"precision_filter": false
}
},
"exchange": {
"name": "binance",
"sandbox": false,
"key": "your_exchange_key",
"secret": "your_exchange_secret",
"password": "",
"ccxt_config": {
"enableRateLimit": true
},
"ccxt_async_config": {
"enableRateLimit": false,
"rateLimit": 500,
"aiohttp_trust_env": false
},
"pair_whitelist": [
"ETH/BTC",
"LTC/BTC",
"ETC/BTC",
"DASH/BTC",
"ZEC/BTC",
"XLM/BTC",
"NXT/BTC",
"TRX/BTC",
"ADA/BTC",
"XMR/BTC"
],
"pair_blacklist": [
"DOGE/BTC"
],
"outdated_offset": 5,
"markets_refresh_interval": 60
},
"edge": {
"enabled": false,
"process_throttle_secs": 3600,
"calculate_since_number_of_days": 7,
"allowed_risk": 0.01,
"stoploss_range_min": -0.01,
"stoploss_range_max": -0.1,
"stoploss_range_step": -0.01,
"minimum_winrate": 0.60,
"minimum_expectancy": 0.20,
"min_trade_number": 10,
"max_trade_duration_minute": 1440,
"remove_pumps": false
},
"telegram": {
// We can now comment out some settings
// "enabled": true,
"enabled": false,
"token": "your_telegram_token",
"chat_id": "your_telegram_chat_id"
},
"api_server": {
"enabled": false,
"listen_ip_address": "127.0.0.1",
"listen_port": 8080,
"username": "freqtrader",
"password": "SuperSecurePassword"
},
"db_url": "sqlite:///tradesv3.sqlite",
"initial_state": "running",
"forcebuy_enable": false,
"internals": {
"process_throttle_secs": 5
},
"strategy": "DefaultStrategy",
"strategy_path": "user_data/strategies/"
}