Skip to content

Commit

Permalink
Merge pull request #1436 from bug-or-feature/issue-1435-minor-issues-11
Browse files Browse the repository at this point in the history
Minor issues 11
  • Loading branch information
bug-or-feature authored Oct 29, 2024
2 parents 4d89b98 + c807c7c commit 4983254
Show file tree
Hide file tree
Showing 34 changed files with 59 additions and 78 deletions.
1 change: 0 additions & 1 deletion data/futures/roll_calendars_csv/.~lock.EU-AUTO.csv#

This file was deleted.

1 change: 0 additions & 1 deletion data/futures/roll_calendars_csv/.~lock.EU-BASIC.csv#

This file was deleted.

5 changes: 2 additions & 3 deletions docs/backtesting.md
Original file line number Diff line number Diff line change
Expand Up @@ -3997,13 +3997,12 @@ of forecasts.

### Working out net costs (both instrument and forecast weights)

Again I recommend you check out this [blog
post](https://qoppac.blogspot.com/2016/05/optimising-weights-with-costs.html).
Again I recommend you check out this [blog post](https://qoppac.blogspot.com/2016/05/optimising-weights-with-costs.html).

```
forecast_weight_estimate: ## can also be applied to instrument weights
equalise_gross: False ## equalise gross returns so that only costs are used for optimisation
cost_multiplier: 0.0 ## multiply costs by this number. Zero means grosss returns used. Higher than 1 means costs will be inflated. Use zero if apply_cost_weight=True (see later)
cost_multiplier: 0.0 ## multiply costs by this number. Zero means gross returns used. Higher than 1 means costs will be inflated. Use zero if apply_cost_weight=True (see later)
```


Expand Down
2 changes: 1 addition & 1 deletion docs/dashboard_and_monitor.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ This document describes how to monitor pysystemtrade in a production environment

It will make no sense unless you've already read:

- [Using pysystemtrade in production(/docs/production.md)
- [Using pysystemtrade in production](/docs/production.md)

Table of Contents
=================
Expand Down
4 changes: 2 additions & 2 deletions docs/instruments.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ It will make no sense unless you've already read:

- [Backtesting with pysystemtrade](/docs/backtesting.md)
- [Storing futures and spot FX data](/docs/data.md)
- [Using pysystemtrade in production(/docs/production.md)
- [Using pysystemtrade in production](/docs/production.md)

Table of Contents
=================
Expand Down Expand Up @@ -350,7 +350,7 @@ Operating in the production environment is a bit more complex, due to the intera

When you're running in simulation things are relatively simple; configuration items are defined in defaults_yaml, but can be overridden by your private_config.yaml, and then also by your own backtest.yaml file.

Importantly, once we're out of the 'backtesting'' part of a production system, we can't see the backtest configuration (which after all is system specific, whereas generally in the production environment we're working with global parameters). So the priority order is `defaults.yaml`, overridden by `private_config.yaml`. The downstream code that produces strategy orders once the production backtest has generated optimal positions, and then trades those orders, will operate only on the configuration in `private_config.yaml` and `defaults.yaml`.
Importantly, once we're out of the 'backtesting' part of a production system, we can't see the backtest configuration (which after all is system specific, whereas generally in the production environment we're working with global parameters). So the priority order is `defaults.yaml`, overridden by `private_config.yaml`. The downstream code that produces strategy orders once the production backtest has generated optimal positions, and then trades those orders, will operate only on the configuration in `private_config.yaml` and `defaults.yaml`.

## Reduce only and other constraints in static systems

Expand Down
4 changes: 2 additions & 2 deletions docs/production.md
Original file line number Diff line number Diff line change
Expand Up @@ -1964,7 +1964,7 @@ We can set the maximum allowable position that can be held in a given instrument

Autopopulate uses current levels of risk to estimate the appropriate position limit. So it will make position limits smaller when risk is higher, and vice versa. It makes a lot of assumptions when setting limits: that all your strategies have the same risk limit (which you can set), and the same IDM (also can be modified), and that all instruments have the same instrument weight (which you can set). It does not use actual instrument weights, and it only sets limits that are global for a particular instrument.

The dynamic optimisation strategy will also use position limits in it's optimisation in production (not in backtests, since fixed position limits make no sense for a historical backtest).
The dynamic optimisation strategy will also use position limits in its optimisation in production (not in backtests, since fixed position limits make no sense for a historical backtest).

#### Trade control / override

Expand Down Expand Up @@ -2845,7 +2845,7 @@ The following are .csv configurations used in both production and sim:
### Set up configuration


The following are used when initialising the database with it's initial configuration, but will also be used in the simulation environment:
The following are used when initialising the database with its initial configuration, but will also be used in the simulation environment:

- [/data/futures/csvconfig/spreadcosts.csv](/data/futures/csvconfig/spreadcosts.csv)

Expand Down
6 changes: 1 addition & 5 deletions sysbrokers/IB/ib_orders.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
from ib_insync import Trade as ibTrade

from copy import copy

import datetime

from sysbrokers.IB.ib_futures_contracts_data import ibFuturesContractData
from sysbrokers.IB.ib_instruments_data import ibFuturesInstrumentData
from sysbrokers.IB.ib_translate_broker_order_objects import (
Expand Down Expand Up @@ -456,7 +452,7 @@ def modify_limit_price_given_control_object(
"""
NOTE this does not update the internal state of orders, which will retain the original order
:param broker_orders_with_controls:
:param broker_order_with_controls:
:param new_limit_price:
:return:
"""
Expand Down
14 changes: 7 additions & 7 deletions syscore/fileutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from syscore.dateutils import SECONDS_PER_DAY

# DO NOTE DELETE: all these are unused: but are required to get the filename padding to work
# DO NOT DELETE: all these are unused: but are required to get the filename padding to work


"""
Expand Down Expand Up @@ -103,7 +103,7 @@ def get_file_or_folder_age_in_days(full_filename_with_ext: str) -> float:


def resolve_path_and_filename_for_package(
path_and_filename: str, seperate_filename=None
path_and_filename: str, separate_filename=None
) -> str:
"""
A way of resolving relative and absolute filenames, and dealing with awkward OS specific things
Expand Down Expand Up @@ -135,10 +135,10 @@ def resolve_path_and_filename_for_package(
"""

path_and_filename_as_list = transform_path_into_list(path_and_filename)
if seperate_filename is None:
if separate_filename is None:
(
path_as_list,
seperate_filename,
separate_filename,
) = extract_filename_from_combined_path_and_filename_list(
path_and_filename_as_list
)
Expand All @@ -147,7 +147,7 @@ def resolve_path_and_filename_for_package(

resolved_pathname = get_pathname_from_list(path_as_list)

resolved_path_and_filename = os.path.join(resolved_pathname, seperate_filename)
resolved_path_and_filename = os.path.join(resolved_pathname, separate_filename)

return resolved_path_and_filename

Expand Down Expand Up @@ -240,9 +240,9 @@ def extract_filename_from_combined_path_and_filename_list(
extension = path_and_filename_as_list.pop()
filename = path_and_filename_as_list.pop()

seperate_filename = ".".join([filename, extension])
separate_filename = ".".join([filename, extension])

return path_and_filename_as_list, seperate_filename
return path_and_filename_as_list, separate_filename


def get_pathname_from_list(path_as_list: List[str]) -> str:
Expand Down
2 changes: 1 addition & 1 deletion sysdata/csv/csv_futures_contract_prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def _get_merged_prices_for_contract_object_no_checking(
"""
Read back the prices for a given contract object
:param contract_object: futuresContract
:param futures_contract_object: futuresContract
:return: data
"""

Expand Down
2 changes: 1 addition & 1 deletion sysdata/futures/spread_costs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## Expected slippage eg half bid-ask spread
## Used to be in instrument config, now seperate
## Used to be in instrument config, now separate
import pandas as pd
from sysdata.base_data import baseData
from syslogging.logger import *
Expand Down
2 changes: 1 addition & 1 deletion sysdata/parquet/parquet_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def _get_filename_given_data_type_and_identifier(
):
path = self._get_pathname_given_data_type(data_type)
return resolve_path_and_filename_for_package(
path, seperate_filename="%s.%s" % (identifier, EXTENSION)
path, separate_filename="%s.%s" % (identifier, EXTENSION)
)

def _get_pathname_given_data_type(self, data_type: str):
Expand Down
6 changes: 4 additions & 2 deletions sysdata/production/capital.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,10 @@ class totalCapitalCalculationData(object):

def __init__(self, capital_data: capitalData, calc_method="full"):
"""
Calculation methods are: full- all profits and losses go to capital, half - profits past the HWM are not added,
fixed - capital is unaffected by profits and losses (not reccomended!)
Calculation methods are:
- full: all profits and losses go to capital
- half: profits past the HWM are not added
- fixed: capital is unaffected by profits and losses (not recommended!)
:param capital_data: strategyCapitalData instance or something that inherits from it
:param calc_method: method for going from profits to capital allocated
Expand Down
4 changes: 2 additions & 2 deletions sysdata/sim/sim_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ def _get_fx_data(self, currency1: str, currency2: str) -> fxPrices:
Get the FX rate currency1/currency2 between two currencies
Or return None if not available
(Normally we'd over ride this with a specific source)
(Normally we'd override this with a specific source)
"""
Expand All @@ -287,7 +287,7 @@ def _get_fx_data_from_start_date(
Get the FX rate currency1/currency2 between two currencies
Or return None if not available
(Normally we'd over ride this with a specific source)
(Normally we'd override this with a specific source)
"""
Expand Down
15 changes: 0 additions & 15 deletions sysexecution/algos/algo_limit_orders.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
"""
Simplest possible execution method, one market order
"""
from copy import copy
from sysexecution.orders.named_order_objects import missing_order
from sysproduction.data.broker import dataBroker

from sysexecution.algos.algo import Algo, limit_price_from_input, limit_order_type
from sysexecution.algos.common_functions import (
post_trade_processing,
MESSAGING_FREQUENCY,
cancel_order,
)
from sysdata.data_blob import dataBlob
from sysexecution.orders.contract_orders import contractOrder
from sysexecution.order_stacks.broker_order_stack import orderWithControls
from sysexecution.orders.broker_orders import market_order_type


class algoLimit(Algo):
Expand Down
2 changes: 1 addition & 1 deletion sysexecution/algos/algo_market.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def prepare_and_submit_trade(self):

if cut_down_contract_order.trade != contract_order.trade:
self.data.log.debug(
"Cut down order to size %s from %s because of algo size limit"
"Cut down order from size %s to %s because of algo size limit"
% (str(contract_order.trade), str(cut_down_contract_order.trade)),
**log_attrs,
)
Expand Down
2 changes: 1 addition & 1 deletion sysexecution/algos/algo_original_best.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def prepare_and_submit_trade(self) -> orderWithControls:
)
if cut_down_contract_order.trade != contract_order.trade:
data.log.debug(
"Cut down order to size %s from %s because of algo size limit"
"Cut down order from size %s to %s because of algo size limit"
% (str(contract_order.trade), str(cut_down_contract_order.trade)),
**log_attrs,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def liquidity_size_contract_order(

if liquid_qty != contract_order_after_trade_limits.trade:
self.log.debug(
"Cut down order to size %s from %s because of liquidity"
"Cut down order from size %s to %s because of liquidity"
% (str(liquid_qty), str(contract_order_after_trade_limits.trade)),
**contract_order_after_trade_limits.log_attributes(),
method="temp",
Expand Down
6 changes: 2 additions & 4 deletions sysinit/futures/barchart_futures_contract_prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from syscore.dateutils import month_from_contract_letter

from sysinit.futures.contract_prices_from_csv_to_arctic import (
init_arctic_with_csv_futures_contract_prices,
init_db_with_csv_futures_contract_prices,
)


Expand Down Expand Up @@ -100,9 +100,7 @@ def strip_file_names(pathname):

def transfer_barchart_prices_to_arctic(datapath):
strip_file_names(datapath)
init_arctic_with_csv_futures_contract_prices(
datapath, csv_config=barchart_csv_config
)
init_db_with_csv_futures_contract_prices(datapath, csv_config=barchart_csv_config)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion sysinit/futures/safely_modify_roll_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def safely_modify_roll_parameters(data: dataBlob):


def modified_roll_parameters(data: dataBlob, instrument_code) -> rollParameters:
print("Existing roll parameters: Must be defined in database config")
print("Existing roll parameters: Must be defined in CSV config")
data_contracts = dataContracts(data)
roll_parameters = data_contracts.get_roll_parameters(instrument_code)
print(str(roll_parameters))
Expand Down
2 changes: 1 addition & 1 deletion sysinit/futures/seed_price_data_from_IB.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def seed_price_data_from_IB(instrument_code):
## This returns yyyymmdd strings, where we have the actual expiry date

for contract_date in list_of_contracts:
## We do this slightly tortorous thing because there are energy contracts
## We do this slightly tortuous thing because there are energy contracts
## which don't expire in the month they are labelled with
## So for example, CRUDE_W 202106 actually expires on 20210528

Expand Down
2 changes: 1 addition & 1 deletion sysproduction/data/risk.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def get_daily_ts_stdev_of_prices(data, instrument_code):

# volconfig contains 'func' and some other arguments
# we turn func which could be a string into a function, and then
# call it with the other ags
# call it with the other args

volfunction = resolve_function(volconfig.pop("func"))
vol = volfunction(dailyreturns, **volconfig)
Expand Down
3 changes: 2 additions & 1 deletion sysproduction/interactive_update_roll_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,8 @@ def manually_update_roll_state_for_code(
)
if roll_state_suggested == ASK_FOR_STATE:
print(
"No specific state suggested: recommend one of Force, Force_Outright or Close)"
"No specific state suggested: recommend one of Force, "
"Force_Outright or Close"
)
default_state = roll_data.original_roll_status.name
else:
Expand Down
2 changes: 1 addition & 1 deletion sysproduction/reporting/adhoc/dynamic_optimisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ def dynamic_optimisation_text(data: dataBlob, strategy_name: str):


if __name__ == "__main__":
### Do two seperate reports, one graphical, one text
### Do two separate reports, one graphical, one text

data = dataBlob()
## interactively get backtest to use
Expand Down
2 changes: 1 addition & 1 deletion sysproduction/reporting/data/rolls.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ def get_or_infer_latest_price(new_multiple_prices, price_col: str = "PRICE"):
If one can't be found, infer (There will always be a price in some column)
:param current_multiple_prices: futuresMultiplePrices
:param new_multiple_prices: futuresMultiplePrices
:param price_col: one of 'PRICE','CARRY','FORWARD'
:return: tuple: float, bool. Bool is true if the price is inferred, otherwise False
"""
Expand Down
2 changes: 1 addition & 1 deletion sysproduction/update_total_capital.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def update_margin(self):
margin_data.add_total_margin_entry(margin_in_base_currency)
margin_series = margin_data.get_series_of_total_margin()

log.debug("Recent margin\n %s" % str(margin_series.tail(10)))
log.debug("Recent margin\n%s" % str(margin_series.tail(10)))

def update_capital(self):
data = self.data
Expand Down
6 changes: 3 additions & 3 deletions sysquant/estimators/correlations.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ def without_missing_data(self):

def quantize(self, quant_factor=0.2):
as_pd = self.as_pd()
multipier = 1 / quant_factor
multiplied_pd = as_pd * multipier
multiplier = 1 / quant_factor
multiplied_pd = as_pd * multiplier
multiplied_pd_rounded = multiplied_pd.round()
pd_quantized = multiplied_pd_rounded / multipier
pd_quantized = multiplied_pd_rounded / multiplier

return correlationEstimate(
values=pd_quantized.values, columns=pd_quantized.columns
Expand Down
2 changes: 1 addition & 1 deletion sysquant/estimators/pooled_correlation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def pooled_correlation_estimator(
## Will need to keep this to adjust lookbacks
length_adjustment = len(downsampled_data)

## We do this to ensure same frequency throughout once concatendate
## We do this to ensure same frequency throughout once concatenated
data_at_common_frequency = downsampled_data.reindex_to_common_index()

# Make into one giant dataframe
Expand Down
12 changes: 6 additions & 6 deletions systems/accounts/account_buffering_subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,17 @@ def apply_buffer(
If we're rounding positions, then we floor and ceiling the buffers.
:param position: optimal position
:type position: pd.Series
:param optimal_position: optimal position
:type optimal_position: pd.Series
:param pos_buffers:
:type pos_buffers: Tx2 pd.dataframe, top_pos and bot_pos
:param trade_to_edge: Trade to the edge (TRue) or the optimal (False)
:param trade_to_edge: Trade to the edge (True) or the optimal (False)
:type trade_to_edge: bool
:param round_positions: Produce rounded positions
:type round_positions: bool
:param roundpositions: Produce rounded positions
:type roundpositions: bool
:returns: pd.Series
"""
Expand Down Expand Up @@ -185,7 +185,7 @@ def apply_buffer_single_period(
:param bot_pos: bottom of buffer
:type bot_pos: float
:param trade_to_edge: Trade to the edge (TRue) or the optimal (False)
:param trade_to_edge: Trade to the edge (True) or the optimal (False)
:type trade_to_edge: bool
:returns: float
Expand Down
4 changes: 2 additions & 2 deletions systems/accounts/account_costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get_SR_cost_for_instrument_forecast(
KEY OUTPUT
"""
## Calculate holding and transaction seperately, as the former could be pooled
## Calculate holding and transaction separately, as the former could be pooled
transaction_cost = self.get_SR_transaction_cost_for_instrument_forecast(
instrument_code=instrument_code, rule_variation_name=rule_variation_name
)
Expand Down Expand Up @@ -184,7 +184,7 @@ def get_SR_holding_cost_only(self, instrument_code: str) -> float:
cost_per_trade = self.get_SR_cost_per_trade_for_instrument(instrument_code)
hold_turnovers = self.get_rolls_per_year(instrument_code) * 2.0

## Assumes no benefit from spread trades i.e. do two seperate trades
## Assumes no benefit from spread trades i.e. do two separate trades
SR_cost_holding = hold_turnovers * cost_per_trade

return SR_cost_holding
Expand Down
Loading

0 comments on commit 4983254

Please sign in to comment.