예제 #1
0
 def setUp(self):
     # Create CsvData class object.
     self._dataProvider = 'iVolatility'
     self._filename = '/Users/msantoro/PycharmProjects/Backtester/sampleData/aapl_sample_ivolatility.csv'
     self._eventQueue = queue.Queue()
     self._csvObj = csvData.CsvData(csvPath=self._filename, dataProvider=self._dataProvider,
                                    eventQueue=self._eventQueue)
예제 #2
0
  def testGetOptionChainBadColumnName(self):
    """Tests that an exception is raised if column name in the CSV doesn't match the one in dataProviders.json."""
    # Create CsvData class object.
    dataProvider = 'iVolatility'
    filename = '/Users/msantoro/PycharmProjects/Backtester/sampleData/bad_column_name.csv'
    eventQueue = queue.Queue()
    csvObj = csvData.CsvData(csvPath=filename, dataProvider=dataProvider, eventQueue=eventQueue)

    with self.assertRaisesRegex(TypeError, ('The dateColumnName was not found in the CSV')):
      csvObj.getNextTick()
예제 #3
0
    def testUpdatePortfolio(self):
        """Test the ability to update option values for a position in the portfolio.
        """
        startingCapital = 1000000
        maxCapitalToUse = 0.5
        maxCapitalToUsePerTrade = 0.5
        portfolioObj = portfolio.Portfolio(self.startingCapital,
                                           self.maxCapitalToUse,
                                           self.maxCapitalToUsePerTrade)

        # Get an option chain from the CSV.
        # Create CsvData class object.
        dataProvider = 'iVolatility'
        directory = '/Users/msantoro/PycharmProjects/Backtester/marketData/iVolatility/SPX/SPX_2011_2017'
        filename = 'RawIV_5day_sample.csv'
        chunkSize = 10000
        eventQueue = queue.Queue()
        csvObj = csvData.CsvData(directory, filename, dataProvider, eventQueue,
                                 chunkSize)

        # Get the first option chain.
        firstOptionChainValid = csvObj.getOptionChain()
        queueObj = eventQueue.get(False)
        firstOptionChainData = queueObj.getData()

        # Choose two of the options in the first option chain to create a strangle; using first expiration.
        putObj = firstOptionChainData[217]  # -0.172245 delta put
        callObj = firstOptionChainData[248]  # 0.154042 delta call

        # Create strangle an add to portfolio.
        orderQuantity = 1
        strangleObj = strangle.Strangle(orderQuantity, callObj, putObj, "SELL")

        # Create signal event.
        event = signalEvent.SignalEvent()
        event.createEvent(strangleObj)

        # Create portfolio onSignal event, which adds the position to the portfolio.
        portfolioObj.onSignal(event)

        # Next, get the prices for the next day (1/4/11) and update the portfolio values.
        newOptionChainValid = csvObj.getOptionChain()
        tickEvent = eventQueue.get(False)

        # Update portfolio values.
        portfolioObj.updatePortfolio(tickEvent)

        # Check that the new portfolio values are correct (e.g., buying power, total delta, total gamma, etc).
        self.assertAlmostEqual(portfolioObj.getTotalBuyingPower(), 28950.0)
        self.assertAlmostEqual(portfolioObj.getVega(), 1.303171)
        self.assertAlmostEqual(portfolioObj.getDelta(), -0.018826)
        self.assertAlmostEqual(portfolioObj.getGamma(), 0.012173)
        self.assertAlmostEqual(portfolioObj.getTheta(), -0.583284)
        self.assertAlmostEqual(portfolioObj.getNetLiq(), 1000060.0)
예제 #4
0
    def __init__(self):

        # Create queue to hold events (ticks, signals, etc.).
        self.eventQueue = queue.Queue()

        # Create CsvData class object.
        dataProvider = 'iVolatility'
        directory = '/Users/msantoro/PycharmProjects/Backtester/marketData/iVolatility/SPX'
        filename = 'combinedCSV.csv'
        chunkSize = 10000
        self.dataHandler = csvData.CsvData(directory, filename, dataProvider, self.eventQueue, chunkSize)

        # Parameters for strangle strategy -- TODO: move params to file.
        optCallDelta = 0.16
        maxCallDelta = 0.30
        optPutDelta = -0.16
        maxPutDelta = -0.30
        startTime = datetime.now(pytz.utc)
        buyOrSell = 'SELL' # 'BUY' OR 'SELL'
        underlying = 'SPX'
        orderQuantity = 1
        expCycle = 'm' # monthly expiration
        daysBeforeClose = 5
        optimalDTE = 45
        minimumDTE = 25
        minCredit = 0.5
        profitTargetPercent = 0.5 # Close out strangle when at least 50% of initial credit has been collected.
        customManagement = False # Use special rules to manage trade.
        maxBidAsk = 15 # A general rule of thumb is to take 0.001*underlyingPrice.  Set to 15 to mostly ignore field.
        minDaysToEarnings = None
        minDaysSinceEarnings = None
        minIVR = None
        startingCapital = 1000000
        maxCapitalToUse = 0.5  # Up to 50% of net liq can be used in trades.
        self.maxCapitalToUsePerTrade = 0.10  # 10% max capital to use per trade / strategy.
        self.minBuyingPower = self.maxCapitalToUsePerTrade*startingCapital # Forced amount of capital to have in market
                                                                            # on one trade / strat (optional parameter).

        # Set up strategy (strangle strategy).
        self.strategyManager = strangleStrat.StrangleStrat(self.eventQueue, optCallDelta, maxCallDelta, optPutDelta,
                                                           maxPutDelta, startTime, buyOrSell, underlying,
                                                           orderQuantity, daysBeforeClose, expCycle=expCycle,
                                                           optimalDTE=optimalDTE, minimumDTE=minimumDTE,
                                                           minDaysToEarnings=minDaysToEarnings, minCredit=minCredit,
                                                           profitTargetPercent=profitTargetPercent,
                                                           customManagement=customManagement, maxBidAsk=maxBidAsk,
                                                           minDaysSinceEarnings=minDaysSinceEarnings, minIVR=minIVR,
                                                           minBuyingPower=self.minBuyingPower)
        # Set up portfolio.
        self.portfolioManager = portfolio.Portfolio(startingCapital, maxCapitalToUse, self.maxCapitalToUsePerTrade)
예제 #5
0
 def testCreateBaseType(self):
   """Tests that Put and Call objects are created successfully."""
   # First row in the sample data is a call, and second row is a put.
   eventQueue = queue.Queue()
   csvObj = csvData.CsvData(csvPath=self._filename, dataProvider=self._dataProvider, eventQueue=eventQueue)
   csvObj.getNextTick()
   optionChainObjs = eventQueue.get().getData()
   desiredCallAskPrice = decimal.Decimal(40.45)
   desiredPutAskPrice = decimal.Decimal(0.01)
   desiredStrikePrice = 55
   desiredUnderlyingTicker = 'AAPL'
   self.assertEqual(optionChainObjs[0].underlyingTicker, desiredUnderlyingTicker)
   self.assertEqual(optionChainObjs[0].strikePrice, desiredStrikePrice)
   self.assertEqual(optionChainObjs[1].underlyingTicker, desiredUnderlyingTicker)
   self.assertEqual(optionChainObjs[1].strikePrice, desiredStrikePrice)
   self.assertAlmostEqual(optionChainObjs[0].askPrice, desiredCallAskPrice)
   self.assertAlmostEqual(optionChainObjs[1].askPrice, desiredPutAskPrice)
예제 #6
0
  def __init__(self):
    # Create queue to hold events (ticks, signals, etc.).
    self.eventQueue = queue.Queue()

    # Create CsvData class object.
    dataProvider = 'iVolatility'
    filename = '/Users/msantoro/PycharmProjects/Backtester/marketData/iVolatility/SPX/combinedCSV.csv'
    self.dataHandler = csvData.CsvData(csvPath=filename, dataProvider=dataProvider, eventQueue=self.eventQueue)

    # Parameters for strangle strategy -- TODO: move params to file.
    optCallDelta = 0.16
    maxCallDelta = 0.30
    optPutDelta = -0.16
    maxPutDelta = -0.30
    startDateTime = datetime.now(pytz.utc)
    buyOrSell = optionPrimitive.TransactionType.SELL
    underlyingTicker = 'SPX'
    orderQuantity = 1
    expCycle = strategy.ExpirationTypes.MONTHLY
    optimalDTE = 45
    minimumDTE = 25
    minCredit = 0.5
    maxBidAsk = 15 # A general rule of thumb is to take 0.001*underlyingPrice.  Set to 15 to mostly ignore field.
    startingCapital = decimal.Decimal(1000000)
    maxCapitalToUse = 0.5  # Up to 50% of net liq can be used in trades.
    maxCapitalToUsePerTrade = 0.10  # 10% max capital to use per trade / strategy.
    minBuyingPower = decimal.Decimal(maxCapitalToUsePerTrade)*startingCapital

    # Set up strategy (strangle strategy) and risk management preference.
    riskManagement = strangleRiskManagement.StrangleRiskManagement(
      strangleRiskManagement.StrangleManagementStrategyTypes.HOLD_TO_EXPIRATION)
    self.strategyManager = strangleStrat.StrangleStrat(self.eventQueue, optCallDelta, maxCallDelta, optPutDelta,
                                                       maxPutDelta, startDateTime, buyOrSell, underlyingTicker,
                                                       orderQuantity, riskManagement, expCycle, optimalDTE,
                                                       minimumDTE, minCredit=minCredit, maxBidAsk=maxBidAsk,
                                                       minBuyingPower=minBuyingPower)
    # Set up portfolio.
    self.portfolioManager = portfolio.Portfolio(startingCapital, maxCapitalToUse, maxCapitalToUsePerTrade)
예제 #7
0
    def setUp(self):
        """Create instance of strangle strategy
    Strangle specific attributes:
      optCallDelta:  Optimal delta for call, usually around 16 delta.
      maxCallDelta:  Max delta for call, usually around 30 delta.
      optPutDelta:  Optimal delta for put, usually around 16 delta.
      maxPutDelta:  Max delta for put, usually around 30 delta.

    General strategy attributes:
      startDateTime:  Date/time to start the live trading or backtest.
      strategy:  Option strategy to use -- e.g., iron condor, strangle
      buyOrSell:  Do we buy an iron condor or sell an iron condor? 0 = buy, 1 = sell.
      underlying:  Which underlying to use for the strategy.
      orderQuantity:  Number of strangles, iron condors, etc.
      daysBeforeClose:  Number of days before expiration to close the trade.

    Optional attributes:
      expCycle:  Specifies if we want to do monthly ('m'); unspecified means we can do weekly, quarterly, etc.
      optimalDTE:  Optimal number of days before expiration to put on strategy.
      minimumDTE:  Minimum number of days before expiration to put on strategy.
      roc:  Minimal return on capital for overall trade as a decimal.
      minDaysToEarnings:  Minimum number of days to put on trade before earnings.
      minCredit:  Minimum credit to collect on overall trade.
      maxBuyingPower:  Maximum buying power to use on overall trade.
      profitTargetPercent:  Percentage of initial credit to use when closing trade.
      maxBidAsk:  Maximum price to allow between bid and ask prices of option (for any strike or put/call).
      maxMidDev:  Maximum deviation from midprice on opening and closing of trade (e.g., 0.02 cents from midprice).
      minDaysSinceEarnings:  Minimum number of days to wait after last earnings before putting on strategy.
      minIVR:  Minimum implied volatility rank needed to put on strategy.
    """
        # Use CSV data source to test.
        tickEventQueue = queue.Queue()
        dataProvider = 'iVolatility'
        filename = '/Users/msantoro/PycharmProjects/Backtester/sampleData/aapl_sample_ivolatility.csv'
        csvObj = csvData.CsvData(csvPath=filename,
                                 dataProvider=dataProvider,
                                 eventQueue=tickEventQueue)
        csvObj.getNextTick()
        self.optionChain = tickEventQueue.get()

        # Create strangle strategy object.
        self.signalEventQueue = queue.Queue()
        self.optCallDelta = 0.16
        self.maxCallDelta = 0.30
        self.optPutDelta = -0.16
        self.maxPutDelta = -0.30
        self.startDateTime = datetime.now(pytz.utc)
        self.buyOrSell = optionPrimitive.TransactionType.SELL
        self.underlyingTicker = 'AAPL'
        self.orderQuantity = 1
        self.riskManagement = strangleRiskManagement.StrangleRiskManagement(
            strangleRiskManagement.StrangleManagementStrategyTypes.
            HOLD_TO_EXPIRATION)
        self.expCycle = strangleStrat.strategy.ExpirationTypes.MONTHLY
        self.optimalDTE = 45
        self.minimumDTE = 25
        self.minimumROC = 0.001
        self.minCredit = 0.5
        self.maxBidAsk = 0.15
        self.minBuyingPower = None
        self.curStrategy = strangleStrat.StrangleStrat(
            self.signalEventQueue, self.optCallDelta, self.maxCallDelta,
            self.optPutDelta, self.maxPutDelta, self.startDateTime,
            self.buyOrSell, self.underlyingTicker, self.orderQuantity,
            self.riskManagement, self.expCycle, self.optimalDTE,
            self.minimumDTE, self.minimumROC, self.minCredit, self.maxBidAsk,
            self.minBuyingPower)
예제 #8
0
 def testOpenDataSourceInvalidDataProvider(self):
   """Tests that an exception is rasied if the requested data provider isn't in the config file."""
   with self.assertRaisesRegex(ValueError, ('The requested data provider: unknown_data_provider was not found in '
     'dataProviders.json')):
     csvData.CsvData(csvPath=self._filename, dataProvider='unknown_data_provider',
                     eventQueue=self._eventQueue)
예제 #9
0
 def testOpenDataSourceNoCSVFound(self):
   """Tests that an exception is raised when no CSV is found."""
   with self.assertRaisesRegex(OSError, 'Unable to open CSV at location: bad_path_name.'):
     csvData.CsvData(csvPath='bad_path_name', dataProvider=self._dataProvider,
                     eventQueue=self._eventQueue)