Connecting to Polygon Websocket Stream from an Async Function

Hi All:

I’m trying to build a streaming stock scanner that will post alerts to a Discord channel.

I’ve tested my scanner without the connection to Discord and it works just fine…prints out results and no errors

My current hurdle is that in order to connect to Discord I have to use the following Async method:

@client.event
async def on_ready():
print(‘Bot is ready and scanning…’)
run(get_tickers())
return

When the run method (my scanner logic) fires, it fails on the websocket connection with the error “The event loop is already running”.

I can definitely share more snippets and pseudocode if need be, but I thought just starting the conversation would be good…I’m not entirely sure this is something that can be accomplished with Discord.py and Polygon streaming.

Has anyone tried this type of thing or have any tips on what to go research next?

Look at my post “Simplest Possible program will not run”. This gives the same error. It appears to me that the people at Alpaca make changes to the API and do not test them thoroughly before putting them into production. This is just a hunch since they have their heads in the sand.
You can also try running some of the sample programs and see if you do not get the same error.

I did see your other couple posts about that error…
In this case I don’t think my issue is with Alpaca API as it works fine if I don’t introduce the second Async method

That being said I’m curious if the provided examples don’t work, I’ll try that out.

Hi @Brian_Krynitsky
The error you see is an asyncio error.
it means you are trying to start the eventloop, but it is already started
so it’s basically not an alpaca package issue per se, but a python asyncio issue.
all you need to do, is to make sure it is started once (or replace the existing one. it’s also a nice option).

add your run() method if you need asistance trying to find what causes this issue.

Thanks @Shlomik, I’m still learning the Asyncio basics…but it sounds like maybe I can control asyncio from attempting to create another event loop…here is the run function:

def run(tickers):
    # Establish streaming connection
    conn = tradeapi.StreamConn()

    symbols = [ticker.ticker for ticker in tickers]

    print('Tracking {} symbols.'.format(len(symbols)))
    minute_history = get_min_history_data(symbols)

    # Connect to Minute Bars Data via Polygon
    @conn.on(r'AM$')
    async def handle_minute_bar(conn, channel, data):
            #a bunch of logic goes in here
            
    # define channels and run the scanner for each
    channels = []
    for symbol in symbols:
        symbol_channels = ['A.{}'.format(symbol), 'AM.{}'.format(symbol)]
        channels += symbol_channels
    print('Watching {} symbols.'.format(len(symbols)))
    run_ws(conn, channels)

# Handle failed websocket connections by reconnecting
def run_ws(conn, channels):
    try:
        conn.run(channels)
    except Exception as e:
        print(e)
        conn.close()
        run_ws(conn, channels)

Where I run into a problem is when I try to call the run from the following function which is part of the Discord.py API:

@client.event
async def on_ready():     
    print('Bot is ready and scanning...')
    run(get_tickers())
    return

if __name__ == "__main__":
    client.run(TOKEN)

Hi @Brian_Krynitsky
so in your case, I think the issue is that discord is trying to run an event loop of their own, and when you execute your code, you try to run an event loop too and this is the result.
you could try to pass the same event loop to the client.
might help you.

if not, you may try the solution I offered @thomaswadeculbertson using nest_asyncio (check his posts for that)

@Shlomik Many thanks :pray: :pray:

1 Like

for completeness on this thread and to help others…it looks like this is going to be the path to success - https://stackoverflow.com/questions/51689285/how-to-add-a-function-to-discord-py-event-loop

I’ll report back with results if I can get it working

sure, happy to help.