SERVING THE QUANTITATIVE FINANCE COMMUNITY

Cuchulainn
Posts: 61103
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

### Re: Python tricks

"Oranje boven" LOL

http://www.datasimfinancial.com
http://www.datasim.nl

Every Time We Teach a Child Something, We Keep Him from Inventing It Himself
Jean Piaget

ISayMoo
Posts: 2273
Joined: September 30th, 2015, 8:30 pm

### Re: Python tricks

As a Dutch patriot, you should be all over Python!

Cuchulainn
Posts: 61103
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

### Re: Python tricks

As a Dutch patriot, you should be all over Python!
I was the first Dutch C++ patriot in 1989. BTW I hate petty nationalism. The Danes, Norsemen and Swedes make better compilers!.
Last edited by Cuchulainn on August 16th, 2019, 1:52 pm, edited 1 time in total.
http://www.datasimfinancial.com
http://www.datasim.nl

Every Time We Teach a Child Something, We Keep Him from Inventing It Himself
Jean Piaget

Cuchulainn
Posts: 61103
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

### Re: Python tricks

One optimises a Python loop by removing the loop.
sum_x = 0
for x in xs:
sum_x += x
to
sum_x = sum(xs)
I agree.
However, my example is slightly different. I don't have a list 'xs' and my reduction variable is constructed differently.
http://www.datasimfinancial.com
http://www.datasim.nl

Every Time We Teach a Child Something, We Keep Him from Inventing It Himself
Jean Piaget

Cuchulainn
Posts: 61103
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

### Re: Python tricks

for i in range (1,NSIM):
VOld = S_0
for j in range (0,NT):
dW = random.normalvariate(0,1)
VNew = VOld + (dt*(r-d)*VOld) + (sqrk * sig*VOld * dW)
VOld = VNew
sumPriceT += Payoff(VNew, K)

price = math.exp(-r * T) * sumPriceT / NSIM
print(price)
What is needed is loop parallelism in Python and reduction variable (like a  OpenMP)
http://www.datasimfinancial.com
http://www.datasim.nl

Every Time We Teach a Child Something, We Keep Him from Inventing It Himself
Jean Piaget

ISayMoo
Posts: 2273
Joined: September 30th, 2015, 8:30 pm

### Re: Python tricks

As a Dutch patriot, you should be all over Python!
I was the first Dutch C++ patriot in 1989. BTW I hate petty nationalism. The Danes, Norsemen and Swedes make better compilers!.
You replaced nationalism by regionalism - or pan-scandinavism.

ISayMoo
Posts: 2273
Joined: September 30th, 2015, 8:30 pm

### Re: Python tricks

for i in range (1,NSIM):
VOld = S_0
for j in range (0,NT):
dW = random.normalvariate(0,1)
VNew = VOld + (dt*(r-d)*VOld) + (sqrk * sig*VOld * dW)
VOld = VNew
sumPriceT += Payoff(VNew, K)

price = math.exp(-r * T) * sumPriceT / NSIM
print(price)
What is needed is loop parallelism in Python and reduction variable (like a  OpenMP)
Use Numpy.
import random
import math
import numpy
import time

def pricerCuch(S_0, NSIM, NT, dt, r, d, sqrk, sig, T, K):
sumPriceT = 0
for i in range (1,NSIM):
VOld = S_0
for j in range (0,NT):
dW = random.normalvariate(0,1)
VNew = VOld + (dt*(r-d)*VOld) + (sqrk * sig*VOld * dW)
VOld = VNew
# Replaced Payoff by European call payoff.
sumPriceT += max(VNew - K, 0)
return math.exp(-r * T) * sumPriceT / NSIM

def pricerNumpy(S_0, NSIM, NT, dt, r, d, sqrk, sig, T, K):
V = numpy.full(NSIM, S_0)
for j in range (1,NT + 1):
dW = numpy.random.randn(NSIM)
V = V + (dt*(r-d)*V) + (sqrk * sig*V * dW)
sumPriceT = sum(numpy.maximum(V - K, 0))
return math.exp(-r * T) * sumPriceT / NSIM

S_0 = 5
K = 5
sig = 0.05
NT = 365
T = 1.
dt = T / NT
r = 0.01
NSIM = 10000
sqrk = math.sqrt(dt)
d = 0

time_start = time.time()
p = pricerCuch(S_0, NSIM, NT, dt, r, d, sqrk, sig, T, K)
time_end = time.time()
print('Price (Cuch) = {}, time = {}'.format(p, time_end - time_start))

time_start = time.time()
p = pricerNumpy(S_0, NSIM, NT, dt, r, d, sqrk, sig, T, K)
time_end = time.time()
print('Price (Numpy) = {}, time = {}'.format(p, time_end - time_start))

Price (Cuch) = 0.12632649206449126, time = 2.5915353298187256
Price (Numpy) = 0.1263925891096993, time = 0.06981277465820312

Cuchulainn
Posts: 61103
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

### Re: Python tricks

Nice! A good experiment would be to compare the respective functions wrt accuracy and performance and try to come up guidelines on 'best practices' (to use an awful phrase). I am leading up to PDE models from C++ to Python because using Python for PDE eases the transition for non-programmers.

BTW you use a hard-code payoff (not even a Payoff function). More generally, a wrapper pattern (FP style) function is good but I have not investigated performance.
http://www.datasimfinancial.com
http://www.datasim.nl

Every Time We Teach a Child Something, We Keep Him from Inventing It Himself
Jean Piaget

Cuchulainn
Posts: 61103
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

### Re: Python tricks

ISM. I have taken a couple,of your ideas on-board when porting C++ to Python for lattice models. The performance is quite good..
I have used while loops but I am sure if it breaks Python Scripture.
"""
# TestBarrierOptionPricerClassic.cpp
#
# Discussion example based on Clewlow and Strickland.
# The code is hard-wired and not flexible.
#
# Additive binomial valuation of an American down-and-out.
#
# (C) Datasim Education BV 2014-2018
#
"""
import random
import math
import numpy as np
import time

def price( K,  T,  S,  sig,  r,  N):	# N = Number of intervals

# Initialise coefficients based on the Trigeorgis approach
dt = T/N;
nu = r - 0.5*sig*sig;
# Up and down jumps
dxu = math.sqrt(sig*sig*dt + (nu*dt)*(nu*dt));
dxd = -dxu;

# Corresponding probabilities
pu = 0.5 + 0.5*(nu*dt/dxu);
pd = 1.0 - pu;

# Precompute constants
disc = math.exp(-r*dt)
dpu = disc*pu
dpd = disc*pd
edxud = math.exp(dxu - dxd)
edxd = math.exp(dxd)

# Initialise asset prices at maturity
St = np.full(N+1,0.0, dtype = float)
St[0] = S*math.exp(N*dxd)
for j in range(1,N+1):
St[j] = edxud*St[j-1]
print(St)
# Option value at maturity ( t = N)
C = np.full(N+1,0, dtype = float)
for j in range (0,N+1):
C[j] = np.maximum(K - St[j], 0.0)

print(C)
# Backwards induction phase
#  for i in range (N-1, 1, -1): ??
i = N-1
while i >= 0:
j = 0

while j <= i:
C[j] = dpd*C[j] + dpu*C[j+1]
St[j] = St[j]/edxd;

# Early exercise condition, Brennan Schwartz condition
C[j] = np.maximum(C[j], K - St[j])

j = j+1
i = i -1
# Early exercise down and out call

return C[0]

# Null test
K = 65.0;
S = 60.0;
T = 0.25;
r = 0.08;
q = 0.0;
sig = 0.3;

N= 800

optionPrice = price(K,T,S,sig,r,N)

print(optionPrice)


http://www.datasimfinancial.com
http://www.datasim.nl

Every Time We Teach a Child Something, We Keep Him from Inventing It Himself
Jean Piaget

ISayMoo
Posts: 2273
Joined: September 30th, 2015, 8:30 pm

### Re: Python tricks

Nice! A good experiment would be to compare the respective functions wrt accuracy and performance and try to come up guidelines on 'best practices' (to use an awful phrase).
It's the same algorithm, so the accuracy should be the same. You can calculate the sample variance if you want.
BTW you use a hard-code payoff (not even a Payoff function).
Yes, for clarity of illustration. It's just a pedagogical example.

ISayMoo
Posts: 2273
Joined: September 30th, 2015, 8:30 pm

### Re: Python tricks

BTW, you will probably be able to simplify and speed up the code more if you evolve log S instead of S.

Cuchulainn
Posts: 61103
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

### Re: Python tricks

Nice! A good experiment would be to compare the respective functions wrt accuracy and performance and try to come up guidelines on 'best practices' (to use an awful phrase).
It's the same algorithm, so the accuracy should be the same. You can calculate the sample variance if you want.
BTW you use a hard-code payoff (not even a Payoff function).
Yes, for clarity of illustration. It's just a pedagogical example.
It's just that Payoff() introduces another level of indirection.
http://www.datasimfinancial.com
http://www.datasim.nl

Every Time We Teach a Child Something, We Keep Him from Inventing It Himself
Jean Piaget

ISayMoo
Posts: 2273
Joined: September 30th, 2015, 8:30 pm

### Re: Python tricks

I removed it from both functions.

Cuchulainn
Posts: 61103
Joined: July 16th, 2004, 7:38 am
Location: Amsterdam
Contact:

### Re: Python tricks

I removed it from both functions.
OK.
On a follow-on question, how many (newbie?) Python programmers fall to the temptation of "Copy and Paste" syndrome. Exhibit I is

I was actually working closely with one such wunderkind for about 3 years. On some sad cases, he was granted an honour to build production-critical programs, despite of my kindest type of warnings to our closest supervisors (who were also - surprise: XYZ). When the landscape (data and the source) around his program was modified even a bit, he started to show some colour on his face. Processing reports using his program took longer and longer due to the fact, that his program was massively hard-coded (program structure and variable initialization). Needless to say, he had never heard about Strategy or Builder patterns. My kind attempts to get him to use XML or JSON as some sort of platform for changing configurations were crudely ignored without any response. “What the ,expletive, this guy could know, since he is not applied mathematician” was the implied message. At the “terminal stage” of this death star program, instead of having program built on different set of changing configurations, this guy had 36 different hard-coded programs (I am not kidding) - one for each of our swap counterparty. The issues we experienced after this point, I do not need to describe here since you already know what happened. Last year (after the guy left the ruins for greener pastures), my supervisors (who are XYZ), asked me to “check that program and improve it for production purposes”. Happy Ending with a twist.
http://www.datasimfinancial.com
http://www.datasim.nl

Every Time We Teach a Child Something, We Keep Him from Inventing It Himself
Jean Piaget

ISayMoo
Posts: 2273
Joined: September 30th, 2015, 8:30 pm

### Re: Python tricks

I once worked with a guy who was getting red in the face whenever someone modified anything touching his code, or even asked questions about it. Later it turned out that he copy&pasted code stolen from his previous employer into our codebase. He was kindly asked to submit his resignation. Now he's a senior developer in a Tier 1 bank, of course.