Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/robcarver17/pysystemtrade
Browse files Browse the repository at this point in the history
…into develop
  • Loading branch information
rob committed Jul 27, 2023
2 parents 3a36f06 + fd2df47 commit a8c7725
Show file tree
Hide file tree
Showing 25 changed files with 63 additions and 139 deletions.
19 changes: 8 additions & 11 deletions docs/backtesting.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ multipliers:
```python
from systems.provided.futures_chapter15.estimatedsystem import futures_system
system=futures_system()
system.set_logging_level("on")
system.portfolio.get_notional_position("EDOLLAR")
```

Expand Down Expand Up @@ -813,15 +812,15 @@ read about [system caching and pickling](#caching) before you reload them).
```python
from systems.provided.futures_chapter15.basesystem import futures_system

system = futures_system(log_level="on")
system = futures_system()
system.accounts.portfolio().sharpe() ## does a whole bunch of calculations that will be saved in the cache

system.cache.pickle("private.this_system_name.system.pck") ## use any file extension you like

## In a new session
from systems.provided.futures_chapter15.basesystem import futures_system

system = futures_system(log_level="on")
system = futures_system()
system.cache.unpickle("private.this_system_name.system.pck")

## this will run much faster and reuse previous calculations
Expand Down Expand Up @@ -1030,7 +1029,7 @@ from sysdata.sim.db_futures_sim_data import dbFuturesSimData
data = dbFuturesSimData()

# using with a system
system = futures_system(log_level="on")
system = futures_system()
print(system.accounts.portfolio().sharpe())
```

Expand Down Expand Up @@ -1644,8 +1643,8 @@ get_list_of_instruments_to_remove
get_list_of_markets_with_trading_restrictions'
```

`system.log` and `system.set_logging_level()` provides access to the system's
log. See [logging](#logging) for more details.
`system.log` provides access to the system's log. See [logging](#logging) for more
details.

<a name="caching"> </a>

Expand Down Expand Up @@ -1737,7 +1736,7 @@ weights, will be excluded and won't be reloaded.
```python
from systems.provided.futures_chapter15.basesystem import futures_system

system = futures_system(log_level="on")
system = futures_system()
system.accounts.portfolio().sharpe() ## does a whole bunch of calculations that will be saved in the cache. A bit slow...

system.cache.get_itemnames_for_stage("accounts") # includes 'portfolio'
Expand All @@ -1750,7 +1749,7 @@ system.cache.pickle("private.this_system_name.system.pck") ## Using the 'dot' me


## Now in a new session
system = futures_system(log_level="on")
system = futures_system()
system.cache.get_items_with_data() ## check empty cache

system.cache.unpickle("private.this_system_name.system.pck")
Expand Down Expand Up @@ -2077,7 +2076,7 @@ from systems.portfolio import Portfolios
from systems.accounts.accounts_stage import Account


def futures_system(data=None, config=None, trading_rules=None, log_level="on"):
def futures_system(data=None, config=None, trading_rules=None):
if data is None:
data = csvFuturesSimData()

Expand All @@ -2091,8 +2090,6 @@ def futures_system(data=None, config=None, trading_rules=None, log_level="on"):
system = System([Account(), Portfolios(), PositionSizing(), RawData(), ForecastCombine(),
ForecastScaleCap(), rules], data, config)

system.set_logging_level(log_level)

return system
```

Expand Down
4 changes: 2 additions & 2 deletions docs/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ Of course it's also possible to mix these two methods. Once you have the data it
```python
from systems.provided.futures_chapter15.basesystem import futures_system
from sysdata.sim.db_futures_sim_data import dbFuturesSimData
system = futures_system(data = dbFuturesSimData(), log_level="on")
system = futures_system(data = dbFuturesSimData())
print(system.data.get_instrument_list())
```
#### A note about multiple configuration files
Expand Down Expand Up @@ -1084,7 +1084,7 @@ class dbFuturesSimData2(genericBlobUsingFuturesSimData):
self.get_instrument_list())


>>> system = futures_system(data = dbFuturesSimData2(), log_level="on")
>>> system = futures_system(data = dbFuturesSimData2())
>>> system.data.data.db_futures_multiple_prices

simData connection for multiple futures prices, arctic production/futures_multiple_prices @ 127.0.0.1
Expand Down
9 changes: 2 additions & 7 deletions docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,6 @@ my_config.use_forecast_div_mult_estimates = True
combiner = ForecastCombine()
my_system = System([my_account, fcs, my_rules, combiner, position_size, raw_data], data, my_config)

## this is a bit slow, better to know what's going on
my_system.set_logging_level("on")

print(my_system.combForecast.get_forecast_weights("US10").tail(5))
print(my_system.combForecast.get_forecast_diversification_multiplier("US10").tail(5))

Expand Down Expand Up @@ -558,8 +555,6 @@ my_config.instrument_weight_estimate=dict(method="shrinkage", date_method="in_sa
my_system = System([my_account, fcs, my_rules, combiner, position_size, raw_data,
portfolio], data, my_config)

my_system.set_logging_level("on")

print(my_system.portfolio.get_instrument_weights())
print(my_system.portfolio.get_instrument_diversification_multiplier())
```
Expand Down Expand Up @@ -733,7 +728,7 @@ You can also get a similar system where forecast scalars are estimated; as well

```python
from systems.provided.futures_chapter15.estimatedsystem import futures_system
system = futures_system(log_level="on")
system = futures_system()
system.portfolio.get_notional_position("EUROSTX").tail(5)
```

Expand All @@ -744,7 +739,7 @@ system.cache.pickle("private.this_system_name.pck") ## use any file extension yo

## In a new session
from systems.provided.futures_chapter15.estimatedsystem import futures_system
system = futures_system(log_level="on")
system = futures_system()
system.cache.unpickle("private.this_system_name.pck")
system.accounts.portfolio().sharpe() ## this will run much faster and reuse previous calculations
```
Expand Down
8 changes: 4 additions & 4 deletions examples/introduction/prebakedsystems.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from systems.provided.example.simplesystem import simplesystem

my_system = simplesystem(log_level="on")
my_system = simplesystem()
print(my_system)
print(my_system.portfolio.get_notional_position("EDOLLAR").tail(5))

Expand All @@ -22,7 +22,7 @@
from systems.provided.futures_chapter15.basesystem import futures_system
from matplotlib.pyplot import show

system = futures_system(log_level="on")
system = futures_system()
print(system.accounts.portfolio().sharpe())
system.accounts.portfolio().curve().plot()
show()
Expand All @@ -32,14 +32,14 @@

from systems.provided.futures_chapter15.estimatedsystem import futures_system

system = futures_system(log_level="on")
system = futures_system()
print(system.accounts.portfolio().sharpe())
system.accounts.portfolio().curve().plot()
system.cache.pickle("private.this_system_name.pck")
show()

del system # just to make sure
system = futures_system(log_level="on")
system = futures_system()
system.cache.unpickle("private.this_system_name.pck")
# this will run much faster and reuse previous calculations
system.accounts.portfolio().sharpe()
5 changes: 0 additions & 5 deletions examples/introduction/simplesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@
[my_account, fcs, my_rules, combiner, raw_data, position_size], data, my_config
)

# this is a bit slow, better to know what's going on
my_system.set_logging_level("on")

print(my_system.combForecast.get_forecast_weights("US10").tail(5))
print(my_system.combForecast.get_forecast_diversification_multiplier("US10").tail(5))

Expand Down Expand Up @@ -169,8 +166,6 @@
my_config,
)

my_system.set_logging_level("on")

print(my_system.portfolio.get_instrument_weights().tail(5))
print(my_system.portfolio.get_instrument_diversification_multiplier().tail(5))

Expand Down
5 changes: 0 additions & 5 deletions examples/production/example_of_custom_run_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ def production_carry_trend_dynamic_system(
base_currency: str = arg_not_supplied,
) -> System:

log_level = "on"

sim_data = get_sim_data_object_for_production(data)
config = Config(config_filename)

Expand All @@ -56,8 +54,6 @@ def production_carry_trend_dynamic_system(
system = futures_system(data=sim_data, config=config)
system._log = log

system.set_logging_level(log_level)

return system


Expand Down Expand Up @@ -96,6 +92,5 @@ def futures_system(data, config):
data,
config,
)
system.set_logging_level("on")

return system
9 changes: 9 additions & 0 deletions sysbrokers/IB/client/ib_orders_client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from ib_insync import TagValue
from ib_insync.order import (
MarketOrder as ibMarketOrder,
LimitOrder as ibLimitOrder,
Expand Down Expand Up @@ -25,6 +26,7 @@
snap_mkt_type,
snap_mid_type,
snap_prim_type,
adaptive_mkt_type,
)

from sysobjects.contracts import futuresContract
Expand Down Expand Up @@ -170,6 +172,13 @@ def _build_ib_order(
totalQuantity=ib_qty,
auxPrice=0.0,
)
elif order_type is adaptive_mkt_type:
# Uses a black-box algo w/ stated aim of balancing execution speed & price
# See https://investors.interactivebrokers.com/en/index.php?f=19091
ib_order = ibMarketOrder(ib_BS_str, ib_qty)
ib_order.algoStrategy = "Adaptive"
# Patient is usually pretty fast. Alternatives are Normal and Urgent
ib_order.algoParams = [TagValue("adaptivePriority", "Patient")]
else:
self.log.critical("Order type %s not recognised!" % order_type)
return missing_order
Expand Down
2 changes: 0 additions & 2 deletions sysdata/data_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ def close(self):
self.db_ib_broker_client_id.release_clientid(self.ib_conn.client_id())

# No need to explicitly close Mongo connections; handled by Python garbage collection
self.log.close_log_file()

@property
def ib_conn(self) -> connectionIB:
Expand Down Expand Up @@ -331,7 +330,6 @@ def log(self):
log = getattr(self, "_log", arg_not_supplied)
if log is arg_not_supplied:
log = get_logger(self.log_name)
log.set_logging_level("on")
self._log = log

return log
Expand Down
13 changes: 13 additions & 0 deletions sysexecution/algos/algo_adaptive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from sysexecution.algos.algo_market import algoMarket
from sysexecution.orders.broker_orders import brokerOrderType, adaptive_mkt_type


class algoAdaptiveMkt(algoMarket):

# Adaptive market orders should eventually execute, but might take a while
# This allows re-using the market order trade management logic, but without timing out
ORDER_TIME_OUT = float("inf")

@property
def order_type_to_use(self) -> brokerOrderType:
return adaptive_mkt_type
11 changes: 6 additions & 5 deletions sysexecution/algos/algo_market.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
from sysexecution.order_stacks.broker_order_stack import orderWithControls
from sysexecution.orders.broker_orders import market_order_type, brokerOrderType

SIZE_LIMIT = 1
ORDER_TIME_OUT = 600


class algoMarket(Algo):
"""
Expand All @@ -25,6 +22,9 @@ class algoMarket(Algo):
"""

SIZE_LIMIT = 1
ORDER_TIME_OUT = 600

def submit_trade(self) -> orderWithControls:
broker_order_with_controls = self.prepare_and_submit_trade()
if broker_order_with_controls is missing_order:
Expand Down Expand Up @@ -52,7 +52,7 @@ def prepare_and_submit_trade(self):
cut_down_contract_order = copy(contract_order)
else:
cut_down_contract_order = contract_order.reduce_trade_size_proportionally_so_smallest_leg_is_max_size(
SIZE_LIMIT
self.SIZE_LIMIT
)

if cut_down_contract_order.trade != contract_order.trade:
Expand Down Expand Up @@ -94,7 +94,8 @@ def manage_live_trade(

is_order_completed = broker_order_with_controls.completed()
is_order_timeout = (
broker_order_with_controls.seconds_since_submission() > ORDER_TIME_OUT
broker_order_with_controls.seconds_since_submission()
> self.ORDER_TIME_OUT
)
is_order_cancelled = (
data_broker.check_order_is_cancelled_given_control_object(
Expand Down
11 changes: 10 additions & 1 deletion sysexecution/orders/broker_orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,15 @@

class brokerOrderType(orderType):
def allowed_types(self):
return ["market", "limit", "balance_trade", "snap_mkt", "snap_mid", "snap_prim"]
return [
"market",
"limit",
"balance_trade",
"snap_mkt",
"snap_mid",
"snap_prim",
"adaptive_mkt",
]


market_order_type = brokerOrderType("market")
Expand All @@ -45,6 +53,7 @@ def allowed_types(self):
snap_mkt_type = brokerOrderType("snap_mkt")
snap_mid_type = brokerOrderType("snap_mid")
snap_prim_type = brokerOrderType("snap_prim")
adaptive_mkt_type = brokerOrderType("adaptive_mkt")


class brokerOrder(Order):
Expand Down
24 changes: 0 additions & 24 deletions syslogging/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ class DynamicAttributeLogger(logging.LoggerAdapter):
# TODO data_blob.update_log
# TODO data.update_log(contract_object.specific_log(data.log))
# TODO data_blob._get_specific_logger
# TODO self.log.close_log_file()
# TODO log_with_attributes
# TODO log_level = "on"
# TODO system.set_logging_level(log_level)
"""

Expand Down Expand Up @@ -102,27 +99,6 @@ def setup_empty_except_keep_type(self):
attributes = {}
return DynamicAttributeLogger(logging.getLogger(self.name), attributes)

def set_logging_level(self, new_log_level):
warnings.warn(
"The 'set_logging_level' function is deprecated;"
"use setLoggingLevel() instead. Or, better still, set log level in config",
DeprecationWarning,
2,
)
if new_log_level == "on":
self.logger.setLevel(logging.DEBUG)
elif new_log_level == "off":
self.logger.setLevel(logging.NOTSET)
else:
self.logger.setLevel(new_log_level)

def close_log_file(self):
warnings.warn(
"The 'close_log_file' function is deprecated, and does nothing anyway",
DeprecationWarning,
2,
)

def _check_attributes(self, attributes: dict):
if attributes:
bad_attributes = get_list_of_disallowed_attributes(attributes)
Expand Down
6 changes: 0 additions & 6 deletions syslogging/tests/logging_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,6 @@ def test_label_bad(self):
with pytest.raises(Exception):
logger.label(stage="left", foo="bar")

def test_set_logging_level(self):
logger = get_logger("Set_Level")
assert logger.getEffectiveLevel() == logging.DEBUG
logger.set_logging_level(logging.INFO)
assert logger.getEffectiveLevel() == 20

def test_setup_empty_with(self):
setup_with = get_logger("Setup_With", {"type": "foo", "stage": "one"})
assert setup_with.extra["type"] == "foo"
Expand Down
Loading

0 comments on commit a8c7725

Please sign in to comment.