def _get_prices_df(self, ticker: Ticker, start_date: datetime, end_date: datetime) -> PricesDataFrame: """ Returns non-adjusted open and close prices, indexed with the Market Open and Market Close time.""" if isinstance(ticker, FutureTicker): ticker.initialize_data_provider(SettableTimer(end_date), self._data_provider) tickers_chain = ticker.get_expiration_dates() if start_date >= tickers_chain.index[-1] or end_date <= tickers_chain.index[0]: # If the futures chain starts after the _end_date or ends before the _start_date - no data available return PricesDataFrame() # Get all tickers from the chain that were valid between the start_date and expiration date of the # currently valid ticker end_date = tickers_chain[tickers_chain == ticker.get_current_specific_ticker()].index[0] tickers_chain = tickers_chain.loc[start_date:end_date] tickers = tickers_chain.values.tolist() open_prices = self._data_provider.get_price(tickers, PriceField.Open, start_date, end_date) close_prices = self._data_provider.get_price(tickers, PriceField.Close, start_date, end_date) else: open_prices = self._data_provider.get_price([ticker], PriceField.Open, start_date, end_date) close_prices = self._data_provider.get_price([ticker], PriceField.Close, start_date, end_date) open_prices.index = [dt + MarketOpenEvent.trigger_time() for dt in open_prices.index] close_prices.index = [dt + MarketCloseEvent.trigger_time() for dt in close_prices.index] prices = concat([open_prices, close_prices]).sort_index() return prices
def position_for_ticker_exists_in_portfolio(ticker: Ticker) -> bool: if isinstance(ticker, FutureTicker): # Check if any of specific tickers with open positions in portfolio belongs to tickers family return any([ ticker.belongs_to_family(t) for t in specific_tickers_with_open_position ]) else: return ticker in specific_tickers_with_open_position
def ticker_to_contract(self, ticker: Ticker) -> IBContract: ticker = ticker.get_current_specific_ticker() if isinstance( ticker, FutureTicker) else ticker contract = self._ticker_to_contract_dict.get(ticker, None) if not contract and ticker.security_type == SecurityType.FUTURE: contract = self._create_futures_contract(ticker) return contract
def _generate_buy_and_hold_returns(self, ticker: Ticker) -> SimpleReturnsSeries: """ Computes series of simple returns, which would be returned by the Buy and Hold strategy. """ if isinstance(ticker, FutureTicker): try: ticker.initialize_data_provider(SettableTimer(self._end_date), self._data_provider) futures_chain = FuturesChain( ticker, self._data_provider, FuturesAdjustmentMethod.BACK_ADJUSTED) prices_series = futures_chain.get_price( PriceField.Close, self._start_date, self._end_date) except NoValidTickerException: prices_series = PricesSeries() else: prices_series = self._data_provider.get_price( ticker, PriceField.Close, self._start_date, self._end_date) returns_tms = prices_series.to_simple_returns().replace( [-np.inf, np.inf], np.nan).fillna(0.0) returns_tms.name = "Buy and Hold" return returns_tms
def get_signal(self, ticker: Ticker, current_exposure: Exposure) -> Signal: self.ticker_name_to_ticker[ticker.name] = ticker suggested_exposure = self.calculate_exposure(ticker, current_exposure) fraction_at_risk = self.calculate_fraction_at_risk(ticker) specific_ticker = ticker.get_current_specific_ticker() if isinstance( ticker, FutureTicker) else ticker last_available_price = self.data_handler.get_last_available_price( specific_ticker) signal = Signal(ticker, suggested_exposure, fraction_at_risk, last_available_price, alpha_model=self) return signal
def _filter_transactions(self, ticker: Ticker, transactions: List[Transaction], start_date: datetime, end_date: datetime) -> QFSeries: """ Filters out transactions, which do not correspond to the given ticker and returns a QFSeries of remaining transactions. Only transactions between start_date market open and end_date market close are considered. """ transactions = [t for t in transactions if start_date + MarketOpenEvent.trigger_time() <= t.time <= end_date + MarketCloseEvent.trigger_time()] if isinstance(ticker, FutureTicker): transactions_for_tickers = [t for t in transactions if ticker.belongs_to_family(t.ticker)] else: transactions_for_tickers = [t for t in transactions if ticker == t.ticker] transactions_records = [(t, t.time) for t in transactions_for_tickers] transactions_series = QFDataFrame.from_records(transactions_records, columns=["Transaction", "Index"]) \ .set_index("Index").iloc[:, 0] return transactions_series
def _insert_table_with_overall_measures(self, prices_df: PricesDataFrame, ticker: Ticker): table = Table(column_names=["Measure", "Value"], css_class="table stats-table") table.add_row(["Instrument", ticker.as_string()]) series = prices_df[PriceField.Close] table.add_row(["Start date", date_to_str(series.index[0])]) table.add_row(["End date", date_to_str(series.index[-1])]) trend_strength_overall = trend_strength(prices_df, self.use_next_open_instead_of_close) table.add_row(["Overall strength of the day trends", trend_strength_overall]) trend_strength_1y = trend_strength(prices_df.tail(252), self.use_next_open_instead_of_close) table.add_row(["Strength of the day trends in last 1Y", trend_strength_1y]) self.ticker_to_trend_dict[ticker] = (trend_strength_1y, trend_strength_overall) table.add_row(["Up trends strength", up_trend_strength(prices_df, self.use_next_open_instead_of_close)]) table.add_row(["Down trends strength", down_trend_strength(prices_df, self.use_next_open_instead_of_close)]) self.document.add_element(table)
def _add_page(self, ticker: Ticker): self._add_header() self.document.add_element(ParagraphElement("\n")) self.document.add_element(HeadingElement(2, ticker.as_string())) self.document.add_element(ParagraphElement("\n")) price_df = self.price_provider.get_price(ticker, PriceField.ohlcv(), self.start_date, self.end_date) self._insert_table_with_overall_measures(price_df, ticker) self.document.add_element(ParagraphElement("\n")) self._add_price_chart(price_df) self.document.add_element(ParagraphElement("\n")) self._add_trend_strength_chart(price_df) self.document.add_element(ParagraphElement("\n")) self._add_up_and_down_trend_strength(price_df) self.document.add_element(NewPageElement()) # add page break
def get_signal(self, ticker: Ticker, current_exposure: Exposure, current_time: Optional[datetime] = None, frequency: Frequency = Frequency.DAILY) -> Signal: current_time = current_time or datetime.now() self.ticker_name_to_ticker[ticker.name] = ticker suggested_exposure = self.calculate_exposure(ticker, current_exposure) fraction_at_risk = self.calculate_fraction_at_risk(ticker) specific_ticker = ticker.get_current_specific_ticker() if isinstance( ticker, FutureTicker) else ticker last_available_price = self.data_provider.get_last_available_price( specific_ticker, frequency, current_time) signal = Signal(ticker, suggested_exposure, fraction_at_risk, last_available_price, current_time, alpha_model=self) return signal
def ticker_to_contract(self, ticker: Ticker) -> Ticker: """ Maps contract parameters to corresponding ticker. """ contract = ticker.get_current_specific_ticker() if isinstance( ticker, FutureTicker) else ticker return contract
def _get_specific_ticker(ticker: Ticker): return ticker.get_current_specific_ticker() if isinstance(ticker, FutureTicker) else ticker