Pedlar is an algorithmic trading platform for Python designed for trading events, competitions and sessions such as Algothons. It includes a live web interface with multiple accounts with account sharing and live chat, an HTTP API with example Python trading agents and a ZeroMQ based broker connection to MetaTrader5.
If there is already a ticker server and web server running, the client API under
pedlar can be used. If not, follow instructions on how to get them in the Hosting section. The client or agent API resolves around connecting to the ticker server (where agents receive price updates) and the web server, in this case handles the broker connection. The ticker is separate to reduce overhead and latencies between making trades and just receiving price updates.
The client API is can be installed using:
pip3 install --no-cache-dir -U pedlar
There are some helpful examples in the
pedlar folder. Here is a overview of the client API:
from pedlar.agent import Agent class MyAgent(Agent): """A trading agent.""" def on_order(self, order): """Called on placing a new order.""" print("New order:", order) print("Orders:", self.orders) # Agent orders only def on_order_close(self, order, profit): """Called on closing an order with some profit.""" print("Order closed", order, profit) print("Current balance:", self.balance) # Agent balance only def on_tick(self, bid, ask, time=None): """Called on every tick update.""" print("Tick:", bid, ask, time) # self.buy() # self.sell() # self.close() def on_bar(self, bopen, bhigh, blow, bclose, time=None): """Called on every bar update.""" print("Bar:", bopen, bhigh, blow, bclose, time) if __name__ == "__main__": import logging logging.basicConfig(level=logging.DEBUG) agent = MyAgent.from_args() agent.run()
The extra parameters are parsed from the command line and can be run using:
python3 -u myagent.py -h
Key things to keep in mind:
self.closewith the stale order id or simply reset the account.
The agents can backtest against a CSV file of the following format, last column time is optional and time format is adjustable through
time_format of the
tick,1.26361,1.26375,2019.01.03 23:44:42 tick,1.2636,1.26374,2019.01.03 23:44:59 tick,1.2636,1.26378,2019.01.03 23:45:00 bar,1.26386,1.26398,1.26355,1.2636,2019.01.03 23:45:00 tick,1.26359,1.26377,2019.01.03 23:45:02 tick,1.26357,1.26375,2019.01.03 23:45:05 tick,1.26356,1.26374,2019.01.03 23:45:07 tick,1.26358,1.26376,2019.01.03 23:45:10
which can be used with an agent
python3 myagent.py -b ticks.csv. Essentially each line will invoke corresponding
on_bar function. The actual profit and trade results are computed offline based on absolute price differences. This means the agent will run completely offline and the actual results are only useful to get an idea about the performance or train a neural network. Any extra broker commissions beyond bid-ask spread, price requotes etc are not factored.
Pedlar involves 4 components that talk to each other to create a platform for agents to trade:
PUBsocket that publishes tick and bar updates that are received by the agents which eventually trigger
on_barmethods. This component runs independently from others to provide a continuous stream of price updates.
The client and server packages are separated to avoid any assumptions between their implementations. The main folders include:
All the extra packages required can be installed using:
pip3 install --no-cache-dir -U -r requirements.txt
To get the ticker and broker components up and running you need to:
libzmq.dllto run. You might need to install a compatible Visual C++ runtime to get ZeroMQ running.
binfolder and move the DLL to
Library\libzmq.dllas that is where the
libzmq.mqhheader expects it.
As an alternative to executing trades live, there is
lbroker.py that implements same interface as the actual MT5 broker but instead executes the orders locally based on the latest ticks provided by MT5. It is a simple stand-alone script:
python3 lbroker.py -h
The web server is a standard Flask application organised into the
pedlarweb package. You need to create a
instance/config.py to customise the default values. Once the
config.py options are as desired, a database can be initialised:
mkdir instance && cp config.py instance/config.py # customise instance/config.py ex. database settings python3 -c "from pedlarweb import db; db.create_all()"
If the in-memory default database is used, tables will be automatically created but data is lost when server is stopped using an in-memory database. Then the server can be run using standard Flask options:
python3 runpedlarweb.py -h usage: runpedlarweb.py [-h] [-d] [--host HOST] [--port PORT] Run pedlarweb. optional arguments: -h, --help show this help message and exit -d, --debug Enable debug server. --host HOST Host IP address. --port PORT Host port.
Due to Flask-SocketIO the
eventlet server would be run. For convinience, a new user is created if none with the username exist from the login page. This choice is done to get people on-board as easy as possible without heavy registration and email confirmation schemes.
pedlarwebto be built as well. Finally, it has an authentication mechanism that is enforced for every request.
Symbol()but there is space for passing the symbol, instrument from agent -> server -> broker. For the target audience of live sessions and competitions, a single instrument seems enough.