mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-22 12:40:30 +08:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ade2989e8 | ||
|
|
b1d5acf2ad | ||
|
|
5d5ec6b9be | ||
|
|
1b84023c5d | ||
|
|
97f3329c1b | ||
|
|
bdeb344999 | ||
|
|
52e1de954f | ||
|
|
7b9eafef4e | ||
|
|
8b141a0c28 | ||
|
|
7f602d7fcc |
@@ -138,8 +138,9 @@ from catalyst.gens.sim_engine import MinuteSimulationClock
|
|||||||
from catalyst.sources.benchmark_source import BenchmarkSource
|
from catalyst.sources.benchmark_source import BenchmarkSource
|
||||||
from catalyst.catalyst_warnings import ZiplineDeprecationWarning
|
from catalyst.catalyst_warnings import ZiplineDeprecationWarning
|
||||||
|
|
||||||
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
log = logbook.Logger("ZiplineLog")
|
log = logbook.Logger("CatalystLog", level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class TradingAlgorithm(object):
|
class TradingAlgorithm(object):
|
||||||
|
|||||||
@@ -76,7 +76,9 @@ from catalyst.utils.numpy_utils import as_column
|
|||||||
from catalyst.utils.preprocess import preprocess
|
from catalyst.utils.preprocess import preprocess
|
||||||
from catalyst.utils.sqlite_utils import group_into_chunks, coerce_string_to_eng
|
from catalyst.utils.sqlite_utils import group_into_chunks, coerce_string_to_eng
|
||||||
|
|
||||||
log = Logger('assets.py')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('assets.py', level=LOG_LEVEL)
|
||||||
|
|
||||||
# A set of fields that need to be converted to strings before building an
|
# A set of fields that need to be converted to strings before building an
|
||||||
# Asset to avoid unicode fields
|
# Asset to avoid unicode fields
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import logbook
|
||||||
|
|
||||||
|
LOG_LEVEL = logbook.INFO
|
||||||
@@ -215,7 +215,7 @@ cpdef _read_bcolz_data(ctable_t table,
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if column_name in ['open', 'high', 'low', 'close']:
|
if column_name in ['open', 'high', 'low', 'close', 'volume']:
|
||||||
where_nan = (outbuf == 0)
|
where_nan = (outbuf == 0)
|
||||||
outbuf_as_float = outbuf.astype(float64) * .000000001
|
outbuf_as_float = outbuf.astype(float64) * .000000001
|
||||||
outbuf_as_float[where_nan] = NAN
|
outbuf_as_float[where_nan] = NAN
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ from catalyst.utils.cli import (
|
|||||||
)
|
)
|
||||||
from catalyst.utils.memoize import lazyval
|
from catalyst.utils.memoize import lazyval
|
||||||
|
|
||||||
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
logbook.StderrHandler().push_application()
|
logbook.StderrHandler().push_application()
|
||||||
log = logbook.Logger(__name__)
|
log = logbook.Logger(__name__, level=LOG_LEVEL)
|
||||||
|
|
||||||
DEFAULT_RETRIES = 5
|
DEFAULT_RETRIES = 5
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ from catalyst.utils.cli import maybe_show_progress
|
|||||||
|
|
||||||
from . import core as bundles
|
from . import core as bundles
|
||||||
|
|
||||||
log = Logger(__name__)
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger(__name__, level=LOG_LEVEL)
|
||||||
seconds_per_call = (pd.Timedelta('10 minutes') / 2000).total_seconds()
|
seconds_per_call = (pd.Timedelta('10 minutes') / 2000).total_seconds()
|
||||||
|
|
||||||
class QuandlBundle(BaseEquityPricingBundle):
|
class QuandlBundle(BaseEquityPricingBundle):
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ from catalyst.errors import (
|
|||||||
HistoryWindowStartsBeforeData,
|
HistoryWindowStartsBeforeData,
|
||||||
)
|
)
|
||||||
|
|
||||||
log = Logger('DataPortal')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('DataPortal', level=LOG_LEVEL)
|
||||||
|
|
||||||
BASE_FIELDS = frozenset([
|
BASE_FIELDS = frozenset([
|
||||||
"open",
|
"open",
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ from ..utils.paths import (
|
|||||||
data_root,
|
data_root,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logbook.Logger('Loader')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
logger = logbook.Logger('Loader', level=LOG_LEVEL)
|
||||||
|
|
||||||
# Mapping from index symbol to appropriate bond data
|
# Mapping from index symbol to appropriate bond data
|
||||||
INDEX_MAPPING = {
|
INDEX_MAPPING = {
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ from catalyst.utils.calendars import get_calendar
|
|||||||
from catalyst.utils.cli import maybe_show_progress
|
from catalyst.utils.cli import maybe_show_progress
|
||||||
from catalyst.utils.memoize import lazyval
|
from catalyst.utils.memoize import lazyval
|
||||||
|
|
||||||
logger = logbook.Logger('MinuteBars')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
logger = logbook.Logger('MinuteBars', level=LOG_LEVEL)
|
||||||
|
|
||||||
US_EQUITIES_MINUTES_PER_DAY = 390
|
US_EQUITIES_MINUTES_PER_DAY = 390
|
||||||
FUTURES_MINUTES_PER_DAY = 1440
|
FUTURES_MINUTES_PER_DAY = 1440
|
||||||
|
|||||||
@@ -83,7 +83,9 @@ from catalyst.utils.cli import (
|
|||||||
from ._equities import _compute_row_slices, _read_bcolz_data
|
from ._equities import _compute_row_slices, _read_bcolz_data
|
||||||
from ._adjustments import load_adjustments_from_sqlite
|
from ._adjustments import load_adjustments_from_sqlite
|
||||||
|
|
||||||
logger = logbook.Logger('UsEquityPricing')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
logger = logbook.Logger('UsEquityPricing', level=LOG_LEVEL)
|
||||||
|
|
||||||
OHLC = frozenset(['open', 'high', 'low', 'close'])
|
OHLC = frozenset(['open', 'high', 'low', 'close'])
|
||||||
OHLCV = frozenset(['open', 'high', 'low', 'close', 'volume'])
|
OHLCV = frozenset(['open', 'high', 'low', 'close', 'volume'])
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
from catalyst.api import order, record, symbol
|
from catalyst.api import order, record, symbol
|
||||||
|
|
||||||
def initialize(context):
|
def initialize(context):
|
||||||
context.asset = symbol('btc_usd')
|
context.asset = symbol('btc_usd')
|
||||||
|
|
||||||
def handle_data(context, data):
|
def handle_data(context, data):
|
||||||
order(asset, 1)
|
order(context.asset, 1)
|
||||||
record(btc=data.current(context.asset, 'price'))
|
record(btc = data.current(context.asset, 'price'))
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
from logbook import Logger
|
from logbook import Logger
|
||||||
|
|
||||||
log = Logger('AssetFinderExchange')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('AssetFinderExchange', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class AssetFinderExchange(object):
|
class AssetFinderExchange(object):
|
||||||
@@ -41,9 +43,9 @@ class AssetFinderExchange(object):
|
|||||||
"""
|
"""
|
||||||
for sid in sids:
|
for sid in sids:
|
||||||
if sid in self._asset_cache:
|
if sid in self._asset_cache:
|
||||||
log.info('got asset from cache: {}'.format(sid))
|
log.debug('got asset from cache: {}'.format(sid))
|
||||||
else:
|
else:
|
||||||
log.info('fetching asset: {}'.format(sid))
|
log.debug('fetching asset: {}'.format(sid))
|
||||||
return list()
|
return list()
|
||||||
|
|
||||||
def lookup_symbol(self, symbol, exchange, as_of_date=None, fuzzy=False):
|
def lookup_symbol(self, symbol, exchange, as_of_date=None, fuzzy=False):
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ requests.adapters.DEFAULT_RETRIES = 20
|
|||||||
|
|
||||||
BITFINEX_URL = 'https://api.bitfinex.com'
|
BITFINEX_URL = 'https://api.bitfinex.com'
|
||||||
|
|
||||||
log = Logger('Bitfinex')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('Bitfinex', level=LOG_LEVEL)
|
||||||
warning_logger = Logger('AlgoWarning')
|
warning_logger = Logger('AlgoWarning')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ from catalyst.finance.order import Order, ORDER_STATUS
|
|||||||
from catalyst.exchange.exchange_utils import get_exchange_symbols_filename, \
|
from catalyst.exchange.exchange_utils import get_exchange_symbols_filename, \
|
||||||
download_exchange_symbols
|
download_exchange_symbols
|
||||||
|
|
||||||
log = Logger('Bittrex')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('Bittrex', level=LOG_LEVEL)
|
||||||
|
|
||||||
URL2 = 'https://bittrex.com/Api/v2.0'
|
URL2 = 'https://bittrex.com/Api/v2.0'
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ from catalyst.exchange.exchange_errors import (
|
|||||||
PricingDataNotLoadedError, InvalidHistoryFrequencyError,
|
PricingDataNotLoadedError, InvalidHistoryFrequencyError,
|
||||||
BundleNotFoundError)
|
BundleNotFoundError)
|
||||||
|
|
||||||
log = Logger('DataPortalExchange')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('DataPortalExchange', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class DataPortalExchangeBase(DataPortal):
|
class DataPortalExchangeBase(DataPortal):
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ from catalyst.exchange.exchange_utils import get_exchange_symbols
|
|||||||
from catalyst.finance.order import ORDER_STATUS
|
from catalyst.finance.order import ORDER_STATUS
|
||||||
from catalyst.finance.transaction import Transaction
|
from catalyst.finance.transaction import Transaction
|
||||||
|
|
||||||
log = Logger('Exchange')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('Exchange', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class Exchange:
|
class Exchange:
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ from catalyst.utils.input_validation import error_keywords, ensure_upper_case, \
|
|||||||
from catalyst.utils.preprocess import preprocess
|
from catalyst.utils.preprocess import preprocess
|
||||||
from catalyst.utils.math_utils import round_nearest
|
from catalyst.utils.math_utils import round_nearest
|
||||||
|
|
||||||
log = logbook.Logger('exchange_algorithm')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('exchange_algorithm', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class ExchangeAlgorithmExecutor(AlgorithmSimulator):
|
class ExchangeAlgorithmExecutor(AlgorithmSimulator):
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ from catalyst.finance.commission import CommissionModel
|
|||||||
from catalyst.finance.slippage import SlippageModel
|
from catalyst.finance.slippage import SlippageModel
|
||||||
from catalyst.finance.transaction import Transaction
|
from catalyst.finance.transaction import Transaction
|
||||||
|
|
||||||
log = Logger('exchange_blotter')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('exchange_blotter', level=LOG_LEVEL)
|
||||||
|
|
||||||
# It seems like we need to accept greater slippage risk in cryptos
|
# It seems like we need to accept greater slippage risk in cryptos
|
||||||
# Orders won't often close at Equity levels.
|
# Orders won't often close at Equity levels.
|
||||||
|
|||||||
@@ -21,16 +21,15 @@ from catalyst.exchange.exchange_utils import get_exchange_folder
|
|||||||
from catalyst.utils.cli import maybe_show_progress
|
from catalyst.utils.cli import maybe_show_progress
|
||||||
from catalyst.utils.paths import ensure_directory
|
from catalyst.utils.paths import ensure_directory
|
||||||
|
|
||||||
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('exchange_bundle', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
BUNDLE_NAME_TEMPLATE = '{root}/{frequency}_bundle'
|
||||||
|
|
||||||
def _cachpath(symbol, type_):
|
def _cachpath(symbol, type_):
|
||||||
return '-'.join([symbol, type_])
|
return '-'.join([symbol, type_])
|
||||||
|
|
||||||
|
|
||||||
BUNDLE_NAME_TEMPLATE = '{root}/{frequency}_bundle'
|
|
||||||
log = Logger('exchange_bundle')
|
|
||||||
log.level = INFO
|
|
||||||
|
|
||||||
|
|
||||||
class ExchangeBundle:
|
class ExchangeBundle:
|
||||||
def __init__(self, exchange):
|
def __init__(self, exchange):
|
||||||
self.exchange = exchange
|
self.exchange = exchange
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ from logbook import Logger
|
|||||||
|
|
||||||
from catalyst.protocol import Portfolio, Positions, Position
|
from catalyst.protocol import Portfolio, Positions, Position
|
||||||
|
|
||||||
log = Logger('ExchangePortfolio')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('ExchangePortfolio', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class ExchangePortfolio(Portfolio):
|
class ExchangePortfolio(Portfolio):
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ from logbook import Logger
|
|||||||
from catalyst.exchange.exchange_errors import \
|
from catalyst.exchange.exchange_errors import \
|
||||||
MismatchingBaseCurrenciesExchanges
|
MismatchingBaseCurrenciesExchanges
|
||||||
|
|
||||||
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
log = Logger('LiveGraphClock')
|
log = Logger('LiveGraphClock', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class LiveGraphClock(object):
|
class LiveGraphClock(object):
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ from catalyst.exchange.exchange_utils import get_exchange_symbols_filename, \
|
|||||||
download_exchange_symbols
|
download_exchange_symbols
|
||||||
from catalyst.finance.transaction import Transaction
|
from catalyst.finance.transaction import Transaction
|
||||||
|
|
||||||
log = Logger('Poloniex')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('Poloniex', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class Poloniex(Exchange):
|
class Poloniex(Exchange):
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ from catalyst.finance.commission import (
|
|||||||
from catalyst.finance.cancel_policy import NeverCancel
|
from catalyst.finance.cancel_policy import NeverCancel
|
||||||
from catalyst.utils.input_validation import expect_types
|
from catalyst.utils.input_validation import expect_types
|
||||||
|
|
||||||
log = Logger('Blotter')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('Blotter', level=LOG_LEVEL)
|
||||||
warning_logger = Logger('AlgoWarning')
|
warning_logger = Logger('AlgoWarning')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ from catalyst.errors import (
|
|||||||
TradingControlViolation,
|
TradingControlViolation,
|
||||||
)
|
)
|
||||||
|
|
||||||
log = logbook.Logger('TradingControl')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('TradingControl', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class TradingControl(with_metaclass(abc.ABCMeta)):
|
class TradingControl(with_metaclass(abc.ABCMeta)):
|
||||||
|
|||||||
@@ -88,7 +88,10 @@ from six import itervalues, iteritems
|
|||||||
|
|
||||||
import catalyst.protocol as zp
|
import catalyst.protocol as zp
|
||||||
|
|
||||||
log = logbook.Logger('Performance')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Performance', level=LOG_LEVEL)
|
||||||
|
|
||||||
TRADE_TYPE = zp.DATASOURCE_TYPE.TRADE
|
TRADE_TYPE = zp.DATASOURCE_TYPE.TRADE
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ import logbook
|
|||||||
from catalyst.assets import Future, Asset
|
from catalyst.assets import Future, Asset
|
||||||
from catalyst.utils.input_validation import expect_types
|
from catalyst.utils.input_validation import expect_types
|
||||||
|
|
||||||
log = logbook.Logger('Performance')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Performance', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class Position(object):
|
class Position(object):
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ from catalyst.assets import (
|
|||||||
)
|
)
|
||||||
from . position import positiondict
|
from . position import positiondict
|
||||||
|
|
||||||
log = logbook.Logger('Performance')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Performance', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
PositionStats = namedtuple('PositionStats',
|
PositionStats = namedtuple('PositionStats',
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ import catalyst.finance.risk as risk
|
|||||||
|
|
||||||
from . position_tracker import PositionTracker
|
from . position_tracker import PositionTracker
|
||||||
|
|
||||||
log = logbook.Logger('Performance')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Performance', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class PerformanceTracker(object):
|
class PerformanceTracker(object):
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ from empyrical import (
|
|||||||
sortino_ratio,
|
sortino_ratio,
|
||||||
)
|
)
|
||||||
|
|
||||||
log = logbook.Logger('Risk Cumulative')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Risk Cumulative', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
choose_treasury = functools.partial(choose_treasury, lambda *args: '10year',
|
choose_treasury = functools.partial(choose_treasury, lambda *args: '10year',
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ from empyrical import (
|
|||||||
sortino_ratio
|
sortino_ratio
|
||||||
)
|
)
|
||||||
|
|
||||||
log = logbook.Logger('Risk Period')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Risk Period', level=LOG_LEVEL)
|
||||||
|
|
||||||
choose_treasury = functools.partial(risk.choose_treasury,
|
choose_treasury = functools.partial(risk.choose_treasury,
|
||||||
risk.select_treasury_duration)
|
risk.select_treasury_duration)
|
||||||
|
|||||||
@@ -63,7 +63,9 @@ from dateutil.relativedelta import relativedelta
|
|||||||
|
|
||||||
from . period import RiskMetricsPeriod
|
from . period import RiskMetricsPeriod
|
||||||
|
|
||||||
log = logbook.Logger('Risk Report')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Risk Report', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class RiskReport(object):
|
class RiskReport(object):
|
||||||
|
|||||||
@@ -61,7 +61,9 @@ Risk Report
|
|||||||
import logbook
|
import logbook
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
log = logbook.Logger('Risk')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Risk', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
TREASURY_DURATIONS = [
|
TREASURY_DURATIONS = [
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ from catalyst.data.loader import load_market_data
|
|||||||
from catalyst.utils.calendars import get_calendar
|
from catalyst.utils.calendars import get_calendar
|
||||||
from catalyst.utils.memoize import remember_last
|
from catalyst.utils.memoize import remember_last
|
||||||
|
|
||||||
log = logbook.Logger('Trading')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = logbook.Logger('Trading', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_CAPITAL_BASE = 1e5
|
DEFAULT_CAPITAL_BASE = 1e5
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ from catalyst.gens.sim_engine import (
|
|||||||
BEFORE_TRADING_START_BAR
|
BEFORE_TRADING_START_BAR
|
||||||
)
|
)
|
||||||
|
|
||||||
log = Logger('Trade Simulation')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('Trade Simulation', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class AlgorithmSimulator(object):
|
class AlgorithmSimulator(object):
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ from catalyst.protocol import (
|
|||||||
)
|
)
|
||||||
from catalyst.assets import Equity
|
from catalyst.assets import Equity
|
||||||
|
|
||||||
logger = Logger('Requests Source Logger')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
logger = Logger('Requests Source Logger', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
def roll_dts_to_midnight(dts, trading_day):
|
def roll_dts_to_midnight(dts, trading_day):
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ from catalyst.exchange.exchange_utils import get_exchange_auth, \
|
|||||||
get_algo_object
|
get_algo_object
|
||||||
from logbook import Logger
|
from logbook import Logger
|
||||||
|
|
||||||
log = Logger('run_algo')
|
from catalyst.constants import LOG_LEVEL
|
||||||
|
|
||||||
|
log = Logger('run_algo', level=LOG_LEVEL)
|
||||||
|
|
||||||
|
|
||||||
class _RunAlgoError(click.ClickException, ValueError):
|
class _RunAlgoError(click.ClickException, ValueError):
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ My first algorithm
|
|||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Lets take a look at a very simple algorithm from the ``examples``
|
Lets take a look at a very simple algorithm from the ``examples``
|
||||||
directory, ``buy_btc.py``:
|
directory: `buy_btc_simple.py <https://github.com/enigmampc/catalyst/blob/master/catalyst/examples/buy_btc_simple.py>`_:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
@@ -225,16 +225,16 @@ Thus, to execute our algorithm from above and save the results to
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2016-9-29 -o buy_simple_btc_out.pickle
|
catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2017-9-30 -o buy_btc_simple_out.pickle
|
||||||
|
|
||||||
|
|
||||||
..
|
.. parsed-literal::
|
||||||
.. parsed-literal
|
|
||||||
|
|
||||||
.. AAPL
|
INFO: run_algo: running algo in backtest mode
|
||||||
.. [2015-11-04 22:45:32.820166] INFO: Performance: Simulated 3521 trading days out of 3521.
|
INFO: exchange_algorithm: initialized trading algorithm in backtest mode
|
||||||
.. [2015-11-04 22:45:32.820314] INFO: Performance: first open: 2000-01-03 14:31:00+00:00
|
INFO: Performance: Simulated 639 trading days out of 639.
|
||||||
.. [2015-11-04 22:45:32.820401] INFO: Performance: last close: 2013-12-31 21:00:00+00:00
|
INFO: Performance: first open: 2016-01-01 00:00:00+00:00
|
||||||
|
INFO: Performance: last close: 2017-09-30 23:59:00+00:00
|
||||||
|
|
||||||
|
|
||||||
``run`` first calls the ``initialize()`` function, and then
|
``run`` first calls the ``initialize()`` function, and then
|
||||||
@@ -255,7 +255,7 @@ slippage model that ``catalyst`` uses).
|
|||||||
|
|
||||||
Let's take a quick look at the performance ``DataFrame``. For this, we
|
Let's take a quick look at the performance ``DataFrame``. For this, we
|
||||||
use ``pandas`` from inside the IPython Notebook and print the first ten
|
use ``pandas`` from inside the IPython Notebook and print the first ten
|
||||||
rows. Note that ``catalyst`` makes heavy usage of
|
rows. and print the first ten rows. Note that ``catalyst`` makes heavy usage of
|
||||||
`pandas <http://pandas.pydata.org/>`_, especially for data input and
|
`pandas <http://pandas.pydata.org/>`_, especially for data input and
|
||||||
outputting so it's worth spending some time to learn it.
|
outputting so it's worth spending some time to learn it.
|
||||||
|
|
||||||
@@ -265,17 +265,196 @@ outputting so it's worth spending some time to learn it.
|
|||||||
perf = pd.read_pickle('buy_btc_simple_out.pickle') # read in perf DataFrame
|
perf = pd.read_pickle('buy_btc_simple_out.pickle') # read in perf DataFrame
|
||||||
perf.head()
|
perf.head()
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<div style="max-height:1000px;max-width:1500px;overflow:auto;">
|
||||||
|
<table border="1" class="dataframe">
|
||||||
|
<thead>
|
||||||
|
<tr style="text-align: right;">
|
||||||
|
<th></th>
|
||||||
|
<th>algo_volatility</th>
|
||||||
|
<th>algorithm_period_return</th>
|
||||||
|
<th>alpha</th>
|
||||||
|
<th>benchmark_period_return</th>
|
||||||
|
<th>benchmark_volatility</th>
|
||||||
|
<th>beta</th>
|
||||||
|
<th>btc</th>
|
||||||
|
<th>capital_used</th>
|
||||||
|
<th>ending_cash</th>
|
||||||
|
<th>ending_exposure</th>
|
||||||
|
<th>...</th>
|
||||||
|
<th>short_exposure</th>
|
||||||
|
<th>short_value</th>
|
||||||
|
<th>shorts_count</th>
|
||||||
|
<th>sortino</th>
|
||||||
|
<th>starting_cash</th>
|
||||||
|
<th>starting_exposure</th>
|
||||||
|
<th>starting_value</th>
|
||||||
|
<th>trading_days</th>
|
||||||
|
<th>transactions</th>
|
||||||
|
<th>treasury_period_return</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>2016-01-01 23:59:00+00:00</th>
|
||||||
|
<td>NaN</td>
|
||||||
|
<td>0.000000e+00</td>
|
||||||
|
<td>NaN</td>
|
||||||
|
<td>-0.010937</td>
|
||||||
|
<td>NaN</td>
|
||||||
|
<td>NaN</td>
|
||||||
|
<td>433.979999</td>
|
||||||
|
<td>0.000000</td>
|
||||||
|
<td>1.000000e+07</td>
|
||||||
|
<td>0.00</td>
|
||||||
|
<td>...</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>NaN</td>
|
||||||
|
<td>1.000000e+07</td>
|
||||||
|
<td>0.00</td>
|
||||||
|
<td>0.00</td>
|
||||||
|
<td>1</td>
|
||||||
|
<td>[]</td>
|
||||||
|
<td>0.0227</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>2016-01-02 23:59:00+00:00</th>
|
||||||
|
<td>0.000011</td>
|
||||||
|
<td>-9.536708e-07</td>
|
||||||
|
<td>-0.000170</td>
|
||||||
|
<td>-0.006480</td>
|
||||||
|
<td>0.173338</td>
|
||||||
|
<td>-0.000062</td>
|
||||||
|
<td>432.700000</td>
|
||||||
|
<td>-442.236708</td>
|
||||||
|
<td>9.999558e+06</td>
|
||||||
|
<td>432.70</td>
|
||||||
|
<td>...</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>-11.224972</td>
|
||||||
|
<td>1.000000e+07</td>
|
||||||
|
<td>0.00</td>
|
||||||
|
<td>0.00</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>[{u'order_id': u'7869f7828fa140328eb40477bb7de...</td>
|
||||||
|
<td>0.0227</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>2016-01-03 23:59:00+00:00</th>
|
||||||
|
<td>0.000011</td>
|
||||||
|
<td>-2.328842e-06</td>
|
||||||
|
<td>-0.000176</td>
|
||||||
|
<td>-0.026512</td>
|
||||||
|
<td>0.197857</td>
|
||||||
|
<td>0.000009</td>
|
||||||
|
<td>428.390000</td>
|
||||||
|
<td>-437.831716</td>
|
||||||
|
<td>9.999120e+06</td>
|
||||||
|
<td>856.78</td>
|
||||||
|
<td>...</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>-12.754262</td>
|
||||||
|
<td>9.999558e+06</td>
|
||||||
|
<td>432.70</td>
|
||||||
|
<td>432.70</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>[{u'order_id': u'be62ff77760c4599abaac43be9cc9...</td>
|
||||||
|
<td>0.0227</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>2016-01-04 23:59:00+00:00</th>
|
||||||
|
<td>0.000011</td>
|
||||||
|
<td>-2.380954e-06</td>
|
||||||
|
<td>-0.000139</td>
|
||||||
|
<td>-0.008640</td>
|
||||||
|
<td>0.269790</td>
|
||||||
|
<td>0.000020</td>
|
||||||
|
<td>432.900000</td>
|
||||||
|
<td>-442.441116</td>
|
||||||
|
<td>9.998677e+06</td>
|
||||||
|
<td>1298.70</td>
|
||||||
|
<td>...</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>-11.287205</td>
|
||||||
|
<td>9.999120e+06</td>
|
||||||
|
<td>856.78</td>
|
||||||
|
<td>856.78</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>[{u'order_id': u'd6dca79513214346a646079213526...</td>
|
||||||
|
<td>0.0224</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>2016-01-05 23:59:00+00:00</th>
|
||||||
|
<td>0.000011</td>
|
||||||
|
<td>-3.650729e-06</td>
|
||||||
|
<td>-0.000158</td>
|
||||||
|
<td>-0.021426</td>
|
||||||
|
<td>0.245989</td>
|
||||||
|
<td>0.000024</td>
|
||||||
|
<td>431.840000</td>
|
||||||
|
<td>-441.357754</td>
|
||||||
|
<td>9.998236e+06</td>
|
||||||
|
<td>1727.36</td>
|
||||||
|
<td>...</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>0</td>
|
||||||
|
<td>-12.333847</td>
|
||||||
|
<td>9.998677e+06</td>
|
||||||
|
<td>1298.70</td>
|
||||||
|
<td>1298.70</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>[{u'order_id': u'505275d6646a41f3856b22b16678d...</td>
|
||||||
|
<td>0.0225</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
There is a row for each trading day, starting on the first day of our
|
There is a row for each trading day, starting on the first day of our
|
||||||
simulation Jan 1st, 2016. In the columns you can find various
|
simulation Jan 1st, 2016. In the columns you can find various
|
||||||
information about the state of your algorithm. The very first column
|
information about the state of your algorithm. The column
|
||||||
``btc`` was placed there by the ``record()`` function mentioned earlier
|
``btc`` was placed there by the ``record()`` function mentioned earlier
|
||||||
and allows us to plot the price of bitcoin. For example, we could easily
|
and allows us to plot the price of bitcoin. For example, we could easily
|
||||||
examine now how our portfolio value changed over time compared to the
|
examine now how our portfolio value changed over time compared to the
|
||||||
bitcoin price.
|
bitcoin price.
|
||||||
|
|
||||||
Our algorithm performance as assessed by the
|
.. code-block:: python
|
||||||
``portfolio_value`` closely matches that of the bitcoin price. This
|
|
||||||
is not surprising as our algorithm only bought bitcoin every chance it got.
|
%pylab inline
|
||||||
|
figsize(12, 12)
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
ax1 = plt.subplot(211)
|
||||||
|
perf.portfolio_value.plot(ax=ax1)
|
||||||
|
ax1.set_ylabel('portfolio value')
|
||||||
|
ax2 = plt.subplot(212, sharex=ax1)
|
||||||
|
perf.btc.plot(ax=ax2)
|
||||||
|
ax2.set_ylabel('bitcoin price')
|
||||||
|
|
||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
Populating the interactive namespace from numpy and matplotlib
|
||||||
|
|
||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
<matplotlib.text.Text at 0x10eaeadd0>
|
||||||
|
|
||||||
|
.. image:: https://s3.amazonaws.com/enigmaco-docs/github.io/buy_btc_simple_graph.png
|
||||||
|
|
||||||
|
Our algorithm performance as assessed by the ``portfolio_value`` closely
|
||||||
|
matches that of the bitcoin price. This is not surprising as our algorithm
|
||||||
|
only bought bitcoin every chance it got.
|
||||||
|
|
||||||
|
|
||||||
Access to previous prices using ``history``
|
Access to previous prices using ``history``
|
||||||
@@ -305,13 +484,14 @@ a function we use in the ``handle_data()`` section:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
from catalyst.api import order, record, symbol
|
%%catalyst --start 2016-1-1 --end 2017-9-30 -x bitfinex -o dma.pickle
|
||||||
|
from catalyst.api import order, record, symbol, order_target
|
||||||
|
|
||||||
def initialize(context):
|
def initialize(context):
|
||||||
context.i = 0
|
context.i = 0
|
||||||
context.asset = symbol('btc_usd')
|
context.asset = symbol('btc_usd')
|
||||||
|
|
||||||
def handle_data(context, data):
|
def handle_data(context, data):
|
||||||
# Skip first 300 days to get full windows
|
# Skip first 300 days to get full windows
|
||||||
context.i += 1
|
context.i += 1
|
||||||
if context.i < 300:
|
if context.i < 300:
|
||||||
@@ -336,6 +516,46 @@ a function we use in the ``handle_data()`` section:
|
|||||||
short_mavg=short_mavg,
|
short_mavg=short_mavg,
|
||||||
long_mavg=long_mavg)
|
long_mavg=long_mavg)
|
||||||
|
|
||||||
|
def analyze(context, perf):
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
fig = plt.figure()
|
||||||
|
ax1 = fig.add_subplot(211)
|
||||||
|
perf.portfolio_value.plot(ax=ax1)
|
||||||
|
ax1.set_ylabel('portfolio value in $')
|
||||||
|
|
||||||
|
ax2 = fig.add_subplot(212)
|
||||||
|
perf['btc'].plot(ax=ax2)
|
||||||
|
perf[['short_mavg', 'long_mavg']].plot(ax=ax2)
|
||||||
|
|
||||||
|
perf_trans = perf.ix[[t != [] for t in perf.transactions]]
|
||||||
|
buys = perf_trans.ix[[t[0]['amount'] > 0 for t in perf_trans.transactions]]
|
||||||
|
sells = perf_trans.ix[
|
||||||
|
[t[0]['amount'] < 0 for t in perf_trans.transactions]]
|
||||||
|
ax2.plot(buys.index, perf.short_mavg.ix[buys.index],
|
||||||
|
'^', markersize=10, color='m')
|
||||||
|
ax2.plot(sells.index, perf.short_mavg.ix[sells.index],
|
||||||
|
'v', markersize=10, color='k')
|
||||||
|
ax2.set_ylabel('price in $')
|
||||||
|
plt.legend(loc=0)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
Here we are explicitly defining an ``analyze()`` function that gets
|
||||||
|
automatically called once the backtest is done.
|
||||||
|
|
||||||
|
Although it might not be directly apparent, the power of ``history()``
|
||||||
|
(pun intended) can not be under-estimated as most algorithms make use of
|
||||||
|
prior market developments in one form or another. You could easily
|
||||||
|
devise a strategy that trains a classifier with
|
||||||
|
`scikit-learn <http://scikit-learn.org/stable/>`__ which tries to
|
||||||
|
predict future market movements based on past prices (note, that most of
|
||||||
|
the ``scikit-learn`` functions require ``numpy.ndarray``\ s rather than
|
||||||
|
``pandas.DataFrame``\ s, so you can simply pass the underlying
|
||||||
|
``ndarray`` of a ``DataFrame`` via ``.values``).
|
||||||
|
|
||||||
|
We also used the ``order_target()`` function above. This and other
|
||||||
|
functions like it can make order management and portfolio rebalancing
|
||||||
|
much easier.
|
||||||
|
|
||||||
|
|
||||||
Conclusions
|
Conclusions
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Incompatible with earlier PIP versions
|
# Incompatible with earlier PIP versions
|
||||||
pip>=7.1.0
|
pip>=7.1.0
|
||||||
# bcolz fails to install if this is not in the build_requires.
|
# bcolz fails to install if this is not in the build_requires.
|
||||||
setuptools>18.0
|
setuptools>36.0
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
Logbook==0.12.5
|
Logbook==0.12.5
|
||||||
|
|||||||
Reference in New Issue
Block a user