Succumbing to the Python in Financial Markets

12
Succumbing to Python in the Financial Markets David Cerezo Sánchez http://cerezo.name

description

 

Transcript of Succumbing to the Python in Financial Markets

Succumbing to Python in the Financial Markets

David Cerezo Sánchezhttp://cerezo.name

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 2

Python Advantages & Drawbacks

Interactive, expressiveness: very quick prototypingReduced development cycle: C++/Python=10:1Time distribution in algorithmic trading (25% devising new strategies; 25% coding; 50% model fine-tuning and code maintenance): Python improvements impact 75% of developmentFree, nonproprietary (vs. Matlab, TradeStation,…)Multi-threading from Python 3.2!SEC mandating cashflow disclosure of ABS securities in PythonDynamic, not strongly typed (Java): errors at runtime!

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 3

Must-Have Python Financial Packages

IbPy: Interactive Brokers Python APIultra-finance, MarWiz, pyfinancial, profitpy, QSToolKit: algorithmic trading librariesQuantlib-python: quantitative finance libraryNumPy, SciPy, PyIMSL: computational, scientific, numerical libraries xlrd: extract data from .xls/.xlsx filesRPy2: wrapper to R, allows R function execution within Python

Code Samples

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 5

Combo Orders with IbPy# define the contract for each legshortContract= makeOptContract(‘MSFT', '', 26, '')longContract= makeOptContract(‘AAPL', '', 350, '')

# instantiate each legshortLeg= makeComboLeg(getConId(1,shortContract), 'SELL', 1)longLeg= makeComboLeg(getConId(2,longContract), 'BUY', 1)

# build a bag with these legscalendarBagContract= makeBagContract(‘MSFT', [shortLeg, longLeg])

# build order to buy 1 spread at $0.5buyOrder= makeOrder(‘BUY', 26, 0.5)

# buy! buy! buy!con.placeOrder(nextOrderId, calendarBagContract, buyOrder)

# watch the messages for a bitsleep(100)

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 6

Basket Options with Quantlib_python# Dates, risk-free rate & option parameterstodaysDate = Date(8,May,2011); Settings.instance().evaluationDate = todaysDatesettlementDate = Date(12,May,2011); riskFreeRate = FlatForward(settlementDate, 0.06, Actual365Fixed())exercise = EuropeanExercise(Date(12,May,2011)); payoff = PlainVanillaPayoff(Option.Call, 10.0)

# Market dataunderlying1 = SimpleQuote(8.0); volatility1 = BlackConstantVol(todaysDate, TARGET(), 0.12, Actual365Fixed())dividendYield1 = FlatForward(settlementDate, 0.06, Actual365Fixed())underlying2 = SimpleQuote(8.0); volatility2 = BlackConstantVol(todaysDate, TARGET(), 0.12, Actual365Fixed())dividendYield2 = FlatForward(settlementDate, 0.06, Actual365Fixed())

process1 = BlackScholesMertonProcess(QuoteHandle(underlying1), YieldTermStructureHandle(dividendYield1), YieldTermStructureHandle(riskFreeRate), BlackVolTermStructureHandle(volatility1))

process2 = BlackScholesMertonProcess(QuoteHandle(underlying2), YieldTermStructureHandle(dividendYield2), YieldTermStructureHandle(riskFreeRate), BlackVolTermStructureHandle(volatility2))

procs = StochasticProcessVector(); procs.push_back(process1); procs.push_back(process2)

matrix = Matrix(2,2); matrix[0][0] = 1.0; matrix[1][1] = 1.0; matrix[0][1] = 0.5; matrix[1][0] = 0.5

process = StochasticProcessArray(procs, matrix)basketoption = BasketOption(AverageBasketPayoff(payoff, 2), exercise)basketoption.setPricingEngine(MCEuropeanBasketEngine(process,'lowdiscrepancy ',timeSteps= 1,requiredSamples =65536))print basketoption.NPV()

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 7

Bermuda Swaption with Quantlib_pythonswaptionVols = [ (Period(1, Years), Period(5, Years), 0.12), (Period(2, Years), Period(4, Years), 0.11), (Period(3, Years), Period(3, Years), 0.10), (Period(4, Years), Period(2, Years), 0.09), (Period(5, Years), Period(1, Years), 0.08) ]todaysDate = Date(8,May,2011); Settings.instance().evaluationDate = todaysDate; calendar = TARGET(); settlementDate = Date(12,May,2011);rate = QuoteHandle(SimpleQuote(0.05)); termStructure = YieldTermStructureHandle(FlatForward(settlementDate,rate,Actual365Fixed()))

fixedLegFrequency = Annual; fixedLegTenor = Period(1,Years); fixedLegConvention = Unadjusted; floatingLegConvention = ModifiedFollowing;fixedLegDayCounter = Thirty360(Thirty360.European); floatingLegFrequency = Semiannual; floatingLegTenor = Period(6,Months)payFixed = VanillaSwap.Payer; fixingDays = 2; index = Euribor6M(termStructure); floatingLegDayCounter = index.dayCounter()swapStart = calendar.advance(settlementDate,1,Years,floatingLegConvention); swapEnd = calendar.advance(swapStart,5,Years,floatingLegConvention)fixedSchedule = Schedule(swapStart, swapEnd, fixedLegTenor, calendar, fixedLegConvention, fixedLegConvention, DateGeneration.Forward, False)floatingSchedule = Schedule(swapStart, swapEnd, floatingLegTenor, calendar, floatingLegConvention, floatingLegConvention, DateGeneration.Forward, False)dummy = VanillaSwap(payFixed, 100.0,fixedSchedule, 0.0, fixedLegDayCounter,floatingSchedule, index, 0.0, floatingLegDayCounter)swapEngine = DiscountingSwapEngine(termStructure); dummy.setPricingEngine(swapEngine);atmRate = dummy.fairRate()atmSwap = VanillaSwap(payFixed, 1000.0,fixedSchedule, atmRate, fixedLegDayCounter,floatingSchedule, index, 0.0,floatingLegDayCounter)otmSwap = VanillaSwap(payFixed, 1000.0,fixedSchedule, atmRate*1.4, fixedLegDayCounter,floatingSchedule, index, 0.0,floatingLegDayCounter)itmSwap = VanillaSwap(payFixed, 1000.0,fixedSchedule, atmRate*0.6, fixedLegDayCounter,floatingSchedule, index, 0.0,floatingLegDayCounter)atmSwap.setPricingEngine(swapEngine);otmSwap.setPricingEngine(swapEngine);itmSwap.setPricingEngine(swapEngine)

helpers = [ SwaptionHelper(maturity, length,QuoteHandle(SimpleQuote(vol)),index, index.tenor(), index.dayCounter(),index.dayCounter(), termStructure) for maturity, length, vol in swaptionVols ]times = dict([(t,1) for t in h.times() for h in helpers])times = times.keys(); times.sort(); grid = TimeGrid(times, 30); BKmodel = BlackKarasinski(termStructure)for h in helpers: h.setPricingEngine(TreeSwaptionEngine(BKmodel,grid))calibrate(BKmodel, helpers, 0.05);bermudanDates = [ d for d in fixedSchedule ][:-1]; exercise = BermudanExercise(bermudanDates)atmSwaption = Swaption(atmSwap, exercise);otmSwaption = Swaption(otmSwap, exercise);itmSwaption = Swaption(itmSwap, exercise)tse=TreeSwaptionEngine(BKmodel, 50); atmSwaption.setPricingEngine(tse);otmSwaption.setPricingEngine(tse);itmSwaption.setPricingEngine(tse)print ('Black-Karasinski numerical', itmSwaption.NPV(), atmSwaption.NPV(), otmSwaption.NPV())

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 8

Fast implementation Investment Strategies

“Portable Alphas from Pension Mispricing”, Journal of Portfolio Management, Summer 2006, 44-53

Pure alpha strategy1.51% (monthly), S=0.26Just 200 lines of Python:

Heavy use of map, reduce, filter, lambdaSciPy: OLSscikits.timeseriesEasier to implement using RPy2 (R wrapper)

What lies ahead…

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 10

Substitutes vs Complements Paradox

Quant/algo trading focused at human trader substitution, but…Moravec’s Paradox: Computer’s excel where humans are weak, and vice versa Vg. Advanced Chess (Computer-Augmented Chess Playing): computer chess programs allowed at human competitions

Computers better at brute-force position evaluation, opening and endgame databases, transposition and refutation tables… Respect human common sense and judgmentPromoted by top players: Kasparov, Anand, Topalov, …

Computer-assisted Playchess.com Freestyle Chess 2005 Tournament:

Amateurs+computers+better process >> specialized chess supercomputers >> grandmasters+computer+inferior process

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 11

Backtesting vs. Forward Testing

Why do people love backtesting so much? overfitted model calibrations will always prove their strategies to have very high alpha&Sharpe ratioWith hindsight, everyone’s a winner

In HFT/algo/quant trading, forward testing should be the golden standard:

Extremely fast changing market conditionsReverse-engineered strategies that stop working

David Cerezo Sánchez http://cerezo.name

Succumbing to Python in the Financial Markets 12

Market Microstructure

Don’t forget about optimal execution sizes!

Or expected trading costs given trading volume and volatility!