If your Python bot hangs forever waiting for the result of an order on IQ Option, you probably fell into the same hole we did: the check_win / check_win_v4 methods of the unofficial iqoptionapi library enter an infinite loop on the new assets with the -op suffix (e.g. USDJPY-op). This article documents the real problem we faced in 2026 running our bot in production (demo account) and the three solutions that are working — with minimal code for each one.

First things first: iqoptionapi is an unofficial library, maintained by the community via reverse engineering of the WebSocket. It can break at any moment, without warning. If you want a foundation with an official, documented API, the alternative is Deriv — that’s where we ported part of our bot.

The problem: why check_win freezes on -op assets

The “-op” assets are IQ Option’s newest options product. The fatal detail: for these assets, the platform does not populate the WebSocket messages the lib expects in order to consider the order closed. check_win_v4 sits in a while True waiting for an event that never arrives — and your bot freezes with it. It’s not a bug in your code: it’s the lib expecting a message contract that the new product doesn’t fulfill. We already covered the normal behavior of these methods in check_win_v4 and the result methods of iqoptionapi.

Solution 1 — Result via balance delta

The most robust of the three, with one precondition: the bot must trade one order at a time (ours does). If there is only one open order, the balance variation after expiry is the result, mathematically: win = +stake × payout, loss = −stake, tie = 0. No waiting for any message.

def resultado_por_delta(api, saldo_antes, stake, tol=0.01): “””Infers the result from the balance variation (1 order at a time!).””” saldo_depois = api.get_balance() delta = round(saldo_depois – saldo_antes, 2) if delta > tol: return “win”, delta # ~ +stake * payout if delta < -tol: return "loss", delta # ~ -stake return "empate", 0.0 # usage: saldo_antes = api.get_balance() ok, order_id = api.buy(stake, "USDJPY-op", "call", 2) # ... wait for settlement (see Solution 2) ... status, lucro = resultado_por_delta(api, saldo_antes, stake)

Simple, with no dependency on check_win. But note the comment “wait for settlement” — that’s where the second trap lives.

Solution 2 — Read the balance at the full minute (the WIN-turned-LOSS bug)

We found out the hard way: IQ Option settles the order on the full-minute boundary (or full quarter-hour), and not at “moment of purchase + N minutes”. If you buy at 14:03:37 with a 2-minute expiry, settlement doesn’t happen at 14:05:37 — it aligns to the platform’s minute grid.

Real bug we lived through: a WIN of +1,120 was recorded as a LOSS by the bot, because it read the balance too early — before the broker credited the payout. The delta was still negative (only the stake debit had landed). In the day’s statistics, a winning trade became a loss. This kind of silent error corrupts all of your numbers.

The fix: align the read to the next full minute after the nominal expiry, and then poll for up to 2-3 minutes until the balance stabilizes (two identical readings in a row):

import time def aguardar_liquidacao(api, saldo_antes, timeout=180): “””Waits for the post-expiry full minute and polls the balance.””” # 1) sleep until the next full minute time.sleep(60 – time.time() % 60 + 1) # 2) poll until the balance changes AND stabilizes fim = time.time() + timeout anterior = api.get_balance() while time.time() < fim: time.sleep(5) atual = api.get_balance() if atual != saldo_antes and atual == anterior: return atual # changed and stabilized: settled anterior = atual return anterior # timeout: use the last reading

Solution 3 — Adaptive expiry (2-min turbo → 15-min binary)

Third stumble: sometimes the broker rejects the turbo order because the schedule for that expiry is closed for the asset. Instead of losing the signal, the bot tries plan B — redoing the order as a 15-minute binary:

def comprar_adaptativo(api, stake, ativo, direcao): “””Tries 2-min turbo; if the schedule rejects it, redoes as 15-min binary.””” ok, order_id = api.buy(stake, ativo, direcao, 2) # 2-min turbo if ok: return order_id, “turbo-2m” ok, order_id = api.buy(stake, ativo, direcao, 15) # 15-min binary if ok: return order_id, “binary-15m” return None, “recusada”

Careful: a different expiry changes the signal’s statistics — log which path was used on each trade, as we do, so you can separate the samples later. The fundamentals of buy and reading the result are in iqoptionapi buy: sending an order and reading the result.

Bonus: the -op assets don’t appear in constants.ACTIVES

Another stumble for anyone migrating to the new assets: they are not listed in constants.ACTIVES, so the lib doesn’t even know they exist. The way out is to inject the IDs at bot startup:

from iqoptionapi import constants # inject the -op assets the lib doesn’t know (id per the platform) ATIVOS_OP = {“USDJPY-op”: 76, “GBPJPY-op”: 79} constants.ACTIVES.update(ATIVOS_OP)

And one account detail, not a code detail: in our case, it was the verified account that unlocked access to the -op assets. If they don’t show up for you, check your account status before hunting for bugs in Python.

The big picture: an unofficial lib is technical debt you accept

The three solutions above are running in production in our bot (on a demo account — the numbers are in Bot results at 3 brokers). But we won’t sugarcoat the situation: all of this is engineering on top of a library that IQ Option does not recognize and could invalidate tomorrow. That’s exactly why we also ported the bot to Deriv, which has an official API — the broker comparison and the lib guide are in Python + IQ Option: the unofficial API.

Tired of reverse engineering? Deriv has an official, documented API with a stable WebSocket — it’s the base of our 45-day study.

Explore the Deriv API (demo account) →

Affiliate link. Always develop and test on demo.

Read next

check_win_v4 and the result methods of iqoptionapi
iqoptionapi buy: sending an order and reading the result (2026)
Python + IQ Option: the unofficial API explained
Deriv Bot: how to create trading bots without coding
The 2 strategies that survived out-of-sample (full rules)

Dan Machado

Developer of the IA Trader Pro project. Builds and documents in public a binary options bot in Python, tested on demo accounts at three brokers (Deriv, IQ Option and Quotex) — publishing the numbers that work and, above all, the ones that don’t.

Disclaimer: binary options are extremely high-risk products and most retail traders lose money. The code in this article consists of educational examples, tested by us on a DEMO account with an unofficial library that can break at any moment. Nothing here is investment advice or a promise of profit. Never trade with money you cannot afford to lose.

Similar Posts