Timeframe
1m
Direction
Long Only
Stoploss
-30.0%
Trailing Stop
No
ROI
0m: 2.5%, 20m: 2.0%, 40m: 1.5%
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 NineSecondSniperV9(IStrategy):
"""
9秒狙击手策略 V9 - 平衡版
V9 思路:
1. 保持高交易频率(符合 9 秒狙击手思想)
2. 移除固定止损(完全依赖 SAR)
3. 调整入场条件,提高信号质量
"""
timeframe = '1m'
max_open_trades = 2
stake_amount = 100
startup_candle_count = 100
# 止盈配置
minimal_roi = {
"0": 0.025, # 2.5% 初始止盈
"20": 0.02, # 20分钟降到 2%
"40": 0.015, # 40分钟降到 1.5%
}
# V9 核心:无固定止损,完全依赖 SAR
stoploss = -0.30 # -30% 极端保险
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': 2.0,
'SOL/USDT:USDT': 1.5,
'XRP/USDT:USDT': 1.0,
'DOGE/USDT:USDT': 1.0
}
def informative_pairs(self) -> list:
return []
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
df = dataframe.copy()
# ========== 核心:SAR 指标 ==========
df['sar'] = ta.SAR(df['high'].values, df['low'].values,
acceleration=0.02, maximum=0.2)
# SAR 当前位置
df['above_sar'] = df['close'] > df['sar']
# SAR 转向检测:从下方突破到上方
df['sar_reversal_up'] = df['above_sar'] & (df['above_sar'].shift(1) == False)
# ========== 核心: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.0005
# ========== 辅助: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)
# ========== 辅助:成交量和 ATR ==========
df['volume_sma'] = ta.SMA(df['volume'].values, timeperiod=20)
df['volume_ratio'] = df['volume'] / df['volume_sma']
df['atr'] = ta.ATR(df['high'].values, df['low'].values, df['close'].values, timeperiod=14)
df['atr_ratio'] = df['atr'] / df['close']
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:
base_leverage *= 0.5
elif current_profit < -0.05:
base_leverage *= 0.5
return min(base_leverage, 2.0)
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
# ========== V9:平衡入场条件 ==========
entry_conditions = (
# 1. SAR 转向上(主信号)
df['sar_reversal_up'] &
# 2. 9秒动向上(确认)
df['momentum_9sec_up'] &
# 3. EMA 趋势向上(辅助)
df['ema_trend_up'] &
# 4. RSI 避免极端(30-70)
(df['rsi'] > 30) & (df['rsi'] < 70) &
# 5. 成交量(1.1x)
(df['volume_ratio'] > 1.1) &
# 6. ATR 波动率过滤(< 0.04)
(df['atr_ratio'] < 0.04)
)
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
# ========== V9:SAR 主导出场 ==========
exit_conditions = (
# 1. SAR 压制(趋势反转 - 主信号)
(df['close'] < df['sar']) |
# 2. EMA 死叉(趋势反转)
(df['ema_9'] < df['ema_21']) |
# 3. RSI 超买(> 75)
(df['rsi'] > 75) |
# 4. 9秒动量向下(< -0.002)
(df['price_change_9sec'] < -0.002)
)
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
return False