DEVELOPING A REAL-TIME AUTOMATED TRADING PLATFORM WITH PYTHON

Miguel Sánchez de León Peque

2016-07-18

About

Us

Me

Motivation

Search engine results

  • TradeStation
  • Metatrader
  • NinjaTrader
  • Many others...

Cons

  • Proprietary
  • Heavily desktop oriented
  • Linux support?
  • Can I use Python to create my strategies?

What we wanted

  • Control
  • Optional GUI
  • Multiplatform
  • Python

Is this possible?

osMarkets

Basics

  • Broker-independent platform
  • Implemented over osBrain
  • Designed for real-time automated trading

Overview

Feeder

  • Get market data
  • Multithread

Overview

Router

  • Broker independent provider
  • Stores/distributes
  • Update/resample

Market data

  • Tick
  • Bar
  • Bar Series

Bar series

Overview

Brain

  • Subscriptions
  • Run algorithms
  • Send orders
  • Great ecosystem
  • Can do anything

Abstraction

Overview

Trader

  • Handle orders
  • Multithread

Example

Other agents

  • Logger
  • Informer
  • Overmind

GUI

Features

  • Real-time market data visualization
  • Real-time indicators visualization
  • Integration with osMarkets

Qt

  • Great portability
  • Probably the most widely used
  • LGPL

PyQtGraph

  • Pure Python graphics library
  • Fast real-time display
  • User interaction
  • MIT

Overview

Note

osBrain

Basics

A general purpose multi-agent system

  • Independent agents
  • Message passing
  • Easy configuration and deployment

Other use cases

Processes vs. threads

Have you met GIL?

ØMQ

ØMQ is very cool - If you don't have a project that needs it... ¡create one!

A basic agent

  • Is a system process
  • Implements methods for easy binding and connecting with different patterns
  • Activates on incoming message
  • Mulithreading may be used (inproc socket)

Configuration

Agents are independent, but they must know the addresses of other agents

  • There may be many sockets!
  • For most agents, assigning a random address is simpler

If only we could...

  • Have a name server
  • Have an Overmind...

Pyro4

  • PYthon Remote Objects
  • Treat remote objects as local
  • Already has a name server implementation

A real agent

  • Is a system process
  • This process runs a Pyro multiplexed server
  • The server serves an actual Agent object
  • Main thread runs the main loop (one-way)

Conclusion

  • General-purpose multi-agent system with Python
  • Independent agents (processes)
  • Message passing using ØMQ
  • Easy deployment and remote configuration using Pyro4

Code examples

An example (I)

from osbrain import run_nameserver
from osbrain import run_agent


if __name__ == '__main__':

    # System deployment
    ns = run_nameserver()
    agent = run_agent('Example', ns)

    # Log a message
    agent.log_info('Hello world!')

An example (II)

import time
from osbrain import random_nameserver
from osbrain import run_agent


def log_message(agent, message):
    agent.log_info('received: %s' % message)


if __name__ == '__main__':

    # System deployment
    ns = random_nameserver()
    sender = run_agent('Alice', ns)
    receiver = run_agent('Bob', ns)

    # System configuration
    addr = sender.bind('PUSH', alias='main')
    receiver.connect(addr, handler=log_message)

    # Send messages
    while True:
        time.sleep(1)
        sender.send('main', 'Hello, world!')

An example (III)

import time
from osbrain import random_nameserver
from osbrain import run_agent
from osbrain import BaseAgent


class Push(BaseAgent):
    def on_init(self):
        self.bind('PUSH', alias='main')

    def hello(self):
        self.send('main', 'Hello, world!')


def log_message(agent, message):
    agent.log_info('received: %s' % message)


if __name__ == '__main__':

    # System deployment
    ns = random_nameserver()
    sender = run_agent('Alice', ns, base=Push)
    receiver = run_agent('Bob', ns)

    # System configuration
    receiver.connect(sender.addr('main'), handler=log_message)

    # Send messages
    while True:
        time.sleep(1)
        sender.hello()

An example (IV)

from osmarkets.brain import Brain
from osmarkets.architecture import OandaArchitecture


class Example(Brain):
    def on_new_bar(self, series):
        # Algorithm
        if series[0].close > series[1].close:
            side = 'buy'
        else:
            side = 'sell'
        # Order
        self.send_order(side=side,
                        size=100,
                        symbol=series.bsid.symbol)


if __name__ == '__main__':

    system = OandaArchitecture(logging=True,
                               account_id=123456,
                               access_token='123abc-345def',
                               environment='live')
    system.stream(['EUR_USD'])

    system.add_brain('example', base=Example)
    system['example'].set_attr(DEBUG=True)
    system['example'].subscribe(('EUR_USD', 1, 'Minutes'), 100)

Final conclusion

♥ Python ♥

One last thing...

The end

Contact

We are hiring!

hired = [name for name, CV in candidates
         if CV in inbox('rrhh@opensistemas.com') and CV]

Thank you!

  • Questions?
  • Comments?
  • Suggestions?