コード例 #1
0
ファイル: benchmark.py プロジェクト: rahulmr/pinkfish
    def _algo(self):
        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = pf.Margin.CASH

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)

            # buy
            if self.tlog.shares == 0:
                self.tlog.buy(date, close)
                print("{0} BUY  {1} {2} @ {3:.2f}".format(
                    date, self.tlog.shares, self.symbol, close))
            # sell
            elif end_flag:
                shares = self.tlog.sell(date, close)
                print("{0} SELL {1} {2} @ {3:.2f}".format(
                    date, -shares, self.symbol, close))

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #2
0
ファイル: strategy.py プロジェクト: tombohub/pinkfish
    def _algo(self):
        """ Algo:
            1. The SPY closes above its upper band, buy
            2. If the SPY closes below its lower band, sell your long position.
        """
        pf.TradeLog.cash = self.capital

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)
            shares = 0

            # buy
            if self.tlog.shares == 0:
                if row.regime > 0:
                    shares = self.tlog.buy(date, close)
            # sell
            else:
                if row.regime < 0 or end_flag:
                    shares = self.tlog.sell(date, close)

            if shares > 0:
                pf.DBG("{0} BUY  {1} {2} @ {3:.2f}".format(
                    date, shares, self.symbol, close))
            elif shares < 0:
                pf.DBG("{0} SELL {1} {2} @ {3:.2f}".format(
                    date, -shares, self.symbol, close))

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #3
0
ファイル: strategy.py プロジェクト: rahulmr/pinkfish
    def _algo(self):
        """ Algo:
            1. S&P 500 index closes above its 200 day moving average
            2. The stock closes above its upper band, buy

            3. S&P 500 index closes below its 200 day moving average
            4. The stock closes below its lower band, sell your long position.
        """
        pf.TradeLog.cash = self.capital
        pf.TradeLog.seq_num = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)
            upper_band = row.sma + row.sma * self.percent_band
            lower_band = row.sma - row.sma * self.percent_band
            shares = 0

            # Sell Logic
            # First we check if an existing position in symbol should be sold
            #  - sell if (use_regime_filter and regime < 0)
            #  - sell if price closes below lower_band
            #  - sell if end of data

            if self.tlog.shares > 0:
                if ((self.regime_filter and row.regime < 0)
                        or close < lower_band or end_flag):

                    # enter sell in trade log
                    shares = self.tlog.sell(date, close)

            # Buy Logic
            # First we check to see if there is an existing position, if so do nothing
            #  - Buy if (regime > 0 or not use_regime_filter)
            #            and price closes above upper_band
            #            and (use_regime_filter and regime > 0)

            else:
                if ((row.regime > 0 or not self.regime_filter)
                        and close > upper_band):

                    # enter buy in trade log
                    shares = self.tlog.buy(date, close)

            if shares > 0:
                pf.DBG("{0} BUY  {1} {2} @ {3:.2f}".format(
                    date, shares, self.symbol, close))
            elif shares < 0:
                pf.DBG("{0} SELL {1} {2} @ {3:.2f}".format(
                    date, -shares, self.symbol, close))

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #4
0
    def _algo(self):
        """ Algo:
            1. The SPY is above its 200-day moving average
            2. The SPY closes at a X-day low, buy some shares.
               If it falls further, buy some more, etc...
            3. If the SPY closes at a X-day high, sell your entire long position.
        """
        pf.TradeLog.cash = self.capital

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)
            shares = 0

            # Sell Logic
            # First we check if an existing position in symbol should be sold
            #  - sell if price close sets a new period_high
            #  - sell if end of data

            if (self.tlog.num_open_trades() > 0
                    and (close == row.period_high or end_flag)):

                # enter sell in trade log
                shares = self.tlog.sell(date, close)

            # Buy Logic
            # First we check to see if we have exceeded max_positions, if so do nothing
            #  - Buy if regime > 0
            #            and price close sets a new period_low

            elif (self.tlog.num_open_trades() < self.max_positions
                  and row.regime > 0 and close == row.period_low):

                # calc number of shares
                buying_power = self.tlog.calc_buying_power(price=close)
                cash = buying_power / (self.max_positions -
                                       self.tlog.num_open_trades())
                shares = self.tlog.calc_shares(price=close, cash=cash)
                # enter buy in trade log
                self.tlog.buy(date, close, shares)

            if shares > 0:
                pf.DBG("{0} BUY  {1} {2} @ {3:.2f}".format(
                    date, shares, self.symbol, close))
            elif shares < 0:
                pf.DBG("{0} SELL {1} {2} @ {3:.2f}".format(
                    date, -shares, self.symbol, close))
            else:
                pass  # HOLD

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #5
0
    def _algo(self):
        """ Algo:
            1. The SPY is above its 200-day moving average
            2. The SPY closes at a X-day low, buy some shares.
               If it falls further, buy some more, etc...
            3. If the SPY closes at a X-day high, sell your entire long position.
        """
        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.margin
        stop_loss = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)
            shares = 0

            # buy
            if (self.tlog.num_open_trades() < self.max_positions
                    and row.regime > 0 and close == row.period_low
                    and not end_flag):

                # calc number of shares
                buying_power = self.tlog.calc_buying_power(price=close)
                cash = buying_power / (self.max_positions -
                                       self.tlog.num_open_trades())
                shares = self.tlog.calc_shares(price=close, cash=cash)
                # enter buy in trade log
                self.tlog.buy(date, close, shares)
                # set stop loss
                stop_loss = self.stop__loss_pct * close

            # sell
            elif (self.tlog.num_open_trades() > 0 and
                  (close == row.period_high or low < stop_loss or end_flag)):

                # enter sell in trade log
                shares = self.tlog.sell(date, close)

            if shares > 0:
                pf.DBG("{0} BUY  {1} {2} @ {3:.2f}".format(
                    date, shares, self.symbol, close))
            elif shares < 0:
                pf.DBG("{0} SELL {1} {2} @ {3:.2f} {4}".format(
                    date, -shares, self.symbol, close,
                    'STOP' if low < stop_loss else ''))

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #6
0
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.margin
        stop_loss = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)
            shares = 0

            # Sell Logic
            # First we check if an existing position in symbol should be sold
            #  - sell if price closes at X day high
            #  - sell if price closes below stop loss
            #  - sell if end of data

            if self.tlog.shares > 0:
                if close == row.period_high or low < stop_loss or end_flag:
                    if close < stop_loss: print('STOP LOSS!!!')
                    shares = self.tlog.sell(date, close)

            # Buy Logic
            # First we check to see if there is an existing position, if so do nothing
            #  - Buy if (regime > 0 or not use_regime_filter)
            #           and price closes at X day low

            else:
                if (((row.regime > 0 or close > row.sma)
                     or not self.use_regime_filter)
                        and close == row.period_low):

                    shares = self.tlog.buy(date, close)
                    # set stop loss
                    stop_loss = self.stop_loss_pct * close

            if shares > 0:
                pf.DBG("{0} BUY  {1} {2} @ {3:.2f}".format(
                    date, shares, self.symbol, close))
            elif shares < 0:
                pf.DBG("{0} SELL {1} {2} @ {3:.2f} {4}".format(
                    date, -shares, self.symbol, close,
                    'STOP' if low < stop_loss else ''))

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #7
0
ファイル: strategy.py プロジェクト: alialamiidrissi/pinkfish
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.options['margin']
        stop_loss = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)

            max_open_trades = self.options['max_open_trades']
            enable_scale_in = self.options['enable_scale_in']
            enable_scale_out = self.options['enable_scale_out']
            max_open_trades_buy = max_open_trades if enable_scale_in else 1
            max_open_trades_sell = max_open_trades if enable_scale_out else 1

            # Buy Logic
            #  - Buy if still open trades slots left
            #       and bull regime
            #       and price closes at period low
            #       and not end end_flag

            if (row.regime > 0 and close == row.period_low and not end_flag):
                # Get current, then set new weight
                weight = self.tlog.share_percent(close)
                weight += 1 / max_open_trades_buy * 100
                weight = _round_weight(weight)
                self.tlog.adjust_percent(date, close, weight)

            # Sell Logic
            # First we check if we have any open trades, then
            #  - Sell if price closes at X day high.
            #  - Sell if price closes below stop loss.
            #  - Sell if end of data.

            elif (self.tlog.shares > 0 and
                  (close == row.period_high or low < stop_loss or end_flag)):
                # Get current, then set new weight
                weight = self.tlog.share_percent(close)
                weight -= 1 / max_open_trades_sell * 100
                weight = _round_weight(weight)
                self.tlog.adjust_percent(date, close, weight)

            # Record daily balance.
            self.dbal.append(date, high, low, close)
コード例 #8
0
ファイル: benchmark.py プロジェクト: alialamiidrissi/pinkfish
    def _algo(self):
        """
        This is a general asset allocation stategy.

        Invest an equal percent in each investment option and
        rebalance every year.
        """
        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = pf.Margin.CASH

        # These dicts are used to track close and weights for
        # each symbol in portfolio
        prices = {}
        weights = {}

        weight = 1 / len(self.portfolio.symbols)
        weights = {symbol: weight for symbol in self.portfolio.symbols}

        # Trading algorithm
        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            end_flag = pf.is_last_row(self.ts, i)
            start_flag = (i == 0)

            # Buy on first trading day
            # Rebalance on the first trading day of each year
            # Close all positions on last trading day
            if row.first_doty or end_flag or start_flag:

                # If last row, then zero out all weights.
                if end_flag:
                    weights = pf.set_dict_values(weights, 0)

                # Get closing prices for all symbols
                p = self.portfolio.get_prices(row, fields=['close'])
                prices = {
                    symbol: p[symbol]['close']
                    for symbol in self.portfolio.symbols
                }

                # Adjust weights of all symbols in portfolio
                self.portfolio.adjust_percents(date, prices, weights, row)

            # Record daily balance.
            self.portfolio.record_daily_balance(date, row)
コード例 #9
0
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.options['margin']
        lookback = None

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)

            # If lookback is None, then select a random lookback of
            # 6,7,8,...,or 12 months, if not in a position.
            if self.tlog.shares == 0:
                if self.options['lookback'] is None:
                    lookback = random.choice(range(6, 12 + 1))
                else:
                    lookback = self.options['lookback']

            #mom = getattr(row, 'mom'+str(lookback))
            mom = self.tlog.get_price(row, 'mom' + str(lookback))

            # Sell Logic
            # First we check if an existing position in symbol should be sold
            #  - if first_dotw
            #            sell if mom < 0
            #            sell if end_flag

            if self.tlog.shares > 0:
                if ((row.first_dotw and mom < 0) or end_flag):
                    self.tlog.sell(date, close)

            # Buy Logic
            #  - if first_dotw
            #            buy if mom > 0

            else:
                if (row.first_dotw and mom > 0):
                    self.tlog.buy(date, close)

            # Record daily balance
            self.dbal.append(date, high, low, close)
コード例 #10
0
    def _algo(self):
        """
        Use simple buy and hold strategy.
        """
        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = pf.Margin.CASH

        for i, row in enumerate(self.ts.itertuples()):
            date = row.Index.to_pydatetime()
            end_flag = pf.is_last_row(self.ts, i)

            # Buy.
            if self.tlog.shares == 0:
                self.tlog.buy(date, row.close)
            # Sell.
            elif end_flag:
                self.tlog.sell(date, row.close)

            # Record daily balance.
            self.dbal.append(date, row.high, row.low, row.close)
コード例 #11
0
    def _algo(self):

        pf.TradeLog.cash = self.capital

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)
            upper_band = row.sma * (1 + self.options['percent_band'] / 100)
            lower_band = row.sma * (1 - self.options['percent_band'] / 100)

            # Sell Logic
            # First we check if an existing position in symbol
            # should be sold
            #  - Sell if (use_regime_filter and regime < 0)
            #  - Sell if price closes below lower_band
            #  - Sell if end of data

            if self.tlog.shares > 0:
                if ((self.options['use_regime_filter'] and row.regime < 0)
                        or close < lower_band or end_flag):
                    self.tlog.sell(date, close)

            # Buy Logic
            # First we check to see if there is an existing position,
            # if so do nothing
            #  - Buy if (regime > 0 or not use_regime_filter)
            #            and price closes above upper_band
            #            and (use_regime_filter and regime > 0)

            else:
                if ((row.regime > 0 or not self.options['use_regime_filter'])
                        and close > upper_band):
                    self.tlog.buy(date, close)

            # Record daily balance
            self.dbal.append(date, high, low, close)
コード例 #12
0
    def _algo(self):

        pf.TradeLog.cash = self.capital

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)

            # Buy
            if self.tlog.shares == 0:
                if row.regime > 0 and self.ts['regime'][i - 1] < 0:
                    self.tlog.buy(date, close)
            # Sell
            else:
                if row.regime < 0 or end_flag:
                    self.tlog.sell(date, close)

            # Record daily balance.
            self.dbal.append(date, high, low, close)
コード例 #13
0
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.options['margin']
        stop_loss = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high; low = row.low; close = row.close 
            end_flag = pf.is_last_row(self.ts, i)
            
            # Sell Logic
            # First we check if we have any shares, then
            #  - Sell if price closes at X day high.
            #  - Sell if price closes below stop loss.
            #  - Sell if end of data.

            if self.tlog.shares > 0:
                if close == row.period_high or low < stop_loss or end_flag:
                    if close < stop_loss: print('STOP LOSS!!!')
                    self.tlog.sell(date, close)
            
            # Buy Logic
            #  - Buy if (regime > 0 or close > row.sma) or not using regime filter)
            #            and price closes at X day low.

            else:
                if (((row.regime > 0 or close > row.sma) or not self.options['use_regime_filter'])
                      and close == row.period_low):
                    self.tlog.buy(date, close)
                    # Set stop loss.
                    stop_loss = (1-self.options['stop_loss_pct'])*close

            # Record daily balance.
            self.dbal.append(date, high, low, close)
コード例 #14
0
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.options['margin']

        # These dicts are used to track close, mom, and weights for
        # each symbol in portfolio
        prices = {}
        mom = {}
        weights = {}

        # A counter to countdown the number of months a lookback has
        # been in place
        month_count = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            end_flag = pf.is_last_row(self.ts, i)

            if month_count == 0:
                # if period is None, then select a random trading period of
                # 6,7,8,...,or 12 months
                if self.options['lookback'] is None:
                    lookback = random.choice(range(6, 12 + 1))
                else:
                    lookback = self.options['lookback']
                month_count = lookback

            # If first day of the month or last row
            if row.first_dotm or end_flag:

                month_count -= 1

                # Get prices for current row
                mom_field = 'mom' + str(lookback)
                p = self.portfolio.get_prices(row, fields=['close', mom_field])

                # Copy data from `p` into prices and mom dicts for
                # convenience, also zero out weights dict.
                for symbol in self.portfolio.symbols:
                    prices[symbol] = p[symbol]['close']
                    mom[symbol] = p[symbol][mom_field]
                    weights[symbol] = 0

                # Rebalance logic:
                #   Assign weights using relative momentum
                #   Then assign using absolute momentum if enabled
                #   Finally rebalance

                # Set weights to zero if last row or using regime
                # filter and regime has turned bearish.
                if end_flag or (self.options['use_regime_filter']
                                and row.regime < 0):
                    # Since weights dict is already zeroed out, all positions
                    # will be closed out below with adjust_percent()
                    pass
                else:
                    # Relative momentum: Sort by highest momentum.
                    mom = pf.sort_dict(mom, reverse=True)

                    # Get the top tier momentum symbols; assign
                    # equal weight to top tier symbols
                    for i in range(self.options['top_tier']):
                        symbol = list(mom.keys())[i]
                        weights[symbol] = 1 / self.options['top_tier']

                # Absolute momentum: Set weight to zero if percent
                # change is negative.
                if self.options['use_absolute_mom']:
                    for symbol, pct_change in mom.items():
                        if pct_change < 0: weights[symbol] = 0

                # Rebalance portfolio
                self.portfolio.adjust_percents(date, prices, weights, row)

            # record daily balance
            self.portfolio.record_daily_balance(date, row)
コード例 #15
0
ファイル: strategy.py プロジェクト: alialamiidrissi/pinkfish
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.options['margin']

        # Create a stop_loss dict for each symbol.
        stop_loss = {symbol: 0 for symbol in self.portfolio.symbols}

        # stop loss pct should range between 0 and 1, user may have
        # expressed this as a percentage 0-100
        if self.options['stop_loss_pct'] > 1:
            self.options['stop_loss_pct'] /= 100

        period_high_field = 'period_high' + str(self.options['period'])
        period_low_field = 'period_low' + str(self.options['period'])

        # Loop though timeseries.
        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            end_flag = pf.is_last_row(self.ts, i)

            # Get the prices for this row, put in dict p.
            p = self.portfolio.get_prices(row,
                                          fields=[
                                              'close', 'regime',
                                              period_high_field,
                                              period_low_field, 'vola'
                                          ])

            # Sum the inverse volatility for each row.
            inverse_vola_sum = 0
            for symbol in self.portfolio.symbols:
                inverse_vola_sum += 1 / p[symbol]['vola']

            # Loop though each symbol in portfolio.
            for symbol in self.portfolio.symbols:

                # Use variables to make code cleaner
                close = p[symbol]['close']
                regime = p[symbol]['regime']
                period_high = p[symbol][period_high_field]
                period_low = p[symbol][period_low_field]
                inverse_vola = 1 / p[symbol]['vola']

                # Sell Logic
                # First we check if an existing position in symbol should be sold
                #  - sell if price closes at X day high
                #  - sell if price closes below stop loss
                #  - sell if end of data by adjusted the percent to zero

                if symbol in self.portfolio.positions:
                    if close == period_high or close < stop_loss[
                            symbol] or end_flag:
                        if close < stop_loss[symbol]: print('STOP LOSS!!!')
                        self.portfolio.adjust_percent(date, close, 0, symbol,
                                                      row)

                # Buy Logic
                # First we check to see if there is an existing position, if so do nothing
                #  - Buy if (regime > 0 or not use_regime_filter) and price closes at X day low

                else:
                    if (regime > 0 or not self.options['use_regime_filter']
                        ) and close == period_low:
                        # Use volatility weight.
                        if self.options['use_vola_weight']:
                            weight = inverse_vola / inverse_vola_sum
                        # Use equal weight.
                        else:
                            weight = 1 / len(self.portfolio.symbols)
                        self.portfolio.adjust_percent(date, close, weight,
                                                      symbol, row)
                        # Set stop loss
                        stop_loss[symbol] = (
                            1 - self.options['stop_loss_pct']) * close

            # record daily balance
            self.portfolio.record_daily_balance(date, row)
コード例 #16
0
ファイル: strategy.py プロジェクト: tombohub/pinkfish
    def _algo(self):
        """ Algo:
            - The future closes above its upper band, buy
            - The future closes below its lower band, sell your long position.
        """
        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.margin
        pf.TradeLog.multiplier = self.multiplier
        stop_loss = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)
            regime = row.regime
            vola = row.vola

            # this yahoo futures data hasn't been cleaned well.  there are zero values in here.

            if end_flag:
                if self.tlog.shares > 0:
                    self.tlog._exit_trade(date,
                                          close,
                                          shares=None,
                                          direction=self.tlog.direction)

            # Sell Logic
            # First we check if an existing position in symbol should be sold
            #  - sell if price closes at X day low
            #  - sell if price closes below stop loss

            elif regime < 0:
                if self.tlog.shares > 0:
                    if self.tlog.direction == pf.Direction.LONG:
                        # exit long trade; enter short trade
                        self.tlog._exit_trade(date,
                                              close,
                                              direction=pf.Direction.LONG)
                        if self.enable_shorts:
                            cash = self.tlog.calc_buying_power(close)
                            shares = self.tlog.calc_shares(close,
                                                           cash=cash /
                                                           self.multiplier)
                            self.tlog._enter_trade(
                                date,
                                close,
                                shares=shares,
                                direction=pf.Direction.SHORT)
                            stop_loss = (2 - self.stop_loss_pct) * close
                    else:
                        pass
                        if self.enable_shorts:
                            if close > stop_loss:
                                print('STOP LOSS!!!')
                                self.tlog._exit_trade(
                                    date, close, direction=pf.Direction.SHORT)
                else:
                    if self.enable_shorts:
                        # enter new short position
                        cash = self.tlog.calc_buying_power(close)
                        shares = self.tlog.calc_shares(close,
                                                       cash=cash /
                                                       self.multiplier)
                        self.tlog._enter_trade(date,
                                               close,
                                               shares=shares,
                                               direction=pf.Direction.SHORT)
                        # set stop loss
                        stop_loss = (2 - self.stop_loss_pct) * close

            # Buy Logic
            # First we check if an existing position in symbol should be bought
            #  - buy if price closes at X day high
            #  - buy if price closes below stop loss

            elif regime > 0:
                if self.tlog.shares > 0:
                    if self.tlog.direction == pf.Direction.SHORT:
                        # exit short trade; enter long trade
                        if self.enable_shorts:
                            self.tlog._exit_trade(date,
                                                  close,
                                                  direction=pf.Direction.SHORT)
                        cash = self.tlog.calc_buying_power(close)
                        shares = self.tlog.calc_shares(
                            close, cash=cash / self.multiplier * .30 / vola)
                        self.tlog._enter_trade(date,
                                               close,
                                               shares=shares,
                                               direction=pf.Direction.LONG)
                        stop_loss = self.stop_loss_pct * close
                    else:
                        if close < stop_loss:
                            print('STOP LOSS!!!')
                            self.tlog._exit_trade(date,
                                                  close,
                                                  direction=pf.Direction.LONG)
                else:
                    # enter new long position
                    cash = self.tlog.calc_buying_power(close)
                    shares = self.tlog.calc_shares(
                        close, cash=cash / self.multiplier * .30 / vola)
                    self.tlog._enter_trade(date,
                                           close,
                                           shares=shares,
                                           direction=pf.Direction.LONG)
                    # set stop loss
                    stop_loss = self.stop_loss_pct * close

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #17
0
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.margin

        close = {}
        mom = {}
        weights = {}
        cnt = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            end_flag = pf.is_last_row(self.ts, i)

            if cnt == 0:
                # if period is None, then select a random trading period of
                # 6,7,8,...,or 12 months
                if self.lookback is None:
                    lookback = random.choice(range(3, 12 + 1))
                    cnt = lookback
                else:
                    lookback = self.lookback

            mom_field = 'mom' + str(lookback)
            p = self.portfolio.get_prices(row, fields=['close', mom_field])

            if row.first_dotm or end_flag:
                # reverse sort by last weights (want current positions first in dict)
                weights = dict(
                    sorted(weights.items(), key=lambda x: x[1], reverse=True))
                for symbol in self.portfolio.symbols:
                    close[symbol] = p[symbol]['close']
                    mom[symbol] = p[symbol][mom_field]
                    weights[symbol] = 0

                # Rebalance logic - assign weights using relative momentum
                # then assign using absolute momentum if enabled
                # finally rebalance

                # relative momentum
                if end_flag or (self.use_regime_filter and row.regime < 0):
                    pass
                else:
                    # sort by highest momentum
                    mom = dict(
                        sorted(mom.items(), key=lambda x: x[1], reverse=True))
                    l = list(mom)
                    for i in range(self.top_tier):
                        symbol = l[i]
                        weights[symbol] = 1 / self.top_tier
                # absolute momentum
                if self.use_absolute_mom:
                    for symbol, roc in mom.items():
                        if roc < 0: weights[symbol] = 0

                # rebalance portfolio
                for symbol, weight in weights.items():
                    self.portfolio.adjust_percent(date, close[symbol],
                                                  weights[symbol], symbol, row)

                if self.lookback is None:
                    cnt -= 1

            # record daily balance
            self.portfolio.record_daily_balance(date, row)
コード例 #18
0
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.options['margin']

        # These dicts are used to track close, mom, and weights for
        # each symbol in portfolio
        prices = {}
        mom = {}
        weights = {}

        # These variables are assigned to the actual EFT
        US_STOCKS = self.symbols['US STOCKS']
        US_BONDS = self.symbols['US BONDS']
        EXUS_STOCKS = self.symbols['EX-US STOCKS']
        TBILL = self.symbols['T-BILL']

        # A counter to countdown the number of months a lookback has
        # been in place
        month_count = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            end_flag = pf.is_last_row(self.ts, i)

            if month_count == 0:
                # if period is None, then select a random trading period of
                # 6,7,8,...,or 12 months
                if self.options['lookback'] is None:
                    lookback = random.choice(range(6, 12 + 1))
                else:
                    lookback = self.options['lookback']
                month_count = lookback

            # If first day of the month or last row
            if row.first_dotm or end_flag:

                month_count -= 1

                # Get prices for current row
                mom_field = 'mom' + str(lookback)
                p = self.portfolio.get_prices(row, fields=['close', mom_field])

                # Copy data from `p` into prices and mom dicts for
                # convenience, also zero out weights dict.
                for symbol in self.portfolio.symbols:
                    prices[symbol] = p[symbol]['close']
                    mom[symbol] = p[symbol][mom_field]
                    weights[symbol] = 0

                # Rebalance logic:
                #   Assign weights using relative momentum
                #   Then assign using absolute momentum if enabled
                #   Finally rebalance

                # GEM strategy
                if end_flag:
                    # Since weights dict is zeroed out, all positions
                    # will be closed out below with adjust_percent()
                    pass
                elif mom[US_STOCKS] > mom[TBILL]:
                    if mom[US_STOCKS] > mom[EXUS_STOCKS]:
                        weights[US_STOCKS] = 1
                    else:
                        weights[EXUS_STOCKS] = 1
                else:
                    weights[US_BONDS] = 1

                # Rebalance portfolio
                self.portfolio.adjust_percents(date, prices, weights, row)

            # record daily balance
            self.portfolio.record_daily_balance(date, row)
コード例 #19
0
    def _algo(self):
        """ Algo:
            1. The SPY is above its 200-day moving average
            2. The SPY closes at a X-day low, buy with full capital.
            3. If the SPY closes at a X-day high, sell some.
               If it sets further highs, sell some more, etc...
            4. If you have free cash, use it all when fresh lows are set.
        """
        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.margin
        stop_loss = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high
            low = row.low
            close = row.close
            end_flag = pf.is_last_row(self.ts, i)
            shares = 0

            # buy
            if (self.tlog.num_open_trades() < self.max_positions
                    and row.regime > 0 and close == row.period_low
                    and not end_flag):

                # calc number of shares
                buying_power = self.tlog.calc_buying_power(price=close)
                shares = self.tlog.calc_shares(price=close, cash=buying_power)

                # if we have enough cash to buy any shares, then buy them
                if shares > 0:

                    # enter buy in trade log
                    self.tlog.buy(date, close, shares)
                    # set stop loss
                    stop_loss = 0 * close
                    # set positions to max_positions
                    self.positions = self.max_positions

            # sell
            elif (self.tlog.num_open_trades() > 0 and
                  (close == row.period_high or low < stop_loss or end_flag)):

                if end_flag:
                    shares = self.tlog.shares
                else:
                    shares = int(self.tlog.shares / (self.positions))
                    self.positions -= 1

                # enter sell in trade log
                shares = self.tlog.sell(date, close, shares)

            if shares > 0:
                pf.DBG("{0} BUY  {1} {2} @ {3:.2f}".format(
                    date, shares, self.symbol, close))
            elif shares < 0:
                pf.DBG("{0} SELL {1} {2} @ {3:.2f}".format(
                    date, -shares, self.symbol, close))

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #20
0
ファイル: strategy.py プロジェクト: tombohub/pinkfish
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.margin

        close = {}
        mom = {}
        weights = {}
        SP500 = self.symbols['SP500']
        BONDS = self.symbols['BONDS']
        EXUS = self.symbols['EXUS']
        TBILL = self.symbols['T-BILL']
        cnt = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            end_flag = pf.is_last_row(self.ts, i)

            if cnt == 0:
                # if period is None, then select a random trading period of
                # 6,7,8,...,or 12 months
                if self.lookback is None:
                    lookback = random.choice(range(3, 12 + 1))
                    cnt = lookback
                else:
                    lookback = self.lookback

            mom_field = 'mom' + str(lookback)
            p = self.portfolio.get_prices(row, fields=['close', mom_field])

            if row.first_dotm or end_flag:
                # reverse sort by last weights (want current positions first in dict)
                weights = dict(
                    sorted(weights.items(), key=lambda x: x[1], reverse=True))
                for symbol in self.portfolio.symbols:
                    close[symbol] = p[symbol]['close']
                    mom[symbol] = p[symbol][mom_field]
                    weights[symbol] = 0

                # Rebalance logic - assign weights using relative momentum
                # then assign using absolute momentum if enabled
                # finally rebalance

                # relative momentum
                if end_flag:
                    pass
                elif mom[SP500] > mom[TBILL]:
                    if mom[SP500] > mom[EXUS]:
                        weights[SP500] = 1
                    else:
                        weights[EXUS] = 1
                else:
                    weights[BONDS] = 1

                # absolute momentum
                if self.use_absolute_mom:
                    if mom[SP500] < 0: weights[SP500] = 0
                    if mom[EXUS] < 0: weights[EXUS] = 0
                    if mom[BONDS] < 0: weights[BONDS] = 0
                    if mom[TBILL] < 0: weights[TBILL] = 0

                # rebalance portfolio
                for symbol, weight in weights.items():
                    self.portfolio.adjust_percent(date, close[symbol],
                                                  weights[symbol], symbol, row)

                if self.lookback is None:
                    cnt -= 1

            # record daily balance
            self.portfolio.record_daily_balance(date, row)
コード例 #21
0
    def _algo(self):
        """ Algo:
            1. The SPY is higher than X days ago, buy
            2. If the SPY is lower than X days ago, sell your long position.
        """
        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.margin
        stop_loss = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high; low = row.low; close = row.close 
            end_flag = pf.is_last_row(self.ts, i)
            shares = 0
                
            if self.tlog.shares == 0:
                # if period is None, then select a random trading period of
                # 6,7,8,...,or 12 months
                if self.period is None:
                    period = random.choice(range(6, 12+1))
                else:
                    period = self.period

            mom = getattr(row, 'mom'+str(period))

            # Sell Logic
            # First we check if an existing position in symbol should be sold
            #  - if first_dotm (or first_dotw)
            #            sell if mom < 0
            #            sell if low < stop_loss
            #            sell if end_flag

            
            if self.tlog.shares > 0:
                #if (row.first_dotm:
                if (row.first_dotw
                    and (mom < 0 or low < stop_loss or end_flag)):
                    # enter sell in trade log
                    shares = self.tlog.sell(date, close)
            
            # Buy Logic
            #  - if first_dotm (or first_dotw)
            #            buy if mom > 0

            else:
                #if (row.first_dotm
                if (row.first_dotw
                     and mom > 0):
                    # enter buy in trade log
                    shares = self.tlog.buy(date, close)
                    # set stop loss
                    stop_loss = 0*close

            if shares > 0:
                pf.DBG("{0} BUY  {1} {2} @ {3:.2f}".format(
                       date, shares, self.symbol, close))
            elif shares < 0:
                pf.DBG("{0} SELL {1} {2} @ {3:.2f}".format(
                       date, -shares, self.symbol, close))

            # record daily balance
            self.dbal.append(date, high, low, close)
コード例 #22
0
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.options['margin']
        stop_loss = 0

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            high = row.high; low = row.low; close = row.close; 
            end_flag = pf.is_last_row(self.ts, i)
            shares = 0

            max_open_trades = self.options['max_open_trades']
            enable_scale_in = self.options['enable_scale_in']
            enable_scale_out = self.options['enable_scale_out']
            max_open_trades_buy  = max_open_trades if enable_scale_in  else 1
            num_open_trades = self.tlog.num_open_trades

            # Buy Logic
            #  - Buy if still open trades slots left
            #       and bull regime
            #       and price closes at period low
            #       and not end end_flag

            if (num_open_trades < max_open_trades_buy
                and row.regime > 0 and close == row.period_low and not end_flag):

                # Calc number of shares for another cash-equal trade.
                buying_power = self.tlog.calc_buying_power(close)
                cash = buying_power / (max_open_trades_buy - num_open_trades)
                shares = self.tlog.calc_shares(close, cash)

                # Buy more shares if we have the cash.
                if shares > 0:
                    # Enter buy in trade log
                    self.tlog.buy(date, close, shares)
                    # Set stop loss
                    stop_loss = (1-self.options['stop_loss_pct'])*close
                    # set sell_parts to max_open_trades
                    num_out_trades = max_open_trades

            # Sell Logic
            # First we check if we have any open trades, then
            #  - Sell if price closes at X day high.
            #  - Sell if price closes below stop loss.
            #  - Sell if end of data.

            elif (num_open_trades > 0 
                  and (close == row.period_high or low < stop_loss or end_flag)):

                if not enable_scale_out or low < stop_loss or end_flag:
                    # Exit all positions.
                    shares = None
                elif enable_scale_in:
                    # Exit one position.
                    shares = -1
                else:
                    # Scaling out is done here by shares, for example
                    # if there are 100 shares and num trades is 4,
                    # then we reduce by 25 each time.  This is
                    # different than scaling out by percentage of
                    # total fund value as is done in strategy.py.
                    shares = int(self.tlog.shares / num_out_trades)
                    num_out_trades -= 1

                # Enter sell in trade log.
                shares = self.tlog.sell(date, close, shares)

            if shares > 0:
                pf.DBG("{0} BUY  {1} {2} @ {3:.2f}".format(
                       date, shares, self.symbol, close))
            elif shares < 0:
                pf.DBG("{0} SELL {1} {2} @ {3:.2f}".format(
                       date, -shares, self.symbol, close))

            # Record daily balance.
            self.dbal.append(date, high, low, close)
コード例 #23
0
ファイル: strategy.py プロジェクト: tombohub/pinkfish
    def _algo(self):

        pf.TradeLog.cash = self.capital
        pf.TradeLog.margin = self.margin

        stop_loss = {symbol: 0 for symbol in self.portfolio.symbols}
        period_high_field = 'period_high' + str(self.period)
        period_low_field = 'period_low' + str(self.period)

        for i, row in enumerate(self.ts.itertuples()):

            date = row.Index.to_pydatetime()
            end_flag = pf.is_last_row(self.ts, i)
            p = self.portfolio.get_prices(row,
                                          fields=[
                                              'close', 'regime',
                                              period_high_field,
                                              period_low_field, 'vola'
                                          ])

            # need to sum the inverse volatility for each row
            inverse_vola_sum = 0
            for symbol in self.portfolio.symbols:
                inverse_vola_sum += 1 / p[symbol]['vola']

            # get symbol row data
            for symbol in self.portfolio.symbols:
                close = p[symbol]['close']
                regime = p[symbol]['regime']
                period_high = p[symbol][period_high_field]
                period_low = p[symbol][period_low_field]
                inverse_vola = 1 / p[symbol]['vola']

                # Sell Logic
                # First we check if an existing position in symbol should be sold
                #  - sell if price closes at X day high
                #  - sell if price closes below stop loss
                #  - sell if end of data

                if symbol in self.portfolio.positions():
                    if close == period_high or close < stop_loss[
                            symbol] or end_flag:
                        if close < stop_loss[symbol]: print('STOP LOSS!!!')
                        self.portfolio.adjust_percent(date, close, 0, symbol,
                                                      row)

                # Buy Logic
                # First we check to see if there is an existing position, if so do nothing
                #  - Buy if (regime > 0 or not use_regime_filter) and price closes at X day low

                else:
                    if (regime > 0 or not self.use_regime_filter
                        ) and close == period_low:
                        # use volatility weight
                        if self.use_vola_weight:
                            weight = inverse_vola / inverse_vola_sum
                        # use equal weight
                        else:
                            weight = 1 / len(self.portfolio.symbols)
                        self.portfolio.adjust_percent(date, close, weight,
                                                      symbol, row)
                        # set stop loss
                        stop_loss[symbol] = self.stop_loss_pct * close

            # record daily balance
            self.portfolio.record_daily_balance(date, row)