You've successfully subscribed to Alpaca Resources
Great! Next, complete checkout for full access to Alpaca Resources
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.
Billing info update failed.
  • Home
  • We're hiring
  • Forum
  • Docs
  • Log in
  • Sign up
Use Cases

Trade & Account Streaming with Slack - Building a Slackbot (Part 3)

Alpaca Team
Alpaca Team

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.

Stock Trading Using a Slackbot - Building a Slackbot #1
Hi, I’m Andrew, an intern at Alpaca from Northwestern! As a college student curious about both tech and financial spaces, I was able to leverage Alpaca’s trading API to build a Slackbot.
Adding More Trading Commands - Building a Slackbot #2
This article is the second installment of a 3-part series, detailing how to add more functionality to the Slackbot I created in the first installment.

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
sbp3-unsub.py
GitHub Gist: instantly share code, notes, and snippets.

/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.

alpacahq/slackbot-trader
A Slackbot that can access the Alpaca API. Contribute to alpacahq/slackbot-trader development by creating an account on GitHub.

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.

Use Cases

Alpaca Team

API-first stock brokerage. *Securities are offered through Alpaca Securities LLC* http://alpaca.markets/#disclosures