Trade & Account Streaming with Slack - Building a Slackbot (Part 3)
Detailing how to implement account and trade updates streaming with Slack and your Alpaca account.
This article is the third and final installment of a 3-part series, detailing how to implement account and trade updates streaming with Slack and your Alpaca account. If you haven’t read the first or second installment, check them out here and here. It will help you get the environment setup, and have semi-robust Slack app to build off of.
Preparing for Streaming Capabilities
Something you may want to implement into your Slackbot is streaming capabilities for account and trading updates. To accomplish this, we’ll have to add a couple more things to the top of our script, shown below:
import multiprocessing
CHANNEL = ""
config = {
...
"channel": os.environ.get("CHANNEL", CHANNEL)
}
# Set up environment
conn = tradeapi.StreamConn(
key_id=config.get('key_id'),
secret_key=config.get('secret_key'),
base_url=config.get('base_url'),
)
# Initialize the dictionary of streams that we are listening to;
# None denotes not listening
streams = {
"trade_updates": None,
}
# Helper function to listen to a stream
def runThread(stream):
conn.run([stream])
We need to import multiprocessing because we’ll need processes that are dedicated to continually listening to updates via Websockets. The CHANNEL constant should be replaced with the channel that the app is installed into.
Next, I initialized a StreamConn object, which uses my API keys and corresponding base URL (change to live endpoint if you have live keys) which will allow me to subscribe and unsubscribe to streaming channels.
After that, I initialized a dictionary of the one stream we will be able to subscribe to: trade_updates.
Finally, I created a small helper method for creating the Websockets connection for channel updates.
Implementing Streaming Capabilities
Subscribe Streaming
First, I added a command to subscribe to streaming channels via Websockets. Info below:
- Command name: /subscribe_streaming
- Description: Subscribe to streaming channels
- Usage hint: <[channels]>
- Code: Link to function
This function takes in arguments (which should be streaming channel names) and subscribes to each given channel. It does this by creating a new process that will infinitely listen to updates from a specific channel, and setting the process equal to the dictionary entry for the channel.
Unsubscribe Streaming
Next, I added a command to unsubscribe from Websockets updates.
- Command name: /unsubscribe_streaming
- Description: Unsubscribe from streaming channels
- Usage hint: <[channels]>
- Code: Link to function
/unsubscribe_streaming command to Slack with a description of: “Unsubscribe from streaming channels,” and a usage hint of: “<[channels]>.” This function just basically does the opposite of subscribe_streaming. It looks up each argument in the streaming dictionary, and if it exists, the process is killed, effectively killing the streaming connection.
Streaming Handlers
Finally, I added a streaming handler to handle any updates received via the Websocket connections with the trade_updates channel. It basically prints the update and any relevant information. I suppressed the “new” trade update type just to clean up my feed, but you can let it print something if you want.
Here’s the link to the handler function.
Here’s the link to the entire, finished script.
Provided that you have the proper environment setup, you should now be able to receive streaming updates from your Slack channel.
Wrapping Up
Even though this is the final installment of creating this Slackbot, there still are a lot more customizations you can make.
An easy customization you can make is directly editing the handler functions. For example, you might want the /account_info command to give you more info. Just navigate to the account_info_handler function and make as many customizations as you’d like. When editing functions, make sure you always return something (even an empty string), otherwise you’ll get timeout errors from Slack.
You can also add extra commands that aren’t included in the script. Just follow the formatting of the existing functions and add the command to your Slack app. Be sure that the end of your Request URL and the parameter for app.route are the same, otherwise it won’t work.
Note: This demo is designed as a quick and simple project that can be deployed very easily. This means there are some security issues if you choose to scale this, such as server security (ngrok is primarily a development server that will not be as secure as a permanent production server). Be sure to know the risks before implementing this at a larger scope.
Technology and services are offered by AlpacaDB, Inc. Brokerage services are provided by Alpaca Securities LLC, member FINRA/SIPC. Alpaca Securities LLC is a wholly-owned subsidiary of AlpacaDB, Inc.