Coder Social home page Coder Social logo

iqoptionapi / iqoptionapi Goto Github PK

View Code? Open in Web Editor NEW

This project forked from evecimar/iqoptionapi

221.0 221.0 152.0 8.08 MB

IQ Option API (Python 3.7.2) - supported by community - ONLY FOR STUDY - Don't use it on your real Account!!!

Home Page: https://iqoptionapi.github.io/iqoptionapi/

Python 100.00%
iq iq-option-api iqoption iqoption-api iqoption-bot iqoptionapi trading

iqoptionapi's Introduction

AJUDE A MANTER O PROJETO ATIVO

EN: HELP KEEPING THIS PROJECT ACTIVE

Para manter o projeto continuamente atualizado contribua com uma doação, com alguma correção ou melhoria.

As doações serão usadas para adicionar novas features citadas abaixo.

https://streamelements.com/iqoptionapi/tip

Español - AYUDA A MANTENER ESTE PROYECTO ACTIVO

Para mantener el proyecto continuamente actualizado, contribuye con una donación, con cualquier corrección o mejora.

Las donaciones se utilizarán para agregar nuevas funciones que se mencionan a continuación.

EN: To keep the project continuously updated you can contribute with a donation or with some correction or improvement.

https://streamelements.com/iqoptionapi/tip

HELP KEEPING THIS PROJECT ACTIVE

To keep project continuously updated, contribute with a donation, with any correction or improvement.

Donations will be used to add new features mentioned below.

https://streamelements.com/iqoptionapi/tip

PLANEJAMENTO DE NOVAS FEATURES

EN: NEW FEATURES PLANNING
ES: PLANIFICACIÓN DE NUEVAS CARACTERÍSTICAS

  • CALENDARIO ECONOMICO / ECONOMIC CALENDAR (UNDER DEVELOPMENT)

    Descrição: Pega o calendario econimico da iqoption. Essa feature vai possibilitar que vocês possar evitar fazer operações quando estiver muito arriscado.

ECONOMIC CALENDAR

  • FEED DE NOTICIAS/ NEWS FEED

    Descrição: Noticias sobre o mercado NEWS FEED

IQOPTION API SUPPORTED BY COMMUNITY

This api is intended to be an open source project to communicate with iqOption site. this is a no official repository, it means it is maintained by community

Esta API é destinada a ser um projeto de código aberto para se comunicar com o site da iqOption. este é um repositório não oficial, significa que é mantido pela comunidade

Esta API está destinada a ser un proyecto de código abierto para comunicarse con el sitio de IqIoption. este es un repositorio no oficial, significa que es mantenido por la comunidad

IMPORTANT NOTE / NOTA IMPORTANTE

Due to the large amount of scammers that have appeared in the market, it is recommended that you DO NOT enter your password into an unknown exe or robot site that operates on iqoption because many of those have stolen people's passwords so be careful. It's best if you develop your robot or hire someone you trust.

Devido a grande quantidade de golpistas que tem aparecido no mercado, recomenda-se que você NÃO inserir sua senha em exe ou sites de robo desconhecidos que opera na iqoption porque muitos desses tem roubado as senhas das pessoas então tomem cuidado. O melhor é você desenvolver seu robo ou contratar alguem de confiança.

Canal no youtube explicando com trabalhar com a api

Kodandao com Faria

https://www.youtube.com/channel/UCetDOTbLD_gCy0aI4aQwMsg

Idiomas | Languages

Português Espanol English


This api is based on Lu-Yi-Hsun

Thanks also for this version he fixed some bugs.

It was not been updated by him. So I decided to study and do this work. I don't know how all works yet but I'll learn and teach you

Summary

Live documentation

documentation

Contribute with Community

Help me to keep this project working. Open relevant issues and give a hand to fix the bug. I'll start a channel on youtube in future as soon as possible to share how I'm working with this project. The channel will be in portuguese but you can help with subtitles.

I'll do lives on twitch to work together with you. And if you enjoy it and could contribute with any donation it will be welcome.

If something is not clear on documentation let me know and I'll try to explain what I know.

Please send me suggestions ... feedbacks are welcome

PYTHON VERSION

I'm using this tools anaconda with python 3.7 with contains a lot of libs pre-installed

How to start

You must have python installed version 3.7 or higher

then you must have websocket-client installed on your project

pip install websocket-client==0.56

Now you can install this project as library:

sudo pip install -U git+git://github.com/iqoptionapi/iqoptionapi.git

OR 

pip install -U https://github.com/iqoptionapi/iqoptionapi/archive/refs/heads/master.zip
# Alto Nivel
from iqoptionapi.stable_api import IQ_Option

# Baixo Nivel
from iqoptionapi.api import IQOptionAPI
.
├── docs
├── iqoptionapi(Código da API)
    ├── http(Realiza requisições HTTP GET/POST)
    └── ws
        ├── chanels(Doing websocket action)
        └── objects(Get back data from websocket action)

Can not loging problem

fix way 1

sudo pip3 uninstall websocket-client
sudo pip3 install websocket-client==0.56

problem 2

websocket conflict with websocket-client

if you have this problem

Lu-Yi-Hsun#66

fix way

sudo pip3 uninstall websocket
sudo pip3 install websocket-client==0.47.0

Littile sample

import time
from iqoptionapi.stable_api import IQ_Option
Iq=IQ_Option("email","password")
goal="EURUSD"
print("get candles")
print(Iq.get_candles(goal,60,111,time.time()))

Funções e exemplos

Import

from iqoptionapi.stable_api import IQ_Option

Debug mode on

Debug

Ligado

import logging
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')

Login

!!!

Login NOT support SMS Authorization yet

I suggest close it because your robot will stop to wait you to check sms code (on phone)....

!!!

Desligado

Iq=IQ_Option("email","password")

default number is 5

Lu-Yi-Hsun#22

Como realizar login

from iqoptionapi.stable_api import IQ_Option

API = IQ_Option("email", "senha")

Iq.set_max_reconnect(number)


---

### Reconnect&check connect


### Reconectar e checar se está conectado

Caso ocorra algum erro e a conexão com a IQ seja perdida, você pode estar implementando isto

```python
from iqoptionapi.stable_api import IQ_Option
import time
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","password")
Iq.set_max_reconnect(-1)#allow unlimited reconnect
while True:
    #you can !!close yuor network!! to simulation network fails
    if Iq.check_connect()==False:#detect the websocket is close
        print("try reconnect")
        Iq.connect()#try to connect
        print("reconnect Success")
    time.sleep(1)

Como realizar login com 2 fatores

from iqoptionapi.stable_api import IQ_Option

print("Conectando...")
api = IQ_Option("email", "password")
status, reason = api.connect()
print('##### Primeira tentativa #####')
print('Status:', status)
print('Reason:', reason)
print("Email:", api.email)

if reason == "2FA":
    print('##### 2FA HABILITADO #####')
    print("Um sms foi enviado com um código para seu número")

    code_sms = input("Digite o código recebido: ")
    status, reason = api.connect_2fa(code_sms)

    print('##### Segunda tentativa #####')
    print('Status:', status)
    print('Reason:', reason)
    print("Email:", api.email)

print("Banca:", api.get_balance())
print("##############################")

Check version

Tipo de conta e banca

Retornar sua banca com get_balance()

API.get_balance()

Resetar conta de TREINAMENTO (10k)

Função para resetar a conta de treinamento(depositar os 10k de testes)

print(Iq.check_connect())
Iq.connect()

active = 'EURUSD'
payout = Iq.get_digital_payout(active)
print(payout)


active = 'EURUSD'
amount = 100.0
action = 'CALL'
duration = 1
status, order_id = Iq.buy_digital_spot_v2(active, amount, action, duration)
print(status, order_id)

active = 'EURUSD'
payout = Iq.get_digital_payout(active)
print(payout)

Retornar ativos e verificar se estão aberto

ATENÇÃO: Tome cuidado, get_all_open_time() é pesado para a internet

  • Função get_all_open_time() retorna um DICT
  • "cfd" inclue ações,Commodities e ativos de ETFs

DICT["forex"/"cfd"/"crypto"/"digital"/"turbo"/"binary"][asset name]["open"]

it will return True/False

from iqoptionapi.stable_api import IQ_Option
import logging
import random
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","password")
ALL_Asset=Iq.get_all_open_time()
#check if open or not
print(ALL_Asset["forex"]["EURUSD"]["open"])
print(ALL_Asset["cfd"]["FACEBOOK"]["open"])#Stock,Commodities,ETFs
print(ALL_Asset["crypto"]["BTCUSD-L"]["open"])
print(ALL_Asset["digital"]["EURUSD-OTC"]["open"])

#Binary have two diffenence type:"turbo","binary"
print(ALL_Asset["turbo"]["EURUSD-OTC"]["open"])
print(ALL_Asset["binary"]["EURUSD-OTC"]["open"])

ATIVOS = API.get_all_open_time()

#Checando se está aberto ou não
print(ATIVOS["forex"]["EURUSD"]["open"])
print(ATIVOS["cfd"]["FACEBOOK"]["open"]) #Ações,Commodities e ETFs
print(ATIVOS["crypto"]["BTCUSD-L"]["open"])
print(ATIVOS["digital"]["EURUSD-OTC"]["open"])

#Binarias tem dois modos diferentes: "turbo" e "binary"
print(ALL_Asset["turbo"]["EURUSD-OTC"]["open"])
print(ALL_Asset["binary"]["EURUSD-OTC"]["open"])

View all ACTIVES Name

you will get right all ACTIVES and code

ACTIVES

Para exibir todas os ativos

print(Iq.get_all_ACTIVES_OPCODE())

for tipo, data in ATIVOS.items(): for ativo_nome,value in data.items(): print(tipo,ativo_nome,value["open"])

---

### Ver o nome e ID de todos os ativos
- [Arquivo com lista de ativos e id's](iqoptionapi/constants.py)

```python
print(API.get_all_ACTIVES_OPCODE())

get the order data by id

from iqoptionapi.stable_api import IQ_Option
import time
#logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","password")

ACTIVES="EURUSD"
duration=1#minute 1 or 5
amount=1
action="call"#put

print("__For_Binary_Option__")
_,id=Iq.buy(amount,ACTIVES,action,duration)
while Iq.get_async_order(id)==None:
    pass
print(Iq.get_async_order(id))
print("\n\n")

print("__For_Digital_Option__spot")
id=Iq.buy_digital_spot(ACTIVES,amount,action,duration)
while Iq.get_async_order(id)==None:
    pass
order_data=Iq.get_async_order(id)
print(Iq.get_async_order(id))
print("\n\n")

print("__For_Forex_Stock_Commodities_Crypto_ETFs") instrument_type="crypto" instrument_id="BTCUSD" side="buy" amount=1.23 leverage=3 type="market" limit_price=None stop_price=None stop_lose_kind="percent" stop_lose_value=95 take_profit_kind=None take_profit_value=None use_trail_stop=True auto_margin_call=False use_token_for_commission=False check,id=Iq.buy_order(instrument_type=instrument_type, instrument_id=instrument_id, side=side, amount=amount,leverage=leverage, type=type,limit_price=limit_price, stop_price=stop_price, stop_lose_value=stop_lose_value, stop_lose_kind=stop_lose_kind, take_profit_value=take_profit_value, take_profit_kind=take_profit_kind, use_trail_stop=use_trail_stop, auto_margin_call=auto_margin_call, use_token_for_commission=use_token_for_commission) while Iq.get_async_order(id)==None: pass order_data=Iq.get_async_order(id) print(Iq.get_async_order(id))


### For Options

```python
API.get_traders_mood(Paridade)
	# Retorno: Sera do tipo float que representa em porcentagem os 'calls'
	# Se você quiser saber a porcentagem de put, tente 100-API.get_traders_mood(Paridade)

Sample

from iqoptionapi.stable_api import IQ_Option
import time
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","pass")
goal="EURUSD"
print("get candles")
print(Iq.get_candles(goal,60,111,time.time()))
Money=1
ACTIVES="EURUSD"
ACTION="call"#or "put"
expirations_mode=1

Iq.buy(Money,ACTIVES,ACTION,expirations_mode)

Explicação

Iq.buy(Money,ACTIVES,ACTION,expirations)
                #Money:How many you want to buy type(int)
                #ACTIVES:sample input "EURUSD" OR "EURGBP".... you can view by get_all_ACTIVES_OPCODE
                #ACTION:"call"/"put" type(str)
                #expirations:input minute,careful too large will false to buy(Closed market time)thank Darth-Carrotpie's code (int)https://github.com/Lu-Yi-Hsun/iqoptionapi/issues/6
                #return:(None/id_number):if sucess return (id_number) esle return(None) 2.1.5 change this

Sample

from iqoptionapi.stable_api import IQ_Option
Iq=IQ_Option("email","password")
Money=[]
ACTIVES=[]
ACTION=[]
expirations_mode=[]

Entrada.append(1)
Paridade.append("EURUSD")
Direcao.append("call") # ou put
Duracao.append(1)

Entrada.append(1)
Paridade.append("EURAUD")
Direcao.append("call")#put
Duracao.append(1)

print("buy multi")
id_list=Iq.buy_multi(Money,ACTIVES,ACTION,expirations_mode)

print("check win only one id (id_list[0])")
print(Iq.check_win_v2(id_list[0]))

Tempo restante para operação com get_remaning()

Formula: tempo de compra = tempo restante - 30

from iqoptionapi.stable_api import IQ_Option
Iq=IQ_Option("email","password")
Money=1
ACTIVES="EURUSD"
ACTION="call"#or "put"
expirations_mode=1
while True:
    remaning_time=Iq.get_remaning(expirations_mode)
    purchase_time=remaning_time-30
    if purchase_time<4:#buy the binary option at purchase_time<4
        Iq.buy(Money,ACTIVES,ACTION,expirations_mode)
        break

Vender operação com sell_option()

O ID('s) passados para o sell_option() devem ser int ou um list contendo os id's

Iq.sell_option(sell_all)#input int or list

Exemplo

from iqoptionapi.stable_api import IQ_Option
import time
print("login...")
Iq=IQ_Option("email","password")

API = IQ_Option("email", "password")

Entrada = 1
Paridade = "EURUSD"
Direcao = "call"
Duracao = 1

id=Iq.buy(Money,ACTIVES,ACTION,expirations_mode)
id2=Iq.buy(Money,ACTIVES,ACTION,expirations_mode)

time.sleep(5)

sell_all=[]
sell_all.append(id)
sell_all.append(id2)
print(Iq.sell_option(sell_all))

check win

print(API.sell_option(sell_all))


#### Verificar resultado da operação nas **BINÁRIA**

> As funções check_win() e check_win_v2() pararam de funcionar

Para pegarmos o resultado de uma operação feito na binarias, podemos estar utilizando o check_win_v3() ou o check_win_v4()


###### check_win_v3()
```python
Iq.check_win(23243221)
#""you need to get id_number from buy function""
#Iq.check_win(id_number)
#this function will do loop check your bet until if win/equal/loose
check_win_v2

API = IQ_Option("email", "password")

Entrada = 1 Paridade = "EURUSD" Direcao = "call" Duracao = 1

id = API.buy(Entrada, Paridade, Direcao, Duracao)

time.sleep(5)

Iq.check_win_v2(23243221)
#""you need to get id_number from buy function""
#Iq.check_win_v2(id_number)
#this function will do loop check your bet until if win/equal/loose

"get_binary_option_detail" and "get_all_profit" are base on "get_all_init()",if you want raw data you can call

Iq.get_all_init()

Dados brutos da BINÁRIA

get_all_init()

"get_binary_option_detail()" e "get_all_profit()" são baseados no "get_all_init()", para retornar os dados "brutos", você pode utilizar:

Exemplo

from iqoptionapi.stable_api import IQ_Option

API = IQ_Option("email", "password")

print(API.get_all_init())

get_binary_option_detail()

sample

from iqoptionapi.stable_api import IQ_Option
print("login...")
Iq=IQ_Option("email","password")
d=Iq.get_binary_option_detail()
print(d["CADCHF"]["turbo"])
print(d["CADCHF"]["binary"])

get all profit

sample

from iqoptionapi.stable_api import IQ_Option
print("login...")
Iq=IQ_Option("email","password")
d=Iq.get_all_profit()
print(d["CADCHF"]["turbo"])
print(d["CADCHF"]["binary"])

get_betinfo

Temos dois modos para fazer isto, para ambos precisamos indicar quantos 'trades' você quer retornar do histórico de trading ( apenas das binárias )

get_optioninfo()
isSuccessful,dict=Iq.get_betinfo(4452272449)
#Iq.get_betinfo
#INPUT: int
#OUTPUT:isSuccessful,dict

print(API.get_optioninfo(10))
get_optioninfo_v2()
print(Iq.get_optioninfo(10))

API = IQ_Option("email", "password")

print(API.get_optioninfo_v2(10))

print(Iq.get_optioninfo_v2(10))

Pegar opções feitas por outro dispositivo com get_option_open_by_other_pc()

Se sua conta está logada em outro celular/PC e está realizando operações, você pode "pegar" a operação do modo abaixo

import time
from iqoptionapi.stable_api import IQ_Option
Iq=IQ_Option("email","password")
while True:
    #please open website iqoption and buy some binary option
    if Iq.get_option_open_by_other_pc()!={}:
        break
    time.sleep(1)
print("Get option from other Pc and same account")
print(Iq.get_option_open_by_other_pc())

id=list(Iq.get_option_open_by_other_pc().keys())[0]
Iq.del_option_open_by_other_pc(id)
print("After del by id")
print(Iq.get_option_open_by_other_pc())


Digital options buy with actual price sample code

Para digitais

from iqoptionapi.stable_api import IQ_Option
import time
import random
Iq=IQ_Option("email","password")

ACTIVES="EURUSD"
duration=1#minute 1 or 5
amount=1
Iq.subscribe_strike_list(ACTIVES,duration)
#get strike_list
data=Iq.get_realtime_strike_list(ACTIVES, duration)
print("get strike data")
print(data)
"""data
{'1.127100':
    {  'call':
            {   'profit': None,
                'id': 'doEURUSD201811120649PT1MC11271'
            },
        'put':
            {   'profit': 566.6666666666666,
                'id': 'doEURUSD201811120649PT1MP11271'
            }
    }............
}
"""
#get price list
price_list=list(data.keys())
#random choose Strategy
choose_price=price_list[random.randint(0,len(price_list)-1)]
#get instrument_id
instrument_id=data[choose_price]["call"]["id"]
#get profit
profit=data[choose_price]["call"]["profit"]
print("choose you want to buy")
print("price:",choose_price,"side:call","instrument_id:",instrument_id,"profit:",profit)
#put instrument_id to buy
buy_check,id=Iq.buy_digital(amount,instrument_id)
if buy_check:
    print("wait for check win")
    #check win
    while True:
        check_close,win_money=Iq.check_win_digital_v2(id)
        if check_close:
            if float(win_money)>0:
                win_money=("%.2f" % (win_money))
                print("you win",win_money,"money")
            else:
                print("you loose")
            break
    Iq.unsubscribe_strike_list(ACTIVES,duration)
else:
    print("fail to buy,please run again")

get_all_strike_list_data()

Formato da informação retornada

{'1.127100': { 'call': {'profit': None, 'id': 'doEURUSD201811120649PT1MC11271'}, 'put': {'profit': 566.6666666666666, 'id': 'doEURUSD201811120649PT1MP11271'} }.......}


Exemplo de uso
```python
from iqoptionapi.stable_api import IQ_Option
import time
Iq=IQ_Option("email","password")
ACTIVES="EURUSD"
duration=1#minute 1 or 5
Iq.subscribe_strike_list(ACTIVES,duration)
while True:
    data=Iq.get_realtime_strike_list(ACTIVES, duration)
    for price in data:
        print("price",price,data[price])
    time.sleep(5)
Iq.unsubscribe_strike_list(ACTIVES,duration)

Realizar operações nas Digitais com buy_digital_spot()

Abrir operação na digital com preço atual

from iqoptionapi.stable_api import IQ_Option

Iq=IQ_Option("email","password")

ACTIVES="EURUSD"
duration=1#minute 1 or 5
amount=1
action="call"#put
print(Iq.buy_digital_spot(ACTIVES,amount,action,duration))

Pegar lucro pós venda com get_digital_spot_profit_after_sale()

from iqoptionapi.stable_api import IQ_Option
Iq=IQ_Option("email","passord")
ACTIVES="EURUSD"
duration=1#minute 1 or 5
amount=100
action="put"#put

Iq.subscribe_strike_list(ACTIVES,duration)
id=Iq.buy_digital_spot(ACTIVES,amount,action,duration)

while True:
    PL=Iq.get_digital_spot_profit_after_sale(id)
    if PL!=None:
        print(PL)

get current price profit

from iqoptionapi.stable_api import IQ_Option
import time
import logging
#logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","password")
ACTIVES="EURUSD"
duration=1#minute 1 or 5
Iq.subscribe_strike_list(ACTIVES,duration)
while True:
    data=Iq.get_digital_current_profit(ACTIVES, duration)
    print(data)#from first print it may be get false,just wait a second you can get the profit
    time.sleep(1)
Iq.unsubscribe_strike_list(ACTIVES,duration)

Buy digit

buy_check,id=Iq.buy_digital(amount,instrument_id)
#get instrument_id from Iq.get_realtime_strike_list

check win for digital

Verificar resultado da operação nas DIGITAIS

this api is implement by get_digital_position()

check_win_digital()

Esta função foi implementada com get_digital_position()

Iq.check_win_digital(id)#get the id from Iq.buy_digital
#return:check_close,win_money
#return sample
#if you loose:Ture,o
#if you win:True,1232.3
#if trade not clode yet:False,None

❗❗ this api is asynchronous get id data,it only can get id data before you call the buy action. if you restart the program,the asynchronous id data can not get again,so check_win_digital_v2 may not working,so you need to use "check_win_digital"!

Iq.check_win_digital_v2(id)#get the id from Iq.buy_digital
#return:check_close,win_money
#return sample
#if you loose:Ture,o
#if you win:True,1232.3
#if trade not clode yet:False,None

Exemplo

from iqoptionapi.stable_api import IQ_Option
import logging
import random
import time
import datetime
#logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","password")

API = IQ_Option("email", "password")


Paridade = "EURUSD"
Duracao = 1 #1 ou 5 minutos
Entrada = 1
Direcao = "call"

ACTIVES="EURUSD"
duration=1#minute 1 or 5
amount=1
action="call"#put
id=(Iq.buy_digital_spot(ACTIVES,amount,action,duration))
print(id)

if id != "error":
    while True:
        check,win=Iq.check_win_digital_v2(id)
        if check==True:
            break
    if lucro < 0:
        print("Voce perdeu "+str(win)+"$")
    else:
        print("Voce ganhou "+str(win)+"$")
else:
    print("Por favor, tente novamente")

close digital

Iq.close_digital_option(id)

get digital data

Pegar informações das DIGITAIS

Utilizando get_digital_position()

from iqoptionapi.stable_api import IQ_Option
import logging
import time
#logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","password")
ACTIVES="EURUSD-OTC"
duration=1#minute 1 or 5
amount=1
action="call"#put
from datetime import datetime

id=Iq.buy_digital_spot(ACTIVES,amount,action,duration)

while True:
    check,_=Iq.check_win_digital(id)
    if check:
        break
print(Iq.get_digital_position(id))
print(Iq.check_win_digital(id))

#####sample 2

#print(Iq.get_order(id))#not work for digital
print(Iq.get_positions("digital-option"))
print(Iq.get_digital_position(2323433))#in put the id
print(Iq.get_position_history("digital-option"))

you need to check Asset is open or close!

try this api get_all_open_time

you can search instrument_type and instrument_id from this file

search instrument_type and instrument_id

Sample

from iqoptionapi.stable_api import IQ_Option
Iq=IQ_Option("email","password")

instrument_type="crypto"
instrument_id="BTCUSD"
side="buy"#input:"buy"/"sell"
amount=1.23#input how many Amount you want to play

#"leverage"="Multiplier"
leverage=3#you can get more information in get_available_leverages()

type="market"#input:"market"/"limit"/"stop"

#for type="limit"/"stop"

# only working by set type="limit"
limit_price=None#input:None/value(float/int)

# only working by set type="stop"
stop_price=None#input:None/value(float/int)

#"percent"=Profit Percentage
#"price"=Asset Price
#"diff"=Profit in Money

stop_lose_kind="percent"#input:None/"price"/"diff"/"percent"
stop_lose_value=95#input:None/value(float/int)

take_profit_kind=None#input:None/"price"/"diff"/"percent"
take_profit_value=None#input:None/value(float/int)

#"use_trail_stop"="Trailing Stop"
use_trail_stop=True#True/False

#"auto_margin_call"="Use Balance to Keep Position Open"
auto_margin_call=False#True/False
#if you want "take_profit_kind"&
#            "take_profit_value"&
#            "stop_lose_kind"&
#            "stop_lose_value" all being "Not Set","auto_margin_call" need to set:True

use_token_for_commission=False#True/False

check,order_id=Iq.buy_order(instrument_type=instrument_type, instrument_id=instrument_id,
            side=side, amount=amount,leverage=leverage,
            type=type,limit_price=limit_price, stop_price=stop_price,
            stop_lose_value=stop_lose_value, stop_lose_kind=stop_lose_kind,
            take_profit_value=take_profit_value, take_profit_kind=take_profit_kind,
            use_trail_stop=use_trail_stop, auto_margin_call=auto_margin_call,
            use_token_for_commission=use_token_for_commission)
print(Iq.get_order(order_id))
print(Iq.get_positions("crypto"))
print(Iq.get_position_history("crypto"))
print(Iq.get_available_leverages("crypto","BTCUSD"))
print(Iq.close_position(order_id))
print(Iq.get_overnight_fee("crypto","BTCUSD"))

Buy

return (True/False,buy_order_id/False)

if Buy sucess return (True,buy_order_id)

"percent"=Profit Percentage

"price"=Asset Price

"diff"=Profit in Money

parameter
instrument_type instrument_type
instrument_id instrument_id
side "buy" "sell"
amount value(float/int)
leverage value(int)
type "market" "limit" "stop"
limit_price None value(float/int):Only working by set type="limit"
stop_price None value(float/int):Only working by set type="stop"
stop_lose_kind None "price" "diff" "percent"
stop_lose_value None value(float/int)
take_profit_kind None "price" "diff" "percent"
take_profit_value None value(float/int)
use_trail_stop True False
auto_margin_call True False
use_token_for_commission True False
check,order_id=Iq.buy_order(
            instrument_type=instrument_type, instrument_id=instrument_id,
            side=side, amount=amount,leverage=leverage,
            type=type,limit_price=limit_price, stop_price=stop_price,
            stop_lose_kind=stop_lose_kind,
            stop_lose_value=stop_lose_value,
            take_profit_kind=take_profit_kind,
            take_profit_value=take_profit_value,
            use_trail_stop=use_trail_stop, auto_margin_call=auto_margin_call,
            use_token_for_commission=use_token_for_commission)
change PENDING

change Position

parameter
ID_Name "position_id" "order_id"
order_id "you need to get order_id from buy_order()"
stop_lose_kind None "price" "diff" "percent"
stop_lose_value None value(float/int)
take_profit_kind None "price" "diff" "percent"
take_profit_value None value(float/int)
use_trail_stop True False
auto_margin_call True False
sample
ID_Name="order_id"#"position_id"/"order_id"
stop_lose_kind=None
stop_lose_value=None
take_profit_kind="percent"
take_profit_value=200
use_trail_stop=False
auto_margin_call=True
Iq.change_order(ID_Name=ID_Name,order_id=order_id,
                stop_lose_kind=stop_lose_kind,stop_lose_value=stop_lose_value,
                take_profit_kind=take_profit_kind,take_profit_value=take_profit_value,
                use_trail_stop=use_trail_stop,auto_margin_call=auto_margin_call)

get_order

get infomation about buy_order_id

return (True/False,get_order,None)

Iq.get_order(buy_order_id)

get_pending

you will get there data

Iq.get_pending(instrument_type)

get_positions

you will get there data

return (True/False,get_positions,None)

❗ not support ""turbo-option""

instrument_type="crypto","forex","fx-option","multi-option","cfd","digital-option"

Iq.get_positions(instrument_type)

get_position

you will get there data

you will get one position by buy_order_id

return (True/False,position data,None)

Iq.get_positions(buy_order_id)

get_position_history

you will get there data

return (True/False,position_history,None)

Iq.get_position_history(instrument_type)

instrument_type="crypto","forex","fx-option","turbo-option","multi-option","cfd","digital-option"

get_position_history_v2(instrument_type,limit,offset,start,end)

from iqoptionapi.stable_api import IQ_Option
import logging
import random
import time
import datetime
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","password")

#instrument_type="crypto","forex","fx-option","turbo-option","multi-option","cfd","digital-option"
instrument_type="digital-option"
limit=2#How many you want to get
offset=0#offset from end time,if end time is 0,it mean get the data from now
start=0#start time Timestamp
end=0#Timestamp
data=Iq.get_position_history_v2(instrument_type,limit,offset,start,end)

print(data)

#--------- this will get data start from 2019/7/1(end) to 2019/1/1(start) and only get 2(limit) data and offset is 0
instrument_type="digital-option"
limit=2#How many you want to get
offset=0#offset from end time,if end time is 0,it mean get the data from now
start=int(time.mktime(datetime.datetime.strptime("2019/1/1", "%Y/%m/%d").timetuple()))
end=int(time.mktime(datetime.datetime.strptime("2019/7/1", "%Y/%m/%d").timetuple()))
data=Iq.get_position_history_v2(instrument_type,limit,offset,start,end)
print(data)

get_available_leverages

get available leverages

return (True/False,available_leverages,None)

Iq.get_available_leverages(instrument_type,actives)

cancel_order

you will do this

return (True/False)

Iq.cancel_order(buy_order_id)

close_position

you will do this

return (True/False)

Iq.close_position(buy_order_id)

get_overnight_fee

return (True/False,overnight_fee,None)

Iq.get_overnight_fee(instrument_type,active)


Candle

get candles

get_candles can not get "real time data" ,it will late about 30sec

if you very care about real time you need use

"get realtime candles" OR "collect realtime candles"

sample

""now"" time 1:30:45sec

  1. you want to get candles 1:30:45sec now

    you may get 1:30:15sec data have been late approximately 30sec

  2. you want to get candles 1:00:33sec

    you will get the right data

Iq.get_candles(ACTIVES,interval,count,endtime)
            #ACTIVES:sample input "EURUSD" OR "EURGBP".... youcan
            #interval:duration of candles
            #count:how many candles you want to get from now to past
            #endtime:get candles from past to "endtime"

❗ try this code to get more than 1000 candle

from iqoptionapi.stable_api import IQ_Option
import time
Iq=IQ_Option("email","password")
end_from_time=time.time()
ANS=[]
for i in range(70):
    data=Iq.get_candles("EURUSD", 60, 1000, end_from_time)
    ANS =data+ANS
    end_from_time=int(data[0]["from"])-1
print(ANS)

get realtime candles

Sample
from iqoptionapi.stable_api import IQ_Option
import logging
import time
#logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
print("login...")
Iq=IQ_Option("email","password")
goal="EURUSD"
size="all"#size=[1,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,28800,43200,86400,604800,2592000,"all"]
maxdict=10
print("start stream...")
Iq.start_candles_stream(goal,size,maxdict)
#DO something
print("Do something...")
time.sleep(10)

print("print candles")
cc=Iq.get_realtime_candles(goal,size)
for k in cc:
    print(goal,"size",k,cc[k])
print("stop candle")
Iq.stop_candles_stream(goal,size)
start_candles_stream
  • input:
    • goal:"EURUSD"...
    • size:[1,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,28800,43200,86400,604800,2592000,"all"]
    • maxdict:set max buffer you want to save

size

get_realtime_candles
  • input:
    • goal:"EURUSD"...
    • size:[1,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,28800,43200,86400,604800,2592000,"all"]
  • output:
    • dict
stop_candles_stream
  • input:
    • goal:"EURUSD"...
    • size:[1,5,10,15,30,60,120,300,600,900,1800,3600,7200,14400,28800,43200,86400,604800,2592000,"all"]

time

the get_server_timestamp time is sync with iqoption

Iq.get_server_timestamp()

this sample get the Purchase time clock

import time

#get the end of the timestamp by expiration time
def get_expiration_time(t):
    exp=time.time()#or Iq.get_server_timestamp() to get more Precision
    if (exp % 60) > 30:
        end = exp - (exp % 60) + 60*(t+1)
    else:
        end = exp - (exp % 60)+60*(t)
    return end

expiration_time=2

end_time=0
while True:
    if end_time-time.time()-30<=0:
        end_time = get_expiration_time(expiration_time)
    print(end_time-time.time()-30)
    time.sleep(1)

Get top_assets_updated

instrument_type="binary-option"/"digital-option"/"forex"/"cfd"/"crypto"

from iqoptionapi.stable_api import IQ_Option
import logging
import time
#logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
Iq=IQ_Option("email","password")
instrument_type="digital-option"#"binary-option"/"digital-option"/"forex"/"cfd"/"crypto"
Iq.subscribe_top_assets_updated(instrument_type)

print("__Please_wait_for_sec__")
while True:
    if Iq.get_top_assets_updated(instrument_type)!=None:
        print(Iq.get_top_assets_updated(instrument_type))
        print("\n\n")
    time.sleep(1)
Iq.unsubscribe_top_assets_updated(instrument_type)

get popularity by top_assets_updated() api

Lu-Yi-Hsun#131

from iqoptionapi.stable_api import IQ_Option
import logging
import time
import operator

#logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
def opcode_to_name(opcode_data,opcode):
    return list(opcode_data.keys())[list(opcode_data.values()).index(opcode)]

Iq=IQ_Option("email","password")
Iq.update_ACTIVES_OPCODE()
opcode_data=Iq.get_all_ACTIVES_OPCODE()

instrument_type="digital-option"#"binary-option"/"digital-option"/"forex"/"cfd"/"crypto"
Iq.subscribe_top_assets_updated(instrument_type)


print("__Please_wait_for_sec__")
while True:
    if Iq.get_top_assets_updated(instrument_type)!=None:
        break

top_assets=Iq.get_top_assets_updated(instrument_type)
popularity={}
for asset in top_assets:
    opcode=asset["active_id"]
    popularity_value=asset["popularity"]["value"]
    try:
        name=opcode_to_name(opcode_data,opcode)
        popularity[name]=popularity_value
    except:
        pass


sorted_popularity = sorted(popularity.items(), key=operator.itemgetter(1))
print("__Popularity_min_to_max__")
for lis in sorted_popularity:
    print(lis)

Iq.unsubscribe_top_assets_updated(instrument_type)

Get mood

for now... only support get binary option mood , i will implement beterr if need..

Sample

from iqoptionapi.stable_api import IQ_Option
Iq=IQ_Option("email","password")
goal="EURUSD"
instrument="forex" ## Option "forex", "turbo-option"
Iq.start_mood_stream(goal, instrument)
print(Iq.get_traders_mood(goal))
Iq.stop_mood_stream(goal)

it returns example: 0.4233422

item means 42 % call/buy

get_traders_mood

get percent of higher(call)

if you want to know percent of lower(put) just 1-higher

Iq.get_traders_mood(goal)
#input:input "EURUSD" OR "EURGBP".... you can view by get_all_ACTIVES_OPCODE
#output:(float) the higher(call)%
#if you want to know lower(put)% try 1-Iq.get_traders_mood(goal)

get_all_traders_mood

get all you start mood

Iq.get_all_traders_mood(goal)
#output:(dict) all mood you start

How to Get Technical indicators

It get technical indicator from any asset cointains it

## api auth then
asset="GBPUSD"
indicators = Iq.get_technical_indicators(asset)
print(indicators)

if assets doesn't contains technical indicator it returns:

{
  "code": "no_technical_indicator_available",
  "message": "Active is not supported: active id 'ACTIVE_ID_PASSED'"
}

Account

get balance

Iq.get_balance()

reset practice balance to $10000

from iqoptionapi.stable_api import IQ_Option
Iq=IQ_Option("email","password")
print(Iq.reset_practice_balance())

Change real/practice Account

Iq.change_balance(MODE)
                        #MODE: "PRACTICE"/"REAL"

iqoptionapi's People

Contributors

dsinmsdj avatar ewertonbello avatar freenetwork avatar gobbluth avatar hugosenari avatar jacekv avatar jafferwilson avatar kgteixeira avatar leonardorick avatar lu-yi-hsun avatar lusqua avatar n1nj4z33 avatar niltonmelox avatar perryawesome avatar poolals avatar rrfaria avatar tejado avatar warwertt123 avatar weslleyjackson avatar wugalde19 avatar zidokobik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iqoptionapi's Issues

Get data from the past

I would like to know if there is a way to get data from a specific date.
When I pass the date (epoch), no matter what it is, it returns the last data of that parity.

Example: "EURUSD" candlestick data for the date 2022-09-19 12:00:00

get_digital_spot_profit_after_sale() for buy_digital_spot_v2 not working

Hello, get digital profit after sale not working for buy digital spot v2 but works without v2. the problem is that buy spot without v2 has a lower payout than th actual payout with v2. Here is my code:

    Iq.subscribe_strike_list(ACTIVES,duration)
    _,id=Iq.buy_digital_spot_v2(ACTIVES,amount,action,duration)
    print(id)
    if id !="error":
        while True:
            PL=Iq.get_digital_spot_profit_after_sale(id)
            if PL!=None:
                PL = round(PL,2)
                print(PL)
            check,win=Iq.check_win_digital_v2(id)
            if check==True:
                break

I am getting the following error:

    get_digital_spot_profit_after_sale
    duration = int(position["instrument_id"][start_duration:end_duration])
    ValueError: invalid literal for int() with base 10: ''

Connection problem

Iq.connect()#connect to iqoption.
Is not possible connect to IQ Option:

if json.loads(reason)['code'] == 'verify':
File "/usr/lib/python3.6/json/init.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Buy digital does not return error for insufficient funds

Description
buy_digital_spot does not return an error for insufficient funds.

To Reproduce
The code:

from iqoptionapi.stable_api import IQ_Option


iq = IQ_Option('email', 'passwod')
check, reason = iq.connect()

if not check:
    print(f'Não foi possível se conectar: {reason}')
    exit(1)

print('Connected')

iq.change_balance('REAL')
ativo, exp = 'EURUSD', 1

# Digital
iq.subscribe_strike_list(ativo, exp)
ok, ret = iq.buy_digital_spot(ativo, 100, 'CALL', exp)
iq.unsubscribe_strike_list(ativo, exp)

print(f'[DIGITAL] Ok: {ok}. Ret: {ret}')

# Binary
ok, ret = iq.buy(100, ativo, 'CALL', exp)
print(f'[BINARY] Ok: {ok}. Ret: {ret}')

Just replace the email and password and run (change the asset if necessary). The console output is:

Connected
[DIGITAL] Ok: True. Ret: 13968126111
[BINARY] Ok: False. Ret: Insufficient funds for this transaction.

Expected behavior
It should return (False, 'an error description for insufficient funds') on buy_digital_spot, but it returns (True, -a_random_integer-). It is important to note that the buy on binary works as expected.

subscribe_live_deal unused argument?

I was checking the method but I don't seem to see where is buffersize used, when I use get_live_deal() it only goes up on size. So I find weird that the buffersize doesn't take effect at all.

def subscribe_live_deal(self, name, active, _type, buffersize): active_id = OP_code.ACTIVES[active] self.api.Subscribe_Live_Deal(name, active_id, _type) """ self.api.live_deal_data[name][active][_type]=deque(list(),buffersize) while len(self.api.live_deal_data[name][active][_type])==0: self.api.Subscribe_Live_Deal(name,active_id,_type) time.sleep(1) """
buffer size isn't used at all in the uncommented code. I tried using clear_live_deal() but I'm still experimenting because I'm not sure what it does.

I posted the issue on Lu-Yi-Hsun github but I'm not sure if it's going to be answered, the problem is that the get method only returns a bigger dictionary, that yes it contains up to date info, but it maintains the old and it looks like it doesn't have a limit.

error proxy

Problem api connect with proxy

Iq=IQ_Option("email","password","ip:port")
Iq.connect()#connect to iqoption
but don't work.

subscribe_strike_list not working

Describe the bug
The data the API return to me is different of the percentage I see in the IQ Option

To Reproduce
Just use this sample code = https://iqoptionapi.github.io/iqoptionapi/en/digital/digital/#get_digital_current_profit

Expected behavior
I expect the right percentage of profits

Screenshots
image

Additional context

Unresolved attribute reference 'set_max_reconnect' for class 'IQ_Option'

Unresolved attribute reference 'set_max_reconnect' for class 'IQ_Option'

The class does not have a function or attribute called "set_max_reconnect".

image

Note:
I have a lot of problems with reconnections. After a long period, the thread responsible for the reconnection crashes when the connection drops and it is necessary to call the api.connect() method.

Em caso de queda de internet não é possível uma reconexão.

Estou enfrentando um problema sério no meu bot que acredito que possa ter relação com o websocket. Utilizo a versão recomendada (0.56).

Quando há alguma desconexão temporária com a internet após ela retornar, mesmo havendo no código solicitação de reconexão, esta não é realizada. ALguém poderia me auxiliar?

Erro:
File "C:\roboqt1\venv\lib\site-packages\websocket_socket.py", line 135, in send
raise WebSocketConnectionClosedException("socket is already closed.")
websocket._exceptions.WebSocketConnectionClosedException: socket is already closed.

Código da reconexão:
(58 Segundos antes do momento da compra ele verifica a conexão e em caso de falha ele tenta reconectar, porém essa reconexão nunca é realizada)

def triggerVerCon(buy_time, self):

    while True:
        
        if time.time() >= (buy_time - 58) and time.time() < (buy_time - 48):
            print("Verificando Conexão")
            check, reason = account.connect()
            try:
                if(check == True):
                    print("Conexão OK")
                    sys.exit(0)
                else:
                    print("\nErro: Conexão falhou. Tentando reconectar...")
                    self.lab_msg.setText("Ocorreu um erro e o auTOMATO foi desconectado! Tentando reconectar...") 
                    self.lab_on_off.setText("Offline")
                    self.lab_on_off.setStyleSheet("color: rgb(255, 0, 0);")

                
                    while True:
                       
                        check, reason = account.connect()
            
                        if(check == True):
                            print('Conexão reestabelecida!')

                            self.lab_msg.setText("Conexão Estabelecida!")
                            self.lab_on_off.setText("Online")
                            self.lab_on_off.setStyleSheet("color: rgb(0, 255, 0);")
                            break
                                                 

                        else:
                            print("\nErro: Conexão falhou. Não foi possível reconectar")
                            self.lab_msg.setText("Você foi desconectado pela corretora e não foi possível reconectar!") 
                            self.lab_on_off.setText("Offline")
                            self.lab_on_off.setStyleSheet("color: rgb(255, 0, 0);")

                        time.sleep(1)
            except:
                print("\nErro: Conexão falhou. Tentando reconectar...")
                self.lab_msg.setText("Ocorreu um erro e o auTOMATO foi desconectado! Tentando reconectar...") 
                self.lab_on_off.setText("Offline")
                self.lab_on_off.setStyleSheet("color: rgb(255, 0, 0);")
                
                
                while True:
                    
                    check, reason = account.connect()
            
                    if(check == True):
                        print('Conexão reestabelecida!')

                        self.lab_msg.setText("Conexão Estabelecida!")
                        self.lab_on_off.setText("Online")
                        self.lab_on_off.setStyleSheet("color: rgb(0, 255, 0);")
                        break
                                                 

                    else:
                        print("\nErro: Conexão falhou. Não foi possível reconectar")
                        self.lab_msg.setText("Você foi desconectado pela corretora e não foi possível reconectar!") 
                        self.lab_on_off.setText("Offline")
                        self.lab_on_off.setStyleSheet("color: rgb(255, 0, 0);")

                    time.sleep(1)



                
        time.sleep(1)

check_win_v2 não funciona

post do Luiz que está funcionando, seria:

# Function by kkagill ( https://github.com/Lu-Yi-Hsun/iqoptionapi/issues/196 | https://github.com/kkagill )
# Function only work with Options!
def check_win_v4(self, id_number):
    while True:
        try:
           if self.api.socket_option_closed[id_number] != None:
               break
        except:
           pass
    x = self.api.socket_option_closed[id_number]
    return x['msg']['win'],(0 if x['msg']['win'] == 'equal' else float(x['msg']['sum']) * -1 if x['msg']['win'] == 'loose' else float(x['msg']['win_amount']) - float(x['msg']['sum']))

# Function by Adenilson ( https://t.me/CardosoSlv )
# Function only work with Options!
def check_win_v3(self, id_number):
       while True:
	          result = self.get_optioninfo_v2(10)
	          if result['msg']['closed_options'][0]['id'][0] == id_number and result['msg']['closed_options'][0]['id'][0] != None:			
		             return result['msg']['closed_options'][0]['win'],(result['msg']['closed_options'][0]['win_amount']-result['msg']['closed_options'][0]['amount'] if result['msg']['closed_options'][0]['win'] != 'equal' else 0)
		             break
	          time.sleep(1)           

get_balance() IQ_Option' object has no attribute 'api'

Do you need to put:

self.api = IQOptionAPI("iqoption.com", self.email, self.password)
self.api.set_session(headers=self.SESSION_HEADER,
                             cookies=self.SESSION_COOKIE)
check, reason = self.api.connect()

Rather than:

#
 # --start
# self.connect()
# this auto function delay too long

In the init function at line 45 of stable_api.py

get_digital_payout holds the script if asset is not open to negociation

Describe the bug
when calling get_digital_payout passing an asset that is currently not open on digital market, the function holds the application waiting forever for a response that never comes

# stable_api.py

    def get_digital_payout(self, active):
        self.api.digital_payout = None
        asset_id = OP_code.ACTIVES[active]

        self.api.subscribe_digital_price_splitter(asset_id)

        while self.api.digital_payout is None:
            pass  # here it holds forever!!!

        self.api.unsubscribe_digital_price_splitter(asset_id)

        return self.api.digital_payout

To Reproduce
Steps to reproduce the behavior:

  1. Authenticate
  2. call API.get_digital_payout(ASSET) passing where asset is an pair of coins that is currently not open on the digital market
  3. The program is stuck inside the function forever

Expected behavior
If the market is closed the api should just return 0 as payout

buy binary return invalid request

Describe the bug
When used the function buy (IQ.buy()) it returned Error and with de logging active I got this:

2021-02-11 02:50:58,204 {"name": "sendMessage", "msg": {"body": {"price": "2", "active_id": 99, "expired": 1613012160, "direction": "put", "option_type_id": 3, "user_balance_id": 8355641}, "na
me": "binary-options.open-option", "version": "1.0"}, "request_id": "buy"}
2021-02-11 02:50:58,446 {"name":"timeSync","msg":1613011859370}
2021-02-11 02:50:58,462 {"name":"heartbeat","msg":1613011859370}
2021-02-11 02:50:58,523 {"name":"result","request_id":"buy","msg":{"success":true}}
2021-02-11 02:50:58,555 {"request_id":"buy","name":"option","msg":{"message":"invalid request","result":{}},"status":4000}

The pair was AUDUSD that in my timezone (GMT-03:00) in this date was opened.

I don´t know if IQ Option changed the API for binary but I´m having this kind of issue only in binary.

To Reproduce

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots

Additional context

[QUESTION] Where api_option_init_all_result_v2 is defined?

I'm having a bug that happens sometimes with get_all_init_v2() returning None, which brakes my code with the following stacktrace:

 Traceback (most recent call last):
File \"/home/leonardo/.local/lib/python3.8/site-packages/iqbotrealtime/main.py\", line 97, in checkOpenMarket
listMarkets = self.IQ.get_all_open_time()
File \"/home/leonardo/.local/lib/python3.8/site-packages/iqoptionapi/stable_api.py\", line 269, in get_all_open_time
for actives_id in binary_data[option][\"actives\"]:
TypeError: 'NoneType' object is not subscriptable

Where main.py is my own code, calling get_all_open_time() from iqoptionapi, that calls get_all_init_v2().

I started debuging and when I look to the function get_all_init_v2(), that returns self.api.api_option_init_all_result_v2, and i lookes like it's variable is never reasigned after being initialized with None, so I'm wondering how it's normaly returns a dict if it's never being updated in this function.

    def get_all_init_v2(self):
        self.api.api_option_init_all_result_v2 = None

        if self.check_connect() == False:
            self.connect()

        self.api.get_api_option_init_all_v2()
        start_t = time.time()
        while self.api.api_option_init_all_result_v2 == None:
            if time.time() - start_t >= 30:
                logging.error('**warning** get_all_init_v2 late 30 sec')
                return None

        return self.api.api_option_init_all_result_v2

Besides that, when it returns a value, it's a dict, but if we look into api.py the variable is defined as a list.
api_option_init_all_result_v2 = []
Is that right? The definition shouldn't be api_option_init_all_result_v2 = {}?

If someone could answer this important question, will make it very easier for me to debug.
Thank's in advance


Tradução para o português:

Eu estou encontrando um bug que acontece com a função get_all_init_v2() retornando None, o que quebra meu código reproduzindo o seguinte erro:

 Traceback (most recent call last):
File \"/home/leonardo/.local/lib/python3.8/site-packages/iqbotrealtime/main.py\", line 97, in checkOpenMarket
listMarkets = self.IQ.get_all_open_time()
File \"/home/leonardo/.local/lib/python3.8/site-packages/iqoptionapi/stable_api.py\", line 269, in get_all_open_time
for actives_id in binary_data[option][\"actives\"]:
TypeError: 'NoneType' object is not subscriptable

Aonde main.py é meu código, chamando get_all_open_time() da api iqoptionapi, que chama get_all_init_v2()

Eu começei a debugar e quando cheguei nessa função get_all_init_v2() de fato, a variável self.api.api_option_init_all_result_v2 que é retornada no final da função, não tem nenhum valor atribuído a ela depois de ser inicializada com None. Então eu fiquei me perguntando como que normalmente essa função retorna um dicionário se essa variável não recebe qualquer valor nessa função.

    def get_all_init_v2(self):
        self.api.api_option_init_all_result_v2 = None

        if self.check_connect() == False:
            self.connect()

        self.api.get_api_option_init_all_v2()
        start_t = time.time()
        while self.api.api_option_init_all_result_v2 == None:
            if time.time() - start_t >= 30:
                logging.error('**warning** get_all_init_v2 late 30 sec')
                return None

        return self.api.api_option_init_all_result_v2

Além disso, quando essa função retorna algum valor, ele vem como dicionário, mas se olharmos dentro de api.py, a variável é definida como uma lista.
api_option_init_all_result_v2 = []

Isso está certo? A definição não deveria ser api_option_init_all_result_v2 = {}?

Se alguém puder responser essa questão, vai me ajudar muito a debugar esse problema.
Obrigado desde já!

.

keep getting ERROR:root:**error** get_profile try reconnect or ERROR:root:**error** get_balance_mode() in the terminal

How to place EOD (End of Day) Binary trade?

Does the api as it currently is allow end of day trades? I can't find the expiration_mode option that would make such a trade.
Thanks for any help. I'd be willing to add this functionality if anyone can point me to the basic steps and resources that would get me started.

2FA Login is not supported problem

Describe the bug
I have been trying to make this 2FA authentication works

To Reproduce
1 . Turn on 2fa login on IQoptions account
2. After installation I just used the example code via documentation

from iqoptionapi.stable_api import IQ_Option
print("Conecting...")
  try:
        api = IQ_Option("[email protected]", "@passExample")
        status, reason = api.connect()
        print('Status:', status)
        print('Reason:', reason)
        print("Email:", api.email)

      if reason == "2FA":
          print('##### 2FA enabled #####')
          print("An sms has been sent with a code to your number")
  
          code_sms = input("Enter the code received: ")
          status, reason = api.connect_2fa(code_sms)
  
          print('##### second try #####')
          print('Status:', status)
          print('Reason:', reason)
          print("Email:", api.email)
  
      print("Balance:", api.get_balance())
      print("##############################")

 except Exception as e:
    print("Error:", e)

Expected behavior
It should promoted a input box ans wait for the code

**But i got this output

Conecting...
Status: False
Reason: This verification method is not supported. Choose another method or try again later.
Email: [email protected]
Error: Connection is already closed.

pip list ouput

altgraph           0.17.2
boto3              1.26.41
botocore           1.29.41
click              8.1.3
Flask              2.2.2
future             0.18.2
importlib-metadata 6.0.0
iqoptionapi        0.5
itsdangerous       2.1.2
Jinja2             3.1.2
jmespath           1.0.1
macholib           1.15.2
MarkupSafe         2.1.2
pip                21.2.4
python-dateutil    2.8.2
s3transfer         0.6.0
setuptools         58.0.4
six                1.15.0
urllib3            1.26.13
websocket-client   0.56.0
Werkzeug           2.2.2
wheel              0.37.0
zipp               3.13.0

Buy function takes too long

When using the following script:


iq = IQ_Option('email', 'password')
iq.buy(10, 'EURUSD', 'put', 1)

the order takes up to 6-7 seconds to be sent to IQ Option platform.
Is there a way to make it faster, please?
Maybe a lower level function that can be useful for this...
I usually get only candles' prices and send orders, perhaps simpler functions could handle this.

Thx!

instrument-quotes-generated should not be used to retrieve digital payout

Describe the bug
instrument-quites-generated should not be used to retrieve payout and use it return a wrong payout value for digital assets.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
this part of the could should be updated:
Code that should be updated:

# ws/client.py line 298
elif message["name"]=="instrument-quotes-generated":

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

tournament not work

Is it no longer possible to log into the tournament account?

in this example below we can see that it no longer shows...

for balance in api.get_profile_ansyc()["balances"]:
	print(balance["type"])
	print(balance)

Does anyone know how to reconnect in tournament?

websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.

File "/home/rchan/Documentos/entornos/bot/lib/python3.9/site-packages/iqoptionapi/stable_api.py", line 272, in get_all_init_v2
File "/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
self.connect()
File "/home/rchan/Documentos/entornos/bot/lib/python3.9/site-packages/iqoptionapi/stable_api.py", line 142, in connect
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
self.run()
File "/usr/lib/python3.9/threading.py", line 892, in run
if json.loads(reason)['code'] == 'verify':
File "/usr/lib/python3.9/json/init.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.9/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
self._target(*self._args, **self._kwargs)
File "/home/rchan/Documentos/entornos/bot/lib/python3.9/site-packages/iqoptionapi/stable_api.py", line 306, in __get_digital_open
digital_data = self.get_digital_underlying_list_data()["underlying"]
File "/home/rchan/Documentos/entornos/bot/lib/python3.9/site-packages/iqoptionapi/stable_api.py", line 949, in get_digital_underlying_list_data
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
self.api.get_digital_underlying()
File "/home/rchan/Documentos/entornos/bot/lib/python3.9/site-packages/iqoptionapi/api.py", line 681, in get_digital_underlying
self.send_websocket_request(name="sendMessage", msg=msg)
File "/home/rchan/Documentos/entornos/bot/lib/python3.9/site-packages/iqoptionapi/api.py", line 277, in send_websocket_request
self.websocket.send(data)
File "/home/rchan/Documentos/entornos/bot/lib/python3.9/site-packages/websocket/_app.py", line 154, in send
raise WebSocketConnectionClosedException(
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.
^C(ROBOT) rchan@debian:~/Documentos/proyectos/alacranbot/alacranbot-master-v3$ git push origin main

Foreign Exchange Futures' API : buy_order() not working

Hello how are you? while I was using this function buy_order , I faced this issue.

  • My environment to use buy_order function

                              instrument_id = "BTCUSD"
                              instrument_type = "crypto"
                              side = "buy"
                              if row[5] == 'BUY' or row[5] == 'buy' or row[5] == 'Buy':
                                  side = "buy"
                              elif row[5] == 'SELL' or row[5] == 'sell' or row[5] == 'Sell':
                                  side = 'sell'
                              amount = 0.23  
                              leverage = 3  
                              type = "market" 
                              limit_price = None
                              stop_price = None 
                              if row[9]:
                                  take_profit_kind = "percent" 
                                  take_profit_value = int(row[9].replace('%', '')) 
                              else:
                                  take_profit_kind = None
                                  take_profit_value = None
                              if row[10]:
                                  stop_lose_kind = "percent"  # input:None/"price"/"diff"/"percent"
                                  stop_lose_value = int(row[10].replace('%', ''))  # input:None/value(float/int)
                              else:
                                  stop_lose_kind = None
                                  stop_lose_value = None
                            
                              use_trail_stop = True  
                              auto_margin_call = False
                              use_token_for_commission = False  
                              check, order_id = self.API_connection.buy_order(instrument_type=instrument_type,
                                                                              instrument_id=instrument_id,
                                                                              side=side, amount=amount,
                                                                              leverage=leverage,
                                                                              type=type, limit_price=limit_price,
                                                                              stop_price=stop_price,
                                                                              stop_lose_value=stop_lose_value,
                                                                              stop_lose_kind=stop_lose_kind,
                                                                              take_profit_value=take_profit_value,
                                                                              take_profit_kind=take_profit_kind,
                                                                              use_trail_stop=use_trail_stop,
                                                                              auto_margin_call=auto_margin_call,
                                                                              use_token_for_commission=use_token_for_commission)
    
  • When I try this code. I got this error lines without any message

File "C:\Users\manato\AppData\Local\Programs\Python\Python37\lib\site-packages\websocket_app.py", line 343, in _callback
callback(*args)
File "C:\Users\manato\AppData\Local\Programs\Python\Python37\lib\site-packages\iqoptionapi\ws\client.py", line 243, in on_message
self.api.buy_order_id = message["msg"]["id"]

  • So I tried to track error myself , then I could get some message in websocket On_message function.
    Message content is like this:

{'request_id': '', 'name': 'order-placed-temp', 'msg': {'message': 'Failed on command execution [4141] PlaceOrderException[Place order exception: ACCOUNT_TYPE_IS_MARGINAL]. Details: PlaceOrder(order=PlaceOrderV4(None,556658042,9,OrderInstrumentDirect(crypto,BTCUSD),buy,market,3,None,Some(0.23),None,None,None,None,Some(1.0),Some(percent),None,None,false,good_till_cancel,None,true,true), userId=117299705, wsTime=Some(2021-11-07T14:06:40.897Z))'}, 'status': 4141}

Can you please teach me what I did wrong or what is the reason? Thank you

reset_practice_balance() doesn't work anymore

reset_practice_balance() send a message to websocket that always return None, resulting a never ending loop

from iqoptionapi.stable_api import IQ_Option Iq=IQ_Option("email","password") Iq.connect()#connect to iqoption print(Iq.reset_practice_balance())

iq.check_win not working

I am using the command 'Iq.check_win(id)' 'Iq.check_win_v2(id,3)' 'Iq.check_win_v3(id)' trying to get the result of a binary option trade and the program get stuck at this point

Iq=IQ_Option("[email protected]","Sor1970**")
Iq.connect()#connect to iqoption
print(Iq.check_connect())
#print(Iq.get_all_ACTIVES_OPCODE())
print('\n\n\n\n')
'''
ACTIVES="EURUSD-OTC"
duration=1#minuto 1 or 5
amount=1
action="call"#put
polling_time = 1
check,id=(Iq.buy_digital_spot(ACTIVES,amount,action,duration))'''
Money=1
ACTIVES="EURUSD-OTC"
ACTION="call"#or "put"
expirations_mode=1

d = Iq.get_all_profit()
print(d['EURUSD-OTC']['turbo'])
print(d['EURUSD-OTC']['binary'])

check,id=Iq.buy(Money,ACTIVES,ACTION,expirations_mode)
print('la id es: ' + str(id))
if check:
print("!buy!")
else:
print("buy fail")
if id !="error":
while True:
print('comprobando...')
print('Primer chequeo')
#print(Iq.check_win(id))
print('Segundo chequeo')
#print(Iq.check_win_v2(id,3))
print('Tercer chequeo')
print(Iq.check_win_v3(id))
Anotación 2022-11-12 120457

Get data from the past

I would like to know if there is a way to get data from a specific date.
When I pass the date (epoch), no matter what it is, it returns the last data of that parity.

Example: "EURUSD" candlestick data for the date 2022-09-19 12:00:00

error_place_digital_order in buy_digital_spot

Hello, i am having this issue when i buy in digital:

{'code': 'error_place_digital_order', 'message': 'quotesApplication.ConsumeQuoteByTime: invalid instrument: doGBPNZD202103221915PT5.0MCSPT'}

How i fix this issue?

To Reproduce
Steps to reproduce the behavior:
On buy_digital_spot function

The API Has No Iq.get_balance_v2() Method

Describe the bug
According to the official documentation (https://iqoptionapi.github.io/iqoptionapi/en/account/account/)
image

You should be able to use Iq.get_balance_v2()
It states that it provides more accuracy. (I have no idea what improvement/s it gives because I never have the chance to try it LOL)

To Reproduce
Steps to reproduce the behavior:

  1. Use the code down below as a template.
    from iqoptionapi.stable_api import IQ_Option Iq = IQ_Option("change_email", "change_password"]) Iq.get_balance_v2()

Expected behavior
It should return a more accurate value of the account balance.

Screenshots
image

Additional context
None

API returning wrong payout

The API is returning the wrong payout for digital transactions, always returning 60% and the purchase is also being made with this payout.

There's no OP Code for GBPJPY-OTC instrument

Describe the bug
There's no OP Code for GBPJPY-OTC instrument

To Reproduce
import iqoptionapi.constants as OP_code
a = OP_code['GBPJPY-OTC']
--> KeyError

Expected behavior
We should get the code number referent to GBPJPY-OTC instrument

Api não conecta

A última linha: "API.get_profile_ansyc()" fica apenas processando e quando o kernnel é interrompido dá a seguinte mensagem:

get_profile_ansyc
    while self.api.profile.msg == None:

Segue abaixo o código:

from iqoptionapi.stable_api import IQ_Option
import configparser

arq = configparser.RawConfigParser()
arq.read('Config.txt')

email = arq.get('LOGIN','email')
senha = arq.get('LOGIN','senha')

#Conexão com a conta da IQ_Option
def fazerconexao(email,senha,tipoconta = 'PRACTICE'):
    API = IQ_Option(email,senha)
    
    API.connect() 
        
    if API.check_connect()==True:
        print("Ok a conexão foi estabelicida")      
    else:
        print("Tivemos problemas na conexão")
    
    return API

API = fazerconexao(email, senha,)

API.get_profile_ansyc()

How to install in Visual Studio 2022

How to install in Visual Studio 2022 ??

PS C:\iqoptionapi> dir

Directorio: C:\iqoptionapi

Mode LastWriteTime Length Name


d----- 24/04/2022 10:43 a. m. .github
d----- 24/04/2022 02:00 p. m. .vs
d----- 24/04/2022 10:43 a. m. doc
d----- 24/04/2022 10:45 a. m. docs
d----- 24/04/2022 01:12 p. m. env
d----- 24/04/2022 10:45 a. m. image
d----- 24/04/2022 11:19 a. m. iqoptionapi
d----- 24/04/2022 10:45 a. m. tests
-a---- 24/04/2022 10:43 a. m. 7976 .coverage
-a---- 24/04/2022 10:43 a. m. 2 .gdb_history
-a---- 24/04/2022 10:43 a. m. 69 .gitignore
-a---- 24/04/2022 10:43 a. m. 276 .travis.yml
-a---- 24/04/2022 10:43 a. m. 1514 ACTIVE_CODE.txt
-a---- 24/04/2022 10:43 a. m. 77937 coverage.xml
-a---- 24/04/2022 10:43 a. m. 20777 instrument.txt
-a---- 24/04/2022 10:43 a. m. 2815 mkdocs.yml
-a---- 24/04/2022 10:43 a. m. 34481 old_document.md
-a---- 24/04/2022 10:43 a. m. 448 Pipfile
-a---- 24/04/2022 10:43 a. m. 137 pylint.rc
-a---- 24/04/2022 10:43 a. m. 41530 README.md
-a---- 24/04/2022 10:43 a. m. 38 requirements.txt
-a---- 24/04/2022 10:43 a. m. 301 setup.cfg
-a---- 24/04/2022 10:43 a. m. 550 setup.py

PS C:\iqoptionapi> python setup.py install
running install
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\site-packages\setuptools\command\install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\site-packages\setuptools\command\easy_install.py:144: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
error: can't create or remove files in install directory

The following error occurred while trying to add or remove files in the
installation directory:

[Errno 13] Permission denied: 'C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python39_64\\Lib\\site-packages\\test-easy-install-7548.write-test'

The installation directory you specified (via --install-dir, --prefix, or
the distutils default setting) was:

C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\Lib\site-packages\

Perhaps your account does not have write access to this directory? If the
installation directory is a system-owned directory, you may need to sign in
as the administrator or "root" account. If you do not have administrative
access to this machine, you may wish to choose a different installation
directory, preferably one that is listed in your PYTHONPATH environment
variable.

For information on other options, you may wish to consult the
documentation at:

https://setuptools.pypa.io/en/latest/deprecated/easy_install.html

Please make the appropriate changes for your system and try again.

PS C:\iqoptionapi>

COPYTRADING IQ SOFTWARE

Bom dia, eu estava observando em seu canal youtube, que você faz copytrading software no IQ Option. Vi que poderia valer cerca de 3.000, gostaria de falar sobre isso porque quero fazer um software com essas características. Estou esperando por sua resposta, sou da Colômbia, TE HABLÉ AL FACEBOOK

how to use my own indicator

I have my own indicator, made in Lua, it works in IQ Option through scripts. I would like to know if using iqoptionapi I could use or integrate with my indicator that is in Lua at IQ Option

problem with get_tecnical_indicators

i have a problem with get_technical_indicators.'IQ_Option' object has no attribute 'get_technical_indicators'.I already installed Iqoption api

Expiration time diferents for Digital and Binary

when I use the Api.buy_digital_spot_v2(pair, stack, direc, 5) the expiration time is set for end of candle,
but when use Api.buy(stack, pair, direc, 5) function starts a full 5 minutes count down
How can i set Api.buy for end of candle like Api.buy_digital_spot_v2?

High CPU usage on API Calls

Most API calls produce high CPU usage, especially if multiple are running in parallel. I suggest changing the "pass" statements to sleep(0.05) or something.

I have done some basic testing on this and the CPU usage is much lower.

get_digital_spot_profit_after_sale()

Describe the bug
No aquivo stable.py entre linha 1094 e 1096, o valor não esta sendo encontrado da forma que esta codigo, pelo que entendi no tempo em que tive lendo o código, o intuito é indentificar o timeframe.

O código

 start_duration = position["instrument_id"].find("PT") + 2
 end_duration = start_duration + \
           position["instrument_id"][start_duration:].find("M")
 duration = int(position["instrument_id"][start_duration:end_duration])

Solução que encontrei

search_position = position["instrument_id"].find("M")
duration = int(position["instrument_id"][search_position-1])

The payout is incorrect

All binary payouts that i get from the function get_all_profit() is incorrect and show a lower payout then iq option traderoom.
is it another way to get payout, like get_digital_payout()?

Buy3 modification

Describe the bug
I haven't test it again but last time I checked if you modify your computer time it will affect the buy function, this is the modification I made that worked for me and wasn't dependent on computers time
this is from iqoptionapi/ws/chanels/buyv3.py

class Buyv3(Base):

    name = "sendMessage"

    def __call__(self, price, active, direction, duration, request_id):

    

        tserver = int(self.api.timesync.server_timestamp)
        if tserver%60 > 30:
            exp = tserver - tserver%60 +60*(1+duration)
        else:
            exp = tserver - tserver%60 + (60*duration)

        if duration <= 5:
            option = 3  # "turbo"
        else:
            option = 1  # "binary"
        data = {
            "body": {"price": price,
                     "active_id": active,
                     "expired": int(exp),
                     "direction": direction.lower(),
                     "option_type_id": option,
                     "user_balance_id": int(global_value.balance_id)
                     },
            "name": "binary-options.open-option",
            "version": "1.0"
        }
        self.send_websocket_request(self.name, data, str(request_id))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.