Пример #1
0
    def get_available_portfolio_dts(self, df, start_dt, end_dt):
        '''
        Gets the available date/datetime points from the range of start_dt and end_dt
        from the provided dataframe
        '''

        dt1 = start_dt if type(start_dt) == datetime.datetime else str_to_ts(
            start_dt)

        if end_dt:
            dt2 = end_dt if end_dt and type(
                end_dt) == datetime.datetime else str_to_ts(end_dt)
            return list(df[(df.index >= dt1)
                           & (df.index <= dt2)].index.unique())
        else:
            return list(df[df.index >= dt1].index.unique())
Пример #2
0
        def _update_signals(signals: pd.DataFrame,
                            df: pd.DataFrame,
                            signal_name: str or None = None):
            if not signal_name:
                # Set up a default signal's name if not provided.
                # Try to define signals_1 as the default name.
                # Find available signals_n if 'signals_1' is busy.
                signal_name = "signals_1"
                while signal_name in signals['signal'].unique():
                    signal_name = signal_name.split('_')[0] + '_' + str(
                        int(signal_name.split('_')[1]) + 1)

            df['signal'] = signal_name
            df['dt'] = df['dt'].apply(lambda x: str_to_ts(x))

            if 'trade_percantage' not in df.columns:
                df['trade_percantage'] = self.default_trade_percantage

            if 'decision_delay' not in df.columns:
                df['decision_delay'] = self.decision_delay

            df['delayed_dt'] = df['dt'] + df['decision_delay']

            df.set_index('delayed_dt', inplace=True)
            df.set_index(df.index.ceil(freq=self._granularity), inplace=True)

            # df = df['dt', 'signal', 'asset', 'decision_delay', 'trade_percantage']
            return signals.append(df)
Пример #3
0
    def __init__(self,
                 start_dt: str or datetime,
                 end_dt: str or datetime or None = None,
                 granularity: str = '1D',
                 decision_delay: int = 0,
                 init_asset: str or None = None,
                 add_asset_once_authorized: bool = False,
                 sell_assets_once_unauthorized: bool = True):
        self._granularity = granularity
        self._start_dt = str_to_ts(start_dt)
        self.end_dt = end_dt
        self.decision_delay = datetime.timedelta(seconds=decision_delay)
        self.init_asset = init_asset
        self.add_asset_once_authorized = add_asset_once_authorized
        self.sell_assets_once_unauthorized = sell_assets_once_unauthorized

        self.assets = Assets(start_dt=start_dt,
                             end_dt=end_dt,
                             granularity=granularity,
                             init_asset=init_asset)
        self.prices = Prices(start_dt=start_dt,
                             end_dt=end_dt,
                             granularity=granularity)
        self.signals = Signals(start_dt=start_dt,
                               end_dt=end_dt,
                               granularity=granularity,
                               decision_delay=decision_delay)

        self.portfolio = pd.DataFrame(None)
        self.asset_shares = pd.DataFrame(None)
        self.trades_log = pd.DataFrame(
            columns=['dt', 'order', 'share', 'from', 'to', 'fee', 'metadata'])
Пример #4
0
        def _remove_assets(assets_df, exclude_asset, exclude_dates, granularity=self._granularity):
            dates = [str_to_ts(dt) for dt in exclude_dates]
            assert len(dates) % 2 == 0, f'Unsupported datetime sequence for {exclude_asset}: odd amount of dates.'

            for i in range(int(len(dates) / 2)):
                exclude_dates = list(pd.date_range(start=dates[2 * i], end=dates[2 * i + 1], freq=granularity))
                assets_df = assets_df[
                    ~((assets_df.index.isin(exclude_dates)) & (assets_df['asset'] == exclude_asset))
                ]
            return assets_df
Пример #5
0
    def __init__(self,
                 start_dt: str or datetime,
                 end_dt: str or datetime or None = None,
                 granularity: str = '1D',
                 decision_delay: int = 0):
        self._granularity = granularity
        self._start_dt = str_to_ts(start_dt)
        self.end_dt = end_dt
        self.decision_delay = datetime.timedelta(seconds=decision_delay)
        self.default_trade_percantage = 1

        self.buy_signals = self._default_signals_df.copy()
        self.sell_signals = self._default_signals_df.copy()
        self.rebalance_signals = self._default_signals_df.copy()
Пример #6
0
    def __init__(
        self,
        start_dt: str or datetime,
        end_dt: str or datetime or None = None,
        granularity: str = '1D',
        init_asset: str or None = None,

    ):
        self._granularity = granularity
        self._start_dt = str_to_ts(start_dt)
        self.end_dt = end_dt
        self.init_asset = init_asset

        self.common_assets = pd.DataFrame(columns=['asset'])
        self.reserve_assets = pd.DataFrame(columns=['asset'])
Пример #7
0
    def __init__(
        self,
        start_dt: str or datetime,
        end_dt: str or datetime or None = None,
        granularity: str = '1D',
        fill_gaps_by_default: bool = False,
        fill_gaps_function: str = 'pad'
    ):
        # These parameters could be used later for checking price gaps, interpolation, etc.
        self._granularity = granularity
        self._start_dt = str_to_ts(start_dt)
        self.end_dt = end_dt

        self.prices = pd.DataFrame(columns=['dt', 'asset', 'price', 'price_change']).set_index('dt')
        self.fill_gaps_by_default = fill_gaps_by_default
        self.fill_gaps_function = fill_gaps_function
Пример #8
0
        def _update_assets(assets, new_assets, granularity=self._granularity):
            ''' Updates assets-in-the-portfolio dataFrame.'''
            for asset_name in new_assets:
                # Convert and test datetimes
                dates = [str_to_ts(dt) for dt in new_assets[asset_name]]
                assert min(dates) >= self._start_dt, \
                    f'Provided datetime ({min(dates)}) is smaller than expected ({self._start_dt}). [{asset_name}]'
                assert len(dates) % 2 == 0, f'Unsupported datetime sequence for {asset_name}: odd amount of dates.'

                # Update assets in the portfolio
                for i in range(int(len(dates) / 2)):
                    assets = assets.append(pd.DataFrame(
                        index=pd.date_range(start=dates[2 * i], end=dates[2 * i + 1], freq=granularity),
                        data={'asset': asset_name}
                    ))

            return assets.reset_index().drop_duplicates().set_index('index').sort_index()
Пример #9
0
    def __init__(self,
                 start_dt: str or datetime.datetime,
                 initial_investment: float = 10**6,
                 default_transfers_limit: int = 1,
                 accuracy: float = 3 * 10**(-6),
                 granularity: str = '1D'):
        self.start_dt = str_to_ts(start_dt)
        self.initial_investment = initial_investment
        self.default_transfers_limit = default_transfers_limit
        self.accuracy = accuracy

        self.prices = Prices(start_dt=self.start_dt, granularity=granularity)

        self.portfolio = pd.DataFrame(None)
        self.net_returns = pd.DataFrame(None)
        self.portfolio_price = pd.DataFrame(None)

        self.trades_log = pd.DataFrame(None)
        self.fees = pd.DataFrame(None)
Пример #10
0
def prepare_df(source_df: pd.DataFrame):
    '''
    DF can be provided to the object with dt index or dt column
    which will be transformed into index.
    '''
    df = source_df.copy()
    if 'dt' in df.columns:
        if not is_datetime(df['dt']):
            df['dt'] = df['dt'].apply(lambda x: str_to_ts(x))
        df.set_index('dt', inplace=True)
    else:
        if type(df.index) != pd.core.indexes.datetimes.DatetimeIndex:
            logging.error(
                'Please provide a df with datetime index or index data using column named "dt"'
            )
            return
        else:
            df.index.name = 'dt'
            df = df.reset_index()
            df['dt'] = [item.replace(tzinfo=None) for item in df['dt']]
            df.set_index('dt', inplace=True)
    return df