fix: refine base_coin extraction to support BTCUSD and fix DB queries (v1.5.4)

This commit is contained in:
Gemini CLI
2026-03-05 23:30:38 +01:00
parent 8b076106dc
commit 57e098c25b

View File

@ -86,7 +86,7 @@ class DatabaseManager:
class PingPongBot:
def __init__(self, config_path="config/ping_pong_config.yaml"):
self.version = "1.5.3"
self.version = "1.5.4"
with open(config_path, 'r') as f:
self.config = yaml.safe_load(f)
@ -113,12 +113,18 @@ class PingPongBot:
password=os.getenv('DB_PASSWORD', '')
)
# Base settings
self.base_coin = self.config['symbol'].upper().replace("USDT", "").replace("USDC", "") # e.g. BTC
# Base settings - Improved extraction
raw_symbol = self.config['symbol'].upper()
# Remove common suffixes to get base coin (e.g., BTCUSD -> BTC, BTCUSDT -> BTC)
self.base_coin = raw_symbol.replace("USDT", "").replace("USDC", "").replace("USD", "")
self.db_symbol = self.base_coin
self.interval = str(self.config['interval'])
# Map interval to DB format: '30' -> '30m'
self.db_interval = self.interval + "m" if self.interval.isdigit() else self.interval
logger.info(f"Bot v{self.version} Initialized | DB Symbol: {self.db_symbol} | DB Interval: {self.db_interval}")
# Dynamic Strategy State
self.direction = None # 'long' or 'short'
self.category = None # 'linear' or 'inverse'
@ -145,7 +151,6 @@ class PingPongBot:
self.console = Console()
# Fixed Parameters from Config
self.tp_pct = float(self.config.get('take_profit_pct', 1.5)) / 100.0
self.partial_exit_pct = float(self.config.get('partial_exit_pct', 0.15))
self.min_val_usd = float(self.config.get('min_position_value_usd', 15.0))
self.pos_size_margin = float(self.config.get('pos_size_margin', 20.0))
@ -186,13 +191,12 @@ class PingPongBot:
async def update_direction(self):
"""Logic Point I: 1D MA44 check and Point II: Asset/Perp selection"""
try:
logger.info("Checking direction based on SMA(44, 1D)...")
# Increase limit to ensure we get enough data even with potential gaps
logger.info(f"Checking direction based on SMA(44, 1D) for {self.db_symbol}...")
candles_1d = await self.db.get_candles(self.db_symbol, "1d", limit=100)
if not candles_1d or len(candles_1d) < 44:
got = len(candles_1d) if candles_1d else 0
logger.warning(f"Not enough 1D data for MA44. Got {got} candles for {self.db_symbol}.")
logger.warning(f"Not enough 1D data for MA44. Got {got} candles for {self.db_symbol} / 1d.")
self.status_msg = f"Error: Need 44 1D candles (Got {got})"
return False
@ -214,14 +218,11 @@ class PingPongBot:
logger.info(f"DIRECTION CHANGE: {self.direction} -> {new_direction} (Price: {current_price:.2f}, MA44: {self.ma_44_val:.2f})")
self.status_msg = f"Switching to {new_direction.upper()}"
# 1. Close all positions (Point III.3)
if self.direction is not None:
await self.close_all_positions()
# 2. Swap Assets on Spot (Point II)
await self.swap_assets(new_direction)
# 3. Update configuration
self.direction = new_direction
if self.direction == "long":
self.category = "inverse"
@ -231,7 +232,7 @@ class PingPongBot:
self.symbol = f"{self.base_coin}USDC"
logger.info(f"Bot configured for {self.direction.upper()} | Symbol: {self.symbol} | Category: {self.category}")
self.last_candle_time = None # Force indicator recalculation
self.last_candle_time = None
return True
return False
@ -276,7 +277,6 @@ class PingPongBot:
usdc_bal = coins.get("USDC", 0)
if usdc_bal > 1.0:
logger.info(f"Spot: Buying {self.base_coin} with {usdc_bal} USDC")
# Spot Market Buy using orderAmount (spending USDC)
await asyncio.to_thread(self.session.place_order,
category="spot", symbol=spot_symbol, side="Buy", orderType="Market",
qty=str(usdc_bal), marketUnit="quote"
@ -316,7 +316,6 @@ class PingPongBot:
last, prev = df.iloc[-1], df.iloc[-2]
rsi_cfg, hurst_cfg = self.config['rsi'], self.config['hurst']
# Signals defined by crossover
l_open = (rsi_cfg['enabled_for_open'] and prev['rsi'] < rsi_cfg['oversold'] and last['rsi'] >= rsi_cfg['oversold']) or \
(hurst_cfg['enabled_for_open'] and prev['close'] > prev['hurst_lower'] and last['close'] <= last['hurst_lower'])
l_close = (rsi_cfg['enabled_for_close'] and prev['rsi'] > rsi_cfg['overbought'] and last['rsi'] <= rsi_cfg['overbought']) or \