sqlite - TD Ameritrade API cadena de comillas múltiples Problema de mensaje Async io

CorePress2024-01-25  8

Tengo la API TD en Python y estoy intentando obtener 423 cotizaciones del portal API de cotizaciones múltiples y no siempre devuelve 423. ¿Suena esto como una situación asincrónica? Este es mi intento de implementar async pero estoy seguro de que no lo hice correctamente. ¿Algún consejo?

n = symbols_list
payload = {'symbol':n}

content = requests.get(url = endpoint, params = payload, headers = headers)
data = content.json()
time.sleep(1)

async def get(
    session: aiohttp.ClientSession,
    n: str,
    **kwargs
) -> dict:
    url = endpoint
    headers = headers
    print(f"Requesting {url}")
    resp = await session.request('GET', url=url, **kwargs)
    # Note that this may raise an exception for non-2xx responses
    # You can either handle that here, or pass the exception through
    data = await resp.json()
    print('Received data for {url}')
    return data


async def main(n, **kwargs):
    # Asynchronous context manager.  Prefer this rather
    # than using a different session for each GET request
    async with aiohttp.ClientSession() as session:
        tasks = []
        for symbols in n:
            try:
                tasks.append(get(session=session, n=symbols, **kwargs))
                payload = {'symbol':symbols}
                a = data
                b = a[symbols]['symbol']
                c = a[symbols]['lastPrice']
                d = a[symbols]['netChange']
                e = a[symbols]['totalVolume']
                f = a[symbols]['regularMarketLastPrice']
                g = a[symbols]['highPrice']
                h = a[symbols]['lowPrice']
                quotes = pd.DataFrame({'symbol' : [symbols], 'last' : [c], 'change' : [d], 'volume' : [e]
                              ,'OOCLast' : [f], 'high' : [g], 'low' : [h]})
                quotes.to_sql(name='quotes', con=engine, if_exists='append')
            except:
                pass
                
        # asyncio.gather() will wait on the entire task set to be
        # completed.  If you want to process results greedily as they come in,
        # loop over asyncio.as_com#pleted()
                htmls = await asyncio.gather(*tasks, return_exceptions=True)
                return htmls
               
            


if __name__ == '__main__':
    n = symbols_list
    # ...
    # Either take colors from stdin or make some default here
    await main(n)


¿Estás usando esto? api.tdameritrade.com/v1/marketdata/quotes. envías los 423 a la vez y obtienes los resultados. También hice un bucle con la API de comillas simples, utilizando solicitudes sin problemas.

- Jonathan León

8 de abril de 2021 a las 1:00

Sí, pero no uso async. Es un poco problemático incluso cuando se abren los mercados. A veces simplemente no obtengo una cotización de todas las cotizaciones que realmente existen. Quiero decir, a veces solo saca 200 comillas y luego la próxima vez saca 405 o algo así. ¿Qué piensas sobre esto?

- Gabe Flagg

9 de abril de 2021 a las 2:44

Por favor, ayúdame hermano.

&Dakota del Norteceniza; Gabe Flagg

9 de abril de 2021 a las 2:47



------------------------------------

Esto puede ser un poco más de lo que buscabas pero puedes modificarlo como desees. Utilizo la primera llamada para obtener el conjunto de datos de símbolos para poder jugar con una lista grande de símbolos y probar los puntos finales de la API.

Ver comentarios en línea:

import pandas as pd
import requests
apikey = 'you api'
sym_list = '[A-Z].*' # this will get ALL symbols tda supports at the time; takes a few seconds to run

endpoint = 'https://api.tdameritrade.com/v1/instruments'
payload ={
'apikey': apikey, #your api key goes here
'symbol': sym_list,
'projection' : 'symbol-regex'
}
response = requests.get(endpoint,params=payload)
print(response.url)
data = response.json()
# print(data)

df = pd.DataFrame(data).T #transpose dataframe 
df = df[df['exchange']=='NYSE'] # filter for just NYSE stock symbols
symbols = df.symbol.unique().tolist() # get symbols to a list for later (over 5,000 symbols)

Nota: algunos sybmols no devuelven nada, pero el siguiente código es bastante consistente y funciona bien para mí.

sym_list = symbols[0:501] # take a slice of the symbols from earlier

chunk_size = 500 # each call has this many symbols returned; pretty sure the max symbols per call is 500, but you can try any number here and it'll just loop the sym_list
num_calls = int(len(sym_list) / chunk_size) + 1

df_hold_list = [] #collect intermidiary calls
for i in range(0,num_calls):
    sym_string = ','.join(sym_list[chunk_size*i:chunk_size*(i+1)]) #make the list into a string
    # print(i, sym_string)
    endpoint = 'https://api.tdameritrade.com/v1/marketdata/quotes'
    payload ={
    'apikey': apikey, #your api key goes here
    'symbol': sym_string,
    }
    response = requests.get(endpoint,params=payload)
    # print(response.url)
    data = response.json()
    # print(data)

    df = pd.DataFrame(data).T #transpose dataframe
    df_hold_list.append(df)

dff = pd.concat(df_hold_list) # final dataframe; from here you can do whatever you wish with the data

Salida:

         assetType assetMainType      cusip    symbol                                        description bidPrice  ... markChangeInDouble markPercentChangeInDouble regularMarketPercentChangeInDouble delayed realtimeEntitled assetSubType
A           EQUITY        EQUITY  00846U101         A            Agilent Technologies, Inc. Common Stock   120.80  ...               1.22                    0.9335                             0.9335    True            False          NaN
B           EQUITY        EQUITY  067806109         B                    Barnes Group, Inc. Common Stock    40.47  ...               0.50                    0.9878                             0.9878    True            False          NaN
C           EQUITY        EQUITY  172967424         C                       Citigroup, Inc. Common Stock    72.42  ...               0.09                    0.1244                             0.1244    True            False          NaN
D           EQUITY        EQUITY  25746U109         D                 Dominion Energy, Inc. Common Stock    76.20  ...               0.09                    0.1181                             0.1181    True            False          NaN
E           EQUITY        EQUITY  26874R108         E                            ENI S.p.A. Common Stock    24.00  ...              -0.21                   -0.8564                            -0.8564    True            False          ADR
...            ...           ...        ...       ...                                                ...      ...  ...                ...                       ...                                ...     ...              ...          ...
ENBA        EQUITY        EQUITY  29250N477      ENBA  Enbridge Inc 6.375% Fixed-to-Floating Rate Sub...    16.49  ...               0.00                    0.0000                             0.0000    True            False          NaN
ENBL        EQUITY        EQUITY  292480100      ENBL  Enable Midstream Partners, LP Common Units rep...     6.83  ...               0.09                    1.3216                             1.3216    True            False          NaN
CVII+       EQUITY        EQUITY  17144M110     CVII+  Churchill Capital Corp VII Warrants, each exer...     1.42  ...              -0.07                   -4.6980                            -6.0403    True            False          NaN
SOV-C.CL    EQUITY        EQUITY             SOV-C.CL  Santander Holdings USA, Inc. Dep Shs repstg 1/...    24.99  ...              25.01                    0.0000                             0.0000    True            False          NaN
ENIA        EQUITY        EQUITY  29274F104      ENIA      Enel Americas S.A. American Depositary Shares     8.62  ...              -0.06                   -0.6865                            -0.6865    True            False          ADR

[492 rows x 49 columns]

8

Eso es exactamente lo que estoy buscando. ¡Gracias!

- Gabe Flagg

12 de abril de 2021 a las 0:24

Conseguí que funcionara la lista de símbolos del instrumento y el ciclo de cotizaciones, pero solo toma los primeros 500 símbolos y luego se detiene. Parece que se supone que su código debe seguir tomando fragmentos hasta que se le acaben. ¿Es eso correcto? Ahora tengo 27.000 símbolos en mi lista. Jaja.

- Gabe Flagg

12 de abril de 2021 a las 11:48

modifique su pregunta con su nuevo código exacto

- Jonathan León

12/04/2021 a las 13:20

Aquí está la segunda parte del código donde realiza la solicitud de cotizaciones. Acabo de copiar y pegar tu código de sym_list=""" ......punto final. Estoy poniendo la clave de API entre paréntesis de request.get en lugar de en el punto final. Eso hace una diferencia? No pude lograr que realizara una solicitud cuando lo puse en el punto final.

- Gabe Flagg

14 de abril de 2021 a las 2:23

No estoy seguro de por qué necesitarías cambiar lo que proporcioné. la clave de API es un parámetro, por eso está en el diccionario de carga útil. No va en el encabezado. los parámetros se añaden a la URL, los encabezados no.

- Jonathan León

14 de abril de 2021 a las 3:17



------------------------------------

Jonatán. ¿Crees que tener mi clave API en la parte de encabezados del paréntesis request.get,en lugar de en los corchetes de carga útil anteriores, ¿tendría algo que ver con eso?

 ##Quotes

from sqlalchemy import create_engine
import pandas as pd
import requests
import sqlite3


engine = create_engine('sqlite:///iterist.db', echo=False)
con = sqlite3.connect("iterist.db")
cur=con.cursor()
cur.execute('drop table if exists quotes2')

distinct_symbols="""select distinct symbol from index_symbols order by symbol asc"""
main_list=pd.read_sql(distinct_symbols, engine)
df = pd.DataFrame(main_list, columns=['symbol'])
symbols_list=df['symbol'].values.tolist()

n = symbols_list

sym_list = n[0:401] # take a slice of the symbols from earlier

chunk_size = 400 # each call has this many symbols returned; pretty sure the max symbols per call is 500, but you can try any number here and it'll just loop the sym_list
num_calls = int(len(sym_list) / chunk_size) + 1

df_hold_list = [] #collect intermidiary calls
for i in range(0,num_calls):
    sym_string = ','.join(sym_list[chunk_size*i:chunk_size*(i+1)]) #make the list into a string
    #print(i, sym_string)
    endpoint = 'https://api.tdameritrade.com/v1/marketdata/quotes'
    payload ={
    'symbol': sym_string,
    }
    response = requests.get(endpoint,params=payload, headers=headers)
    # print(response.url)
    data = response.json()
    # print(data)
    df = pd.DataFrame(data).T #transpose dataframe
    #print(df)
    df_hold_list.append(df)

dff = pd.concat(df_hold_list) # final dataframe; from here you can do whatever you    wish with the data
dff.to_sql(name='quote2', con=engine, if_exists='replace')
Compartir mejorar esta respuesta Seguir Respondido

14 de abril de 2021 a las 2:28

Gabe Flagg

Gabe Flagg

9

1

1 insignia de bronce

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare