← Назад"""
Parser for Profit_GAME Telegram channel posts.
Post format:
PROVE фьючи - актив в ИГРЕ! 💥
#PROVE | #Futures | #Chart | PROVEUSDT
❗ Точка входа → 📈
Extracts: ticker, market (futures/spot), pair (TICKERUSDT)
"""
import re
import logging
logger = logging.getLogger(__name__)
def parse_profit_game_post(text: str) -> dict | None:
"""Parse a Profit_GAME channel post and extract signal data."""
if not text:
return None
# Must contain "ИГРЕ" or "актив" to be a signal post
if "ИГРЕ" not in text and "актив" not in text:
return None
result = {
"ticker": None,
"market": None, # "futures" or "spot"
"pair": None, # e.g. "BTCUSDT"
"raw_text": text,
}
# Extract market type
text_lower = text.lower()
if "фьючи" in text_lower or "futures" in text_lower:
result["market"] = "futures"
elif "спот" in text_lower or "spot" in text_lower:
result["market"] = "spot"
# Extract ticker from hashtags: #PROVE | #Futures | #Chart | PROVEUSDT
# Look for pattern: #TICKER |
hashtag_match = re.search(r'#(\w+)\s*\|\s*#(?:Futures|Spot|futures|spot)', text)
if hashtag_match:
result["ticker"] = hashtag_match.group(1).upper()
# Fallback: extract from first word before "фьючи"/"спот"
if not result["ticker"]:
first_word_match = re.match(r'(\w+)\s+(?:фьючи|спот)', text_lower)
if first_word_match:
result["ticker"] = first_word_match.group(1).upper()
# Extract pair: TICKERUSDT at end of hashtag line
pair_match = re.search(r'(\w+USDT)\b', text.upper())
if pair_match:
result["pair"] = pair_match.group(1)
elif result["ticker"]:
result["pair"] = f"{result['ticker']}USDT"
# Extract % move if present in image caption
# Pattern: TICKER/USDT (15m) +72.15% ▲ $0.0862
move_match = re.search(r'([+-]?\d+\.?\d*)\s*%', text)
if move_match:
result["move_percent"] = float(move_match.group(1))
if not result["ticker"]:
logger.debug(f"Could not parse ticker from: {text[:100]}")
return None
logger.info(f"Parsed signal: {result['ticker']} ({result['market']}) pair={result['pair']}")
return result
def classify_signal(move_percent: float) -> dict:
"""Classify signal by move magnitude."""
abs_move = abs(move_percent)
if abs_move >= 30:
priority = "HIGH"
emoji = "🔥"
if move_percent > 0:
strategy = "momentum_long"
description = "Strong pump - momentum play"
else:
strategy = "mean_reversion_long"
description = "Strong dump - bounce play"
elif abs_move >= 10:
priority = "MEDIUM"
emoji = "⚡"
strategy = "check_pattern"
description = "Moderate move - check for pattern"
else:
priority = "LOW"
emoji = "😐"
strategy = "skip"
description = "Noise - skip"
return {
"priority": priority,
"emoji": emoji,
"strategy": strategy,
"description": description,
"move_percent": move_percent,
}