first add

This commit is contained in:
zhangkun9038@dingtalk.com 2025-11-25 21:08:34 +08:00
parent e66eac733d
commit 2efedb9745
3 changed files with 165 additions and 0 deletions

View File

@ -0,0 +1,60 @@
{
"strategy": "SmartBBGrid",
"$schema": "https://schema.freqtrade.io/schema.json",
"redis": {
"url": "redis://192.168.1.215:6379/0"
},
"trading_mode": "spot",
"margin_mode": "isolated",
"max_open_trades": 55,
"stake_currency": "USDT",
"stake_amount": "unlimited",
"tradable_balance_ratio": 1,
"process_only_new_candles": false,
"dry_run": true,
"timeframe": "4h",
"dry_run_wallet": 3000,
"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": 200,
"exchange": {
"name": "okx",
"key": "314e75b0-1113-47e8-ad01-1fca7e3c0496",
"secret": "9C8B170390F46EA6FB87592AD46F5A34",
"password": "nekFoylf:Om0",
"ccxt_config": {
"enableRateLimit": true,
"rateLimit": 500
},
"pair_whitelist": ["BTC/USDT", "ETH/USDT", "SOL/USDT"]
},
"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": "SmartBBGrid-2025",
"initial_state": "running",
"force_entry_enable": false,
"internals": {
"process_throttle_secs": 5,
"heartbeat_interval": 20,
"loglevel": "INFO"
}
}

View File

@ -0,0 +1,3 @@
{
"strategy_name": "SmartBBGrid"
}

View File

@ -0,0 +1,102 @@
# user_data/strategies/SmartBBGrid.py
from freqtrade.strategy import IStrategy
from pandas import DataFrame
import talib.abstract as ta
class SmartBBGrid(IStrategy):
INTERFACE_VERSION = 3
timeframe = '4h'
can_short = False
minimal_roi = {"0": 100} # 不自动ROI
stoploss = -0.99
startup_candle_count = 200
use_exit_signal = True
exit_profit_only = False
ignore_roi_if_entry_signal = True
# ---------- 指标 ----------
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
# 布林带20期 2.3倍)
bb = ta.BBANDS(dataframe, timeperiod=20, nbdevup=2.3, nbdevdn=2.3)
dataframe['bb_lower'] = bb['lowerband']
dataframe['bb_upper'] = bb['upperband']
dataframe['bb_mid'] = bb['middleband']
dataframe['bb_width'] = (dataframe['bb_upper'] - dataframe['bb_lower']) / dataframe['bb_mid']
# ADX
dataframe['adx'] = ta.ADX(dataframe, timeperiod=14)
return dataframe
# ---------- 买入 ----------
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['enter_long'] = False
# 震荡或强牛市都允许在下轨补仓
oscillating = (dataframe['adx'] < 24) & (dataframe['bb_width'] > 0.04)
strong_bull = dataframe['adx'] > 30
dataframe.loc[
((oscillating | strong_bull) &
(dataframe['close'] <= dataframe['bb_lower'] * 1.006) &
(dataframe['volume'] > 0)),
'enter_long'] = True
return dataframe
# ---------- 卖出 ----------
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
dataframe['exit_long'] = False
# 只有震荡市才卖,牛市死拿
dataframe.loc[
(dataframe['adx'] < 24) & (
(dataframe['close'] >= dataframe['bb_upper'] * 0.994) | # 碰到上轨卖
(dataframe['close'] >= dataframe['bb_mid'] * 1.13) # 赚13%全清
),
'exit_long'] = True
return dataframe
# ---------- 每币25-30个订单 ----------
def custom_stake_amount(self, pair: str, current_time, current_rate,
proposed_stake, min_stake, max_stake,
entry_tag, **kwargs) -> float:
# 目标:每个币对保持 25-30 个订单
TARGET_ORDERS_PER_PAIR = 27 # 中位数
# 1. 拿到当前钱包总余额
total_balance = self.wallets.get_total_stake_amount()
# 2. 定义每个币对的资金占比
weights = {
'BTC/USDT': 0.30,
'ETH/USDT': 0.30,
'SOL/USDT': 0.40,
}
# 3. 该币对应该占的总金额
target_for_this_pair = total_balance * weights.get(pair, 0.33)
# 4. 该币对已经占了多少
used_for_this_pair = self.wallets.get_used_for_pair(pair)
# 5. 还剩多少可以投入
available = target_for_this_pair - used_for_this_pair
if available <= 0:
return 0
# 6. 根据目标订单数,计算每笔应该投多少
# 假设还需要投入的订单数 = 目标订单数 - 当前订单数
current_trades_for_pair = len([t for t in self.trades if t.pair == pair])
remaining_orders = max(1, TARGET_ORDERS_PER_PAIR - current_trades_for_pair)
# 平均分配剩余资金给剩余订单
per_order_stake = available / remaining_orders
# 取最小值(不超过可用资金)
stake = min(per_order_stake, proposed_stake)
stake = max(stake, min_stake * 2) # 防止太小
return stake