the-james-burton / the-turbine

The turbine is a set of server-side components that perform automated technical analysis on stocks.
MIT License
15 stars 7 forks source link

the-turbine Build Status

What is it?

The turbine is a set of server-side components that perform automated technical analysis on stocks. It it not actually connected just yet to any real source of stock prices, instead, it currently generates random data so that the project can be further developed. This data is also analysed with common technical indicators and trading strategies and the results of that analysis are persisted into Elasticsearch for further analysis downstream.

DO NOT USE THIS APP FOR REAL TRADING !!

What does it looks like?

This is a server-side only app and thus has no UI. However, it is easily possible (by design) to view the data in Kibana. Simple dashboards look like this...

kibana

It is broken up into modules...

How does it work?

The coarse sequence of events flows like this...

  1. The furnace creates stock 'ticks' These 'tick' objects are simple and contain just a high, low, open and close price, plus a few co-ordinates (market/symbol) and a timestamp. These ticks are currently generated at random using a simple algorithm to ensure continuity in the data.
  2. The furnace publishes the ticks to rabbitMQ and that is the job of the furnace finished! It will do more work when it is connected to a source of real market data.
  3. The condenser receives the ticks via the rabbitMQ camel component.
  4. The condenser does the indicator and strategy analysis This is the meat of the work done by the condenser. It runs a suite of indicators (such as Bollinger bands) and trading strategies (such as CCI correction) and creates suitable objects for them.
  5. The condenser publishes the ticks and analysis to elasticsearch and websockets (via rabbitMQ) Once it has completed its work, the condenser will save the incoming ticks and the analysis results to elasticsearch, where generic tools such as Kibana can be used to chart the results. It will also publish them to websockets, via the webstomp plugin from RabbitMQ so that my atacama web client can receive them as an inbound message.

The architecture looks like this...

architecture

Everything is sent around as JSON. This makes it easy to persist in elasticsearch and use in a web app. Note how the condenser app is not client-facing. This is a less common design trait. I decided to make it this way because...

  1. I didn't want to implement another bespoke elasticsearch API and client. Why not just use the built-in REST API and factory client? Well, that's what I did.
  2. RabbitMQ supports stomp over websockets! and spring boot lets you plug it right in as a websocket broker. This lets rabbitMQ take control of all the asynchronous messaging.

NOTE: Issue #24 describes a limitation with the Spring websocket RabbitMQ relay that is described above. Using it means I can't use reactor 3! So for now I have gone back to using the built-in Spring websocker broker until Spring 5/Boot 2 is released which will use reactor 3.

I believe a main concern with this design is security. To secure the connections to elasticsearch, I would most likely put ApiMan or similar over the top. To secure the rabbitMQ webstomp connections I am not so sure. I need to do more research. However it is very easy to stop using rabbitMQ as websocket broker and use the native spring support instead.

Do I need anything installed?

Yes, this is intended to be considered as an enterprise app and it expects a number of services to be available on the host machine

Elasticsearch 2.3.2

This DOES need to be 2.3.2 because of #17483 affecting 2.3.1.

  1. Copy the contents of the elasticsearch.yml file into your elasticsearch.yml file to make sure that CORS support is enabled correctly to allow atacama to connect.

Kibana 4.5.0

It is not strictly necessary to install Kibana, but it will let you view the results without needing to get my atacama project running.

RabbitMQ 3.6.x

Will also work with RabbitMQ 3.5.x and maybe lower versions too. Development is continuing with RabbitMQ 3.6.x so I advise you to use the same.

  1. Install the web-stomp RabbitMQ plugin to enable support for Stomp over Websockets within rabbitMQ. You can do this by running the following command:./sbin/rabbitmq-plugins enable rabbitmq_web_stomp
  2. Configure CORS support in RabbitMQ by running the following command: ./sbin/rabbitmqctl set_permissions -p /localhost guest ".*" ".*" ".*"

Optional extra config for SSL (not needed by default)

  1. Copy the rabbitmq.config file and the into a etc/rabbitmq directory inside your RabbitMQ install dir (or merge the contents). This may need to go somewhere else for you depending on how you installed RabbitMQ - check your RabbitMQ logs as they will tell you where it looked for the rabbitmq.config file.
  2. Copy the certificate.crt and certificate.key files and the into the same etc/rabbitmq directory. You could generate your own certificates instead, if you wanted to. Some help is in this README.md file.
  3. Edit your copy of the rabbitmq.config file that you took above and update the properties that reference the certificate.* files so that they are prefixed with the full path to them on your system.

How do I use it?

The only way at present to get it up and running is to clone this repo, build it then run it in eclipse using the provided launch configurations. Make sure you have java 8, maven, rabbitMQ (with the webstomp plugin), elasticsearch and kibana installed then run something like the following...

git clone https://github.com/the-james-burton/the-turbine/the-turbine.git the-turbine
cd the-turbine
mvn clean install

Then open the project in Eclipse and run the launch configurations in ide/eclipse/launch. You need to start the condenser and then the furnace. If working, you should see logging activity as the furnace generates random stock ticks and the condenser analyses them. You should then browse to your kibana dashboard and see if you have any data in the turbine-* indicies.

At some point I will provide an easier way of installing and running this app using spring boot packaging best practice, but it remains a development project for now.

Help, I get 'insecure response' errors!

You may see this if you have turned on SSL/HTTPS. If oyu do, then you need to tell your browser to trust these HTTPS URLs. In chrome, you can do this by simply browsing to the URLs, clicking 'advanced' and then trusting them.

https://localhost:15671/stomp/info
https://localhost:48002/user

What is it built on?

It is a multi-module maven project written in Java 8. Amongst others, it makes use of the following superb open source projects...

It communicates with two principal back end components...

What new-ish things have been done?

What is already done?

What is going to be done soon?

What is going to be done in the long term?

What is unlikely to be done?

Where did the names come from?

The name was originally coined when this project was going to be a simple messaging performance test suite. However, it has since expanded into a full technical analysis suite. We can try and force the name turbine into a backronym, something like 'Technical Understanding Reached By Implementing New Executables', if we must. The names of the subprojects are meant to evoke interpretations of parts of an electricity generating turbine, although it doesn't really hold up to a pedantic analysis of the metaphor.

Notes and issues...

I currently have a problem with elasticsearch sometimes hanging and not restarting after my laptop resumes from suspend (linux mint 18.1 xfce). No logs, nothing just hanging. After hacking about with the elasticsearch.sh I got this error out of it...

2017-03-30 18:12:03,009 main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrustPermission" "register")

I think the solution might be this suggestion, which is to add this line inside the grant{} block in the active java.policy file. For me, this is /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/java.policy...

grant {
  permission javax.management.MBeanTrustPermission "register";
}