Skip to content

Commit

Permalink
Merge pull request #107 from nautechsystems/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
cjdsellers committed Nov 2, 2020
2 parents a3de5d7 + 1e28083 commit be02c55
Show file tree
Hide file tree
Showing 27 changed files with 288 additions and 514 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test-tag-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:

steps:
- uses: actions/checkout@v2
with:
fetch-depth: 2

# Python setup
- name: Set up Python environment
Expand Down
8 changes: 5 additions & 3 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: nautilus_trader
type: sphinx
base: docs/source
version: 2

sphinx:
configuration: docs/source/conf.py

python:
version: 3.8
install:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[![codacy-quality](https://api.codacy.com/project/badge/Grade/a1d3ccf7bccb4483b091975681a5cb23)](https://app.codacy.com/gh/nautechsystems/nautilus_trader?utm_source=github.com&utm_medium=referral&utm_content=nautechsystems/nautilus_trader&utm_campaign=Badge_Grade_Dashboard)
![build](https://github.com/nautechsystems/nautilus_trader/workflows/build/badge.svg)
[![Documentation Status](https://readthedocs.org/projects/nautilus-trader/badge/?version=latest)](https://nautilus-trader.readthedocs.io/en/latest/?badge=latest)
[![codecov](https://codecov.io/gh/nautechsystems/nautilus_trader/branch/master/graph/badge.svg?token=DXO9QQI40H)](https://codecov.io/gh/nautechsystems/nautilus_trader)
![pypi-pythons](https://img.shields.io/pypi/pyversions/nautilus_trader)
![pypi-version](https://img.shields.io/pypi/v/nautilus_trader)
[![Downloads](https://pepy.tech/badge/nautilus-trader)](https://pepy.tech/project/nautilus-trader)
Expand Down Expand Up @@ -39,7 +40,7 @@ is written mostly in Python with optional additional C-inspired syntax.
## Documentation

The documentation for the latest version of the package is available on _readthedocs_.
The documentation for the latest version of the package is available at _readthedocs_.

> https://nautilus-trader.readthedocs.io
Expand Down
8 changes: 4 additions & 4 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@


def _build_extensions() -> List[Extension]:
"""Build Extensions to feed into cythonize()."""
# Build Extensions to feed into cythonize()
# Profiling requires special macro directives
if PROFILING_MODE or ANNOTATION_MODE:
define_macros = [("CYTHON_TRACE", "1")]
Expand All @@ -77,7 +77,7 @@ def _build_extensions() -> List[Extension]:


def _build_distribution(extensions: List[Extension]) -> Distribution:
"""Build a Distribution using cythonize()."""
# Build a Distribution using cythonize()
# Determine the build output directory
if PROFILING_MODE:
# For subsequent annotation, the c source needs to be in
Expand Down Expand Up @@ -105,7 +105,7 @@ def _build_distribution(extensions: List[Extension]) -> Distribution:


def _copy_build_dir_to_project(cmd: build_ext) -> None:
"""Copy built extensions back to the project tree."""
# Copy built extensions back to the project tree
for output in cmd.get_outputs():
relative_extension = os.path.relpath(output, cmd.build_lib)
if not os.path.exists(output):
Expand All @@ -120,7 +120,7 @@ def _copy_build_dir_to_project(cmd: build_ext) -> None:


def build(setup_kwargs):
# Construct the extensions and distribution
"""Construct the extensions and distribution.""" # noqa
extensions = _build_extensions()
distribution = _build_distribution(extensions)

Expand Down
6 changes: 0 additions & 6 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,8 @@
#

import os
import sys

import sphinx_rtd_theme


sys.path.insert(0, os.path.abspath("../.."))


# -- Project information -----------------------------------------------------

project = "NautilusTrader"
Expand Down
6 changes: 3 additions & 3 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ to be universal, with any REST/FIX/WebSockets API able to be integrated via modu
Thus the platform can handle high-frequency trading operations for any asset classes
including FX, Equities, Futures, CFDs or Crypto - across multiple venues simultaneously.

Value Proposition
-----------------
Why NautilusTrader?
-------------------
One of the key value propositions of `NautilusTrader` is that it addresses the
challenge of keeping the backtest environment consistent with the production
live trading environment. Normally research and backtesting may be conducted in
Expand All @@ -29,7 +29,7 @@ platform was designed from the ground up to hold its own in terms of performance
and quality. Python has simply caught up in performance
(via Cython offering C level speed) and general tooling, making it a suitable language for implementing
a large system such as this. The benefit here being that a Python native environment
can be offered suitable for professional quantitative traders and hedge funds.
can be offered, suitable for professional quantitative traders and hedge funds.

Why Python?
-----------
Expand Down
2 changes: 1 addition & 1 deletion examples/strategies/ema_cross_cython.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ cdef class EMACross(TradingStrategy):
self.log.info(f"Received {bar_type} Bar({bar})")

# Check if indicators ready
if not self.indicators_initialized:
if not self.indicators_initialized():
self.log.info(f"Waiting for indicators to warm up "
f"[{self.data.bar_count(self.bar_type)}]...")
return # Wait for indicators to warm up...
Expand Down
2 changes: 1 addition & 1 deletion examples/strategies/ema_cross_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def on_bar(self, bar_type: BarType, bar: Bar):
self.log.info(f"Received {bar_type} Bar({bar})")

# Check if indicators ready
if not self.indicators_initialized:
if not self.indicators_initialized():
self.log.info(f"Waiting for indicators to warm up "
f"[{self.data.bar_count(self.bar_type)}]...")
return # Wait for indicators to warm up...
Expand Down
6 changes: 2 additions & 4 deletions nautilus_trader/backtest/engine.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ from nautilus_trader.trading.portfolio cimport Portfolio
from nautilus_trader.trading.strategy cimport TradingStrategy


# noinspection: Object has warned attribute
# noinspection PyUnresolvedReferences
cdef class BacktestEngine:
"""
Provides a backtest engine to run a portfolio of strategies inside a Trader
Expand Down Expand Up @@ -329,7 +327,7 @@ cdef class BacktestEngine:
# Run the backtest
self.log.info(f"Running backtest...")

for strategy in self.trader.strategies:
for strategy in self.trader.strategies():
strategy.clock.set_time(start)

self.trader.start()
Expand All @@ -355,7 +353,7 @@ cdef class BacktestEngine:
cdef TradingStrategy strategy
cdef TimeEventHandler event_handler
cdef list time_events = [] # type: [TimeEventHandler]
for strategy in self.trader.strategies:
for strategy in self.trader.strategies():
# noinspection: Object has warned attribute
# noinspection PyUnresolvedReferences
time_events += sorted(strategy.clock.advance_time(timestamp))
Expand Down
12 changes: 12 additions & 0 deletions nautilus_trader/common/factories.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ cdef class OrderFactory:
initial_count=initial_count,
)

@property
def count(self):
"""
The count of identifiers generated.
Returns
-------
int
"""
return self._id_generator.count

cpdef void set_count(self, int count) except *:
"""
System Method: Set the internal order identifier generator count to the
Expand Down
4 changes: 3 additions & 1 deletion nautilus_trader/common/generators.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ cdef class IdentifierGenerator:
cdef str _prefix
cdef IdTag _id_tag_trader
cdef IdTag _id_tag_strategy
cdef int _count

cdef readonly int count
"""The count of identifiers generated.\n\n:returns: `int`"""

cpdef void set_count(self, int count) except *
cpdef void reset(self) except *
Expand Down
15 changes: 6 additions & 9 deletions nautilus_trader/common/generators.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.
# -------------------------------------------------------------------------------------------------

from datetime import datetime
from cpython.datetime cimport datetime

from nautilus_trader.common.clock cimport Clock
Expand Down Expand Up @@ -67,7 +68,7 @@ cdef class IdentifierGenerator:
self._prefix = prefix
self._id_tag_trader = id_tag_trader
self._id_tag_strategy = id_tag_strategy
self._count = initial_count
self.count = initial_count

cpdef void set_count(self, int count) except *:
"""
Expand All @@ -79,15 +80,15 @@ cdef class IdentifierGenerator:
The count to set.
"""
self._count = count
self.count = count

cpdef void reset(self) except *:
"""
Reset the identifier generator.
All stateful values are reset to their initial value.
"""
self._count = 0
self.count = 0

cdef str _generate(self):
"""
Expand All @@ -98,13 +99,13 @@ cdef class IdentifierGenerator:
str
"""
self._count += 1
self.count += 1

return (f"{self._prefix}-"
f"{self._get_datetime_tag()}-"
f"{self._id_tag_trader.value}-"
f"{self._id_tag_strategy.value}-"
f"{self._count}")
f"{self.count}")

cdef str _get_datetime_tag(self):
"""
Expand All @@ -116,8 +117,6 @@ cdef class IdentifierGenerator:
"""
cdef datetime utc_now = self._clock.utc_now()
# noinspection: CPython datetime attributes
# noinspection PyUnresolvedReferences
return (f"{utc_now.year}"
f"{utc_now.month:02d}"
f"{utc_now.day:02d}"
Expand Down Expand Up @@ -177,8 +176,6 @@ cdef class OrderIdGenerator(IdentifierGenerator):
return ClientOrderId(self._generate())


# noinspection: Object has warned attribute
# noinspection PyUnresolvedReferences
cdef class PositionIdGenerator:
"""
Provides a generator for unique PositionId(s).
Expand Down
3 changes: 1 addition & 2 deletions nautilus_trader/data/aggregation.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,8 @@ cdef class TimeBarAggregator(BarAggregator):
return

bar = self._builder.build(event.timestamp)
self._handle_bar(bar)
except ValueError as ex:
# Bar was somehow malformed
self._log.exception(ex)
return

self._handle_bar(bar)
17 changes: 8 additions & 9 deletions nautilus_trader/data/engine.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
The `DataEngine` is the central component of the entire data stack for the platform.
Its primary responsibility is to orchestrate interactions between the individual
`DataClient` instances, and the rest of the platform. This is could include
ongoing subscriptions to specific data types, for particular endpoints. As well as
hydrating a `DataCache` layer which presents a read-only facade for its clients
to consume cached data through.
`DataClient` instances, and the rest of the platform. This includes consumers
subscribing to specific data types, as well as hydrating a `DataCache` layer
which presents a read-only facade for consumers.
Alternative implementations can be written on top which just need to override
the engines `execute` and `process` methods.
Expand Down Expand Up @@ -140,7 +139,7 @@ cdef class DataEngine:
list[Venue]
"""
return list(self._clients.keys())
return sorted(list(self._clients.keys()))

@property
def subscribed_quote_ticks(self):
Expand All @@ -152,7 +151,7 @@ cdef class DataEngine:
list[Symbol]
"""
return list(self._quote_tick_handlers.keys())
return sorted(list(self._quote_tick_handlers.keys()))

@property
def subscribed_trade_ticks(self):
Expand All @@ -164,7 +163,7 @@ cdef class DataEngine:
list[Symbol]
"""
return list(self._trade_tick_handlers.keys())
return sorted(list(self._trade_tick_handlers.keys()))

@property
def subscribed_bars(self):
Expand All @@ -176,7 +175,7 @@ cdef class DataEngine:
list[BarType]
"""
return list(self._bar_handlers.keys())
return sorted(list(self._bar_handlers.keys()))

@property
def subscribed_instruments(self):
Expand All @@ -188,7 +187,7 @@ cdef class DataEngine:
list[Symbol]
"""
return list(self._instrument_handlers.keys())
return sorted(list(self._instrument_handlers.keys()))

# --REGISTRATION -----------------------------------------------------------------------------------

Expand Down
6 changes: 3 additions & 3 deletions nautilus_trader/execution/engine.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ cdef class ExecutionEngine:
set[StrategyId]
"""
return list(self._clients.keys())
return sorted(list(self._clients.keys()))

@property
def registered_strategies(self):
Expand All @@ -157,7 +157,7 @@ cdef class ExecutionEngine:
list[StrategyId]
"""
return list(self._strategies.keys())
return sorted(list(self._strategies.keys()))

# -- REGISTRATION ----------------------------------------------------------------------------------

Expand Down Expand Up @@ -776,7 +776,7 @@ cdef class ExecutionEngine:
cdef list positions = self.cache.positions()

# Count positions per symbol
cdef dict counts = {} # type: {Symbol: int}
cdef dict counts = {} # type: dict[Symbol, int]
cdef Position position
for position in positions:
if position.symbol not in counts:
Expand Down
4 changes: 2 additions & 2 deletions nautilus_trader/model/identifiers.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ cdef class StrategyId(Identifier):
@staticmethod
cdef StrategyId null_c()
cdef inline bint is_null(self) except *
cdef inline bint not_null(self) except *
cdef inline bint not_null(self) except *

@staticmethod
cdef StrategyId from_string_c(str value)
Expand Down Expand Up @@ -111,7 +111,7 @@ cdef class PositionId(Identifier):
@staticmethod
cdef PositionId null_c()
cdef inline bint is_null(self) except *
cdef inline bint not_null(self) except *
cdef inline bint not_null(self) except *


cdef class ExecutionId(Identifier):
Expand Down
12 changes: 8 additions & 4 deletions nautilus_trader/trading/filters.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ cdef class ForexSessionFilter:


cdef class NewsEvent:
cdef datetime _timestamp
cdef object _impact
cdef str _name
cdef str _currency
cdef readonly datetime timestamp
"""The news events timestamp.\n\n:returns: `datetime`"""
cdef readonly object impact
"""The expected news impact.\n\n:returns: `object`"""
cdef readonly str name
"""The descriptive name of the news event.\n\n:returns: `str`"""
cdef readonly str currency
"""The currency affected by the news event.\n\n:returns: `str`"""


cdef class EconomicNewsEventFilter:
Expand Down
Loading

0 comments on commit be02c55

Please sign in to comment.