Многопоточность в Python: как удержать код внутри цикла for и ограничить 20 потоков за один разPython

Программы на Python
Ответить
Anonymous
 Многопоточность в Python: как удержать код внутри цикла for и ограничить 20 потоков за один раз

Сообщение Anonymous »

Я работаю над проектом для алгоритмической торговли с использованием API брокера Zerodha.
Я пытаюсь реализовать многопоточность, чтобы сэкономить на дорогостоящей операции вызова функции API для получения исторических данных для 50 акций одновременно, а затем применить моя стратегия покупки/продажи.

Вот мой код:
  • функция исторических данных:

Код: Выделить всё

def historicData(token, start_dt, end_dt):
data = pd.DataFrame( kite.historical_data( token,
start_dt,
end_dt,
interval   = 'minute',
continuous = False,
oi         = False
)
)
# kite.historical_data() is the API call with limitation of 20 requests/sec
return data.tail(5)
  • Функция стратегии:

Код: Выделить всё

def Strategy(token, script_name):
start_dt = (datetime.now() - timedelta(3)).strftime("%Y-%m-%d")
end_dt = datetime.now().strftime("%Y-%m-%d")

ScriptData = historicData(token, start_dt, end_dt)
# perform operations on ScriptData
print(token,script_name)
  • одновременный вызов вышеуказанной функции:

Код: Выделить всё

# concurrent code
from threading import Thread, Lock

start_dt = (datetime.now() - timedelta(3)).strftime("%Y-%m-%d")
end_dt = datetime.now().strftime("%Y-%m-%d")

th_list = [None]*10

start = sleep.time()
for i in range(0,50,20):             # trying to send 20 request in a form of 20 threads in one go
token_batch = tokens[i:i+20]     # data inside is ['123414','124124',...] total 50
script_batch = scripts[i:i+20]   # data inside is ['RELIANCE','INFY',...] total 50
j=0

for stock_script in zip(token_batch,script_batch):
th_list[j] = Thread( target = Strategy,
args   = ( stock_script[0],
stock_script[1]
)
)
th_list[j].start()
j+=1

end = sleep.time()
print('time is : ', end-start)
Теперь есть две проблемы, которые я не могу решить после двух дней попыток множества решений в Интернете.
  • Узким местом сервера API является то, что он принимает 20 вызовов API в секунду и отклоняет, если выполняются дополнительные вызовы. Всего акций в списке 50, и я пытаюсь получить данные по 20 акциям за раз, затем получить еще 20 на следующем этапе, а затем оставшиеся 10 на третьем этапе. Общий список акций вскоре вырастет до 200 акций, поэтому последовательное выполнение слишком затратно для работы моей стратегии.
  • При одновременном запуске этой функции создается слишком много потоков одновременно. и запрос API превышает... и print('time is : ', end-start) запускается, как только я запускаю третью ячейку.
Итак, как мне заблокировать код? выйти из внутреннего цикла for до того, как все потоки завершат свое выполнение.

и

Правильно ли я получаю максимум 20 потоков в секунду? Должен ли я где-нибудь разместить Sleep(1)?

Подробнее здесь: https://stackoverflow.com/questions/617 ... d-limit-20
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»