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

Succumbing to the Python in Financial Markets

  • Author
    dcerezo

  • View
    9.542

  • Download
    59

Embed Size (px)

DESCRIPTION

 

Text of Succumbing to the Python in Financial Markets

 Succumbing to Python in the Financial MarketsDavid Cerezo Snchezhttp://cerezo.name Python Advantages & DrawbacksInteractive, 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! Must-Have Python Financial PackagesIbPy: 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 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) 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.5process = StochasticProcessArray(procs, matrix)basketoption = BasketOption(AverageBasketPayoff(payoff, 2), exercise)basketoption.setPricingEngine(MCEuropeanBasketEngine(process,'lowdiscrepancy ',timeSteps= 1,requiredSamples =65536))print basketoption.NPV() 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()) Fast implementation Investment StrategiesPortable Alphas from Pension Mispricing, Journal of Portfolio Management, Summer 2006, 44-53Pure 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 Substitutes vs Complements ParadoxQuant/algo trading focused at human trader substitution, butMoravecs Paradox: Computers excel where humans are weak, and vice versa Vg. Advanced Chess (Computer-Augmented Chess Playing): computer chess programs allowed at human competitionsComputers 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 Backtesting vs. Forward TestingWhy do people love backtesting so much? overfitted model calibrations will always prove their strategies to have very high alpha&Sharpe ratioWith hindsight, everyones a winnerIn HFT/algo/quant trading, forward testing should be the golden standard:Extremely fast changing market conditionsReverse-engineered strategies that stop working Market MicrostructureDont forget about optimal execution sizes!Or expected trading costs given trading volume and volatility!