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)
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()
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)
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)
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)
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)
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)
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)
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)