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

This commit is contained in:
zhangkun9038@dingtalk.com 2025-11-27 13:30:36 +08:00
parent 94c5929960
commit 1a4560aedc

View File

@ -1,6 +1,7 @@
# /freqtrade/user_data/strategies/StaticGrid.py
from freqtrade.strategy import IStrategy
from pandas import DataFrame
from typing import Optional
import logging
import sys
@ -36,12 +37,13 @@ class StaticGrid(IStrategy):
def populate_entry_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
"""
Static Grid Entry Logic:
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)
- Also buy AT CURRENT PRICE and below it
- When price is at or below a grid level, produce buy signal
"""
dataframe['enter_long'] = False
dataframe['enter_tag'] = ""
if len(dataframe) == 0:
return dataframe
@ -59,7 +61,6 @@ class StaticGrid(IStrategy):
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)
# This ensures we can buy immediately at current price
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)
@ -67,13 +68,15 @@ class StaticGrid(IStrategy):
grid_levels.sort()
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:
dataframe['enter_long'] = True
entry_count += 1
tag = f"grid_{int(grid_price)}"
grid_tags.append(tag)
if entry_count <= 5: # Only print first 5 for brevity
print(f"[StaticGrid] Entry at grid {grid_price:.0f}", file=sys.stderr, flush=True)
@ -82,6 +85,12 @@ class StaticGrid(IStrategy):
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:
@ -105,5 +114,30 @@ class StaticGrid(IStrategy):
return dataframe
def custom_stake_amount(self, **kwargs) -> float:
return self.STAKE
def adjust_trade_position(self, trade, current_rate: float,
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