• Stars
    star
    619
  • Rank 72,496 (Top 2 %)
  • Language
    Python
  • Created about 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A working example algorithm for scalping strategy trading multiple stocks concurrently using python asyncio

Concurrent Scalping Algo

This python script is a working example to execute scalping trading algorithm for Alpaca API. This algorithm uses real time order updates as well as minute level bar streaming from Polygon via Websockets (see the document for Polygon data access). One of the contributions of this example is to demonstrate how to handle multiple stocks concurrently as independent routine using Python's asyncio.

The strategy holds positions for very short period and exits positions quickly, so you have to have more than $25k equity in your account due to the Pattern Day Trader rule, to run this example. For more information about PDT rule, please read the document.

Dependency

This script needs latest Alpaca Python SDK. Please install it using pip

$ pip3 install alpaca-trade-api

or use pipenv using Pipfile in this directory.

$ pipenv install

Usage

$ python main.py --lot=2000 TSLA FB AAPL

You can specify as many symbols as you want. The script is designed to kick off while market is open. Nothing would happen until 21 minutes from the market open as it relies on the simple moving average as the buy signal.

Strategy

The algorithm idea is to buy the stock upon the buy signal (20 minute moving average crossover) as much as lot amount of dollar, then immediately sell the position at or above the entry price. The assumption is that the market is bouncing upward when this signal occurs in a short period of time. The buy signal is extremely simple, but what this strategy achieves is the quick reaction to exit the position as soon as the buy order fills. There are reasonable probabilities that you can sell the positions at the better prices than or the same price as your entry within the small window. We send limit order at the last trade or position entry price whichever the higher to avoid unnecessary slippage.

The buy order is canceled after 2 minutes if it does not fill, assuming the signal is not effective anymore. This could happen in a fast-moving market situation. The sell order is left indifinitely until it fills, but this may cause loss more than the accumulated profit depending on the market situation. This is where you can improve the risk control beyond this example.

The buy signal is calculated as soon as a minute bar arrives, which typically happen about 4 seconds after the top of every minute (this is Polygon's behavior for minute bar streaming).

This example liquidates all watching positions with market order at the end of market hours (03:55pm ET).

Implementation

This example heavily relies on Python's asyncio. Although the thread is single, we handle multiple symbols concurrently using this async loop.

We keep track of each symbol state in a separate ScalpAlgo class instance. That way, everything stays simple without complex data structure and easy to read. The main() function creates the algo instance for each symbol and creates streaming object to listen the bar events. As soon as we receive a minute bar, we invoke event handler for each symbol.

The main routine also starts a period check routine to do some work in background every 30 seconds. In this background task, we check market state with the clock API and liquidate positions before the market closes.

Algo Instance and State Management

Each algo instance initializes its state by fetching day's bar data so far and position/order from Alpaca API to synchronize, in case the script restarts after some trades. There are four internal states and transitions as events happen.

  • TO_BUY: no position, no order. Can transition to BUY_SUBMITTED
  • BUY_SUBMITTED: buy order has been submitted. Can transition to TO_BUY or TO_SELL
  • TO_SELL: buy is filled and holding position. Can transition to SELL_SUBMITTED
  • SELL_SUBMITTED: sell order has been submitted. Can transition to TO_SELL or TO_BUY

Event Handlers

on_bar() is an event handler for the bar data. Here we calculate signal that triggers a buy order in the TO_BUY state. Once order is submitted, it goes to the BUY_SUBMITTED state.

If order is filled, on_order_update() handler is called with event=fill. The state transitions to TO_SELL and immediately submits a sell order, to transition to the SELL_SUBMITTED state.

Orders may be canceled or rejected (caused by this script or you manually cancel them from the dashboard). In these cases, the state transitions to TO_BUY (if not holding a position) or TO_SELL (if holding a position) and wait for the next events.

checkup() method is the background periodic job to check several conditions, where we cancel open orders and sends market sell order if there is an open position.

It exits once the market closes.

Note

Each algo instance owns its child logger, prefixed by the symbol name. The console log is also emitted to a file console.log under the same directory for your later review.

Again, the beautify of this code is that there is no multithread code but each algo instance can focus on the bar/order/position data only for its own. It still handles multiple symbols concurrently plus runs background periodic job in the same async loop.

The trick to run additional async routine is as follows.

    loop = stream.loop
    loop.run_until_complete(asyncio.gather(
        stream.subscribe(channels),
        periodic(),
    ))
    loop.close()

We use asyncio.gather() to run all bar handler, order update handler and periodic job in one async loop indifinitely. You can kill it by Ctrl+C.

Customization

Instead of using this buy signal of 20 minute simple moving average cross over, you can use your own buy signal. To do so, extend the ScalpAlgo class and write your own _calc_buy_signal() method.

    class MyScalpAlgo(ScalpAlgo):
        def _calculate_buy_signal(self):
            '''self._bars has all minute bars in the session so far. Return True to
            trigger buy order'''
            pass

And use it instead of the original class.

More Repositories

1

marketstore

DataFrame Server for Financial Timeseries Data
Go
1,814
star
2

alpaca-trade-api-python

Python client for Alpaca's trade API
Python
1,552
star
3

pylivetrader

Python live trade execution library with zipline interface.
Python
622
star
4

example-hftish

Example Order Book Imbalance Algorithm
Python
615
star
5

Momentum-Trading-Example

An example algorithm for a momentum-based day trading strategy.
Python
568
star
6

alpaca-backtrader-api

Alpaca Trading API integrated with backtrader
Python
524
star
7

alpaca-trade-api-js

Node.js library for Alpaca Trade API.
JavaScript
428
star
8

alpaca-trade-api-go

Go client for Alpaca's trade API
Go
318
star
9

alpaca-py

The Official Python SDK for Alpaca API
Python
249
star
10

alpaca-trade-api-csharp

C# SDK for Alpaca Trade API https://docs.alpaca.markets/
C#
208
star
11

pipeline-live

Pipeline Extension for Live Trading
Python
198
star
12

alpaca-ts

A TypeScript Node.js library for the https://alpaca.markets REST API and WebSocket streams.
TypeScript
144
star
13

Alpaca-API

The Alpaca API is a developer interface for trading operations and market data reception through the Alpaca platform.
136
star
14

pymarketstore

Python driver for MarketStore
Python
103
star
15

user-docs

Documentation for the Alpaca platform.
HTML
72
star
16

samplealgo01

Sample algo
Python
69
star
17

slait

A time-series data cache
Go
47
star
18

roboadvisor

Python
43
star
19

example-portfolio-manager

Simple portfolio management script in python
Python
42
star
20

insomnia-workspace

An Insomnia Workspace for Alpaca API
34
star
21

ribbit-backend

Backend for Ribbit, Broker API Reference App
Go
33
star
22

blogmaterials

Jupyter Notebook
30
star
23

alpaca-postman

Postman collections for Alpaca's APIs
29
star
24

alpaca-zipline

Alpaca riding on a zipline
Python
28
star
25

ribbit-ios

iOS app for Ribbit, Broker API Reference App
Swift
28
star
26

plug-and-play-strategies

Jupyter Notebook
27
star
27

sp100algo

Follow S&P100
Python
16
star
28

alpaca-erasure

Example script to generate Erasure data
Python
15
star
29

slackbot-trader

A Slackbot that can access the Alpaca API
Python
14
star
30

ribbit-android

Android app for Ribbit, Broker API Reference App
Java
12
star
31

alpaca-docs

Developer documentation for Alpaca API's
HTML
10
star
32

broker-fastapi-backend

A reference backend for Alpaca's Broker API utilizing Python & FastAPI
Python
8
star
33

bkdocs

Broker API Documentation
HTML
8
star
34

notebooks

A collection of Jupyter notebooks for getting started with Alpaca
Jupyter Notebook
6
star
35

Alpaca-Flutter-Demo-App

A boilerplate trading application to trade crypto on Alpaca. Made with Flutter and Dart.
C++
5
star
36

alpacadecimal

Similar and compatible with decimal.Decimal, but optimized for Alpaca's data sets.
Go
5
star
37

supertrend_crypto_bot

An Alpaca Live Crypto Trading Bot built with Python!
Python
4
star
38

Triangular-Arbitrage-with-Alpaca-API-s

Python
3
star
39

quantopian-fundamentals-examples

Implementations of algorithms from https://blog.quantopian.com/fundamentals-contest-winners/ using Alpaca's API.
Python
3
star
40

plprofiler

Python
2
star
41

alpaca-discord-bot

Python
1
star
42

go-onfido

Wrapper around the go-onfido-openapi package
1
star
43

alexa-trader-skill

An Alexa skill that can access the Alpaca API
1
star
44

go-onfido-openapi

Golang sdk for onfido. Generated from openapi
Shell
1
star