Tradingbot Sample
Tradingbot Sample
Shekhar Varshney
This book is for sale at http://leanpub.com/tradingbot
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing
process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and
many iterations to get reader feedback, pivot until you have the right book and build traction once
you do.
1
Introduction to Trading Bot 2
which can be setup on a unix cron² to run every hour, during trading hours. It has no strategy,
nor any external interface or dependencies. It is a one liner to place an order which has an equal
probability to be in profit or in loss.
On the other end of the spectrum, it could be a complex program based on a distributed architecture,
consuming lots of feeds from various sources, analysing them in realtime and then placing an order.
It would be highly available with extremely low latency.
The scale and scope of the bot, as we can see is varied. To be effective, the bot should be able to
accomplish the following tasks:
• Consume market data and/or ,external news events, social media feeds and distribute to
interested components within the system.
• Have atleast one strategy which provides a trading signal.
• Based on a trading signal place Orders with the brokerage platform.
• Account management, i.e., have the ability to keep track of margin requirements, leverage,
PNL, amount remaining etc. in order to curb trading if the amount available breaches a given
threshold.
• Position Management i.e. keep track of all currently active positions of various instruments,
units of such positions, average price etc.
• Have the ability to handle events which are triggered by the brokerage platform such as
ORDER_FILLED, STOP_LOSS etc. and if required take appropriate decisions for such events.
• Some basic monitoring and alerting.
• Some basic risk management. For e.g. loss limitation by using stop losses for orders or making
sure that risk is distributed between risky and safe haven instruments. These are just examples
and by no means a comprehensive list of fully managing the risk.
¹https://en.wikipedia.org/wiki/CURL
²https://en.wikipedia.org/wiki/Cron
Introduction to Trading Bot 3
The trading bot is an attempt to generalise these tasks in a framework and provide an ability to
provide the broker/exchange platform specific implementation at run time, using a dependency
injection³ framework like Spring. Therefore, theoretically speaking, it would just be a change in
the Spring configuration file, where we define our implementations for various interfaces that
implement these services, and la voila, we should be able to support various broker/exchange
platforms.
³https://en.wikipedia.org/wiki/Dependency_injection
Introduction to Trading Bot 4
• Account Management
• Integration with realtime market data feed
• Dissemination of market data
• Place orders
• Handle order/trade and account events
• Analysis of historic prices
• Integration with Twitter
• Strategies
Introduction to Trading Bot 5
1 /**
2 * A provider of services for instrument positions. A position for an instrument
3 * is by definition aggregated trades for the instrument with an average price
4 * where all trades must all be a LONG or a SHORT. It is a useful service to
5 * project a summary of a given instrument and also if required close all trades
6 * for a given instrument, ideally using a single call.
7 *
8 * The implementation might choose to maintain an internal cache of positions in
9 * order to reduce latency. If this is the case then it must find means to
10 * either 1) hook into the event streaming and refresh the cache based on an
11 * order/trade event or 2) regularly refresh the cache after a given time
12 * period.
13 *
14 * @param <M>
15 * The type of instrumentId in class TradeableInstrument
16 * @param <N>
17 * the type of accountId
18 *
19 * @see TradeableInstrument
20 */
21 public interface PositionManagementProvider<M, N> {
22
23 /**
24 *
25 * @param accountId
26 * @param instrument
27 * @return Position<M> for a given instrument and accountId(may be null if
28 * all trades under a single account).
29 */
30 Position<M> getPositionForInstrument(N accountId, TradeableInstrument<M> instrument);
31
32 /**
33 *
34 * @param accountId
35 * @return Collection of Position<M> objects for a given accountId.
36 */
37 Collection<Position<M>> getPositionsForAccount(N accountId);
38
39 /**
40 * close the position for a given instrument and accountId. This is one shot
41 * way to close all trades for a given instrument in an account.
42 *
43 * @param accountId
44 * @param instrument
Introduction to Trading Bot 6
If we create such specifications/interfaces for each aspect of the platform interaction, we can in
theory create providers for these services and swap them as when required, through the Spring
configuration. From code organisation perspective, all these interfaces, therefore would go in a
project, that form part of the core api. This project would therefore be broker/exchange provider
agnostic and would comprise such interfaces and services.
• Write services that solve a single business problem or a collection of related problems. These
services lend themselves to easy unit testability and code reuse that eventually leads to better
software quality.
• Loosely couple services. This enables reducing system dependencies and as a result results
in more maintainable software. Our software would be continuously evolving as one might
decide to integrate more social media feeds or add more complex strategies. Writing loosley
coupled components ensures that we have little knock on effect on already working code.
• High unit test coverage. It is extremely important that we aim to have a high unit test
coverage. When used in a production environment where real money could be involved, a
large unit tests coverage will ensure that we catch regressions and bugs early on and prevent
the manifestation of bugs as much as possible in the production environment.
Introduction to Trading Bot 7
• trading-core is the core of the project. It comprises all the specifications/interfaces that must
be implemented. It also comprises all the generic services which make use of the core interfaces
and provide additional useful API methods.
• oanda-restapi is our reference implementation for the specification and will be discussed in
the book. You are more than welcome to swap this over with your own.
• tradingbot-app is the main application that uses Spring to inject the provider api at runtime.
It is also the project where we define our strategies and can implement app specific stuff.
Later in the book, we are going to talk about integration with social media, especially Twitter,
which we would implement in this project.
Introduction to Trading Bot 8
Java Projects
To build our bot we are going to use the following set of software and tools
Once you have successfully signed up, you are now ready to sign into you practice account. You will
see the login screen below when you are ready to login.
Introduction to Trading Bot 11
After a successful sign on, you would be taken to the account homepage which looks like the screen
below
Introduction to Trading Bot 12
In order to commence api trading, we need to first generate a personal API token, which will be
used by the OANDA platform to authenticate the request. You need to click on the link Manage API
Access, highlighted by a red arrow in the screen above. You will next be taken to the screen below
Introduction to Trading Bot 13
When you click generate, the platform will generate a token with you, which must be included in
every request you make to the platform which hosts your practice account. The token generated will
be presented and you must take note of it.
Introduction to Trading Bot 14
Now you are ready to trade. OANDA provides a very useful web interface⁶ to test your REST requests
and see the responses in situ. You can also get a feeling of how the REST resource urls are organised
and which resource url to invoke, for fulfilling a given request.
The screen below demonstrates how we make a request to get a list of all instruments which can be
traded. The GET request requires an accountId to be passed in (this is the id that you can find on the
account page and for a practice account, comes loaded with 100,000 units of the account currency).
It is imperative to provide the header as well and can be specified as Bearer <Your API Token goes
here>
⁶http://developer.oanda.com/rest-live/console/??utm_source=oandaapi&utm_medium=link&utm_campaign=accesstoken_email
Introduction to Trading Bot 15
1 {"tick":{"instrument":"AUD_CAD","time":"1401919217201682","bid":1.01484,"ask":1.01502}}
1 {
2 "id": 1800805337,
3 "units": 3000,
4 "side": "sell",
5 "instrument": "CHF_JPY",
6 "time": "2015-03-18T06:33:36.000000Z",
7 "price": 120.521,
8 "takeProfit": 110,
9 "stopLoss": 150,
10 "trailingStop": 0,
11 "trailingAmount": 0
12 }
From the 2 examples above, we can also see the key used for event date is time. Since the same keys
are used to denote a given attribute, we can create public static final String variables for
these keys. So therefore the concept of the class OandaJsonKeys was born. Instead of polluting the
code with lines below in many classes
it is much better practice to create a constant and use that instead. The same code snippet would
look like:
There are a lot of keys, but most of the keys that we use in our trading bot are captured in the
OandaJsonKeys class.
In all our OANDA API implementations, which will be discussed in the subsequent chapters, we
would be directly using this class and statically importing constants instead of hardcoding the string
literals for a given json key.
• API url
• username
• access token
As we know, OANDA has different environments where we can run our bot, such as sandpit, practice
and live. These environments have different urls, access tokens and can have different usernames for
the same individual. These external configuration properties are passed in as constructor parameters
for various OANDA implementations. For e.g.
Introduction to Trading Bot 18
1 public OandaAccountDataProviderService(final String url, final String userName, final String accessToken) {
2 this.url = url;
3 this.userName = userName;
4 this.authHeader = OandaUtils.createAuthHeader(accessToken);
5 }
The parameters are passed to this implementation in the Spring configuration as seen below
Since these variables are provided in a property file, we can easily change them at runtime, without
having to do a new build or change code. It would be sufficient to just change the property file. We
would cover this topic in more detail in later chapters when we talk about configuration in detail.
Introduction to Trading Bot 19
In the code snippet above we have an infinite while loop that listens on new ticks being pushed on
to the live stream by the OANDA platform. When a tick json payload is received, it is parsed and
further disseminated via a queue or an event bus.
The diagram depicts a typical chain of events, that might be triggered by a single event.
Introduction to Trading Bot 20
This basically is the essence of an event driven architecture. Since we could have many components at
play at the same time, it is extremely important that we decouple components as much as possible, so
that new publishers and subscribers can be added with zero or minimal changes. This architecture
lends itself to take advantage of Java multithreaded programming capabilities. However, by the
same token, it dictates the developer to exercise great caution when performing state changes of
business objects present in caches, for e.g. the trades cache in our example. We must put adequate
synchronization and locking in place to make sure that the observed state of a shared object is always
consistent.
⁷https://code.google.com/p/guava-libraries/wiki/EventBusExplained
Introduction to Trading Bot 21
• Create Publisher: It is sufficient to just call the post(Object payload) to post it to the
EventBus.
• Consume Payload: The EventBus finds the appropriate subscriber by matching the method
signature based on the input type passed into the method and ofcourse annotated by the
@Subscribe annotation. This method must have one and only one input parameter. There is
a choice to go as fine grained or coarse grained as possible. In the case of coarse grained
subscription, we have the input parameter as an object which is the super class of all
known payloads in the system. The worst case being the payload java.lang.Object, in
which case the subscription is the most coarse grained. This method will be called for every
eventBus.post performed in the system. On the other hand, using individual subtypes
as input parameters to methods, make it extremely fine grained. In the example below
handleMarketDataEvent will only be called by the EventBus if the payload is of the type
MarketDataPayLoad or any of it’s subtypes.
Introduction to Trading Bot 22
1 @Subscribe
2 @AllowConcurrentEvents
3 public void handleMarketDataEvent(MarketDataPayLoad<T> marketDataPayLoad) {
4 if (instrumentRecentPricesCache.containsKey(marketDataPayLoad.getInstrument())) {
5 instrumentRecentPricesCache.get(
6 marketDataPayLoad.getInstrument())
7 .put(marketDataPayLoad.getEventDate(),marketDataPayLoad);
8 }
9 }
Introduction to Trading Bot 23
• GBP_USD
• GBPUSD
• GBP/USD
• GBP-USD
• buy
• long
• +1 (or any other positive number)
• Platform specific enum, for e.g. TRADEACTION.BUY
In order to deal with such variances in notation provided by different providers, we need to create
an interface that provides methods to address these differences. It looks like
1 /**
2 *
3 * @param <T>
4 * The type of Long/Short notation
5 */
6 public interface ProviderHelper < T > {
7
8 /**
9 *
10 * @param instrument
11 * in ISO currency standard, such as GBPUSD
12 * @return currency pair denoted in the platform specific format
13 */
14 String fromIsoFormat(String instrument);
15
16 /**
17 *
18 * @param instrument
19 * in platform specific format such as GBP_USD
20 * @return currency pair denoted in ISO format
21 */
22 String toIsoFormat(String instrument);
23
24 /**
25 *
26 * @param instrument
27 * in a 7 character format, separated by an arbitrary separator
Introduction to Trading Bot 24
The need for this interface was felt, when I was consuming data from external sources like Twitter
and sites which publish economic events. Various Twitter users and external sites had their own way
of denoting currency pairs and long/short trades. In order to deal with this plethora of conventions,
the need for such interface was strongly felt. I am pretty sure that there would be many more, which
need to be interpreted in the platform specific ways and should therefore be added to this interface.
Introduction to Trading Bot 25
As different users may have different runtime values, these values form part of the external
configuration. These need to be configured in the Spring configuration (we will discuss it in detail
when we talk about Configuration and Deployment). It is strongly recommended to configure as
much as possible instead of hardcoding them inside various services.
Lets check out how the code looks like
93 }
Some of these member variables here may not make sense now but all will fall into place in later
chapters.
Introduction to Trading Bot 28
We will discuss how this code can be built and run locally in later chapters.
Introduction to Trading Bot 29
1 <project xmlns="http://maven.apache.org/POM/4.0.0"
2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
4 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 <modelVersion>4.0.0</modelVersion>
6 <groupId>com.precioustech</groupId>
7 <artifactId>tradingbot-demo-programs</artifactId>
8 <version>1.0</version>
9 <properties>
10 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
11 <spring.framework.version>4.1.1.RELEASE</spring.framework.version>
12 <spring.framework.social.version>1.1.0.RELEASE</spring.framework.social.version>
13 </properties>
14 <dependencies>
15 <dependency>
16 <groupId>com.precioustech</groupId>
17 <artifactId>tradingbot-core</artifactId>
18 <version>1.0</version>
19 </dependency>
20 <dependency>
21 <groupId>com.precioustech.fxtrading</groupId>
22 <artifactId>tradingbot-app</artifactId>
23 <version>1.0</version>
24 </dependency>
25 <dependency>
26 <groupId>com.precioustech</groupId>
27 <artifactId>oanda-restapi</artifactId>
28 <version>1.0</version>
29 </dependency>
30
31 </dependencies>
32 </project>
This demo project has a very simple dependency requirement on the 3 projects which comprise the
bot.