BTC 1H 合约多空 v5 — 唐奇安通道突破
Timeframe
1h
Direction
Long & Short
Stoploss
-2.0%
Trailing Stop
Yes
ROI
0m: 5.0%, 240m: 3.0%, 720m: 1.0%, 1440m: 0.0%
Interface Version
3
Startup Candles
60
Indicators
5
# BTC 1H Long/Short Futures Strategy v5
# Donchian breakout + Volume confirmation + ATR-based stop
# Works in trending markets, auto-switches direction
from pandas import DataFrame
import talib.abstract as ta
from freqtrade.strategy import IStrategy
class Btc1hDualStrategy(IStrategy):
"""
BTC 1H 合约多空 v5 — 唐奇安通道突破
做多: 价格突破20周期高点 + 放量 + EMA50向上
做空: 价格跌破20周期低点 + 放量 + EMA50向下
风控: ATR倍数止损 + 移动止损
"""
INTERFACE_VERSION = 3
timeframe = '1h'
can_short = True
stoploss = -0.02
trailing_stop = True
trailing_stop_positive = 0.015
trailing_stop_positive_offset = 0.02
trailing_only_offset_is_reached = True
minimal_roi = {"0": 0.05, "240": 0.03, "720": 0.01, "1440": 0}
max_open_trades = 3
startup_candle_count = 60
process_only_new_candles = True
use_exit_signal = False # ROI handles profit-taking, trailing protects gains
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# Donchian Channel
dataframe['dc_upper'] = dataframe['high'].rolling(20).max().shift(1)
dataframe['dc_lower'] = dataframe['low'].rolling(20).min().shift(1)
dataframe['dc_mid'] = (dataframe['dc_upper'] + dataframe['dc_lower']) / 2
# EMA
dataframe['ema50'] = ta.EMA(dataframe, timeperiod=50)
# Volume
dataframe['volume_sma'] = ta.SMA(dataframe['volume'], timeperiod=20)
dataframe['volume_ratio'] = dataframe['volume'] / dataframe['volume_sma']
# ATR
dataframe['atr'] = ta.ATR(dataframe, timeperiod=14)
# ADX for trend strength
dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# === 做多: 突破高点 + ADX强趋势 + 放量 ===
dataframe.loc[
(
(dataframe['close'] > dataframe['dc_upper']) &
(dataframe['adx'] > 25) &
(dataframe['volume_ratio'] > 1.3) &
(dataframe['volume'] > 0)
),
['enter_long', 'enter_tag']
] = (1, 'breakout_long')
# === 做空: 跌破低点 + ADX强趋势 + 放量 ===
dataframe.loc[
(
(dataframe['close'] < dataframe['dc_lower']) &
(dataframe['adx'] > 25) &
(dataframe['volume_ratio'] > 1.3) &
(dataframe['volume'] > 0)
),
['enter_short', 'enter_tag']
] = (1, 'breakout_short')
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 回到通道中轨 = 突破失败,退出
dataframe.loc[
(dataframe['close'] < dataframe['dc_mid']),
['exit_long', 'exit_tag']
] = (1, 'dc_mid_exit')
dataframe.loc[
(dataframe['close'] > dataframe['dc_mid']),
['exit_short', 'exit_tag']
] = (1, 'dc_mid_exit')
return dataframe