Trading Venues at lemon.markets — the what, why and how


blog photo
Published by Joanne Snel on July 15, 2021
Product


Hi! My name is Joanne, and I am a recent addition to the (steadily growing) lemon.markets team. We are building an API that allows developers to create their own brokerage experience at the stock market. As our closed-beta launched a few weeks ago (have you already signed up to our waitlist?), I would like to introduce you to some of the functionalities of our API. This week’s topic: Trading Venues. Think of a trading venue as a stock exchange or other type of exchange where instruments are traded, for example, the London Stock Exchange (LSE).

At lemon.markets, we created a number of endpoints concerned with addressing specific trading venues. In this blog post, I will walk you through these endpoints and explain why you might want to use them. I will also show you how they can be used to set up automated emails that notify you when the market is closed.

trading venues at lemon markets

Trading Venues is a new feature we decided to incorporate into our restructured API because we think it adds a powerful functionality. On our path to create a transparent 21st century broker, we think it's important that our users know (and have the option to decide) which trading venue they are placing their orders at. But before we discuss trading venues in a specific lemon.markets context, let us first dive into a bit of background information here:

At the time of writing this blog post (July 2021), there are 21 major stock exchanges in the world that have a market capitalisation of over $1 trillion US dollars, you might have heard of them referred to as the “$1 Trillion Club”. And there are also plenty of stock exchanges that have a smaller reach; have you heard of the Maldives Stock Exchange (MSE) that has just 10 listings? As you can see, the options (get it? 😉) for trading are endless.

Depending on what you are trying to do/build, it can be helpful to know the ins and outs of the stock exchange you are operating on to ensure that your trades go according to plan. By talking to our users, we noticed that there may be different needs and preferences regarding different trading venues, so we wanted to lay a flexible foundation for our API that allows us to integrate additional trading venues in the future.

A small Trading Venue Repository

We built a small project to demonstrate a number of use cases regarding trading venues. You can find the GitHub repository here 👩🏿‍💻👨‍💻👩🏼‍💻🧑🏿‍💻.

Setting the Foundation

Initially, we need to define a few helper functions. As we want to send emails at some point during our script, we define a class “EmailSenderSendgrid”. Surprisingly, we use Sendgrid, which makes API-based email sending super easy. In order to use our repo, you need to have a Sendgrid Account and pass your Sendgrid API Key as an environment variable. If you do not have an account, yet: sign up here.

Next, we define functions for get, put and post requests to be able to use them throughout the script.

Additionally, we need to define a number of environment variables to be able to use the script:

  • TOKEN_KEY = “Your lemon.markets Access Token”
  • BASE_URL = “The base URL of our Paper Money API”
  • MIC = “Market Identifier Code of Trading Venue”
  • SPACE_UUID = “UUID of your space”
  • SENDGRID_API_KEY = “Your Sendgrid API Key”
  • EMAIL_FROM = “Email you want to send emails from”
  • EMAIL_TO= “Email you want to send emails to”
1import os
2import smtplib
3from email.mime.multipart import MIMEMultipart
4from email.mime.text import MIMEText
5import requests
6from dotenv import load_dotenv
7from sendgrid import SendGridAPIClient
8from sendgrid.helpers.mail import Mail
9class EmailSenderSendgrid:
10    def __init__(self, mail_text: str, mail_subject: str):
11        load_dotenv()
12        message = Mail(
13            from_email=os.environ.get('EMAIL_FROM'),
14            to_emails=os.environ.get('EMAIL_TO'),
15            subject=mail_subject,
16            html_content=mail_text)
17        try:
18            sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
19            response = sg.send(message)
20            print(response.status_code)
21            print('email successfully delivered')
22        except Exception as e:
23            print(e.message)
24class RequestHandler:
25    load_dotenv()
26    url: str = os.environ.get("BASE_URL")
27    def get_data(self, endpoint: str):
28        """
29        :param endpoint: {str} only append the endpoint to the base url
30        :return:
31        """
32        response = requests.get(self.url + endpoint,
33                                headers={
34                                    "Authorization": "Bearer "+os.environ.get("TOKEN_KEY")
35                                })
36        return response.json()
37    def put_data(self, endpoint: str):
38        response = requests.put(self.url + endpoint,
39                                headers={
40                                    "Authorization": "Bearer " + os.environ.get("TOKEN_KEY")
41                                })
42        return response.json()
43    def post_data(self, endpoint: str, data):
44        response = requests.post(self.url + endpoint,
45                                 data,
46                                 headers={
47                                     "Authorization": "Bearer " + os.environ.get("TOKEN_KEY")
48                                 })
49        return response.json()

Determining the Trading Venue

When all base work is done, we can move on and start to actually deal with Trading Venues.

Imagine you want to buy a few shares of your favourite stock, but are unsure about where to begin? We think a good first step is to determine through which Trading Venue you would like to place your order. There are a few reasons why you might choose one venue over another, for example, a larger offering, lower transaction costs or more desirable opening hours. To see which Trading Venues lemon.markets has incorporated, you can use the following request URL, which returns a list of all the venues we offer:

1https://paper-data.lemon.markets/v1/venues/

Use the code snippet below to get a json response in your Python script.

1from helpers import RequestHandler
2class TradingVenues(RequestHandler):
3    def get_all_trading_venues(self):
4        endpoint = 'venues/'
5        response = self.get_data(endpoint)
6        print(response)
7if __name__ == "__main__":
8    TradingVenues().get_all_trading_venues()

If you use this endpoint and take a closer look at the request response, you will notice that for the lemon.markets beta version we currently only support one trading venue. However, keep your eyes peeled for additional trading venues. In the future, we expect lemon.markets to integrate several different stock exchanges, which means even more stocks, bonds, funds, ETFs and warrants from which to choose. Obviously, our users will be the first to know when we integrate additional trading venues.

Besides getting an overview of all available trading venues, you can also retrieve a single trading venue through this endpoint:

1https://paper-data.lemon.markets/v1/venues/?mic={mic}

Again, we are using Python to showcase a specific code snippet. Notice the “{mic}” in the request URL? This is the place where you can specify the trading venue you are interested in. It stands for“Market Identifier Code”.In our script, this is solved by setting an environment variable, which we then use inside the request URL, but you can obviously also set it manually if you are building a different kind of use case.

1import os 
2from dotenv import load_dotenv
3from helpers import RequestHandler  
4class SingleTradingVenue(RequestHandler):    
5   def get_single_trading_venue(self):        
6        load_dotenv()        
7        mic = os.getenv("MIC")        
8        endpoint = f'venues/?mic={mic}'        
9        response = self.get_data_data(endpoint)        
10        print(response)  
11
12if __name__ == "__main__":   
13     SingleTradingVenue().get_single_trading_venue()

Using this endpoint will result in the following response.

1{ 
2  “name”: “Example Stock Exchange”, 
3  “title”: “stex”, 
4  “mic”: “XEXAMPLE”, 
5  “is_open”: true 
6}

As you can see, besides general information about the trading venue, the endpoint also returns whether the trading venue is currently open, which in our opinion is a valuable piece of information that you can very easily integrate into your trading strategy. We will come to that in a second and show you a specific example of how you can set up a simple email notification that tells you when a trading venue is closed.

Each Trading Venue has a list of instruments that are tradable there, and you can conveniently find out which ones those are using the following endpoint:

1https://paper-data.lemon.markets/v1/instruments/?mic={mic}&search=SEARCHTERM

In the code snippet below, we are searching for Tesla and the type = stock, but you can also use other query parameters, such as the currency or whether it is currently tradable. Also, you can search for ISIN or WKN if you like those better. The more narrow you define your query parameters, the more specific your results will be.

1import os
2from dotenv import load_dotenv
3from helpers import RequestHandler  
4
5class TradingVenueInstrument(RequestHandler):    
6  def get_trading_venue_instruments(self):        
7        load_dotenv()        
8        mic = os.getenv("MIC")        
9        endpoint = f'instruments/?mic={mic}&search=Tesla&type=stock'
10        response = self.get_data_data(endpoint)
11        print(response)
12if __name__ == "__main__":
13    TradingVenueInstrument().get_trading_venue_instruments()

Opening Times

One of the most requested features for our prototype that we launched in autumn last year was the possibility to check trading venue opening times. We took this feedback to heart and integrated just that.

With our API, you have to option to request the opening days and times of a certain Trading Venue. For this, we have built the following endpoint:

1https://paper-data.lemon.markets/v1/venues/?mic={mic}

The code snippet below returns a list of days with specific opening and closing times.

1import os
2from dotenv import load_dotenv
3from helpers import RequestHandler  
4class TradingVenueOpeningDays(RequestHandler):
5    def get_trading_venue_opening_days(self):
6        load_dotenv()
7        mic = os.getenv("MIC")
8        endpoint = f'venues/?mic={mic}'
9        response = self.get_data_data(endpoint)
10        opening_days = response['results'][0].get('opening_days', None)
11        print(opening_days)
12 if __name__ == "__main__":
13    TradingVenueOpeningDays().get_trading_venue_opening_days()

With the response, you get the current and all future days and you can use that information to adapt your strategy so that it only places orders when the trading venue is actually open. This avoids a scenario where you place an order, only to realise it is a Saturday and the order will not be filled for another two days. Or to place a market order after close, only to have it filled at an undesirable opening price the next morning.

As you can see, you get the UNIX Timestamps for the current and all future days and you can use that information to adapt your strategy so that it only places orders when the trading venue is actually open. This avoids a scenario where you place an order, only to realise it is a Saturday and the order will not be filled for another two days. Or to place a market order after close, only to have it filled at an undesirable opening price the next morning.

But it does not have to be! By incorporating the opening times of your chosen market, you can configure your strategy such that, for example, unfilled orders expire after market close, no new orders are placed during the most volatile times of the trading day or you are notified when the market opens and closes.

A little Use Case

We at lemon.markets aim to provide you with content that easily lets you start building things and hopefully inspires you to some extent. We created a little Python script that checks whether the trading venue is currently open. If it is, your order is placed. If it is not, you get an automatic email telling you about it. Additionally, the script sends you an automated email at market close that tells you about your portfolio items.

As mentioned above, we use Sendgrid to send emails and we highly recommend you do so as well, as it integrates with your python script perfectly.

As a start, we define a few helper functions:

  1. a function to get the “next closing time”. For that, we retrieve the first element of the json array containing opening and closing times for the specific trading venue and return the first array element.
  2. a function to get the portfolio. For that, we use the portfolio endpoint, transform the json response into a string and pass it to our “send email” function (see below).
  3. a function that sleeps until the market closes and then sends out an email with the portfolio items. We determine the current time as UNIX timestamp and subtract it from the next market close. Then we send the function into a well deserved sleep and retrieve our portfolio “when it wakes up”.
  4. a function to check whether the specific trading venue is currently open. We use the endpoint to retrieve a single trading venue, access the “is_open” attribute and return the boolean value.
  5. a function to activate a placed order. In our paper money API, you will have to activate all orders after you placed them. This helper function takes the Order UUID as an input parameter and calls the activate order endpoint afterwards.

Finally, we can define our main function: place_order(). Here, all of our previously defined helper functions come in handy. We first check if the trading venue is currently open. If it is not, we send out an email saying that market is currently closed. If it is, we place our order. Additionally, we wait until the market closes and then send out the email containing our portfolio at market close.

1import os
2from dotenv import load_dotenv
3import json  
4from helpers import RequestHandler, EmailSenderSendgrid  
5
6class TradingVenue(RequestHandler):
7        def send_out_email(self):
8        load_dotenv()
9        space_uuid = os.getenv("SPACE_UUID")
10        endpoint = f'spaces/{space_uuid}/portfolio/'
11        response = self.get_data_trading(endpoint)
12        email_text = json.dumps(response)
13        subject = "Your Portfolio at market close"
14        EmailSenderSendgrid(email_text, subject)
15
16     def check_if_open(self):
17        load_dotenv()
18        mic = os.getenv("MIC")
19        endpoint = f'venues/?mic={mic}'
20        response = self.get_data_data(endpoint)
21        is_open = response['results'][0].get('is_open', 'It was not possible to retrieve the is_open attribute')  
22        print(is_open)
23        return is_open    
24  def activate_order(self, order_uuid):
25        load_dotenv()
26        space_uuid = os.getenv("SPACE_UUID")
27        endpoint = f'spaces/{space_uuid}/orders/{order_uuid}/activate/'
28        response = self.put_data(endpoint)
29        print(response)     def place_order(self):
30             load_dotenv()
31            if not self.check_if_open():
32            email_text = "Hey there. You tried to place an order with the lemon.markets API, but the market is currently closed. Please try again later."
33            subject = "The market is currently closed"
34            EmailSenderSendgrid(email_text, subject)
35            return         # send notification email if trading venue is closed
36                 try:            order_details = {
37                "isin": "DE0008232125",  # ISIN of Lufthansa
38                "valid_until": 2000000000,  # specify your timestamp
39                "side": "buy",
40                "quantity": 1,
41            }
42            space_uuid = os.getenv("SPACE_UUID")
43            endpoint = f'spaces/{space_uuid}/orders/'
44            response = self.post_data(endpoint, order_details)
45            order_uuid = response.get('uuid')
46            # access helper function to activate the order
47            self.activate_order(order_uuid)
48            print('order was activated')
49            # additionally, we send an email with the portfolio items at market close
50            self.send_out_email()
51        # throw exception in case something goes wrong
52        except Exception as e:
53            print('placing order not possible', e)
54if __name__ == "__main__":    TradingVenue().place_order()

Obviously, this little script is only a point of departure for you that shows you how to specifically use our trading venue endpoints to bring more flexibility and stability to your automated trading strategy. If you are interested, take a look at our public GitHub repository that accompanies this blog post and open a pull request. How about we send another email when the market reopens? How about we wait a little bit until we activate the order to get the best possible price? How about we place the order the next morning 2 hours after the trading venue opens. Feel free to play around with it and go crazy 😵. We are super excited to see your ideas.

What else to do with the Trading Venue endpoints?

While we covered a basic use case above, there are a lot of other interesting ideas for our trading venue endpoints.

Perhaps consider connecting your program to your calendar to automatically mark the days on which the market is closed. We suggest calling upon the GET /trading-venues/{mic}/opening-days endpoint to obtain all the opening days of a given trading venue. For any day not included in the list, you can assume that the market is closed. You may also want to filter out weekends because we know that the market is closed then. These days can be fed into, for example, the Google Calendar API. Then, using the calendars() and events() resources both a new calendar and corresponding events can be created.

You can also configure your program to send an automated email outlining how your portfolio has performed once the market closes. This can be achieved by requesting the same endpoint as above, GET /trading-venues/{mic}/opening-days, and when “closing_time” matches the current time, to trigger an e-mail notification using the same email resource as in the use case we shared above. In the e-mail, you might want to simply report the overall growth of your portfolio, by comparing the value of your portfolio at market close to that of the day before (try using the GET spaces/{space_uuid}/portfolio endpoint, more information about Spaces can be found here). You might even want to get fancy by measuring performance using a (Python) library such as f.fn(). If you’re not a big fan of receiving emails: how about automatically updating your own trading dashboard at the end of each day with your portfolio value at the market close? We hate to repeat ourselves, but the possibilities are (almost) endless.

Do you have additional ideas? We would love to hear (and obviously see) what kinds of interesting applications for the Trading Venue endpoints you come up with.

To start building, make sure you sign up to our waitlist to test out this API concept out in real life. Feel free to reach out to us by leaving a comment, emailing us at [email protected] or joining our growing Slack community.

See you on lemon.markets 🍋

Joanne

You might also be interested in

Setting up your own Telegram bot to trade with the lemon.markets API (Part 1 of 2)

blog photo

Hi! My name is Joanne and I’m part of the team at lemon.markets. I’ve been working on a fun use-case for our product for the past few weeks and I’m very excited to share it with you! There’s hundreds of use-cases for our product, from automated trading strategies to portfolio visualisation dashboards. Today, I’ll show you how you can connect the lemon.markets API to the Telegram API. Why? So you can have a personalised butler — ahem, bot — that can place trades with a few very simple messages.

Creating your own lemon.markets Dashboard using Flutter

blog photo

Hey there. My name is Marius, and I am part of lemon.markets, an early-stage startup from the heart of Berlin that is working on an infrastructure that lets you build your own brokerage experience at the stock market. In this blog post, I will walk you through a project developed by our community member Melanie, where we will tackle the basics of building your own mobile-optimised Trading dashboard using Flutter. Does that sound like fun to you? Then let’s not waste any more time and get going.

Building a Mean Reversion Strategy with the lemon.markets API & hosting it in the cloud

blog photo

In this post, I want to diveinto how you can use the lemon.markets API to build one of the most well-known trading strategies: the Mean reversion Strategy. And, to set you up for success, I will also walk you through the steps to host your strategy up in the cloud using Heroku, to make sure your program continues to run, even when your laptop is closed.

Dive Deeper

Find more resources to get started easily

Check out our documentation to find out more about our API structure, different endpoints and specific use cases.

Engage

Join lemon.markets community

Join our Slack channel to actively participate in our community, ask questions to other users and stay up to date at all times.

Contribute

Interested in building lemon.markets with us?

We are always looking for great additions to our team that help us build a brokerage infrastructure for the 21st century.

Products
Pricing
For Developers
SlackGithubBlog
© lemon.markets 2021Privacy PolicyImprint
All systems normal