Esempio n. 1
0
 def plot(self,
          figsize: Tuple[int, int] = (15, 8),
          date_range: Optional[Union[Tuple[str, str],
                                     Tuple[np.datetime64,
                                           np.datetime64]]] = None,
          sampling_frequency: str = None,
          title: str = 'Price / Volume') -> None:
     '''
     Plot a candlestick or line plot depending on whether we have ohlc data or just close prices
     
     Args:
         figsize: Size of the figure (default (15,8))
         date_range: A tuple of strings or numpy datetimes for plotting a smaller sample of the data, e.g. ("2018-01-01", "2018-01-06")
         sampling_frequency: Downsample before plotting.  See pandas frequency strings for possible values.
         title: Title of the graph, default "Price / Volume"
     '''
     if date_range and isinstance(date_range[0], str):
         date_range = strtup2date(date_range)
     data: Union[TradeBarSeries, TimeSeries]
     if self.has_ohlc():
         data = TradeBarSeries('price', self.timestamps, self.o, self.h,
                               self.l, self.c, self.v, self.vwap)
     else:
         data = TimeSeries('price', self.timestamps, self.c)
     subplot = Subplot(data)
     plot = Plot([subplot],
                 figsize=figsize,
                 date_range=date_range,
                 sampling_frequency=sampling_frequency,
                 title=title)
     plot.draw()
Esempio n. 2
0
 def __init__(self,
              subplot_list: Sequence[Subplot],
              title: str = None,
              figsize: Tuple[float, float] = (15, 8),
              date_range: Union[Tuple[str, str],
                                Tuple[Optional[np.datetime64],
                                      Optional[np.datetime64]]] = None,
              date_format: str = None,
              sampling_frequency: str = None,
              show_grid: bool = True,
              show_date_gaps: bool = True,
              hspace: Optional[float] = 0.15) -> None:
     '''
     Args:
         subplot_list: List of Subplot objects to draw
         title: Title for this plot.  Default None
         figsize: Figure size.  Default (15, 8)
         date_range: Tuple of strings or numpy datetime64 limiting timestamps to draw.  e.g. ("2018-01-01 14:00", "2018-01-05"). Default None
         date_format: Date format to use for x-axis
         sampling_frequency: Set this to downsample subplots that have a datetime x axis.  
           For example, if you have minute bar data, you might want to subsample to hours if the plot is too crowded.
           See pandas time frequency strings for possible values.  Default None
         show_grid: If set to True, show a grid on the subplots.  Default True
         show_date_gaps: If set to True, then when there is a gap between timestamps will draw a dashed vertical line. 
           For example, you may have minute bars and a gap between end of trading day and beginning of next day. 
           Even if set to True, this will turn itself off if there are too many gaps to avoid clutter.  Default True
         hspace: Height (vertical) space between subplots.  Default 0.15
     '''
     if isinstance(subplot_list, Subplot): subplot_list = [subplot_list]
     assert (len(subplot_list))
     self.subplot_list = subplot_list
     self.title = title
     self.figsize = figsize
     self.date_range = strtup2date(date_range)
     self.date_format = date_format
     self.sampling_frequency = sampling_frequency
     self.show_date_gaps = show_date_gaps
     self.show_grid = show_grid
     self.hspace = hspace
Esempio n. 3
0
    def plot(self, 
             contract_groups: Sequence[ContractGroup] = None, 
             primary_indicators: Sequence[str] = None,
             primary_indicators_dual_axis: Sequence[str] = None,
             secondary_indicators: Sequence[str] = None,
             secondary_indicators_dual_axis: Sequence[str] = None,
             indicator_properties: PlotPropertiesType = None,
             signals: Sequence[str] = None,
             signal_properties: PlotPropertiesType = None, 
             pnl_columns: Sequence[str] = None, 
             title: str = None, 
             figsize: Tuple[int, int] = (20, 15), 
             _date_range: DateRangeType = None, 
             date_format: str = None, 
             sampling_frequency: str = None, 
             trade_marker_properties: PlotPropertiesType = None, 
             hspace: float = 0.15) -> None:
        
        '''
        Plot indicators, signals, trades, position, pnl
        
        Args:
            contract_groups: Contract groups to plot or None (default) for all contract groups. 
            primary indicators: List of indicators to plot in the main indicator section. Default None (plot everything)
            primary indicators: List of indicators to plot in the secondary indicator section. Default None (don't plot anything)
            indicator_properties: If set, we use the line color, line type indicated for the given indicators
            signals: Signals to plot.  Default None (plot everything).
            plot_equity: If set, we plot the equity curve.  Default is True
            title: Title of plot. Default None
            figsize: Figure size.  Default (20, 15)
            date_range: Used to restrict the date range of the graph. Default None
            date_format: Date format for tick labels on x axis.  If set to None (default), will be selected based on date range. 
                See matplotlib date format strings
            sampling_frequency: Downsampling frequency.  The graph may get too busy if you have too many bars of data, 
                so you may want to downsample before plotting.  See pandas frequency strings for possible values. Default None.
            trade_marker_properties: A dictionary of order reason code -> marker shape, marker size, marker color for plotting trades
                with different reason codes. By default we use the dictionary from the :obj:`ReasonCode` class
            hspace: Height (vertical) space between subplots.  Default is 0.15
        '''
        date_range = strtup2date(_date_range)
        if contract_groups is None: contract_groups = self.contract_groups
        if isinstance(contract_groups, ContractGroup): contract_groups = [contract_groups]
        if pnl_columns is None: pnl_columns = ['equity']
        
        for contract_group in contract_groups:
            primary_indicator_names = [ind_name for ind_name in self.indicator_values[contract_group].__dict__
                                       if hasattr(self.indicator_values[contract_group], ind_name)]
            if primary_indicators:
                primary_indicator_names = list(set(primary_indicator_names).intersection(primary_indicators))
            secondary_indicator_names: List[str] = []
            if secondary_indicators:
                secondary_indicator_names = list(secondary_indicators)
            signal_names = [sig_name for sig_name in self.signals.keys() if hasattr(self.signal_values[contract_group], sig_name)]
            if signals:
                signal_names = list(set(signal_names).intersection(signals))
 
            primary_indicator_list = _get_time_series_list(self.timestamps, primary_indicator_names, 
                                                           self.indicator_values[contract_group], indicator_properties)
            secondary_indicator_list = _get_time_series_list(self.timestamps, secondary_indicator_names, 
                                                             self.indicator_values[contract_group], indicator_properties)
            signal_list = _get_time_series_list(self.timestamps, signal_names, self.signal_values[contract_group], signal_properties)
            df_pnl_ = self.df_pnl(contract_group)
            pnl_list = [TimeSeries(pnl_column, 
                                   timestamps=df_pnl_.timestamp.values, 
                                   values=df_pnl_[pnl_column].values) for pnl_column in pnl_columns]
            
            trades = [trade for trade in self._trades if trade.order.contract.contract_group == contract_group]
            if trade_marker_properties:
                trade_sets = trade_sets_by_reason_code(trades, trade_marker_properties, remove_missing_properties=True)
            else:
                trade_sets = trade_sets_by_reason_code(trades)
                
            primary_indicator_subplot = Subplot(
                primary_indicator_list + trade_sets,  # type: ignore # mypy does not allow adding heterogeneous lists
                secondary_y=primary_indicators_dual_axis,
                height_ratio=0.5, 
                ylabel='Primary Indicators')
 
            if len(secondary_indicator_list):
                secondary_indicator_subplot = Subplot(secondary_indicator_list, 
                                                      secondary_y=secondary_indicators_dual_axis,
                                                      height_ratio=0.5, 
                                                      ylabel='Secondary Indicators')
            signal_subplot = Subplot(signal_list, ylabel='Signals', height_ratio=0.167)
            pnl_subplot = Subplot(pnl_list, ylabel='Equity', height_ratio=0.167, log_y=True, y_tick_format='${x:,.0f}')
            position = df_pnl_.position.values
            disp_attribs = FilledLinePlotAttributes()
            pos_subplot = Subplot(
                [TimeSeries('position', timestamps=df_pnl_.timestamp, values=position, display_attributes=disp_attribs)], 
                ylabel='Position', height_ratio=0.167)
            
            title_full = title
            if len(contract_groups) > 1:
                if title is None: title = ''
                title_full = f'{title} {contract_group.name}'
                
            plot_list = []
            if len(primary_indicator_list): plot_list.append(primary_indicator_subplot)
            if len(secondary_indicator_list): plot_list.append(secondary_indicator_subplot)
            if len(signal_list): plot_list.append(signal_subplot)
            if len(position): plot_list.append(pos_subplot)
            if len(pnl_list): plot_list.append(pnl_subplot)
            
            if not len(plot_list): return
                
            plot = Plot(plot_list, 
                        figsize=figsize, 
                        date_range=date_range, 
                        date_format=date_format, 
                        sampling_frequency=sampling_frequency, 
                        title=title_full, 
                        hspace=hspace)
            plot.draw()