Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: alpacahq/pylivetrader
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.1.0
Choose a base ref
...
head repository: alpacahq/pylivetrader
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Loading
Showing with 1,253 additions and 3,323 deletions.
  1. +14 −3 .circleci/config.yml
  2. +35 −0 .pyup.yml
  3. +0 −1 Dockerfile
  4. +75 −13 README.md
  5. +1 −6 dockerfiles/Dockerfile
  6. +15 −0 dockerfiles/Dockerfile-dev
  7. +0 −19 dockerfiles/Pipfile
  8. +0 −901 dockerfiles/Pipfile.lock
  9. +51 −0 examples/MACD/README.md
  10. +63 −0 examples/MACD/macd_example.py
  11. +15 −0 examples/MACD/smoke_macd.py
  12. +7 −16 examples/README.md
  13. +0 −5 examples/dual_moving_avg/README.md
  14. +0 −29 examples/dual_moving_avg/dual_moving_avg.py
  15. +0 −300 examples/graham-fundamentals/GrahamFundamentals.py
  16. +0 −8 examples/graham-fundamentals/README.md
  17. +2 −3 examples/heroku-dockerfile/README.md
  18. +15 −0 examples/portfolio_management/README.md
  19. +49 −0 examples/portfolio_management/management_example.py
  20. +0 −13 examples/q01/Dockerfile
  21. +0 −18 examples/q01/Pipfile
  22. +0 −774 examples/q01/Pipfile.lock
  23. +0 −1 examples/q01/Procfile
  24. +0 −56 examples/q01/README.md
  25. +0 −354 examples/q01/algo.py
  26. +0 −355 examples/q01/original.py
  27. +0 −1 examples/q01/runtime.txt
  28. +56 −0 examples/using_pipeline_live/README.md
  29. +93 −0 examples/using_pipeline_live/pipeline_live_example.py
  30. +19 −0 examples/using_pipeline_live/smoke_pipelinelive.py
  31. +176 −10 pylivetrader/__main__.py
  32. +1 −1 pylivetrader/_version.py
  33. +54 −11 pylivetrader/algorithm.py
  34. +186 −139 pylivetrader/backend/alpaca.py
  35. +8 −2 pylivetrader/backend/base.py
  36. +40 −15 pylivetrader/data/bardata.py
  37. +1 −1 pylivetrader/data/data_portal.py
  38. +5 −5 pylivetrader/executor/realtimeclock.py
  39. +6 −1 pylivetrader/misc/configloader.py
  40. +164 −0 pylivetrader/misc/migration_tool.py
  41. +26 −2 pylivetrader/misc/parallel_utils.py
  42. +2 −0 pylivetrader/shell.py
  43. +14 −1 pylivetrader/testing/fixtures.py
  44. +28 −3 pylivetrader/testing/smoke/backend.py
  45. +2 −6 pylivetrader/testing/smoke/harness.py
  46. +15 −0 requirements/requirements.txt
  47. +3 −0 requirements/requirements_test.txt
  48. +9 −19 setup.py
  49. +0 −228 tests/test_backend/test_alpaca.py
  50. +3 −3 tests/test_data/test_bardata.py
17 changes: 14 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -12,12 +12,18 @@ jobs:
python3 -m venv venv
. venv/bin/activate
pip3 install setuptools --upgrade
pip install numpy==1.19.4
python3 setup.py develop
- save_cache:
key: deps-{{ checksum "setup.py" }}
paths:
- venv
- run: python3 setup.py flake8 test
- run:
command: |
. venv/bin/activate
pip install -r requirements/requirements_test.txt
flake8 ./pylivetrader && echo "Flake8 passed"
pytest
build-python37:
docker:
@@ -36,10 +42,15 @@ jobs:
key: deps-{{ checksum "setup.py" }}
paths:
- venv
- run: python3 setup.py flake8 test
- run:
command: |
. venv/bin/activate
pip install -r requirements/requirements_test.txt
flake8 ./pylivetrader && echo "Flake8 passed"
pytest
workflows:
version: 2
build:
jobs:
- build-python36
- build-python36
35 changes: 35 additions & 0 deletions .pyup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# configure updates globally
# default: all
# allowed: all, insecure, False
update: all

# configure dependency pinning globally
# default: True
# allowed: True, False
pin: True

# set the default branch
# default: empty, the default branch on GitHub
branch: master

# update schedule
# default: empty
# allowed: "every day", "every week", ..
schedule: "every week"

# search for requirement files
# default: True
# allowed: True, False
search: True

# Specify requirement files by hand, default is empty
# default: empty
# allowed: list
requirements:
- requirements/requirements.txt:
# update all dependencies and pin them
update: all
pin: True
- requirements/requirements_test.txt:
# don't update dependencies, use global 'pin' default
update: False
1 change: 0 additions & 1 deletion Dockerfile

This file was deleted.

88 changes: 75 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[![PyPI version](https://badge.fury.io/py/pylivetrader.svg)](https://badge.fury.io/py/pylivetrader)
[![CircleCI](https://circleci.com/gh/alpacahq/pylivetrader.svg?style=shield)](https://circleci.com/gh/alpacahq/pylivetrader)
[![Updates](https://pyup.io/repos/github/alpacahq/pylivetrader/shield.svg)](https://pyup.io/repos/github/alpacahq/pylivetrader/)
[![Python 3](https://pyup.io/repos/github/alpacahq/pylivetrader/python-3-shield.svg)](https://pyup.io/repos/github/alpacahq/pylivetrader/)

# pylivetrader

@@ -8,9 +10,22 @@ The main purpose is to run algorithms developed in the Quantopian platform in
live trading via broker API. In order to convert your algorithm for pylivetrader,
please read the [migration document](./migration.md).

## example code
check out the [examples](https://github.com/alpacahq/pylivetrader/tree/master/examples)
folder. you will find there the following examples:
* simple MACD "momentum" trading
* using pipeline-live to screen top stocks every day
* a potfolio optimizer (used to optimize an existing porfolio. not to buy new
stocks)

each sample code contains a readme file and a smoke runner (read further to
understand what smoke is)

## Simple Usage

Here is the example dual moving average algorithm (by [quantopian/zipline](https://github.com/quantopian/zipline/blob/master/zipline/examples/dual_moving_average.py)). We provide mostly the same API interfaces with zipline.
Here is the example dual moving average algorithm (by
[quantopian/zipline](https://github.com/quantopian/zipline/blob/master/zipline/examples/dual_moving_average.py)).
We provide mostly the same API interfaces with zipline.

```py
from pylivetrader.api import order_target, symbol
@@ -49,8 +64,9 @@ Config file is just simple yaml or json format.
$ cat config.yaml
key_id: BROKER_API_KEY
secret: BROKER_SECRET
base_url: https://paper-api.alpaca.markets
feed: iex # <== change to pro if you have a paid account
```

### Usage with redis

If you are running pylivetrader in an environment with an ephemeral file store and need your context
@@ -73,10 +89,12 @@ Assuming you have redis running, this will now serialize your context object to

## Installation

Install with pip. **pylivetrader currently supports Python 3.5, 3.6 and 3.7+**
Install with pip. **pylivetrader currently supports only Python 3.6.

```
$ pip install pylivetrader
$ python3.6 -m venv venv
$ source venv/bin/activate
(venv)$ pip install pylivetrader
```

Additionally, pylivetrader works well with [pipeline-live](https://github.com/alpacahq/pipeline-live).
@@ -92,7 +110,7 @@ before the session starts) or if it starts after that. Once the session
starts, it calls the `handle_data()` function every minute until the
session ends, or any functions that are registered by `schedule_function` API.

The options are as follows.
The options are as follows

- `-f` or `--file`: the file path to the algorithm source
- `-b` or `--backend`: the name of backend to use
@@ -107,15 +125,45 @@ The options are as follows.
`pylivetrader shell` goes into the IPython interactive shell mode as if you are
in the algorithm script namespace. It means, you can call Algorithm API
such as `symbol()` and `data.history()` so you can check the behavior
of each operation. At the start of shell, nothing has been called, so you
may want to initialize the context by `initialize(context)` which would
execute your `initialize()` function.
of each operation.

```
$ pylivetrader shell algo.py
```

The options are the same as `run`.

The options are as follows

- `-f` or `--file`: the file path to the algorithm source
- `-b` or `--backend`: the name of backend to use
- `--backend-config`: the yaml file for backend parameters

#### things you could do with the shell
* get asset price data. e.g: data.history(symbol("AAPL"), "close", 10, "1d")
* check if you can trade a certain asset. e.g: data.can_trade(symbol("AAPL"))
* get your account information: context.account
* get your portfolio information: context.account.portfolio
* get all opened orders: context.get_open_orders()
* get all orders: context.get_all_orders()
* get a list of all available assets. eg: context._backend._api.list_assets(asset_class='us_equity')

### migrate

`pylivetrader migrate` allows you to easily migrate your quantopian/zipline code to pylivetrader compatible code.<br>
how to run:
```sh
pylivetrader migrate -i zipline_code.py -o pylivetrader_compatible.py
```
now you could execute it with the `run` command
<br>note: we do not support the optimize api by quantopian since it is not a part of zipline

## Working with Pipline-live
You can see an example usage under the examples folder.<br>
To work with pipeline-live you need to do the following steps:
* Create the pipeline (usually you will create it in a method, convention name is `make_pipeline()`. Inside you will define your universe and add factors and filters.
* DO NOT store the pipe in the context object. We cannot store it to the statefile and you don't need to do it. we store it for you.
* attach the pipeline to the Algortihm instance. do it like this: `context.attach_pipeline(pipe, "my_pipe")`. this should be done in the `intialize()` or `before_trading_start()` methods.
* Now, to get the output of the pipeline, you do this: `context.pipeline_output('my_pipe')`. you should call it in `handle_data()` or any other method you use the scheduler for.

## State Management

@@ -131,7 +179,7 @@ restored on the next startup.
Second, because the context properties are restored, you may need to
take care of the extra steps. Often an algorithm is written under
the assumption that `initialize()` is called only once and
`before_start_trading()` is called once every morning. If you are
`before_trading_start()` is called once every morning. If you are
to restart the program in the middle of day, these functions are
called again, with the restored context object. Therefore, you
might need to check if the fields are from the other session
@@ -168,16 +216,20 @@ try our [docker image `alpacamarkets/pylivetrader`](https://hub.docker.com/r/alp
This has installed pylivetrader so you can start right away without
worrying about your python environment. See more details in the
`dockerfiles` directory.

If your algorithm file is called `algo.py`, this could be it.
<br>If your algorithm file is called `algo.py`, this could be all you need to run it.

```sh
docker run -v $PWD:/work -w /work alpacamarkets/pylivetrader pylivetrader run -f algo.py
```

Make sure you set up environment variables for the backend
Make sure you set up environment variables for the backend
(use `-e KEY=VAL` for docker command).


you could also build the docker image from source like this:<br>
`docker build -t alpaca/pylivetrader-dev -f dockerfiles/Dockerfile-dev .`<br>
it gives you the power to run it locally and edit or debug the code if you desire.

## Smoke Test

pylivetrader provides a facility for smoke testing. This helps catch
@@ -243,3 +295,13 @@ Again, the purpose of this smoke testing is to actually exercise various
code paths to make sure there are no easy mistakes. This code works well
with standard test frameworks such as `pytest` and you can easily report
line coverage using those frameworks too.

## Running Multiple Strategies
There's a way to execute more than one algorithm at once.<br>
The websocket connection is limited to 1 connection per account. <br>
For that exact purpose this ![project](https://github.com/shlomikushchi/alpaca-proxy-agent) was created<br>
The steps to execute this are:
* Run the Alpaca Proxy Agent as described in the project's README
* Define this env variable: `DATA_PROXY_WS` to be the address of the proxy agent. (e.g: `DATA_PROXY_WS=ws://127.0.0.1:8765`)
* execute your algorithm. it will connect to the servers through the proxy agent allowing you to execute multiple strategies

7 changes: 1 addition & 6 deletions dockerfiles/Dockerfile
Original file line number Diff line number Diff line change
@@ -9,9 +9,4 @@ RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
make install
RUN rm -R ta-lib ta-lib-0.4.0-src.tar.gz

RUN pip install pipenv

ADD Pipfile Pipfile.lock /tmp/
ADD Pipfile Pipfile.lock /

RUN pipenv install --system --dev
RUN pip install pylivetrader==0.5.5
15 changes: 15 additions & 0 deletions dockerfiles/Dockerfile-dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM python:3.6-stretch

# Install talib
RUN wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz && \
tar -xvzf ta-lib-0.4.0-src.tar.gz && \
cd ta-lib/ && \
./configure --prefix=/usr && \
make && \
make install
RUN rm -R ta-lib ta-lib-0.4.0-src.tar.gz


ADD . /opt/project
WORKDIR /opt/project
RUN pip install -e .
19 changes: 0 additions & 19 deletions dockerfiles/Pipfile

This file was deleted.

Loading