new_contents: # Source: http://gbeced.github.io/pyalgotrade/docs/v0.17/html/tutorial.html#optimizing
  # Accessed: 06/10/16 1515Z
  
  from pyalgotrade import strategy
  from pyalgotrade.technical import ma
  from pyalgotrade.technical import rsi
  from pyalgotrade.technical import cross
  
  
  class RSI2(strategy.BacktestingStrategy):
      def __init__(self, feed, instrument, entrySMA, exitSMA, rsiPeriod, overBoughtThreshold, overSoldThreshold):
          strategy.BacktestingStrategy.__init__(self, feed)
          self.__instrument = instrument
          # We'll use adjusted close values, if available, instead of regular close values.
          if feed.barsHaveAdjClose():
              self.setUseAdjustedValues(True)
          self.__priceDS = feed[instrument].getPriceDataSeries()
          self.__entrySMA = ma.SMA(self.__priceDS, entrySMA)
          self.__exitSMA = ma.SMA(self.__priceDS, exitSMA)
          self.__rsi = rsi.RSI(self.__priceDS, rsiPeriod)
          self.__overBoughtThreshold = overBoughtThreshold
          self.__overSoldThreshold = overSoldThreshold
          self.__longPos = None
          self.__shortPos = None
  
      def getEntrySMA(self):
          return self.__entrySMA
  
      def getExitSMA(self):
          return self.__exitSMA
  
      def getRSI(self):
          return self.__rsi
  
      def onEnterCanceled(self, position):
          if self.__longPos == position:
              self.__longPos = None
          elif self.__shortPos == position:
              self.__shortPos = None
          else:
              assert(False)
  
      def onExitOk(self, position):
          if self.__longPos == position:
              self.__longPos = None
          elif self.__shortPos == position:
              self.__shortPos = None
          else:
              assert(False)
  
      def onExitCanceled(self, position):
          # If the exit was canceled, re-submit it.
          position.exitMarket()
  
      def onBars(self, bars):
          # Wait for enough bars to be available to calculate SMA and RSI.
          if self.__exitSMA[-1] is None or self.__entrySMA[-1] is None or self.__rsi[-1] is None:
              return
  
          bar = bars[self.__instrument]
          if self.__longPos is not None:
              if self.exitLongSignal():
                  self.__longPos.exitMarket()
          elif self.__shortPos is not None:
              if self.exitShortSignal():
                  self.__shortPos.exitMarket()
          else:
              if self.enterLongSignal(bar):
                  shares = int(self.getBroker().getCash() * 0.9 / bars[self.__instrument].getPrice())
                  self.__longPos = self.enterLong(self.__instrument, shares, True)
              elif self.enterShortSignal(bar):
                  shares = int(self.getBroker().getCash() * 0.9 / bars[self.__instrument].getPrice())
                  self.__shortPos = self.enterShort(self.__instrument, shares, True)
  
      def enterLongSignal(self, bar):
          return bar.getPrice() > self.__entrySMA[-1] and self.__rsi[-1] <= self.__overSoldThreshold
  
      def exitLongSignal(self):
          return cross.cross_above(self.__priceDS, self.__exitSMA) and not self.__longPos.exitActive()
  
      def enterShortSignal(self, bar):
          return bar.getPrice() < self.__entrySMA[-1] and self.__rsi[-1] >= self.__overBoughtThreshold
  
      def exitShortSignal(self):
          return cross.cross_below(self.__priceDS, self.__exitSMA) and not self.__shortPos.exitActive()
  
subject: Create rsi2.py