first add

This commit is contained in:
zhangkun9038@dingtalk.com 2025-11-26 10:15:13 +08:00
parent 016f89e921
commit de1601d9ff
3 changed files with 140 additions and 41 deletions

View File

@ -0,0 +1,50 @@
{
"strategy": "StaticGrid",
"$schema": "https://schema.freqtrade.io/schema.json",
"trading_mode": "spot",
"margin_mode": "isolated",
"max_open_trades": 100,
"stake_currency": "USDT",
"stake_amount": "unlimited",
"tradable_balance_ratio": 1,
"process_only_new_candles": false,
"dry_run": true,
"timeframe": "4h",
"dry_run_wallet": 3500,
"cancel_open_orders_on_exit": true,
"max_entry_position_adjustment": -1,
"position_adjustment_enable": true,
"amount_reserve_percent": 0.05,
"unfilledtimeout": {
"entry": 5,
"exit": 15
},
"startup_candle_count": 1,
"exchange": {
"name": "okx",
"pair_whitelist": ["ETH/USDT"],
"ccxt_config": {
"enableRateLimit": true,
"rateLimit": 500
}
},
"entry_pricing": {
"price_side": "same",
"use_order_book": true,
"order_book_top": 1
},
"exit_pricing": {
"price_side": "other",
"use_order_book": true,
"order_book_top": 1
},
"pairlists": [{"method": "StaticPairList"}],
"bot_name": "StaticGrid-ETH",
"initial_state": "running",
"force_entry_enable": false,
"internals": {
"process_throttle_secs": 5,
"heartbeat_interval": 20,
"loglevel": "INFO"
}
}

View File

@ -17,44 +17,3 @@ class SmartBBGrid(IStrategy):
position_adjustment_enable = True
max_entry_position_adjustment = 1
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# ADX & DI
dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)
dataframe['plus_di'] = ta.PLUS_DI(dataframe, timeperiod=14)
dataframe['minus_di'] = ta.MINUS_DI(dataframe, timeperiod=14)
# 平衡布林带倍数:既要频繁,又要精准
dataframe['bb_mult'] = np.where(
dataframe['minus_di'] > dataframe['plus_di'],
1.8, # 熊市适度
1.6 # 牛市适度 ← 兼顾频率和准确率
)
# qtpylib 动态布林带
bollinger = qtpylib.bollinger_bands(
qtpylib.typical_price(dataframe),
window=20,
stds=dataframe['bb_mult']
)
dataframe['bb_lower'] = bollinger['lower']
dataframe['bb_upper'] = bollinger['upper']
dataframe['bb_mid'] = bollinger['mid']
return dataframe
# ← 这里结束
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 纯网格逻辑:只要价格接近下轨就买入
dataframe['enter_long'] = (
(dataframe['close'] <= dataframe['bb_lower'] * 1.02) & # 下轨附近 2% 范围
(dataframe['volume'] > 0)
)
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 纯网格逻辑:只要小幅反弹就卖出
dataframe['exit_long'] = (
(dataframe['close'] >= dataframe['bb_lower'] * 1.005) # 反弹 0.5% 就卖
)
return dataframe

View File

@ -0,0 +1,90 @@
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import numpy as np
class StaticGrid(IStrategy):
"""
纯静态网格策略 - ETH/USDT
价格范围1500 ~ 4800
网格间距50
网格数量66
"""
INTERFACE_VERSION = 3
timeframe = '4h'
can_short = False
# 基础配置
minimal_roi = {"0": 100}
stoploss = -0.99
startup_candle_count = 1
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = True
# 加仓配置
position_adjustment_enable = True
max_entry_position_adjustment = -1 # 无限加仓
# ========== 静态网格参数 ==========
GRID_LOW = 1500 # 网格下限
GRID_HIGH = 4800 # 网格上限
GRID_STEP = 50 # 网格间距
GRID_COUNT = 66 # 网格数量
# 计算网格点
GRID_LEVELS = np.linspace(GRID_LOW, GRID_HIGH, GRID_COUNT)
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 静态网格不需要复杂的指标,仅需要价格
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
入场逻辑
- 价格每次跌破一个网格点就在该网格点买入
- 从上往下遍历所有网格点
"""
dataframe['enter_long'] = False
# 对每个网格点进行判断
for i, grid_level in enumerate(self.GRID_LEVELS[:-1]): # 不包括最后一个点
# 价格接近或低于该网格点就买入
# 使用 <= grid_level * 1.001 来避免浮点数精度问题
dataframe.loc[
(dataframe['close'] <= grid_level * 1.001) &
(dataframe['close'] > (grid_level - self.GRID_STEP)) &
(dataframe['volume'] > 0),
'enter_long'
] = True
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
出场逻辑
- 每笔交易进场后在上一个网格点卖出
- 每层网格的利润 = GRID_STEP / 当前价格
"""
dataframe['exit_long'] = False
# 简单策略:价格每上升 GRID_STEP就卖出
# 这里我们使用一个简化的方法:如果价格上升了 GRID_STEP 点以上,就卖出
# 计算相对于入场价格的涨幅百分比目标50点收益
# 假设平均入场价在 2650 左右50点 = 1.88%
# 为了泛用,我们设定:只要有 0.9% 的利润就卖出
dataframe['exit_long'] = (
dataframe['close'] >= (dataframe['close'].shift(1) * 1.009)
)
return dataframe
def custom_stake_amount(self, pair: str, current_time, current_rate,
proposed_stake, min_stake, max_stake,
entry_tag, **kwargs) -> float:
"""
每笔投入金额固定 50 USDT
目标总投入 = 50 * 66 = 3300 USDT
"""
return 50.0