最后一次尝试 单币对多交易
This commit is contained in:
parent
1a4560aedc
commit
f8cb87374f
@ -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",
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user