Skip to content

Commit

Permalink
Add currencies to data handler
Browse files Browse the repository at this point in the history
  • Loading branch information
eirik-thorp committed Nov 7, 2024
1 parent 16d827a commit 127bc4a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ def use_data_preloading(self, tickers: Union[Ticker, Sequence[Ticker]], time_del
# The tickers and price fields are sorted in order to always return the same hash of the data bundle for
# the same set of tickers and fields
tickers, _ = convert_to_list(tickers, Ticker)

if self.portfolio.currency is not None:
currencies = set([ticker.currency for ticker in tickers])
if any(currency != self.portfolio.currency for currency in currencies):
currencies.discard(self.portfolio.currency)
tickers += [
self.data_provider.create_exchange_ticker(currency, self.portfolio.currency) for currency in currencies
]

self.data_handler.use_data_bundle(sorted(tickers), sorted(PriceField.ohlcv()), data_start, self.end_date,
self.frequency)
self._hash_of_data_bundle = compute_container_hash(self.data_handler.data_provider.data_bundle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ def __init__(self, settings: Settings, pdf_exporter: PDFExporter, excel_exporter
self._initial_risk = None
self._benchmark_tms = None
self._monitor_settings = None
self.currency_exchange_tickers = None

self._contract_ticker_mapper = SimulatedContractTickerMapper()

Expand Down Expand Up @@ -199,6 +198,17 @@ def set_initial_cash(self, initial_cash: int):
assert type(initial_cash) is int and initial_cash > 0
self._initial_cash = initial_cash

@ConfigExporter.update_config
def set_portfolio_currency(self, currency: str):
"""Sets the portfolio currency.
Parameters
-----------
currency: str
ISO code of the portfolio currency (Ex. 'EUR' for Euro)
"""
self._currency = currency

@ConfigExporter.update_config
def set_initial_risk(self, initial_risk: float):
"""Sets the initial risk value.
Expand Down Expand Up @@ -410,8 +420,7 @@ def build(self, start_date: datetime, end_date: datetime) -> BacktestTradingSess
self._data_handler = self._create_data_handler(self._data_provider, self._timer)
signals_register = self._signals_register if self._signals_register else BacktestSignalsRegister()

self._portfolio = Portfolio(self._data_handler, self._initial_cash, self._timer,
self._currency, self.currency_exchange_tickers)
self._portfolio = Portfolio(self._data_handler, self._initial_cash, self._timer, self._currency)

self._backtest_result = BacktestResult(self._portfolio, signals_register, self._backtest_name, start_date,
end_date, self._initial_risk)
Expand Down
5 changes: 4 additions & 1 deletion qf_lib/data_providers/bloomberg/bloomberg_data_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ def get_current_values(self, tickers: Union[BloombergTicker, Sequence[BloombergT

return casted_result

def create_exchange_rate_ticker(self, base_currency: str, quote_currency: str):
return BloombergTicker.from_string(f'{base_currency}{quote_currency} Curncy')

def get_last_available_exchange_rate(self, base_currency: str, quote_currency: str,
frequency: Frequency = Frequency.DAILY):
"""
Expand All @@ -226,7 +229,7 @@ def get_last_available_exchange_rate(self, base_currency: str, quote_currency: s
float
last available exchange rate
"""
currency_ticker = BloombergTicker.from_string(f'{base_currency}{quote_currency} Curncy')
currency_ticker = self.create_exchange_rate_ticker(base_currency, quote_currency)
quote_factor = self.get_current_values(currency_ticker, fields="QUOTE_FACTOR")
return self.get_last_available_price(currency_ticker, frequency=frequency)/quote_factor

Expand Down

0 comments on commit 127bc4a

Please sign in to comment.