Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Packaging #44

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
sudo: false

language: python

env:
- PYTHON=2.7 PANDAS=0.17.1
- PYTHON=3.4 PANDAS=0.17.1
- PYTHON=3.5 PANDAS=0.17.1

#matrix:
# allow_failures:
# - env: PYTHON=2.7 PANDAS=0.13.0
# - env: PYTHON=2.7 PANDAS=0.12.0
# - env: PYTHON=2.7 PANDAS=0.11.0

install:
- pip install -qq flake8
# You may want to periodically update this, although the conda update
# conda line below will keep everything up-to-date. We do this
# conditionally because it saves us some downloading if the version is
# the same.
- if [[ "$PYTHON" == "2.7" ]]; then
wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
else
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
fi
- bash miniconda.sh -b -p $HOME/miniconda
- export PATH="$HOME/miniconda/bin:$PATH"
- hash -r
- conda config --set always_yes yes --set changeps1 no
- conda config --add channels pandas
- conda update -q conda
# Useful for debugging any issues with conda
- conda info -a
- conda create -q -n test-environment python=$PYTHON pandas=$PANDAS nose coverage setuptools
- source activate test-environment
- pip install coveralls --quiet
- conda list
- python setup.py install

script:
- flake8 --ignore E501 qstrader
- nosetests -v --with-coverage --cover-package=qstrader

after_success:
- coveralls
File renamed without changes.
File renamed without changes.
File renamed without changes.
1,630 changes: 1,630 additions & 0 deletions data/SP500TR.csv

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions examples/test_mac_backtest.py → examples/mac_backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@
from qstrader.compliance.compliance import TestCompliance
from qstrader import settings
from qstrader.strategy.moving_average_cross_strategy import MovingAverageCrossStrategy
try:
import Queue as queue
except ImportError:
import queue
from qstrader.compat.compat import queue


if __name__ == "__main__":
def main(config, testing=False):
tickers = ["SP500TR"]

# Set up variables needed for backtest
events_queue = queue.Queue()
csv_dir = settings.CSV_DATA_DIR
csv_dir = config.CSV_DATA_DIR
initial_equity = Decimal("500000.00")
heartbeat = 0.0
max_iters = 10000000000
Expand Down Expand Up @@ -66,4 +63,7 @@
statistics,
initial_equity
)
backtest.simulate_trading()
backtest.simulate_trading(testing=testing)

if __name__ == "__main__":
main(settings.DEFAULT, testing=False)
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@
from qstrader.compliance.compliance import TestCompliance
from qstrader import settings
from qstrader.strategy.strategy import BuyAndHoldStrategy
try:
import Queue as queue
except ImportError:
import queue
from qstrader.compat.compat import queue

if __name__ == "__main__":

def main(config, testing=False):
tickers = ["SP500TR"]

# Set up variables needed for backtest
events_queue = queue.Queue()
csv_dir = settings.CSV_DATA_DIR
csv_dir = config.CSV_DATA_DIR
initial_equity = Decimal("500000.00")
heartbeat = 0.0
max_iters = 10000000000
Expand Down Expand Up @@ -65,4 +63,7 @@
statistics,
initial_equity
)
backtest.simulate_trading()
backtest.simulate_trading(testing=testing)

if __name__ == "__main__":
main(settings.DEFAULT, testing=False)
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,15 @@
from qstrader.compliance.compliance import TestCompliance
from qstrader import settings
from qstrader.strategy.strategy import TestStrategy
try:
import Queue as queue
except ImportError:
import queue
from qstrader.compat.compat import queue

if __name__ == "__main__":

def main(config, testing=False):
tickers = ["GOOG"]

# Set up variables needed for backtest
events_queue = queue.Queue()
csv_dir = settings.CSV_DATA_DIR
csv_dir = config.CSV_DATA_DIR
initial_equity = Decimal("500000.00")
heartbeat = 0.0
max_iters = 10000000000
Expand All @@ -45,13 +43,13 @@
position_sizer, risk_manager
)

# Use the TestCompliance component
compliance = TestCompliance();
# Use the TestCompliance component
compliance = TestCompliance();

# Use a simulated IB Execution Handler
execution_handler = IBSimulatedExecutionHandler(
events_queue, price_handler, compliance
)
# Use a simulated IB Execution Handler
execution_handler = IBSimulatedExecutionHandler(
events_queue, price_handler, compliance
)
# Use the default Statistics
statistics = SimpleStatistics(portfolio_handler)

Expand All @@ -64,4 +62,7 @@
statistics,
initial_equity
)
backtest.simulate_trading()
backtest.simulate_trading(testing=testing)

if __name__ == "__main__":
main(settings.DEFAULT, testing=False)
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 3 additions & 2 deletions backtest/backtest.py → qstrader/backtest/backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def _run_backtest(self):
iters += 1


def simulate_trading(self):
def simulate_trading(self, testing=False):
"""
Simulates the backtest and outputs portfolio performance.
"""
Expand All @@ -112,4 +112,5 @@ def simulate_trading(self):
print("Sharpe Ratio: %s" % results["sharpe"])
print("Max Drawdown: %s" % results["max_drawdown"])
print("Max Drawdown Pct: %s" % results["max_drawdown_pct"])
self.statistics.plot_results()
if not testing:
self.statistics.plot_results()
File renamed without changes.
4 changes: 4 additions & 0 deletions qstrader/compat/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
try:
import Queue as queue
except ImportError:
import queue
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
44 changes: 44 additions & 0 deletions qstrader/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import os
import warnings


ENV_VAR_ROOT = 'QSTRADER'


def get_info(key, default_value=None):
"""Returns a value (url, login, password)
using either default_value or using environment variable"""
ENV_VAR_KEY = ENV_VAR_ROOT + "_" + key.upper()
if default_value == '' or default_value is None:
try:
return(os.environ[ENV_VAR_KEY])
except:
warnings.warn("You should pass %s using --%s or using environment variable %r" % (key, key, ENV_VAR_KEY))
return(default_value)
else:
return(default_value)


class SettingsDefault(object):
_CSV_DATA_DIR = "~/data"
_OUTPUT_DIR = "~/qstrader"

@property
def CSV_DATA_DIR(self):
return get_info("CSV_DATA_DIR", os.path.expanduser(self._CSV_DATA_DIR))

@property
def OUTPUT_DIR(self):
return get_info("OUTPUT_DIR", os.path.expanduser(self._CSV_DATA_DIR))


class SettingsTest(SettingsDefault):
_CSV_DATA_DIR = "data"
_OUTPUT_DIR = "out"


DEFAULT = SettingsDefault()
TEST = SettingsTest()

CSV_DATA_DIR = DEFAULT.CSV_DATA_DIR
OUTPUT_DIR = DEFAULT.OUTPUT_DIR
Empty file added qstrader/statistics/__init__.py
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
pass
import matplotlib.pyplot as plt
import seaborn as sns
from qstrader import settings

class Statistics(object):
"""
Expand Down
Empty file added qstrader/strategy/__init__.py
Empty file.
File renamed without changes.
8 changes: 8 additions & 0 deletions qstrader/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
__author__ = "Michael Halls-Moore"
__copyright__ = "Copyright 2016"
__license__ = "MIT"
__version__ = "0.0.1"
__maintainer__ = "mhallsmoore"
__email__ = ""
__status__ = "Development"
__url__ = "https://github.com/mhallsmoore/qstrader"
2 changes: 0 additions & 2 deletions settings.py.example

This file was deleted.

119 changes: 119 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from setuptools import setup, find_packages # Always prefer setuptools over distutils
from os import path
import io

here = path.abspath(path.dirname(__file__))

try:
import pypandoc
long_description = pypandoc.convert('README.md', 'rst')
except(IOError, ImportError):
print("Can't import pypandoc - using README.md without converting to RST")
long_description = open('README.md').read()

NAME = 'qstrader'
with io.open(path.join(here, NAME, 'version.py'), 'rt', encoding='UTF-8') as f:
exec(f.read())

setup(
name=NAME,

# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/development.html#single-sourcing-the-version
#version='0.0.2',
version=__version__,

description='QuantStart.com - Advanced Trading Infrastructure',
long_description=long_description,

# The project's main homepage.
url=__url__,

# Author details
author=__author__,
author_email=__email__,

# Choose your license
license=__license__,

# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
# How mature is this project? Common values are
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
'Development Status :: 3 - Alpha',

# Indicate who your project is intended for
'Environment :: Console',
#'Topic :: Software Development :: Build Tools',
'Intended Audience :: Developers',
'Operating System :: OS Independent',

# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
'Programming Language :: Cython',

'Programming Language :: Python',
#'Programming Language :: Python :: 2',
#'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
#'Programming Language :: Python :: 3',
#'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',

# Pick your license as you wish (should match "license" above)
'License :: OSI Approved :: MIT License',

],

# What does your project relate to?
keywords='python trading technical analysis backtesting',

# You can just specify the packages manually here if your project is
# simple. Or you can use find_packages().
packages=find_packages(exclude=['contrib', 'docs', 'tests*']),

# List run-time dependencies here. These will be installed by pip when your
# project is installed. For an analysis of "install_requires" vs pip's
# requirements files see:
# https://packaging.python.org/en/latest/technical.html#install-requires-vs-requirements-files
install_requires=['pandas'],

# List additional groups of dependencies here (e.g. development dependencies).
# You can install these using the following syntax, for example:
# $ pip install -e .[dev,test]
extras_require = {
'dev': ['check-manifest', 'nose'],
'test': ['coverage', 'nose'],
},

# If there are data files included in your packages that need to be
# installed, specify them here. If using Python 2.6 or less, then these
# have to be included in MANIFEST.in as well.
#package_data={
# 'samples': ['samples/*.py'],
#},

# Although 'package_data' is the preferred approach, in some case you may
# need to place data files outside of your packages.
# see http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files
# In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
#data_files=[('my_data', ['data/data_file'])],

# To provide executable scripts, use entry points in preference to the
# "scripts" keyword. Entry points provide cross-platform support and allow
# pip to create the appropriate form of executable for the target platform.
#entry_points={
# 'console_scripts': [
# 'sample=sample:main',
# ],
#},
#tests_require=['xlrd'],
#test_suite='tests',
)
Loading