【问题标题】:Getting Pool apply_async return too slow获取池 apply_async 返回太慢
【发布时间】:2021-07-06 12:48:31
【问题描述】:

我正在尝试为 IQ Option 制作一个机器人。

我已经做了,但是我一个一个地做了,比如我必须打开 10 个机器人,这样我才能检查 10 对。

我整天都在尝试使用 ThreadPool、Threadings、map 和 starmap(我认为我没有尽可能地使用它们)。

问题是:我正在检查过去 100 分钟的货币对 (EURUSD, EURAUD...) 值。当我一个一个地做时,每个都需要 80 到 300 毫秒才能返回。我现在正在尝试以一种可以同时进行所有调用的方式来执行此操作,并在大约同一时间将它们的结果传递给它们各自的 var。

Atm 我的代码是这样的:

from iqoptionapi.stable_api import IQ_Option
from functools import partial
from multiprocessing.pool import ThreadPool as Pool
from time import *
from datetime import datetime, timedelta
import os
import sys
import dados #my login data
import config #atm is just payoutMinimo = 0.79

parAtivo = {}

class PAR:
    def __init__(self, par, velas):
        self.par = par
        self.velas = velas
        self.lucro = 0
        self.stoploss = 50000
        self.stopgain = 50000

def verificaAbertasPayoutMinimo(API, payoutMinimo):
    status = API.get_all_open_time()
    profits = API.get_all_profit()
    abertasPayoutMinimo = []

    for x in status['turbo']:        
        if status['turbo'][x]['open'] and profits[x]['turbo'] >= payoutMinimo:
            abertasPayoutMinimo.append(x)
    return abertasPayoutMinimo

def getVelas(API, par, tempoAN, segundos, numeroVelas):
    return API.get_candles(par, tempoAN*segundos, numeroVelas, time()+50)


def logVelas(velas, par):
    global parAtivo
    parAtivo[par] = PAR(par, velas)


def verificaVelas(API, abertasPayoutMinimo, tempoAN, segundos, numeroVelas):    
    pool = Pool()
    global parAtivo
    
    for par in abertasPayoutMinimo:
        print(f"Verificando par {par}")

        pool = Pool()

        if par not in parAtivo:
            callbackFunction = partial(logVelas, par=par)
            
            pool.apply_async(
                getVelas,
                args=(API, par, tempoAN, segundos, numeroVelas),
                callback=callbackFunction
            )
    
    pool.close()
    pool.join()

def main():
    tempoAN = 1
    segundos = 60
    numeroVelas = 20
    tempoUltimaVerificacao = datetime.now() - timedelta(days=99)
    global parAtivo
    
    conectado = False

    while not conectado:
        API = IQ_Option(dados.user, dados.pwd)
        API.connect()

        if API.check_connect():
            os.system("cls")
            print("Conectado com sucesso.")
            sleep(1)
            conectado = True
        else:
            print("Erro ao conectar.")
            sleep(1)
            conectado = False
    
    API.change_balance("PRACTICE")
    
    while True:
        if API.get_balance() < 2000:
            API.reset_practice_balance()

        if datetime.now() > tempoUltimaVerificacao + timedelta(minutes=5):
            abertasPayoutMinimo = verificaAbertasPayoutMinimo(API, config.payoutMinimo)
            tempoUltimaVerificacao = datetime.now()

        verificaVelas(API, abertasPayoutMinimo, tempoAN, segundos, numeroVelas)
        
        for item in parAtivo:
            print(parAtivo[item])

        break #execute only 1 time for testing
    

if __name__ == "__main__":
    main()

@edit1:只是补充了更多信息,实际上这就是现在的全部代码。

@edit2:当我这样打印时:

for item in parAtivo:
    print(parAtivo[item].velas[-1]['close']

我明白了:

0.26671
0.473878
0.923592
46.5628
1.186974
1.365679
0.86263

没错,问题是时间太长了,差不多3秒,就像我没有线程池一样。

【问题讨论】:

  • 请添加更多关于您正在使用的软件包的信息,以及一些更紧迫的对象(例如API 等),但不要透露敏感信息。不知道这些功能从何而来,很难提供帮助。
  • @Felipe 做到了,对不起。第一次在这里发帖...
  • 如果 IQ Option 正式支持非浏览器/非人工访问其 API,则在其网站上并不明显。 IQ 选项完全有可能只按顺序处理您的请求,尤其是当您似乎使用的是测试帐户时。因此,您至少需要有多个客户端才能并行处理您的请求。编辑:或者可能是所有的处理时间都在你身上(也许客户端效率低下),在这种情况下,由于全局解释器锁(GIL),线程池将无济于事。
  • @Dunes 据我所知,目前我可能正在做一个浏览器应用程序。我只是在寻找硬币对的价值,我可以实时并排显示它们。
  • 我不确定我是否理解您的评论。我只是想提出一些为什么多线程可能没有帮助的原因。你是如何为你的代码计时的?只是从程序开始到程序结束吗?我注意到您总是调用verificaAbertasPayoutMinimo,然后只运行一次while 循环(带中断)。是不是 verificaAbertasPayoutMinimo 花了三秒钟的大部分时间?

标签: python asynchronous threadpool pool starmap


【解决方案1】:

解决了。

使用threadings.Thread,像这样:

for par in abertasPayoutMinimo:        
        t = threading.Thread(
            target=getVelas,
            args=(API, par, tempoAN, segundos)
        )
        t.start()
        t.join()

【讨论】:

  • 这将按顺序运行,一个接一个。
  • @HTF 真的吗?这很奇怪,因为现在我可以在不到 50 毫秒的时间内获得所有呼叫的结果
猜你喜欢
  • 2016-09-25
  • 2018-01-28
  • 1970-01-01
  • 2013-11-02
  • 2021-12-23
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
  • 2023-02-02
相关资源
最近更新 更多