{"id":13460936,"url":"https://github.com/alpacahq/pylivetrader","last_synced_at":"2025-04-08T08:11:42.960Z","repository":{"id":32869350,"uuid":"143319472","full_name":"alpacahq/pylivetrader","owner":"alpacahq","description":"Python live trade execution library with zipline interface.","archived":false,"fork":false,"pushed_at":"2022-10-04T15:17:22.000Z","size":630,"stargazers_count":667,"open_issues_count":20,"forks_count":195,"subscribers_count":68,"default_branch":"master","last_synced_at":"2025-04-01T07:45:59.162Z","etag":null,"topics":["algorithmic-trading","hacktoberfest","python","python3","quant","zipline"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pylivetrader/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alpacahq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-02T16:26:17.000Z","updated_at":"2025-03-17T23:41:21.000Z","dependencies_parsed_at":"2022-08-07T18:15:44.778Z","dependency_job_id":null,"html_url":"https://github.com/alpacahq/pylivetrader","commit_stats":null,"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alpacahq%2Fpylivetrader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alpacahq%2Fpylivetrader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alpacahq%2Fpylivetrader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alpacahq%2Fpylivetrader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alpacahq","download_url":"https://codeload.github.com/alpacahq/pylivetrader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247801170,"owners_count":20998339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithmic-trading","hacktoberfest","python","python3","quant","zipline"],"created_at":"2024-07-31T10:00:51.152Z","updated_at":"2025-04-08T08:11:42.937Z","avatar_url":"https://github.com/alpacahq.png","language":"Python","funding_links":[],"categories":["Trading System","Trading System (Back Test \u0026 Live trading)","Python","Execution and HFT"],"sub_categories":["Traditional Market","Trading \u0026 Backtesting","交易与回测"],"readme":"[![PyPI version](https://badge.fury.io/py/pylivetrader.svg)](https://badge.fury.io/py/pylivetrader)\n[![CircleCI](https://circleci.com/gh/alpacahq/pylivetrader.svg?style=shield)](https://circleci.com/gh/alpacahq/pylivetrader)\n[![Updates](https://pyup.io/repos/github/alpacahq/pylivetrader/shield.svg)](https://pyup.io/repos/github/alpacahq/pylivetrader/)\n[![Python 3](https://pyup.io/repos/github/alpacahq/pylivetrader/python-3-shield.svg)](https://pyup.io/repos/github/alpacahq/pylivetrader/)\n\n# pylivetrader\n\npylivetrader is a simple python live trading framework with zipline interface.\nThe main purpose is to run algorithms developed in the Quantopian platform in\nlive trading via broker API. In order to convert your algorithm for pylivetrader,\nplease read the [migration document](./migration.md).\n\n## example code\ncheck out the [examples](https://github.com/alpacahq/pylivetrader/tree/master/examples) \nfolder. you will find there the following examples:\n* simple MACD \"momentum\" trading\n* using pipeline-live to screen top stocks every day\n* a potfolio optimizer (used to optimize an existing porfolio. not to buy new\n stocks)\n \neach sample code contains a readme file and a smoke runner (read further to\n  understand what smoke is)\n\n## Simple Usage\n\nHere is the example dual moving average algorithm (by \n[quantopian/zipline](https://github.com/quantopian/zipline/blob/master/zipline/examples/dual_moving_average.py)).\n We provide mostly the same API interfaces with zipline.\n\n```py\nfrom pylivetrader.api import order_target, symbol\n\ndef initialize(context):\n    context.i = 0\n    context.asset = symbol('AAPL')\n\ndef handle_data(context, data):\n    # Compute averages\n    # data.history() has to be called with the same params\n    # from above and returns a pandas dataframe.\n    short_mavg = data.history(context.asset, 'price', bar_count=100, frequency=\"1m\").mean()\n    long_mavg = data.history(context.asset, 'price', bar_count=300, frequency=\"1m\").mean()\n\n    # Trading logic\n    if short_mavg \u003e long_mavg:\n        # order_target orders as many shares as needed to\n        # achieve the desired number of shares.\n        order_target(context.asset, 100)\n    elif short_mavg \u003c long_mavg:\n        order_target(context.asset, 0)\n```\n\nYou can run your algorithm from the CLI tool named `pylivetrader`, simply\nlike below. Then your algorithm starts running with broker API.\nYou don't need the data bundle file in advance unlike zipline does.\n\n```sh\n$ pylivetrader run -f algo.py --backend-config config.yaml\n```\n\nConfig file is just simple yaml or json format.\n\n```\n$ cat config.yaml\nkey_id: BROKER_API_KEY\nsecret: BROKER_SECRET\nbase_url: https://paper-api.alpaca.markets\nfeed: iex  # \u003c== change to pro if you have a paid account\n```\n### Usage with redis\n\nIf you are running pylivetrader in an environment with an ephemeral file store and need your context\nto persist across restarts, you can use the redis storage engine. This is useful if you launch in a\nplace like heroku.\n\nTo use this, you must install the redis-py library.\n\n```sh\n$ pip install redis\n```\n\nAfter that everything is the same as above, except the `run` command looks like the following:\n\n```sh\n$ pylivetrader run -f algo.py --backend-config config.yaml --storage-engine redis\n```\n\nAssuming you have redis running, this will now serialize your context object to and from redis.\n\n## Installation\n\nInstall with pip. **pylivetrader currently supports only Python 3.6.\n\n```\n$ python3.6 -m venv venv\n$ source venv/bin/activate\n(venv)$ pip install pylivetrader\n```\n\nAdditionally, pylivetrader works well with [pipeline-live](https://github.com/alpacahq/pipeline-live).\n\n## Command Reference\n\n### run\n\n`pylivetrader run` starts live trading using your algorithm script. It starts\nby calling the `initialize()` function if any, and waits until the market opens.\nIt calls the `before_trading_start` function if it is 8:45 ET (45 minutes\nbefore the session starts) or if it starts after that. Once the session\nstarts, it calls the `handle_data()` function every minute until the\nsession ends, or any functions that are registered by `schedule_function` API.\n\nThe options are as follows\n\n- `-f` or `--file`: the file path to the algorithm source\n- `-b` or `--backend`: the name of backend to use\n- `--backend-config`: the yaml file for backend parameters\n- `--storage-engine`: the storage engine to use for persisting the context. ('file' or 'redis')\n- `-s` or `--statefile`: the file path to the persisted state file (look for the State Management section below)\n- `-r` or `--retry`: the algorithm runner continues execution in the event a general exception is raised\n- `-l` or `--log-level`: the minimum level of log which will be written ('DEBUG', 'INFO', 'WARNING', 'ERROR', or 'CRITICAL')\n\n### shell\n\n`pylivetrader shell` goes into the IPython interactive shell mode as if you are\nin the algorithm script namespace. It means, you can call Algorithm API\nsuch as `symbol()` and `data.history()` so you can check the behavior\nof each operation.\n\n```\n$ pylivetrader shell algo.py\n```\n\n\nThe options are as follows\n\n- `-f` or `--file`: the file path to the algorithm source\n- `-b` or `--backend`: the name of backend to use\n- `--backend-config`: the yaml file for backend parameters\n\n#### things you could do with the shell\n* get asset price data. e.g: data.history(symbol(\"AAPL\"), \"close\", 10, \"1d\")\n* check if you can trade a certain asset. e.g: data.can_trade(symbol(\"AAPL\"))\n* get your account information: context.account\n* get your portfolio information: context.account.portfolio\n* get all opened orders: context.get_open_orders()\n* get all orders: context.get_all_orders()\n* get a list of all available assets. eg: context._backend._api.list_assets(asset_class='us_equity')\n\n### migrate\n\n`pylivetrader migrate` allows you to easily migrate your quantopian/zipline code to pylivetrader compatible code.\u003cbr\u003e\nhow to run:\n```sh\npylivetrader migrate -i zipline_code.py -o pylivetrader_compatible.py\n```\nnow you could execute it with the `run` command\n\u003cbr\u003enote: we do not support the optimize api by quantopian since it is not a part of zipline\n\n## Working with Pipline-live\nYou can see an example usage under the examples folder.\u003cbr\u003e\nTo work with pipeline-live you need to do the following steps:\n* 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.\n* 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.\n* 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.\n* 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.\n\n## State Management\n\nOne of the things you need to understand in live trading is that things can\nhappen and you may need to restart the script or the program dies in the middle\nof process due to some external errors. There are couple of things\nto know in advance.\n\nFirst, pylivetrader saves the property fields to the disk that you add to\nthe `context` object. It is stored in the pickle format and will be\nrestored on the next startup.\n\nSecond, because the context properties are restored, you may need to\ntake care of the extra steps. Often an algorithm is written under\nthe assumption that `initialize()` is called only once and\n`before_trading_start()` is called once every morning. If you are\nto restart the program in the middle of day, these functions are\ncalled again, with the restored context object. Therefore, you\nmight need to check if the fields are from the other session\nor in the same session to make sure you don't override the\nindermediate states in the day.\n\n## Supported Brokers\n\n### Alpaca\n\nConfiguration by environment variables.\n\n```\n$ export APCA_API_KEY_ID={your api key id}\n$ export APCA_API_SECRET_KEY={your api secret key}\n$ export APCA_API_BASE_URL={https://api.alpaca.markets/ or https://paper-api.alpaca.markets}\n$ pylivetrader run -f algo.py\n```\n\nConfiguration by config file. Either yaml or json.\n\n```\n$ cat config.yaml\nkey_id: {your api key id}\nsecret: {your api secret key}\nbase_url: {https://api.alpaca.markets/ or https://paper-api.alpaca.markets}\n$ pylivetrader run -f algo.py --backend-config config.yaml\n```\n\n## Docker\n\nIf you are already familiar with Docker, it is a good idea to\ntry our [docker image `alpacamarkets/pylivetrader`](https://hub.docker.com/r/alpacamarkets/pylivetrader/).\nThis has installed pylivetrader so you can start right away without\nworrying about your python environment.  See more details in the\n`dockerfiles` directory.\n\u003cbr\u003eIf your algorithm file is called `algo.py`, this could be all you need to run it.\n\n```sh\ndocker run -v $PWD:/work -w /work alpacamarkets/pylivetrader pylivetrader run -f algo.py\n```\n\nMake sure you set up environment variables for the backend\n(use `-e KEY=VAL` for docker command).\n\n\nyou could also build the docker image from source like this:\u003cbr\u003e\n`docker build -t alpaca/pylivetrader-dev -f dockerfiles/Dockerfile-dev .`\u003cbr\u003e\nit gives you the power to run it locally and edit or debug the code if you desire.\n\n## Smoke Test\n\npylivetrader provides a facility for smoke testing. This helps catch\nissues such as typos, program errors and simple oversights. The following\nis an example of smoke testing.\n\n```py\nimport algo\n\nfrom pylivetrader.testing.smoke import harness\n\n\ndef before_run(context, backend):\n    '''This hook is called before algorithm starts.'''\n\n    # Populate existing position\n    backend.set_position(\n        'A', 10, 200,\n    )\n\n    # modify some fields of context after `initialize(context)` is called\n    _init = context._initialize\n    def wrapper(ctx):\n        _init(ctx)\n        ctx.age[ctx.symbol('A')] = 3\n        ctx.age[ctx.symbol('B')] = 2\n\n    context._initialize = wrapper\n\ndef test_algo():\n    pipeline = harness.DefaultPipelineHooker()\n\n    # run the algorithm under the simulation environment\n    harness.run_smoke(algo,\n        before_run_hook=before_run,\n        pipeline_hook=pipeline,\n    )\n\n\nif __name__ == '__main__':\n    import logging\n    logging.basicConfig(level=logging.DEBUG)\n    test_algo()\n```\n\nThis exercises the algorithm code by harnessing synthetic backend and price data.\nThe `pylivetrader.testing.smoke` package provides the backend and simulator\nclock classes so that it simulates a market day from open to close.\n\nBy default, the backend creates a universe with 50 stocks ('A' .. 'AX').\nFor each symbol, you can query synthetic historical price, and orders\nare managed within this simulator without having to set up a real remote\nbackend API. Additionally, you can hook up a couple of code injection\npoints such as `before_run_hook` and `pipeline_hook`. In this example,\nthe setup code creates a pre-populated position in the backend so you can\ntest the algorithm code path that accepts existing positions.\n\nA `DefaultPipelineHooker` instance can return a synthetic pipeline result\nwith the same column names/types, inferred from the pipeline object\ngiven in the `attach_pipeline` API.\n\nAgain, the purpose of this smoke testing is to actually exercise various\ncode paths to make sure there are no easy mistakes. This code works well\nwith standard test frameworks such as `pytest` and you can easily report\nline coverage using those frameworks too.\n\n## Running Multiple Strategies\nThere's a way to execute more than one algorithm at once.\u003cbr\u003e\nThe websocket connection is limited to 1 connection per account. \u003cbr\u003e\nFor that exact purpose this ![project](https://github.com/shlomikushchi/alpaca-proxy-agent)  was created\u003cbr\u003e\nThe steps to execute this are:\n* Run the Alpaca Proxy Agent as described in the project's README\n* 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`)\n* execute your algorithm. it will connect to the servers through the proxy agent allowing you to execute multiple strategies\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falpacahq%2Fpylivetrader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falpacahq%2Fpylivetrader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falpacahq%2Fpylivetrader/lists"}