Creating your own lemon.markets Dashboard using Flutter


blog photo
Published by Marius Sprenger on September 16, 2021
Insights


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.

Community involvement was and is one of the key ingredients of lemon.markets. We are building a product for developers, therefore the only reasonable thing to do when designing such a product is to continuously ask our users for their input on specific product decisions. We are on a good way to creating an active community that is closely involved in our development process, and we will continue to really listen to what our users want.

Besides getting feedback on specific API functionality, we are also trying to better understand what our users are actually building. To us, it is really fulfilling to see all the community projects that are slowly coming to life, and we will always help to improve them wherever we can. A while ago, we reached out to our beta users and asked if there might be a way to collaborate and create content pieces out of their projects to inspire other (soon-to-be) users to start building. Melanie told us about her Flutter project, in which she is working on her own custom mobile dashboard that allows her to conveniently monitor her portfolio. We were immediately hooked.

Melanie was one of the first people we onboarded to lemon.markets and she has been an active contributor ever since. When the pandemic hit in early 2020, she started to develop a general interest for trading and the stock market. However, being a professional developer (by day, she is a Java software developer in the logistics area) with the corresponding mindset, she quickly realized that she would enjoy using a service that allows her to automate her tradings and provides reliable market data. Therefore, she started looking for something in Germany that offered her that flexibility. Luckily, she stumbled across lemon.markets. She immediately saw the advantages of the product we are building and quickly started developing her first project with it: her own trading dashboard, built with Flutter.


She told us that she enjoys the freedom to create a dashboard that is perfectly adapted to her needs, instead of using a (web) app that would always feel like a compromise. With lemon.markets, she can design a project just for herself and her use case.

When she is not working on advancing her dashboard (although it is hard to imagine that someone would not use every free minute with lemon.markets 😉), she enjoys spending time in her garden, where she tries to not let her planted vegetables go dry. Also, she likes to tackle additional tech/dev projects, whenever she finds the time. Being married with two young kids, that is not always easy, though (it was really fun to be in Zoom calls with Melanie right after she finished work and before her kids came home from school).


We love this project, as it perfectly captures how we think about lemon.markets. In the end, we are an API-first company, which means that we will dedicate most of our resources to building stable and convenient programming interfaces. Even though there will always be a number of visual touch points, they will always only be supplements to our API(s). Other companies are successfully providing a frontend-first experience in brokerage, but that is not our way to go: we want to silently run in the background. Our vision is that, in a few years, a large majority of European citizens will regularly buy stocks at the stock market through different providers without realizing that these providers are “powered by lemon.markets”. We obviously have a long way ahead of us, but projects like the one from Melanie really motivate us to keep going and improve/expand our services.

Working with Flutter

Melanie decided to build her own trading dashboard using Flutter. Before we dive into the advantages of Flutter, let us first clarify what Flutter even is:

Flutter is an Open-Source UI Development Kit by Google that was released in 2017. It quickly gained popularity, which the following graphic confirms, as it shows the share of cross-platform mobile frameworks used by software developers worldwide from 2019 to 2021.

Source: Statista

What does cross-platform framework mean?

Well, with a growing number of devices and operating systems, writing apps for each one independently can be quite a challenge that is both time consuming and expensive. That is why, in recent years, cross-platform frameworks have emerged. Those frameworks allow you to write a code only once and then ensure that the applications/software is capable of running on several different platforms such as Android, iOS, macOS, Windows or Linux. Naturally, usage of those frameworks has increased steadily (we ourselves are using React Native to build our mobile app) and many developers are building beautiful projects with it that work on many different platforms in an (almost) identical way.

Actually, some of the most widely used apps are developed with cross-platform frameworks, such as Facebook, Instagram and Tesla (React Native) or Google Ads and Groupon (Flutter). As you can see above, React Native and Flutter are head-to-head when it comes to the share of developers who use either one or the other, with Flutter marginally overtaking React Native in 2021.

Why Flutter, then?

While we do not want to get too deep into the discussion on Flutter vs. React Native (there are some interesting articles herehere and here), we still want to take a minute to outline why building a project with Flutter might be a good idea:

  • The Flutter documentation is extensive and it helps you to easily get started with your project. There is also the Flutter Doctor that guides you through the Flutter setup so that everything is working as intended and you can create a new project straight away. In general, the extensive resources to get started with Flutter lead to a comparatively low entry burden.
  • The Hot Reload functionality included in Flutter is a huge selling point. It basically allows you to instantly see your code changes in action, which dramatically speeds up the development process and makes collaboration with, e.g., the design apartment super convenient.
  • Flutter comes with a large number of components that basically allow you to build any mobile app you can imagine. Due to the included widget, you have every UI element you need, preventing the need to include third-party providers. Also, there is a large community around the framework, which means that an answer to any question imaginable is only one click away.

When we talked to Melanie about the advantages of Flutter, she also mentioned the rich GUI toolkit that allows you to build beautiful UIs very easily. Also, she likes that, besides the mobile app, you automatically get a web app through the same code base as well. And (which may be one of the most important aspects): Melanie has a lot of fun using Flutter.

Creating a lemon.markets Trading Dashboard

As mentioned above, one of Melanie’s main arguments for using lemon.markets was the possibility to create a custom project with it, a trading dashboard in her case. Melanie quickly noticed the need for a Flutter lemon.markets SDK that would make her development life easier.

First things first: A Flutter lemon.markets SDK

As a result of working on the dashboard project, the Flutter lemon.markets SDK pretty much emerged as a “side effect”. If you are interested in building you own mobile app with lemon.markets, check out the corresponding GitHub repository.

The Flutter SDK allows you to conveniently use most of the lemon.markets API functionality such as seeing your state and spaces, retrieving your portfolio, placing and activating an order, seeing previous orders and transactions or searching for specific instruments. It is a great starting point if you want to get started with building your own brokerage (mobile) application and you are highly encouraged to contribute to it.

Next things next: Building the Dashboard

You can find Melanie’s Dashboard project here. You are greeted with a simple 3 tab Interface at the bottom. Through the settings symbol, you have the option to add a Space to the dashboard. You can also conveniently search for different instruments by using the search tab. You additionally have the option to filter for stocks, bonds, ETFs, etc.

Dashboard View. Here, we are using the search function to find Tesla equities.

Under the portfolio tab, you can access sub pages for the spaces you connected to the Dashboard via your client ID/client secret. All portfolio items are listed below each other and you can get specific information by clicking on them.

This will bring you to a sub page that provides you with additional options. You can see a performance graph for the specific instrument, which you can filter for day, week and month. Also, you can see at which price the instrument is currently traded and you even have the option to buy more shares of it or sell some of your existing shares.

If you click on the third tab, you get a nice overview of all your orders and transactions. You can conveniently scroll down the list get the most important information at a glance. Pretty cool, right?

Sooo: how do I do this on my own?

Going into extensive detail on the complete implementation of the Flutter Dashboard would go beyond the scope of this blog post, but we still want to take a moment to focus on a few key steps so you get a general understanding of the project structure. You can find an example implementation here.

Before you start, make sure that you have the Flutter SDK and a suitable IDE installed. If you are new to Flutter, we recommend that you dig yourself through the documentation first.

Adding the lemon.markets SDK to your Project

After you’ve created a new project in your IDE, you need to install the lemon.markets SDK to be able to use it throughout your project. As the SDK is not published on pub.dev, yet, you need to use a different approach:

Go to the SDK GitHub repository and git clone the project. Afterwards, you can add the package in the pubspec.yaml file through:

1dependencies:
2  flutter:
3    sdk: flutter
4
5  lemon_markets_client:
6    path: "../lemon_market_client"

Alternatively, you can also directly refer to the GitHub URL:

1dependencies:
2  flutter:
3    sdk: flutter
4  lemon_markets_client:
5    git:
6      url: https://github.com/stormqueen23/lemonMarketsClient.git

More details on how to add packages to your app can be found here. Now, all you need to is run:

1flutter pub get

and you can use the SDK in your project.

Getting Started

The example project uses some other packages besides the lemon.markets SDK. The most important are provider and get_it. The provider package is used to hold the state of the application and the get_it package manages all service calls.

As a first step, we want to create a home screen, which takes place in the main.dart() file and which is our only screen throughout the app. We can do that through:

1class LemonMarketsDashboardApp extends StatelessWidget {
2  @override
3  Widget build(BuildContext context) {
4    return MaterialApp(
5      title: 'Lemon markets dashboard',
6      theme: ThemeData(
7        primarySwatch: Colors.yellow,
8      ),
9      darkTheme: ThemeData(
10        brightness: Brightness.dark,
11        primarySwatch: Colors.yellow,
12        accentColor: Colors.yellow,
13        tabBarTheme: TabBarTheme(indicator: BoxDecoration(color: Colors.yellow), labelColor: Colors.grey[800], unselectedLabelColor: Colors.yellow),
14      ),
15      themeMode: ThemeMode.dark,
16      home: HomeScreen(),
17    );
18  }
19}

Since you need a lemon.markets account and respectively space credentials for using the lemon.markets SDK, we want to create two different widgets to deal with a scenario where the space credentials are provided and one where they are not.

  1. No credentials can be found (AddSpaceWidget)
  2. Credentials can be found (MainTabWidget)
1class HomeScreen extends StatelessWidget {
2  
3  HomeScreen({Key? key}) : super(key: key);
4  @override
5  Widget build(BuildContext context) {
6    return FutureBuilder(
7      future: context.read<LemonMarketsProvider>().init(),
8      builder: (context, projectSnap) {
9        if (projectSnap.connectionState != ConnectionState.done) {
10          return Scaffold(body: LemonLoadingWidget());
11        }
12        return HomeWidget();
13      },
14    );
15  }
16}
17class HomeWidget extends StatelessWidget {
18  const HomeWidget({Key? key}) : super(key: key);
19  @override
20  Widget build(BuildContext context) {
21    AuthData? currentSpace = context.watch<LemonMarketsProvider>().selectedSpace;
22    bool noSpace = currentSpace == null;
23    return noSpace
24        ? Scaffold(
25            appBar: AppBar(
26              centerTitle: true,
27              title: Text('- No Space -'),
28            ),
29            body: Center(child: AddSpaceWidget()),
30          )
31        : MainTabWidget(currentSpace: currentSpace);
32  }
33}

The lemon.markets Provider

In order to find out which widget should be displayed we need the LemonMarketsProvider. It handles all application-wide data like the selected space. So, on a high level in our widget tree we need to initialise this provider to get the relevant data for the whole application. The init() method checks whether authentication data was saved or not.

If no authentication data can be found we want to have the possibility to add the credentials. The AddSpaceWidget provides two input fields for adding a clientId / a clientSecret and a button that sends this data to our LemonMarketsProvider:

1String? manualClientId;
2String? manualClientSecret;
3...
4ElevatedButton(
5	onPressed: manualClientId != null && manualClientSecret != null
6		? () => context.read<LemonMarketsProvider>().addSpace(manualClientId!, manualClientSecret!) : null,
7	child: Text('add'),
8)

The LemonMarketsProvider receives this call and collects all the data that is needed: (and maybe persists the data)

1class LemonMarketsProvider with ChangeNotifier {
2	LemonMarketService _marketService = GetIt.instance<LemonMarketService>();
3	
4	AuthData? selectedSpace;
5	...
6	
7	Future<void> addSpace(String clientId, String clientSecret) async {
8		AuthData authData = AuthData(clientId, clientSecret);
9		
10		AccessToken? _token = await _marketService.requestToken(authData.clientId, authData.clientSecret);
11		authData.token = _token;
12		
13		ResultList<Space>? spacesForId = await _marketService.getSpaces(authData.token!);
14		
15		if (spacesForId != null) {
16		  if (spacesForId.result.isNotEmpty) {
17			authData.spaceUuid = spacesForId.result.first.uuid;
18			authData.spaceName = spacesForId.result.first.name;
19		  }
20		}
21		
22		selectedSpace = authData;
23		notifyListeners();
24  }
25  
26}

After finishing this step, we now have our first contact with the lemon.markets SDK, as we want to retrieve an access token for the provided client ID and client secret. After receiving the token, we want to get some additional information for the space (e.g. the UUID, as we need that for some of the endpoints). As the overall goal is to encapsulate all API calls in a service we have the LemonMarketService.

The LemonMarketService

This is the place where all the SDK calls happen. At first, we need to create an instance of LemonMarkets. Via this class we have access to all endpoints of the lemon.markets API that the lemon.markets Flutter SDK supports. For now we need a function to request an access token and get some space detail data:

1class LemonMarketService {
2 
3  LemonMarkets _market = LemonMarkets();
4  Future<AccessToken?> requestToken(String clientId, String clientSecret) async {
5    try {
6      AccessToken result = await _market.requestToken(clientId, clientSecret);
7      return result;
8    } on LemonMarketsException catch (e) {
9      throw LemonMarketsError(e.toString());
10    }
11  }
12  
13  Future<ResultList<Space>?> getSpaces(AccessToken token) async {
14    try {
15      ResultList<Space> result = await _market.getSpaces(token);
16      return result;
17    } on LemonMarketsException catch (e) {
18      throw LemonMarketsError(e.toString());
19    }
20  }
21}

Now we have all the required data (Access Token and Space UUID), which allows us to make all further requests and thus, get all the data required for our application.

The MainTabWidget

Once you have entered your credentials you are greeted with a screen with two tabs. The search tab and the portfolio tab. Both tabs have one or more widgets for displaying the data and a provider for their state management.

Search Tab

The search tab is very simple. It contains a drop down button for the different instrument types, a text field and a button that starts the search. The different search types are represented by the enum SearchType from the lemon.markets SDK. In the text field you can enter the query you want to search for and subsequently press the button that starts the search. In the widget:

1IconButton(
2  icon: Icon(
3    Icons.search,
4  ),
5  onPressed: () {
6    if (!searching) {
7      context.read<SearchProvider>().searchInstruments(widget.authData);
8    }
9  },
10)

For the search you need the AccessToken that was received earlier in the LemonMarketsProvider. The search is done in the SearchProvider who delegates it to the MarketService:

1class SearchProvider with ChangeNotifier {
2  LemonMarketService marketService = GetIt.instance<LemonMarketService>();
3  
4  String? searchString;
5  SearchType searchType = SearchType.stock;
6  
7  List<Instrument> instruments = [];
8  String? previousUrl;
9  String? nextUrl;
10  
11  void searchInstruments(AuthData authData) {
12    marketService
13        .searchInstruments(authData.token!, search: searchString, type: searchType)
14        .then(
15          (result) {
16            if (result != null) {
17              this.instruments = result.result;
18              this.nextUrl = result.next;
19              this.previousUrl = result.previous;
20            }
21          },
22    );
23    notifyListeners();
24  }
25}

Additionally, the Market Service needs one more method:

1Future<ResultList<Instrument>?> searchInstruments(AccessToken token, {String? search, SearchType? type, bool? tradable, String? currency, String? limit, int? offset}) async {
2    try {
3      ResultList<Instrument> result = await _market.searchInstruments(token, currency: currency, limit: limit, offset: offset, query: search, tradable: tradable, types: type != null ? [type] : null);
4      return result;
5    } on LemonMarketsException catch (e) {
6      throw LemonMarketsError(e.toString());
7    }
8  }

As you can see the search for instruments returns the type ResultList. This is a type from the lemon.markets SDK that, besides of the results, contains a url for the previous and next results. You can use this url for pagination. Depending on whether this next (or previous) is set, a button is displayed that triggers the search for the next url In the widget:

1context.watch<SearchProvider>().nextUrl != null ? IconButton(
2   icon: Icon(
3      Icons.forward,
4   ),
5   onPressed: () {
6      if (!searching) {
7         context.read<SearchProvider>().searchNext(widget.authData);
8      }
9   },
10)
11: Container(),

In the SearchProvider:

1void searchNext(AuthData authData) {
2 if (nextUrl != null) {
3   marketService
4       .searchInstrumentsByUrl(authData.token!, nextUrl)
5       .then(
6         (result) {
7       if (result != null) {
8         this.instruments = result.result;
9         this.nextUrl = result.next;
10         this.previousUrl = result.previous;
11       }
12     },
13   );
14   notifyListeners();
15 }
16}

In the marketService:

1Future<ResultList<Instrument>?> searchInstrumentsByUrl(AccessToken token, String url) async {
2   try {
3      ResultList<Instrument> result = await _market.searchInstrumentsByUrl(token, url);
4      return result;
5   } on LemonMarketsException catch (e) {
6      throw LemonMarketsError(e.toString());
7   }
8}

For all API calls that return the type ResultList, a second method exists where you just need the AccessToken and the url as parameters. In this case, the complete function is:

1searchInstruments(token, currency: currency, limit: limit, offset: offset, query: search, tradable: tradable, types: type != null ? [type] : null)

and the corresponding function with just the url:

1searchInstrumentsByUrl(token, url)

Finally we need a widget to display the result of our instrument search. In our example this is a ListView:

1ListView(
2   children: _getAllInstruments(context),
3)
4...
5List<Card> _getAllInstruments(BuildContext context) {
6   List<Card> result = [];
7   context.watch<SearchProvider>().instruments.forEach((element) {
8      ListTile tile = ListTile(
9         title: Text('${element.title}'),
10         subtitle: Text('${element.isin}'),
11        );
12      result.add(Card(child: tile));
13   });
14   return result;
15}

Alright, that’s it. Our Search Tab is done. Time to rest a little.

The Portfolio Tab

Did you take a deep breath and found your inner peace again? Good, then let’s continue.

In general, the Portfolio Tab is a bit more complex. It first collects data from different endpoints before it displays the (aggregated) information. Similar to the Search Tab, it has a provider for storing the data and different widgets for displaying them.

Let’s take a look at the Portfolio Provider. During the init() method it collects all data that is needed to display the basic structure of the portfolio view with all items in the portfolio and the balance of the current space. Thus, it:

  1. receives the current state of the space (used to display balance and the cash to invest)
  2. receives all portfolio items.
1class PortfolioProvider with ChangeNotifier {
2   ...
3   Future<void> init(AuthData authData) async {
4      spaceStateDetails = await _marketService.getSpaceState(authData);
5      items = await _marketService.getPortfolioItems(authData);
6      ...
7   }
8}

For this we need two new methods in our MarketService:

1Future<SpaceState?> getSpaceState(AuthData authData) async {
2 try {
3   SpaceState state = await _market.getSpaceState(authData.token!, authData.spaceUuid!);
4   return state;
5 } on LemonMarketsException catch (e) {
6   throw LemonMarketsError(e.toString());
7 }
8}
9Future<List<PortfolioItem>> getPortfolioItems(AuthData authData) async {
10 List<PortfolioItem> result = [];
11 try {
12   ResultList<PortfolioItem> tmp = await _market.getPortfolioItems(authData.token!, authData.spaceUuid!);
13   result.addAll(tmp.result);
14   String? nextUrl = tmp.next;
15   while (nextUrl != null) {
16     tmp = await _market.getPortfolioItems(authData.token!, nextUrl);
17     result.addAll(tmp.result);
18     nextUrl = tmp.next;
19   }
20 } on LemonMarketsException catch (e) {
21   throw LemonMarketsError(e.toString());
22 }
23 return result;
24}

Again, the lemon.markets SDK returns something of type ResultList for the portfolio items endpoint.

1ResultList<PortfolioItem> tmp = await _market.getPortfolioItems(authData.token!, authData.spaceUuid!);

We have seen this before in the searchInstruments() method, but here we handle it a little bit different. Since we need all items for calculating the current portfolio sum, we repeat calling the function for getting the portfolio items unless there are no more items to catch.

1while (nextUrl != null) {
2     tmp = await _market.getPortfolioItems(authData.token!, nextUrl);
3     ...
4}

After getting the Space state and the portfolio items, we now have all data to display the basic structure of our portfolio list and we can start rendering the UI. We use a FutureBuilder to show a loadingWidget until all data in the init() method has been collected.

1FutureBuilder(
2   future: context.read<PortfolioProvider>().init(widget.authData),
3   builder: (context, projectSnap) {
4     if (projectSnap.connectionState != ConnectionState.done) {
5       // space state and portfolio items are loading
6       return Center(child: CircularProgressIndicator());
7     }
8     // space state and portfolio items received!
9     return Padding(
10       padding: const EdgeInsets.all(16.0),
11       child: PortfolioWidget(),
12     );
13   },
14 ),

The last step during the init() method is calling the endpoints for latest quote for each portfolio item and all orders. We use the latest quote to calculate and display the current value of each portfolio item. The orders are used to display the buy and sell dates for each item. We do not need to wait for the result of those calls, as the UI can be updated in the moment a result is received. In the PortfolioProvider:

1Future<void> init(AuthData authData) async {
2   ...
3   _initLatestQuoteForItems(authData);
4   _initOrdersForItems(authData);
5}
6void _initLatestQuoteForItems(AuthData authData) {
7 items.forEach((element) {
8   _marketService.getLatestQuote(authData, element.instrument.isin).then((value) {
9     latestQuotes[element.instrument.isin] = value;
10     if (_latestQuotesInitialized()) {
11       _calculateSum();
12       sumInitialized = true;
13     }
14     notifyListeners();
15   });
16 });
17}
18void _initOrdersForItems(AuthData currentSpace) {
19 _marketService.getOrders(currentSpace, null, OrderStatus.executed).then((value) {
20   value.forEach((element) {
21     existingOrders[element.instrument.isin]?.add(element);
22     if (element.processedAt != null) {
23       notifyListeners();
24     }
25   });
26 });
27}

Therefore, we need two new methods in the MarketService:

1Future<Quote?> getLatestQuote(AuthData authData, String isin) async {
2 try {
3   Quote? result;
4   ResultList<Quote>? all = await _market.getLatestQuotes(authData.token!, [isin]);
5   result = all.result.where((element) => element.isin == isin).first;
6   return result;
7 } on LemonMarketsException catch (e) {
8   throw LemonMarketsError(e.toString());
9 }
10}
11Future<List<ExistingOrder>> getOrders(AuthData authData, OrderSide? side, OrderStatus? status) async {
12 List<ExistingOrder> result = [];
13 try {
14   ResultList<ExistingOrder> tmp = await _market.getOrders(authData.token!, authData.spaceUuid!, side: side, status: status);
15   result.addAll(tmp.result);
16   String? nextUrl = tmp.next;
17   while (nextUrl != null) {
18     tmp = await _market.getOrdersByUrl(authData.token!, nextUrl);
19     result.addAll(tmp.result);
20     nextUrl = tmp.next;
21   }
22 } on LemonMarketsException catch (e) {
23   throw LemonMarketsError(e.toString());
24 }
25 return result;
26}

The result of the getOrders endpoint is again of type ResultList and as we have seen before in the getPortfolioItems() method, we want to get all of them to find out all dates of buying and selling an instrument. So we keep calling the endpoint for the orders unless there is no nextUrl.

That’s pretty much all the logic we need to display the portfolio tab. Finally we need some widgets to display our data. We have an expandable header that displays the sums for the portfolio and again a listView that displays all information for the portfolio items:

1class PortfolioWidget extends StatelessWidget {
2 
3  @override
4  Widget build(BuildContext context) {
5    return Column(
6      children: [
7        PortfolioHeaderWidget(),
8        Container(
9          height: 8,
10        ),
11        Expanded(
12          child: PortfolioItemsListWidget(),
13        ),
14      ],
15    );
16  }
17}

Aaand, this concludes our little example tutorial. As you could see, we built a small Dashboard with two tabs (Search and Portfolio) using the lemon.markets Flutter SDK. We hope you could follow the implementation steps and are now motivated to build your own mobile application with lemon.markets 👩‍💻 👨‍💻.

Possible extensions

While Melanie’s Dashboard already uses many of our endpoints to create a customised trading dashboard, there are still (almost) a million possible extensions and we want to take a minute to recognise them.

For example, you might be interested in learning more about your portfolio development over time. You could build a graph that visualises how your portfolio items are performing. You could also build a nice pie chart to see the distribution of portfolio items.

How about updating the price development graph for the instruments so that it additionally displays the quotes besides the OHLC data? Or maybe include a real-time price stream on the instruments page (this can only be done when we provide the live market data, we are working on it 😬).

You could also use external data sources to provide even more information on different instruments. How about including a news section on each instruments sub page that displays current news articles, e.g. when Tesla once again presents a crazy feature they’re working on (human-like robots that walk around. Really, Elon?).

We are really excited and a little bit proud that we were able to present Melanie’s Flutter project. If you are as early-stage as we are, it’s really nice to see community projects come to life that perfectly embody our take on lemon.markets. We hope you had fun reading this article, got inspired to build your own dashboard (or brokerage project in general) and were able to follow the implementation.

Once again, you can find the GitHub repo for the lemon.markets Flutter Wrapper here, an example project here and the current project version here.

And of course, don’t forget to sign up to lemon.markets here.

We are looking forward to welcoming you on lemon.markets very soon.

Marius and the 🍋.markets Team

You might also be interested in

Mapping a Ticker Symbol to ISIN using OpenFIGI & lemon.markets

blog photo

When you start trading on different exchanges, you’ll notice that sometimes they have unique ways of identifying financial instruments. For example, US exchanges often use tickers, whereas German exchanges reference an ISIN. And sometimes, moving between these symbologies isn’t as smooth as you’d expect.  Instead, automate the process by writing (less than 10 lines of) code to make this ‘translation’ for you. Keep reading to learn how you can use the OpenFIGI and lemon.markets APIs to map tickers to ISINs.

10 mistakes when it comes to (automated) trading & how to avoid them

blog photo

Hi! My name is Joanne and I’m part of the lemon.markets team in Berlin. We’re building a brokerage API to enable developers to curate their own stock market experience. Along with that, we hope to foster an environment where users can find and share their knowledge on the intersection between algorithm development and the stock market, among other things. We want to contribute to this conversation as well, and that’s why we’ve gathered a list of ten mistakes that those beginning in automated trading (and, to be fair, sometimes even seasoned pros) might make. But, most importantly, we’ve also listed how you can avoid them. 

Integrating lemon.markets into your Telegram bot (Part 2 of 2)

blog photo

Hi! I’m Joanne and I’m part of the team at lemon.markets. We’re a Berlin-based start-up powering programmatic trading via APIs. Our goal is to provide the tools to allow developers to design their own brokerage experience at the stock market. There’s about a hundred and one use-cases for our product, one of them being to create your own frontend interface to place trades. You could start from scratch or you could use a preexisting service, like Telegram. In this article, I’ll be extending the project presented in our previous article. We’ll be adding various conversation states that communicate with the lemon.markets endpoints.

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