Succumbing to the Python in Financial Markets

Download Succumbing to the Python in Financial Markets

Post on 17-Aug-2014




21 download




  • Succumbing to Python in the Financial Markets
    David Cerezo Snchez
  • Python Advantages & Drawbacks
    Interactive, expressiveness: very quick prototyping
    Reduced development cycle: C++/Python=10:1
    Time distribution in algorithmic trading (25% devising new strategies; 25% coding; 50% model fine-tuning and code maintenance): Python improvements impact 75% of development
    Free, nonproprietary (vs. Matlab, TradeStation,)
    Multi-threading from Python 3.2!
    SEC mandating cashflow disclosure of ABS securities in Python
    Dynamic, not strongly typed (Java): errors at runtime!
  • Must-Have Python Financial Packages
    IbPy: Interactive Brokers Python API
    ultra-finance, MarWiz, pyfinancial, profitpy, QSToolKit: algorithmic trading libraries
    Quantlib-python: quantitative finance library
    NumPy, SciPy, PyIMSL: computational, scientific, numerical libraries
    xlrd: extract data from .xls/.xlsx files
    RPy2: wrapper to R, allows R function execution within Python
  • Code Samples
  • Combo Orders with IbPy
    # define the contract for each leg
    shortContract= makeOptContract(MSFT', '', 26, '')
    longContract= makeOptContract(AAPL', '', 350, '')
    # instantiate each leg
    shortLeg= makeComboLeg(getConId(1,shortContract), 'SELL', 1)
    longLeg= makeComboLeg(getConId(2,longContract), 'BUY', 1)
    # build a bag with these legs
    calendarBagContract= makeBagContract(MSFT', [shortLeg, longLeg])
    # build order to buy 1 spread at $0.5
    buyOrder= makeOrder(BUY', 26, 0.5)
    # buy! buy! buy!
    con.placeOrder(nextOrderId, calendarBagContract, buyOrder)
    # watch the messages for a bit
  • Basket Options with Quantlib_python
    # Dates, risk-free rate & option parameters
    todaysDate = Date(8,May,2011); Settings.instance().evaluationDate = todaysDate
    settlementDate = Date(12,May,2011); riskFreeRate = FlatForward(settlementDate, 0.06, Actual365Fixed())
    exercise = EuropeanExercise(Date(12,May,2011)); payoff = PlainVanillaPayoff(Option.Call, 10.0)
    # Market data
    underlying1 = 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()
  • Bermuda Swaption with Quantlib_python
    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),
    (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)
    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:
    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 Strategies
    Portable Alphas from Pension Mispricing, Journal of Portfolio Management, Summer 2006, 44-53
    Pure alpha strategy
    1.51% (monthly), S=0.26
    Just 200 lines of Python:
    Heavy use of map, reduce, filter, lambda
    SciPy: OLS
    Easier to implement using RPy2 (R wrapper)
  • What lies ahead
  • Substitutes vs Complements Paradox
    Quant/algo trading focused at human trader substitution, but
    Moravecs Paradox: Computers 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 judgment
    Promoted by top players: Kasparov, Anand, Topalov,
    Computer-assisted Freestyle Chess 2005 Tournament:
    Amateurs+computers+better process >> specialized chess supercomputers >> grandmasters+computer+inferior process
  • 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 ratio
    With hindsight, everyones a winner
    In HFT/algo/quant trading, forward testing should be the golden standard:
    Extremely fast changing market conditions
    Reverse-engineered strategies that stop working
  • Market Microstructure
    Dont forget about optimal execution sizes!
    Or expected trading costs given trading volume and volatility!


View more >