Assest scan and payout issue #104
shattaroadrekrdz
started this conversation in
General
Replies: 3 comments 13 replies
-
|
@Rick-29 could you please review this and help us? |
Beta Was this translation helpful? Give feedback.
3 replies
-
|
Hello! Normally this issue is resolved in BinaryOptionsToolsV2 |
Beta Was this translation helpful? Give feedback.
9 replies
-
|
My tik tok @Khal1d.84 |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi, I am having an issue where the assest scan seems to freeze the bot and sometiesm the payout timed out also keeps doing this is a loop where it timed out, then no signal found then that just keeps looping.
I am not sure how I can solve this issue. it didt seem to happen at 1st but then as I progress with the built i notinced it and based on my check the old version of my build had the same potention issue even though it never happedn before but then I also noticed that all my old versiosn satrted doign that.
1st log issue is we would be stuck scanning
2nd log issue is
[08:11:29 AM] [RSI-M] No signal — re-scanning in 5s...
[08:11:47 AM] [RSI-M] Payout fetch timed out — retrying
[08:11:47 AM] [RSI-M] No signal — re-scanning in 5s...
[08:12:04 AM] [RSI-M] Payout fetch timed out — retrying
[08:12:04 AM] [RSI-M] No signal — re-scanning in 5s...
[08:12:21 AM] [RSI-M] Payout fetch timed out — retrying
[08:12:21 AM] [RSI-M] No signal — re-scanning in 5s...
[08:12:28 AM] [Classic Mode] Strategy auto-switched: RSI-M → RSI-R
[08:12:38 AM] [RSI-R] Payout fetch timed out — retrying
[08:12:38 AM] [RSI-R] No signal — re-scanning in 5s...
here is the is the code surrounding these I am not sure what I am doing worng:
Focused Classic Mode Extract — Candles, Payout, and Scanning
Source: Rust2.pyw via Classic_Mode_System_Extract.pyw
Original file was not modified.
Purpose:
This file isolates the Classic mode pieces you asked for:
- Candle fetching
- RSI/EMA signal calculation
- Payout filtering
- Asset scanning
Important external dependencies from the full bot:
- _bot_lib_client: active PocketOption/BinaryOptionsToolsV2 client
- _bot_lib_lock: lock around the client
- ENVIRONMENT: "DEMO" or "REAL"
- log(message): GUI/log output function
- threading, random, time, re imports
This is an extraction for analysis, not a standalone runnable bot module.
>>> ORIGINAL EXTRACT LINES 1-5
Extracted Classic Mode System from Rust2.pyw
This file keeps the original source unchanged.
Included: config/globals, full Classic strategy engine, and shared trading engine used by Classic.
Note: UI methods and startup hooks are placed in Classic_Mode_UI_Control_Snippets.txt for analysis.
>>> ORIGINAL EXTRACT LINES 123-124
ENVIRONMENT = "REAL"
>>> ORIGINAL EXTRACT LINES 168-183
SELECTED_CLASSIC_STRATEGY = "RSI-M"
CLASSIC_MODE_AUTO_SWITCH_ENABLED = True
CLASSIC_MODE_AUTO_SWITCH_MIN_SCANS = 4
CLASSIC_MODE_AUTO_SWITCH_MAX_SCANS = 9
----------------------
CLASSIC MODE NATURAL PACING
----------------------
Lightweight pacing only: randomized scan order, random cooldown before trades,
and short post-trade pauses. No session breaks, same-asset cap, trade-rate cap,
spike filter, or choppy-market filter.
CLASSIC_NATURAL_PACING_ENABLED = True
CLASSIC_RANDOMIZE_SCAN_ORDER = True
CLASSIC_MIN_SECONDS_BETWEEN_TRADES = 8
CLASSIC_MAX_SECONDS_BETWEEN_TRADES = 22
>>> ORIGINAL EXTRACT LINES 187-217
CLASSIC_MODE_STRATEGIES = {
"RSI-M": {
"expiry_time": "5 Seconds",
"expiry_seconds": 5,
"description": "Scans all assets with ≥92% payout and trades RSI(14) + EMA(9) trends on the 30-second chart. Buys when RSI > 70 AND price is above EMA9 (uptrend confirmed), sells when RSI < 30 AND price is below EMA9 (downtrend confirmed). Stops when take profit or stop loss is hit.",
"buy_condition": "RSI(14) on the 30-second chart is above 70 AND last close is above EMA(9) — uptrend confirmed, BUY.",
"sell_condition": "RSI(14) on the 30-second chart is below 30 AND last close is below EMA(9) — downtrend confirmed, SELL.",
"rsi_period": 14,
"rsi_candle_seconds": 30,
"rsi_overbought": 70,
"rsi_oversold": 30,
"min_payout_percent": 92,
"ema_period": 9, # EMA trend filter — only trade when price aligns with trend
},
"RSI-R": {
"strategy_type": "reversal",
"expiry_time": "5 Seconds",
"expiry_seconds": 5,
"description": "RSI reversal strategy on the 30-second chart. Scans all assets with ≥92% payout and waits for RSI to turn from an extreme zone with candle confirmation before entering.",
"buy_condition": "Previous RSI(14) is at/below 30, current RSI turns upward, current RSI remains near the oversold zone, and last close is above the previous close — reversal BUY.",
"sell_condition": "Previous RSI(14) is at/above 70, current RSI turns downward, current RSI remains near the overbought zone, and last close is below the previous close — reversal SELL.",
"rsi_period": 14,
"rsi_candle_seconds": 30,
"rsi_overbought": 70,
"rsi_oversold": 30,
"rsi_reversal_buffer": 6,
"min_payout_percent": 92,
"ema_period": 9,
},
}
>>> ORIGINAL EXTRACT LINES 545-669
_rsi14_strategy_thread = None
_rsi14_strategy_stop = threading.Event()
_classic_runtime_strategy_name = SELECTED_CLASSIC_STRATEGY
_classic_runtime_scans_until_switch = 0
_classic_runtime_scan_count = 0
_classic_last_trade_time = 0.0
def _calculate_rsi(closes, period=14):
"""Wilder's RSI — pure Python, no extra dependencies."""
if len(closes) < period + 1:
return None
gains, losses = [], []
for i in range(1, len(closes)):
delta = closes[i] - closes[i - 1]
gains.append(max(delta, 0))
losses.append(max(-delta, 0))
avg_gain = sum(gains[:period]) / period
avg_loss = sum(losses[:period]) / period
for i in range(period, len(gains)):
avg_gain = (avg_gain * (period - 1) + gains[i]) / period
avg_loss = (avg_loss * (period - 1) + losses[i]) / period
if avg_loss == 0:
return 100.0
rs = avg_gain / avg_loss
return round(100.0 - (100.0 / (1.0 + rs)), 2)
def _calculate_ema(closes, period=9):
"""Exponential Moving Average — pure Python, no extra dependencies.
Returns the current EMA value (last bar), or None if not enough data.
Uses standard smoothing factor: k = 2 / (period + 1).
"""
if len(closes) < period:
return None
k = 2.0 / (period + 1)
ema = sum(closes[:period]) / period # seed with SMA of first
periodbarsfor price in closes[period:]:
ema = price * k + ema * (1.0 - k)
return round(ema, 8)
def _get_candles_for_rsi(asset, candle_seconds=30, rsi_period=14, log_label="RSI-M"):
"""Fetch REAL 30s Pocket Option candles for RSI-M."""
needed = 100
duration = candle_seconds * needed
def _get_rsi14_signal(asset, strategy):
>>> ORIGINAL EXTRACT LINES 672-681
def _classic_strategy_log_prefix(strategy):
try:
for name, cfg in CLASSIC_MODE_STRATEGIES.items():
if cfg is strategy:
return name
return strategy.get("name") or strategy.get("strategy_name") or SELECTED_CLASSIC_STRATEGY or "RSI-M"
except Exception:
return "RSI-M"
def _classic_wait_random(min_seconds, max_seconds, label="Classic Mode", reason="pause"):
>>> ORIGINAL EXTRACT LINES 727-874
def _get_rsi14_signal_raw(asset, raw_key, strategy):
"""Return ('BUY'/'SELL'/None, rsi_value). Tries raw_key then normalised asset for candle fetch.
Also applies an EMA trend filter for RSI-M exactly like the first Rust version,
with RSI-R added as a separate requested strategy.
"""
strategy_type = str(strategy.get("strategy_type", "momentum")).lower().strip()
label = _classic_strategy_log_prefix(strategy)
rsi_period = strategy.get("rsi_period", 14)
candle_secs = strategy.get("rsi_candle_seconds", 30)
overbought = strategy.get("rsi_overbought", 70)
oversold = strategy.get("rsi_oversold", 30)
ema_period = strategy.get("ema_period", 9)
# Try raw key first, then normalised
closes = _get_candles_for_rsi(raw_key, candle_secs, rsi_period, label)
if not closes and raw_key != asset:
closes = _get_candles_for_rsi(asset, candle_secs, rsi_period, label)
if not closes:
return None, None
rsi = _calculate_rsi(closes, rsi_period)
if rsi is None:
return None, None
ema = _calculate_ema(closes, ema_period)
last_close = closes[-1]
ema_text = f"EMA{ema_period}={ema:.5f}" if ema is not None else f"EMA{ema_period}=n/a"
def _call_with_timeout(fn, timeout=8, default=None):
"""Run fn() in a thread; return its result or default if it exceeds timeout."""
result_box = [default]
exc_box = [None]
def _worker():
try:
result_box[0] = fn()
except Exception as e:
exc_box[0] = e
t = threading.Thread(target=_worker, daemon=True)
t.start()
t.join(timeout)
if exc_box[0] is not None:
raise exc_box[0]
return result_box[0]
def _scan_assets_for_rsi14(strategy):
"""Scan all assets via client.payout(), filter by min payout, check RSI.
Returns (asset, raw_key, direction, rsi) or (None, None, None, None).
"""
label = _classic_strategy_log_prefix(strategy)
min_payout = strategy.get("min_payout_percent", 92)
try:
with _bot_lib_lock:
client = _bot_lib_client
if client is None:
log(f"[{label}] Cannot scan — not connected to Pocket Option")
return None, None, None, None
# Pass the demo flag so PO returns the payout for the correct account type.
# Without this, the payout figures may come from the wrong account (Real vs Demo),
# causing wrong asset filtering and wrong stake calculations.
is_demo_mode = (ENVIRONMENT == "DEMO")
try:
raw_payout = _call_with_timeout(lambda: client.payout(demo=is_demo_mode), timeout=10)
except TypeError:
raw_payout = _call_with_timeout(client.payout, timeout=10)
if raw_payout is None:
log(f"[{label}] Payout fetch timed out — retrying")
return None, None, None, None
except Exception as e:
log(f"[{label}] Payout fetch error: {e}")
return None, None, None, None
def _rsi14_wait_for_result(trade_id, expiry_secs, balance_before=None, stake=None, trade_placed_at=None, strategy_label="RSI-M"):
>>> ORIGINAL EXTRACT LINES 1532-1541
def normalise_asset(raw: str) -> str:
upper = str(raw or "").upper()
is_otc = "OTC" in upper
# Pocket Option expects OTC assets like CADJPY_otc.
# Remove OTC before rebuilding the pair so CAD/JPY OTC and CADJPY_otc both stay CADJPY_otc.
upper = upper.replace("OTC", "")
letters = re.sub(r"[^A-Z]", "", upper)
return f"{letters}_otc" if is_otc else letters
Asset display name mapping for known symbols with special chars
>>> ORIGINAL EXTRACT LINES 1863-1864
_bot_lib_client = None
_bot_lib_lock = threading.Lock()
Beta Was this translation helpful? Give feedback.
All reactions