Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Succumbing to the Python in Financial Markets


Published on

Published in: Technology, Economy & Finance

Succumbing to the Python in Financial Markets

  1. 1. Succumbing to Python in the Financial Markets<br />David Cerezo Sánchez<br /><br />
  2. 2. Python Advantages & Drawbacks<br />Interactive, expressiveness: very quick prototyping<br />Reduced development cycle: C++/Python=10:1<br />Time distribution in algorithmic trading (25% devising new strategies; 25% coding; 50% model fine-tuning and code maintenance): Python improvements impact 75% of development<br />Free, nonproprietary (vs. Matlab, TradeStation,…)<br />Multi-threading from Python 3.2!<br />SEC mandating cashflow disclosure of ABS securities in Python<br />Dynamic, not strongly typed (Java): errors at runtime!<br />
  3. 3. Must-Have Python Financial Packages<br />IbPy: Interactive Brokers Python API<br />ultra-finance, MarWiz, pyfinancial, profitpy, QSToolKit: algorithmic trading libraries<br />Quantlib-python: quantitative finance library<br />NumPy, SciPy, PyIMSL: computational, scientific, numerical libraries <br />xlrd: extract data from .xls/.xlsx files<br />RPy2: wrapper to R, allows R function execution within Python<br />
  4. 4. Code Samples<br />
  5. 5. Combo Orders with IbPy<br /># define the contract for each leg<br />shortContract= makeOptContract(‘MSFT', '', 26, '')<br />longContract= makeOptContract(‘AAPL', '', 350, '')<br /># instantiate each leg<br />shortLeg= makeComboLeg(getConId(1,shortContract), 'SELL', 1)<br />longLeg= makeComboLeg(getConId(2,longContract), 'BUY', 1)<br /># build a bag with these legs<br />calendarBagContract= makeBagContract(‘MSFT', [shortLeg, longLeg])<br /># build order to buy 1 spread at $0.5<br />buyOrder= makeOrder(‘BUY', 26, 0.5)<br /># buy! buy! buy!<br />con.placeOrder(nextOrderId, calendarBagContract, buyOrder)<br /># watch the messages for a bit<br />sleep(100)<br />
  6. 6. Basket Options with Quantlib_python<br /># Dates, risk-free rate & option parameters<br />todaysDate = Date(8,May,2011); Settings.instance().evaluationDate = todaysDate<br />settlementDate = Date(12,May,2011); riskFreeRate = FlatForward(settlementDate, 0.06, Actual365Fixed())<br />exercise = EuropeanExercise(Date(12,May,2011)); payoff = PlainVanillaPayoff(Option.Call, 10.0)<br /># Market data<br />underlying1 = SimpleQuote(8.0); volatility1 = BlackConstantVol(todaysDate, TARGET(), 0.12, Actual365Fixed())<br />dividendYield1 = FlatForward(settlementDate, 0.06, Actual365Fixed())<br />underlying2 = SimpleQuote(8.0); volatility2 = BlackConstantVol(todaysDate, TARGET(), 0.12, Actual365Fixed())<br />dividendYield2 = FlatForward(settlementDate, 0.06, Actual365Fixed())<br />process1 = BlackScholesMertonProcess(QuoteHandle(underlying1), YieldTermStructureHandle(dividendYield1),<br /> YieldTermStructureHandle(riskFreeRate), BlackVolTermStructureHandle(volatility1))<br />process2 = BlackScholesMertonProcess(QuoteHandle(underlying2), YieldTermStructureHandle(dividendYield2),<br /> YieldTermStructureHandle(riskFreeRate), BlackVolTermStructureHandle(volatility2))<br />procs = StochasticProcessVector(); procs.push_back(process1); procs.push_back(process2)<br />matrix = Matrix(2,2); matrix[0][0] = 1.0; matrix[1][1] = 1.0; matrix[0][1] = 0.5; matrix[1][0] = 0.5<br />process = StochasticProcessArray(procs, matrix)<br />basketoption = BasketOption(AverageBasketPayoff(payoff, 2), exercise)<br />basketoption.setPricingEngine(MCEuropeanBasketEngine(process,'lowdiscrepancy ',timeSteps= 1,requiredSamples =65536))<br />print basketoption.NPV()<br />
  7. 7. Bermuda Swaption with Quantlib_python<br />swaptionVols = [ (Period(1, Years), Period(5, Years), 0.12), (Period(2, Years), Period(4, Years), 0.11), (Period(3, Years), Period(3, Years), 0.10),<br /> (Period(4, Years), Period(2, Years), 0.09), (Period(5, Years), Period(1, Years), 0.08) ]<br />todaysDate = Date(8,May,2011); Settings.instance().evaluationDate = todaysDate; calendar = TARGET(); settlementDate = Date(12,May,2011);<br />rate = QuoteHandle(SimpleQuote(0.05)); termStructure = YieldTermStructureHandle(FlatForward(settlementDate,rate,Actual365Fixed()))<br />fixedLegFrequency = Annual; fixedLegTenor = Period(1,Years); fixedLegConvention = Unadjusted; floatingLegConvention = ModifiedFollowing;<br />fixedLegDayCounter = Thirty360(Thirty360.European); floatingLegFrequency = Semiannual; floatingLegTenor = Period(6,Months)<br />payFixed = VanillaSwap.Payer; fixingDays = 2; index = Euribor6M(termStructure); floatingLegDayCounter = index.dayCounter()<br />swapStart = calendar.advance(settlementDate,1,Years,floatingLegConvention); swapEnd = calendar.advance(swapStart,5,Years,floatingLegConvention)<br />fixedSchedule = Schedule(swapStart, swapEnd, fixedLegTenor, calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Forward, False)<br />floatingSchedule = Schedule(swapStart, swapEnd, floatingLegTenor, calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Forward, False)<br />dummy = VanillaSwap(payFixed, 100.0,fixedSchedule, 0.0, fixedLegDayCounter,floatingSchedule, index, 0.0, floatingLegDayCounter)<br />swapEngine = DiscountingSwapEngine(termStructure); dummy.setPricingEngine(swapEngine);atmRate = dummy.fairRate()<br />atmSwap = VanillaSwap(payFixed, 1000.0,fixedSchedule, atmRate, fixedLegDayCounter,floatingSchedule, index, 0.0,floatingLegDayCounter)<br />otmSwap = VanillaSwap(payFixed, 1000.0,fixedSchedule, atmRate*1.4, fixedLegDayCounter,floatingSchedule, index, 0.0,floatingLegDayCounter)<br />itmSwap = VanillaSwap(payFixed, 1000.0,fixedSchedule, atmRate*0.6, fixedLegDayCounter,floatingSchedule, index, 0.0,floatingLegDayCounter)<br />atmSwap.setPricingEngine(swapEngine);otmSwap.setPricingEngine(swapEngine);itmSwap.setPricingEngine(swapEngine)<br />helpers = [ SwaptionHelper(maturity, length,QuoteHandle(SimpleQuote(vol)),index, index.tenor(), index.dayCounter(),index.dayCounter(), termStructure) <br /> for maturity, length, vol in swaptionVols ]<br />times = dict([(t,1) for t in h.times() for h in helpers])<br />times = times.keys(); times.sort(); grid = TimeGrid(times, 30); BKmodel = BlackKarasinski(termStructure)<br />for h in helpers:<br /> h.setPricingEngine(TreeSwaptionEngine(BKmodel,grid))<br />calibrate(BKmodel, helpers, 0.05);bermudanDates = [ d for d in fixedSchedule ][:-1]; exercise = BermudanExercise(bermudanDates)<br />atmSwaption = Swaption(atmSwap, exercise);otmSwaption = Swaption(otmSwap, exercise);itmSwaption = Swaption(itmSwap, exercise)<br />tse=TreeSwaptionEngine(BKmodel, 50); atmSwaption.setPricingEngine(tse);otmSwaption.setPricingEngine(tse);itmSwaption.setPricingEngine(tse)<br />print ('Black-Karasinski numerical', itmSwaption.NPV(), atmSwaption.NPV(), otmSwaption.NPV())<br />
  8. 8. Fast implementation Investment Strategies<br />“Portable Alphas from Pension Mispricing”, Journal of Portfolio Management, Summer 2006, 44-53<br />Pure alpha strategy<br />1.51% (monthly), S=0.26<br />Just 200 lines of Python:<br />Heavy use of map, reduce, filter, lambda<br />SciPy: OLS<br />scikits.timeseries<br />Easier to implement using RPy2 (R wrapper)<br />
  9. 9. What lies ahead…<br />
  10. 10. Substitutes vs Complements Paradox<br />Quant/algo trading focused at human trader substitution, but…<br />Moravec’s Paradox: Computer’s excel where humans are weak, and vice versa <br />Vg. Advanced Chess (Computer-Augmented Chess Playing): computer chess programs allowed at human competitions<br />Computers better at brute-force position evaluation, opening and endgame databases, transposition and refutation tables… <br />Respect human common sense and judgment<br />Promoted by top players: Kasparov, Anand, Topalov, …<br />Computer-assisted Freestyle Chess 2005 Tournament:<br />Amateurs+computers+better process >> specialized chess supercomputers >> grandmasters+computer+inferior process<br />
  11. 11. Backtesting vs. Forward Testing<br />Why do people love backtesting so much? <br />overfitted model calibrations will always prove their strategies to have very high alpha&Sharpe ratio<br />With hindsight, everyone’s a winner<br />In HFT/algo/quant trading, forward testing should be the golden standard:<br />Extremely fast changing market conditions<br />Reverse-engineered strategies that stop working<br />
  12. 12. Market Microstructure<br />Don’t forget about optimal execution sizes!<br />Or expected trading costs given trading volume and volatility!<br />