添加新的策略
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"""
|
||||
SOL15mStrategy - 基于15m时间框架的SOL/USDT期货策略
|
||||
|
||||
核心逻辑:
|
||||
- 15m EMA26/EMA52 交叉做多做空
|
||||
- RSI过滤:做多要求RSI<65,做空要求RSI>35(避免超买超卖区入场)
|
||||
- 使用 trailing_stop 让利润奔跑
|
||||
- 宽止损(2%),给交易足够呼吸空间
|
||||
|
||||
使用命令:
|
||||
freqtrade backtesting -c ./user_data/Chan/config/Local_Test.json --strategy SOL15mStrategy --strategy-path ./user_data/Chan/strategies --timerange=20250301-
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
import talib.abstract as ta
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.strategy import IStrategy
|
||||
|
||||
|
||||
class SOL15mStrategy(IStrategy):
|
||||
INTERFACE_VERSION: int = 3
|
||||
|
||||
# === 基础配置 ===
|
||||
timeframe = "15m"
|
||||
can_short = True
|
||||
startup_candle_count: int = 200
|
||||
|
||||
# 止损 2%
|
||||
stoploss = -0.02
|
||||
use_custom_stoploss = False
|
||||
|
||||
# trailing stop: 利润达到1.5%后开始追踪,回撤0.5%止盈
|
||||
trailing_stop = True
|
||||
trailing_stop_positive = 0.005
|
||||
trailing_stop_positive_offset = 0.015
|
||||
trailing_only_offset_is_reached = True
|
||||
|
||||
# ROI: 阶梯式止盈
|
||||
minimal_roi = {
|
||||
"0": 0.04, # 4%直接止盈
|
||||
"60": 0.025, # 60分钟后 2.5%
|
||||
"180": 0.015, # 3小时后 1.5%
|
||||
"480": 0.005, # 8小时后 0.5%
|
||||
"720": 0, # 12小时后保本退出
|
||||
}
|
||||
|
||||
order_types = {
|
||||
"entry": "market",
|
||||
"exit": "market",
|
||||
"stoploss": "market",
|
||||
"stoploss_on_exchange": False,
|
||||
}
|
||||
|
||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
# EMA
|
||||
dataframe["ema26"] = ta.EMA(dataframe, timeperiod=26)
|
||||
dataframe["ema52"] = ta.EMA(dataframe, timeperiod=52)
|
||||
dataframe["ema100"] = ta.EMA(dataframe, timeperiod=100)
|
||||
|
||||
# RSI
|
||||
dataframe["rsi"] = ta.RSI(dataframe, timeperiod=14)
|
||||
|
||||
# MACD
|
||||
macd = ta.MACD(dataframe, fastperiod=12, slowperiod=26, signalperiod=9)
|
||||
dataframe["macd"] = macd["macd"]
|
||||
dataframe["macdsignal"] = macd["macdsignal"]
|
||||
|
||||
# EMA26上穿EMA52
|
||||
dataframe["ema26_cross_up_52"] = (
|
||||
(dataframe["ema26"] > dataframe["ema52"])
|
||||
& (dataframe["ema26"].shift(1) <= dataframe["ema52"].shift(1))
|
||||
)
|
||||
|
||||
# EMA26下穿EMA52
|
||||
dataframe["ema26_cross_dn_52"] = (
|
||||
(dataframe["ema26"] < dataframe["ema52"])
|
||||
& (dataframe["ema26"].shift(1) >= dataframe["ema52"].shift(1))
|
||||
)
|
||||
|
||||
# MACD死叉
|
||||
dataframe["macd_cross_dn"] = (
|
||||
(dataframe["macd"] < dataframe["macdsignal"])
|
||||
& (dataframe["macd"].shift(1) >= dataframe["macdsignal"].shift(1))
|
||||
)
|
||||
|
||||
return dataframe
|
||||
|
||||
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
# 做多: EMA26上穿EMA52 + RSI < 65 (不在超买区)
|
||||
dataframe.loc[
|
||||
(dataframe["ema26_cross_up_52"])
|
||||
& (dataframe["rsi"] < 65),
|
||||
["enter_long", "enter_tag"],
|
||||
] = (1, "ema26x52_long")
|
||||
|
||||
# 做空: EMA26下穿EMA52 + RSI > 35 (不在超卖区)
|
||||
dataframe.loc[
|
||||
(dataframe["ema26_cross_dn_52"])
|
||||
& (dataframe["rsi"] > 35),
|
||||
["enter_short", "enter_tag"],
|
||||
] = (1, "ema26x52_short")
|
||||
|
||||
return dataframe
|
||||
|
||||
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
# 不使用信号退出,完全由 trailing_stop + ROI + stoploss 控制
|
||||
return dataframe
|
||||
|
||||
def leverage(
|
||||
self,
|
||||
pair: str,
|
||||
current_time: datetime,
|
||||
current_rate: float,
|
||||
proposed_leverage: float,
|
||||
max_leverage: float,
|
||||
entry_tag: Optional[str],
|
||||
side: str,
|
||||
**kwargs,
|
||||
) -> float:
|
||||
return 1.0
|
||||
Reference in New Issue
Block a user