高频剥头皮策略 - 时间周期: 1m - 信号: EMA + VWAP + 成交量激增 - 止盈止损: 小幅快速止盈,极紧止损
Timeframe
1m
Direction
Long Only
Stoploss
-0.5%
Trailing Stop
No
ROI
0m: 0.2%
Interface Version
3
Startup Candles
N/A
Indicators
4
freqtrade/freqtrade-strategies
Strategy 003 author@: Gerald Lonlas github@: https://github.com/freqtrade/freqtrade-strategies
# Filename: ScalpingStrategy.py
# Author: Grok 4
# Description: A scalping strategy for Freqtrade on Binance futures, with hyperopt support and dynamic leverage.
# Supports 1m timeframe, RSI and EMA crossover for entries/exits.
# Dynamic leverage: Adjusts based on volatility (ATR) - higher volatility, lower leverage to reduce risk.
from freqtrade.strategy import IStrategy, informative
from freqtrade.strategy.parameters import IntParameter, DecimalParameter
from pandas import DataFrame
import talib.abstract as ta
import freqtrade.vendor.qtpylib.indicators as qtpylib
class ScalperStrategy(IStrategy):
"""
高频剥头皮策略
- 时间周期: 1m
- 信号: EMA + VWAP + 成交量激增
- 止盈止损: 小幅快速止盈,极紧止损
"""
# Strategy metadata
INTERFACE_VERSION = 3
timeframe = '1m' # High frequency: 1 minute candles
minimal_roi = {"0": 0.002} # Minimal ROI: 0.2% to exit
stoploss = -0.005 # Fixed stoploss: -0.5%
trailing_stop = False # Optional: Can enable for better exits
can_short: bool = True
# Hyperopt parameters - These will be optimized
rsi_period = IntParameter(5, 20, default=14, space='buy')
rsi_buy_threshold = IntParameter(20, 40, default=30, space='buy')
rsi_sell_threshold = IntParameter(60, 80, default=70, space='sell')
ema_fast_period = IntParameter(3, 10, default=5, space='buy')
ema_slow_period = IntParameter(10, 30, default=15, space='sell')
max_leverage = DecimalParameter(5.0, 20.0, default=10.0, space='buy') # Max leverage for dynamic adjustment
# Remove duplicate custom_leverage method (keeping only the leverage method below)
def informative_pairs(self):
# No additional informative pairs needed
return []
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Calculate indicators
dataframe['rsi'] = ta.RSI(dataframe, timeperiod=self.rsi_period.value)
dataframe['ema_fast'] = ta.EMA(dataframe, timeperiod=self.ema_fast_period.value)
dataframe['ema_slow'] = ta.EMA(dataframe, timeperiod=self.ema_slow_period.value)
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14) # For dynamic leverage
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Long entry: RSI oversold in an uptrend (EMA bullish) - wait for RSI bounce
dataframe.loc[
(dataframe['rsi'] < self.rsi_buy_threshold.value) &
(dataframe['ema_fast'] > dataframe['ema_slow']), # Uptrend confirmed
'enter_long'] = 1
# Short entry: RSI overbought in a downtrend (EMA bearish) - wait for RSI drop
dataframe.loc[
(dataframe['rsi'] > self.rsi_sell_threshold.value) &
(dataframe['ema_fast'] < dataframe['ema_slow']), # Downtrend confirmed
'enter_short'] = 1
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Long exit: RSI overbought (or ROI/stoploss handles)
dataframe.loc[
(dataframe['rsi'] > self.rsi_sell_threshold.value),
'exit_long'] = 1
# Short exit: RSI oversold
dataframe.loc[
(dataframe['rsi'] < self.rsi_buy_threshold.value),
'exit_short'] = 1
return dataframe
# 动态杠杆:根据波动率(ATR)和止损幅度自适应调整
def leverage(self, pair, current_time, current_rate, proposed_leverage, max_leverage, entry_tag, side, **kwargs) -> float:
"""
Dynamically adjust leverage based on volatility (ATR) and stoploss.
Higher volatility -> lower leverage to reduce risk.
"""
try:
# Get the latest dataframe for ATR-based adjustment
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
if len(dataframe) > 0 and 'atr' in dataframe.columns:
atr = dataframe['atr'].iloc[-1]
if atr > 0:
# Normalize ATR as percentage
normalized_atr = atr / current_rate
# Reduce leverage when volatility is high
volatility_factor = max(0.5, 1 - min(normalized_atr * 50, 0.5))
else:
volatility_factor = 1.0
else:
volatility_factor = 1.0
# Also consider stoploss for leverage calculation
sl = abs(float(self.stoploss)) if getattr(self, 'stoploss', None) is not None else 0.005
sl_factor = 0.05 / sl if sl > 0 else 1.0
# Combine both factors
base_leverage = min(self.max_leverage.value, sl_factor) * volatility_factor
final_leverage = max(1.0, min(float(base_leverage), float(max_leverage)))
return final_leverage
except Exception:
# Fallback to safe leverage
return max(1.0, min(5.0, float(max_leverage)))