9秒狙击手策略 V6 - 移除止损版
Timeframe
1m
Direction
Long Only
Stoploss
-20.0%
Trailing Stop
No
ROI
0m: 4.0%, 30m: 3.0%, 60m: 2.0%
Interface Version
N/A
Startup Candles
100
Indicators
5
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import pandas as pd
import talib.abstract as ta
from datetime import datetime
import numpy as np
class NineSecondSniperV6(IStrategy):
"""
9秒狙击手策略 V6 - 移除止损版
V6 核心改进:
1. 移除固定止损 - SAR 压制作为主要出场信号
2. 提高 ROI 止盈 - 3%-5% 给趋势更多空间
3. 优化 SAR 信号 - 添加波动率和 ATR 过滤
4. 严格入场 - 只在高质量 SAR 转向时入场
"""
timeframe = '1m'
max_open_trades = 2
stake_amount = 100
startup_candle_count = 100
# V6 核心:提高 ROI 止盈,移除止损
minimal_roi = {
"0": 0.04, # 4% 初始止盈 - 大幅提高
"30": 0.03, # 30分钟降到 3%
"60": 0.02, # 60分钟降到 2%
}
# V6 核心:移除固定止损,依赖 SAR 压制
stoploss = -0.20 # -20% 作为极端保险
trailing_stop = False
order_types = {
'entry': 'market',
'exit': 'market',
'stoploss': 'market',
'stoploss_on_exchange': False,
'entry_pricing': 'same',
'exit_pricing': 'same'
}
unfilledtimeout = {
'entry': 10,
'exit': 10,
'unit': 'seconds'
}
# 杠杆配置
base_leverage_config = {
'BTC/USDT:USDT': 2.0,
'ETH/USDT:USDT': 1.5,
'SOL/USDT:USDT': 1.5,
'XRP/USDT:USDT': 1.0,
'DOGE/USDT:USDT': 1.0
}
# 价格缓冲区
price_buffer_size = 9
price_buffers = {}
def informative_pairs(self) -> list:
return []
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe.copy()
pair = metadata['pair']
# ========== 核心:SAR 指标 ==========
df['sar'] = ta.SAR(df['high'].values, df['low'].values,
acceleration=0.015, maximum=0.25)
# SAR 当前位置
df['above_sar'] = df['close'] > df['sar']
# SAR 转向检测:从下方突破到上方
df['sar_reversal_up'] = df['above_sar'] & (df['above_sar'].shift(1) == False)
# ========== ATR 波动率指标(过滤假突破)==========
df['atr'] = ta.ATR(df['high'].values, df['low'].values, df['close'].values, timeperiod=14)
df['atr_ratio'] = df['atr'] / df['close']
# ========== 辅助:EMA 趋势确认 ==========
df['ema_9'] = ta.EMA(df['close'].values, timeperiod=9)
df['ema_21'] = ta.EMA(df['close'].values, timeperiod=21)
df['ema_trend_up'] = df['ema_9'] > df['ema_21']
# ========== 辅助:RSI(避免超买)==========
df['rsi'] = ta.RSI(df['close'].values, timeperiod=14)
# ========== 核心:9秒动能 ==========
df['price_9sec_ago'] = df['close'].shift(9)
df['price_change_9sec'] = (df['close'] - df['price_9sec_ago']) / df['price_9sec_ago']
df['momentum_9sec_up'] = df['price_change_9sec'] > 0.002 # 提高阈值
# ========== 成交量确认 ==========
df['volume_sma'] = ta.SMA(df['volume'].values, timeperiod=20)
df['volume_ratio'] = df['volume'] / df['volume_sma']
# ========== 价格缓冲区 ==========
if pair not in self.price_buffers:
self.price_buffers[pair] = np.zeros(self.price_buffer_size)
buffer = self.price_buffers[pair]
for i in range(len(df)):
if i >= self.price_buffer_size:
buffer[:-1] = buffer[1:]
buffer[-1] = df['close'].iloc[i]
df['buffer_momentum'] = 0.0
if len(buffer) >= self.price_buffer_size:
df['buffer_momentum'] = (buffer[-1] - buffer[0]) / buffer[0]
return df
def leverage(self, pair: str, current_time: datetime, current_rate: float,
current_profit: float = 0.0, min_stops: float = 0.0,
max_stops: float = 0.0, current_time_rows: DataFrame = None,
**kwargs) -> float:
base_leverage = self.base_leverage_config.get(pair, 1.0)
# 保守策略
if current_profit > 0.02: # 盈利 > 2%
base_leverage *= 0.5
elif current_profit < -0.05: # 亏损 > 5%
base_leverage *= 0.5
return min(base_leverage, 2.0) # 最大杠杆 2x
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe.copy()
df['enter_long'] = 0
if len(df) < self.startup_candle_count:
return df
# ========== V6 核心:更严格的入场条件 ==========
entry_conditions = (
# 1. SAR 转向上(主信号)
df['sar_reversal_up'] &
# 2. 9秒动向上(确认)
df['momentum_9sec_up'] &
# 3. EMA 趋势向上(辅助)
df['ema_trend_up'] &
# 4. RSI 不超买(有空间)
(df['rsi'] > 35) & (df['rsi'] < 60) &
# 5. 成交量放大(真突破)
(df['volume_ratio'] > 1.5) &
# 6. 缓冲区动量确认
(df['buffer_momentum'] > 0.0005) &
# 7. ATR 波动率不过高(过滤极端波动)
(df['atr_ratio'] < 0.03)
)
df.loc[entry_conditions, 'enter_long'] = 1
return df
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe.copy()
df['exit'] = 0
# ========== V6 核心:SAR 压制是主要出场信号 ==========
exit_conditions = (
# 1. SAR 压制(趋势反转 - 主信号)
(df['close'] < df['sar']) |
# 2. EMA 死叉(趋势反转)
(df['ema_9'] < df['ema_21']) |
# 3. RSI 超买(短期顶部)
(df['rsi'] > 75)
)
df.loc[exit_conditions, 'exit'] = 1
return df
def custom_exit(self, pair: str, current_time: datetime, current_rate: float,
current_profit: float, **kwargs) -> bool:
# 只作为极端情况保险
# 紧急止损 - 只有大幅亏损才退出
if current_profit < -0.20: # -20% 紧急
return True
# 快速止盈
if current_profit > 0.10: # 10% 强制止盈
return True
return False