最后一次尝试 单币对多交易

This commit is contained in:
zhangkun9038@dingtalk.com 2025-11-27 13:31:18 +08:00
parent 1a4560aedc
commit f8cb87374f
2 changed files with 33 additions and 76 deletions

View File

@ -8,9 +8,9 @@
"dry_run": false,
"dry_run_wallet": 7766,
"timeframe": "1h",
"position_adjustment_enable": true,
"position_adjustment_enable": false,
"process_only_new_candles": false,
"max_entry_position_adjustment": -1,
"max_entry_position_adjustment": 0,
"exchange": {
"name": "okx",
"key": "cbda9fde-b9e3-4a2d-94f9-e5c3705dfb5c",

View File

@ -1,7 +1,7 @@
# /freqtrade/user_data/strategies/StaticGrid.py
from freqtrade.strategy import IStrategy
from freqtrade.strategy import IStrategy, merge_informative_pair
from pandas import DataFrame
from typing import Optional
from typing import Optional, Dict, Any
import logging
import sys
@ -11,39 +11,34 @@ class StaticGrid(IStrategy):
INTERFACE_VERSION = 3
timeframe = '1h'
can_short = False
minimal_roi = {"0": 100}
minimal_roi = {"0": 0.001} # 极小收益就卖
stoploss = -0.99
use_exit_signal = True
position_adjustment_enable = True
max_entry_position_adjustment = -1
position_adjustment_enable = False # 关闭加仓
cooldown_candles = 0
# Lock configuration - disable lockout to allow immediate re-entry
cooldown_candles = 0 # No cooldown between trades
# Grid parameters
LOWER = 1500.0 # Minimum price
UPPER = 4500.0 # Maximum price
STEP = 50.0 # Grid spacing
STAKE = 40.0 # Per-trade stake
LOWER = 1500.0
UPPER = 4500.0
STEP = 50.0
STAKE = 40.0
def __init__(self, config: dict) -> None:
super().__init__(config)
# Force write to stderr immediately on startup
print("[StaticGrid] Strategy initialized!", file=sys.stderr, flush=True)
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
print(f"[StaticGrid] populate_indicators called, df len: {len(dataframe)}", file=sys.stderr, flush=True)
return dataframe
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Static Grid Entry Logic using multiple enter_tags:
- Each grid level gets its own enter_tag (entry_grid_XXXX)
- This allows Freqtrade to create multiple orders per candle
- Buy at predefined grid levels: 1500, 1550, 1600, ..., 4500 (step 50)
激进网格入场
- 当价格低于任何网格点时强制产生买入信号
- 使用 enter_tag 来区分不同网格点
"""
dataframe['enter_long'] = False
dataframe['enter_tag'] = ""
dataframe['enter_tag'] = ''
if len(dataframe) == 0:
return dataframe
@ -52,61 +47,43 @@ class StaticGrid(IStrategy):
current_low = dataframe['low'].iloc[-1]
print(f"[StaticGrid] Current price: {current_price:.2f}, low: {current_low:.2f}", file=sys.stderr, flush=True)
# Define static grid levels
LOWER = 1500.0
UPPER = 4500.0
STEP = 50.0
# Generate all grid levels in the range
grid_levels = [LOWER + i * STEP for i in range(int((UPPER - LOWER) / STEP) + 1)]
# IMPORTANT: Add current price as a grid level too (rounded to nearest STEP)
current_grid_level = round(current_price / STEP) * STEP
if current_grid_level not in grid_levels and LOWER <= current_grid_level <= UPPER:
grid_levels.append(current_grid_level)
grid_levels.sort()
# 生成所有网格点
grid_levels = [self.LOWER + i * self.STEP for i in range(int((self.UPPER - self.LOWER) / self.STEP) + 1)]
entry_count = 0
grid_tags = [] # Collect all grid levels that should trigger entry
# For each grid level, check if price is at or below it
# 对每个网格点检查是否应该入场
for grid_price in grid_levels:
# Buy if current low is at or below this grid level (with 0.5% tolerance)
if current_low <= grid_price * 1.005:
entry_count += 1
# 激进条件:价格低于网格点就买
if current_low <= grid_price:
dataframe.loc[dataframe.index[-1], 'enter_long'] = True
tag = f"grid_{int(grid_price)}"
grid_tags.append(tag)
if entry_count <= 5: # Only print first 5 for brevity
# 累加所有适用的标签
if dataframe.loc[dataframe.index[-1], 'enter_tag']:
dataframe.loc[dataframe.index[-1], 'enter_tag'] += f",{tag}"
else:
dataframe.loc[dataframe.index[-1], 'enter_tag'] = tag
entry_count += 1
if entry_count <= 5:
print(f"[StaticGrid] Entry at grid {grid_price:.0f}", file=sys.stderr, flush=True)
if entry_count > 5:
print(f"[StaticGrid] ... and {entry_count - 5} more grid levels", file=sys.stderr, flush=True)
print(f"[StaticGrid] Total entry signals: {entry_count}", file=sys.stderr, flush=True)
# Set enter_long = True for the last row (current candle)
if entry_count > 0:
dataframe.loc[dataframe.index[-1], 'enter_long'] = True
# Use the grid tags separated by comma
dataframe.loc[dataframe.index[-1], 'enter_tag'] = ','.join(grid_tags)
return dataframe
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Exit Logic - AGGRESSIVE:
- Exit as soon as price moves up at all (even 0.01% profit)
- This ensures we close positions quickly for grid trading
极端出场任何上升就卖
"""
dataframe['exit_long'] = False
if len(dataframe) < 2:
return dataframe
# EXTREME: Exit on ANY upward movement (even micro profits)
# This forces position closure to allow new entries
dataframe['exit_long'] = (dataframe['close'] > dataframe['open']).fillna(False)
# 只要收盘价高于开盘价就卖出
dataframe['exit_long'] = (dataframe['close'] > dataframe['open'])
exits = dataframe['exit_long'].sum()
if exits > 0:
@ -118,26 +95,6 @@ class StaticGrid(IStrategy):
current_profit: float, min_stake: float,
max_stake: float, **kwargs) -> Optional[float]:
"""
Network Grid Position Adjustment (DCA - Dollar Cost Averaging):
每当价格跌到新的网格点时自动加仓
不使用加仓
"""
LOWER = 1500.0
UPPER = 4500.0
STEP = 50.0
# Only add position if price drops to a new grid level
grid_level = round(current_rate / STEP) * STEP
# Calculate how many positions we've already opened
open_positions = trade.nr_of_successful_entries
# Maximum positions per pair = (UPPER - LOWER) / STEP
max_positions = int((UPPER - LOWER) / STEP) + 1
if open_positions < max_positions and LOWER <= grid_level <= UPPER:
# Add position at each grid level
print(f"[StaticGrid] Adding position at grid level {grid_level:.0f}, current rate {current_rate:.2f}",
file=sys.stderr, flush=True)
return self.STAKE
return None