Module serve
Sub-modules
Classes
class EmailRenderer (style: str = 'light')-
It renders only the trading signals in a html file. As opposed to the HTMLRenderer which renders the performances, the portfolio and other useful stats, this renderer is more lightweight and is designed to be sent by email. This being said, it is designed to be viewed on mobile devices. It also looks good on desktop though. The three styles are: - light: A light theme - dark: A dark theme (Darcula style) - rich: Another dark theme with another color palette
Args:
template_path: The path to the template directory. The directory should contain a file named main.htmlIt should also contain a directory named components that contains all the components that will be used in themain template. The css files used as themes should be in the main directory or in a styles subdirectory. Thenames of the files are used as the theme names. Same thing for the scripts.Parent
class HTMLRenderer (style: str = 'light')-
It expects that the tradeSignals object contains the index data, the tickers data and the main idx of the tickers data. Stats are calculated based on a year of data except when specified all-time. In that case, the stats are calculated from the first data point to the last.
The three styles are: - light: A light theme - dark: A dark theme (Darcula style) - rich: Another dark theme with another color palette
Args:
template_path: The path to the template directory. The directory should contain a file named main.htmlIt should also contain a directory named components that contains all the components that will be used in themain template. The css files used as themes should be in the main directory or in a styles subdirectory. Thenames of the files are used as the theme names. Same thing for the scripts.Parent
class JSONRenderer (sub_dir: Union[pathlib.PurePath, str] = 'signals', store_portfolio: bool = False, store_broker: bool = False, store_account: bool = False)-
This renderer render the signals in JSON format. You can also store the portfolio state, the broker state and the account state in the json.
Args:
sub_dir: The sub directory where the json file will be stored.
store_portfolio: Whether to store the portfolio state in the json.
store_broker: Whether to store the broker state in the json.
store_account: Whether to store the account state in the json.Parent
class LogRenderer (sub_dir: Union[pathlib.PurePath, str] = 'signals')-
Append signals to a log file. (csv format) The columns are: - timestamp - security - signal_type - price_lower_limit - price_upper_limit - n_shares - n_shares_borrowed - expiry
Parent
class MarkupObject (template: str, format_: str = '{{.*?}}')-
Args:
template: The template file as a string. Can be a full markup file or a component.
format_: This is a regex expression that should contain only one '.*?'. It corresponds to the key thatwill be replaced by the data when the render method is called.Static methods
def extract_keys(template: str, format_: str) ‑> Set[str]-
Extracts the keys from the template
Args:
template: string
format_: The format string that contains the keyReturns:
A set of keys
Methods
def render(self, data: Optional[Dict[str, str]] = None, **kwargs) ‑> str-
Render the template with the given data. If no data is provided, it will use the kwargs. If no kwargs are provided, it will use the data that was saved with the call method.
Args:
data: The data to use to render the template
kwargs: It is also possible to pass the data as kwargsReturns:
- The rendered template as a string
Raises:
RuntimeError: If a key is defined in the template, but not in the data
class MarkupRenderer (template_path: pathlib.PurePath = PurePosixPath('/Users/alavertu/PycharmProjects/backtestPro/src/backtest/serve/renderers/html_templates'))-
Class designed to facilitate the creation of custom reports builder based on html. It includes a set of method that helps extract the relevant data from the state object and render components in a hierarchical manner. Note: This class is not as flexible and easy to use as I would like it to be so it may change in the near future.
The class is designed to be derived from. The user should implement the render method to render the final report.
Currently, this class can only build single file html reports(, or pdf with a pdf renderer.)
How to use: 1. Create a new class that inherits from this class. 2. Implement the render method.
Example: Check the html renderer or the email renderer for examples.
Args:
template_path: The path to the template directory. The directory should contain a file named main.htmlIt should also contain a directory named components that contains all the components that will be used in themain template. The css files used as themes should be in the main directory or in a styles subdirectory. Thenames of the files are used as the theme names. Same thing for the scripts.Parent
Static methods
def chart_builder(portfolio_worth: numpy.ndarray, porfolio_timestamps: pandas.core.indexes.datetimes.DatetimeIndex, index_worth: numpy.ndarray, index_timestamps: pandas.core.indexes.datetimes.DatetimeIndex, dark_theme: bool = False, index_name: str = 'Index') ‑> plotly.graph_objs._figure.Figure-
Build a performance chart comparing the strategy performance with the index performance.
Args:
portfolio_worth: An array of the portfolio worth
porfolio_timestamps: The corresponding timestamps
index_worth: An array of the index worth
index_timestamps: The corresponding timestamps
dark_theme: Whether to use a theme meant for dark backgrounds or not
index_name: The name of the index. Used as a label in the chart.Returns:
- The chart object. (plotly figure)
def get_ticker_info(ticker: str, data: List[Dict[str, TSData]], main_idx: int) ‑> Dict[str, float]-
Extracts performance data for a given ticker. It calculates the change in dollars, the change in percent and the current value.
Returns:
The change in dollars, the change in percent and its current value
def prepare_data(state: StateSignals) ‑> (typing.List[str],) -
Extracts the relevant up-to-date data (current timestep) from the state object and returns it as an array with the corresponding security names.
Returns:
- The security names and the data as a numpy array. The data is in the shape (n, 4) where n is thenumber of securities and the 4 columns are the OHLC data.
def render_portfolio(position: Position, ticker_info: Dict[str, float]) ‑> str-
Renders a position as a html row [str]. The columns are: Ticker, Average_buy_price, Quantity, Change ($), Change (%), Unrealized P&L ($), Unrealized P&L (%)
Args:
position: The position object
ticker_info: The performance data for the tickerReturns:
- The rendered row as a string
def render_signal(signal: TradeOrder)-
Renders a signal as a html row [str] The columns are: Timestamp, Ticker, Signal type, Price limit low, Price limit high, Quantity, Quantity borrowed, Expiry.
Args:
signal: The signal objectReturns:
- The rendered row as a string
Methods
def get_performance_data(self, state: StateSignals, cutoff_delta: pandas._libs.tslibs.timedeltas.Timedelta = Timedelta('365 days 00:00:00')) ‑> Tuple[pandas.core.series.Series, pandas.core.series.Series, str]-
Build a series of the portfolio worth and the index worth for easier comparison.
Args:
state: The StateSignals object
cutoff_delta: The amount of time before which the data is not considered.Returns:
- The historical worth of the portfolio for the given period (cutoff_days) and the historical worth of theindex for the same period, the name of the index took. (In case there are more than 1, only one is used)
def get_script(self, name: str) ‑> str-
Load any script that is in the 'template_path' main directory, or in a scripts subdirectory.
Args:
name: The name of the file without the .js. It should be in the main directory or in the scripts subdirectory.Returns:
- The text in the file.
def get_style(self, name: str) ‑> str-
Load any stylesheet that is in the 'template_path' main directory, or in a styles subdirectory.
Args:
name: The name of the file without the .css. It should be in the main directory or in the styles subdirectory.Returns:
- The text in the file.
def prerender(self, component: str, **kwargs) ‑> str-
Render the component with the given data. It stores internally the rendered component. By default, if a component depends on another component that hasn't been rendered, it is assumed that the component was optional, and it will be rendered as an empty string (ignored).
Args:
component: The component name
kwargs: The data to render the componentReturns:
- The rendered component (text)
def render_template(self, **kwargs) ‑> str-
Render the main template with the given data. It will automatically map pre-rendered components to their corresponding tag in the template. By default, if a component is required to render the main template, but hasn't been rendered, the component will be rendered as an empty string (ignored).
Args:
kwargs: The data to add that isn't in the components.Returns:
- The rendered template as a string.
class PDFDoc (header: Optional[MarkupObject], footer: Optional[MarkupObject], *args, **kwargs)-
Class representing a PDF document. It can contain multiple pages, a header and footer. It is possible to add a new page with the new_page method. The document can be rendered to a string with the render method.
Args:
template: The template file as a string. Can be a full markup file or a component.
format_: This is a regex expression that should contain only one '.*?'. It corresponds to the key thatwill be replaced by the data when the render method is called.Parent
Methods
def new_page(self, header: bool = False, footer: bool = False) ‑> PDFPage-
Creates a new page and returns a reference to it.
Returns:
- The new page object
class PDFPage (*args, **kwargs)-
Class representing a page in a PDF document. It can contain multiple children objects. It is possible to append a component to the page with the append method. Once the page is built, it can be rendered to a string with the render method.
Args:
template: The template file as a string. Can be a full markup file or a component.
format_: This is a regex expression that should contain only one '.*?'. It corresponds to the key thatwill be replaced by the data when the render method is called.Parent
Methods
def append(self, obj: MarkupObject)-
Append a child object to the page. The child objects must be pre-rendered before calling this method. Call the object and gives it the necessary data to render before appending it to the page.
Args:
obj: The object to append to the pageReturns:
- None
class PDFRenderer (report_title: str = 'Financial Report', style: str = 'light')-
Renders a report with the same information as the HTML renderer, but in a PDF format. The three styles are: - light: A light theme - dark: A dark theme (Darcula style) - rich: Another dark theme with another color palette
Args:
report_title: The title of the report
style: The theme of the report. Can be "light", "dark" or "rich"Parent