Succumbing to the Python in Financial Markets
Post on 17-Aug-2014
8.585 views
DESCRIPTION
TRANSCRIPT
- Succumbing to Python in the Financial Markets
David Cerezo Snchez
http://cerezo.name - 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
sleep(100) - 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)
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 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
scikits.timeseries
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 Playchess.com 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!
Recommended
FINANCIAL MARKETS IN RECOVERY - Civic Research Markets in... FINANCIAL MARKETS IN RECOVERY ... Staff