0

I have the following code which works perfect:

    from __future__ import division
    from math import log, sqrt
    from scipy.stats import norm
    from datetime import datetime

    #Default values used for testing
    s1 = 10; s2 = 20
    sigma1 = 1.25; sigma2 = 1.45
    t = 0.5; rho = 0.89
    rate=0.05; y=0; k0 = 0.000001

    sigma = lambda sig1=sigma1, sig2=sigma2, corr=rho: sqrt(sig1**2+sig2**2 -2*corr*sig1*sig2)
    m_d1 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: (log(stock1/stock2)+1/2*sigma()**2*time)/(sigma()*sqrt(time))
    m_d2 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: m_d1() -sigma()*sqrt(time)
    m_delta1 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: norm.cdf(m_d1())
    m_delta2 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: -norm.cdf(m_d2())
    m_gamma11 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: norm.pdf(m_d1())/(stock1*sigma()*sqrt(time))
    m_gamma22 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: norm.pdf(m_d2())/(stock2*sigma()*sqrt(time))
    m_gamma12 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho:-norm.pdf(m_d1())/(stock2*sigma()*sqrt(time))
    m_theta = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: -stock1*sigma()*norm.pdf(m_d1())/(2*sqrt(time))
    m_vega1 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: stock1*sqrt(t)*norm.pdf(m_d1())*((sig1-(corr*sig2))/sigma())
    m_vega2 = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: stock1*sqrt(t)*norm.pdf(m_d1())*((sig2-(corr*sig1))/sigma()) 
    m_correlation = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: -stock1*sqrt(t)*norm.pdf(m_d1())*((sig1*sig2)/sigma()) 
    m_margrabe = lambda stock1=s1, stock2=s2, sig1=sigma1, sig2=sigma2, time=t, corr=rho: stock1*norm.cdf(m_d1())-stock2*norm.cdf(m_d2())

    print "Margrabe = "+str(m_margrabe()) + "\n"
    print "THE GREEKS \n"
    print "Delta Asset 1 = "+str(m_delta1())
    print "Delta Stock 2 = "+str(m_delta2()) +"\n"
    print "Gamma Asset 11 = "+str(m_gamma11())
    print "Gamma Stock 12 = "+str(m_gamma12())
    print "Gamma Stock 22 = "+str(m_gamma22()) + "\n"
    print "Theta = "+str(m_theta()) +"\n"
    print "Vega sigma 1 = "+str(m_vega1())
    print "Vega sigma 2 = "+str(m_vega2()) + "\n"
    print "Correlation = "+str(m_correlation()) + "\n"

It works perfect, but now I want to see how long my computer takes to run this program. So after googling the problem I found 2 alternatives:

1) from timeit import Timer . and in the part where I print the results, I added:

    print "Margrabe = "+str(m_margrabe()) +"\n"
    t1 = Timer(lambda: m_margrabe()).timeit(number=1)
    print "THE GREEKS \n"
    print "Delta Asset 1 = "+str(m_delta1())
    t2 = Timer(lambda: m_delta1()).timeit(number=1)
    print "Delta Stock 2 = "+str(m_delta2()) +"\n"
    t3 = Timer(lambda: m_delta2()).timeit(number=1)
    print "Gamma Asset 11 = "+str(m_gamma11())
    t4 = Timer(lambda: m_gamma11()).timeit(number=1)
    print "Gamma Stock 12 = "+str(m_gamma12())
    t5 = Timer(lambda: m_gamma12()).timeit(number=1)
    print "Gamma Stock 22 = "+str(m_gamma22()) +"\n"
    t6 = Timer(lambda: m_gamma22()).timeit(number=1)
    print "Theta = "+str(m_theta()) + "\n"
    t7 = Timer(lambda: m_theta()).timeit(number=1)
    print "Vega sigma 1 = "+str(m_vega1())
    t8 = Timer(lambda: m_vega1()).timeit(number=1)
    print "Vega sigma 2 = "+str(m_vega2()) +"\n"
    t9 = Timer(lambda: m_vega2()).timeit(number=1)
    print "Correlation = "+str(m_correlation()) + "\n"
    t10 = Timer(lambda: m_correlation()).timeit(number=1)
    print "Running Time = " + str(t1+t2+t3+t4+t5+t6+t7+t8+t9+t10)

this works fine: I get Running Time = 0.00682769470029

2)from datetime import datetime and:

    startTime = datetime.now()
    # Same code as before"
    print(datetime.now()-startTime)

This also works fine and i get: 0:00:00.010000

My question is: Why are both methods different? Why do I get a different result? Is there a way to do this "calculating the running time" in one line?

Thank you

UPDATE:

    def printit():  
        print "Margrabe = "+str(m_margrabe()) + "\n"
        print "THE GREEKS \n"
        print "Delta Asset 1 = "+str(m_delta1())
        print "Delta Stock 2 = "+str(m_delta2()) +"\n"
        print "Gamma Asset 11 = "+str(m_gamma11())
        print "Gamma Stock 12 = "+str(m_gamma12())
        print "Gamma Stock 22 = "+str(m_gamma22()) + "\n"
        print "Theta = "+str(m_theta()) +"\n"
        print "Vega sigma 1 = "+str(m_vega1())
        print "Vega sigma 2 = "+str(m_vega2()) + "\n"
        print "Correlation = "+str(m_correlation()) + "\n"


    if __name__=='__main__':
        printit()

So on i can type (my file is saved as time1.py)

    python -m timeit -s "import time1; time1.main()"

but i get an error: "Attribute Error: 'module' object has no attribute 'main'

Oniropolo
  • 879
  • 2
  • 12
  • 18
  • for #2) using ``import time; time.time()`` would be better than ``datetime`` – sotapme Feb 12 '13 at 21:04
  • Michael Foukarkis suggested I time it using the command line. So I put my printings in a separate function, and i called that function from the main. But clearly im doing it wrong. I also tried to call all the functions from the main, but i get the same error. Help me! – Oniropolo Feb 12 '13 at 22:00
  • That's because it's not called ``main`` you called it ``printit`` - ``python -m timeit -s "import time1; time1.printit()`` - works for me. – sotapme Feb 12 '13 at 22:09
  • ``python -m timeit -r 1 -n 1 -s "import time1; time1.printit()"`` may work better if you just want it timed once - esp. with all those print statements. – sotapme Feb 12 '13 at 22:16
  • OHHHHH silly me. One more tiny question: can i run the loop 50 times? Would it be python -m timeit -s -50 "import time1; time1.printit()" ? I tried but i get " 10 loops " – Oniropolo Feb 12 '13 at 22:31
  • Oh got you! repeat the statement once, execute each statement once. Wouldnt only -n 1 suffice? – Oniropolo Feb 12 '13 at 22:33

1 Answers1

2

You don't need to instrument or change anything in your program to measure it. From the command line,

python -m timeit -s "import mymodule; mymodule.main()"

will tell you the running time of your module's main(). Modify the statement to measure exactly what you need.

The difference between the result from timeit and datetime is presumably because of low precision supported by datetime, but it is supposed to have microsecond precision so I cannot say for sure. At any rate, timeit is the right tool for the job at hand.

Michael Foukarakis
  • 39,737
  • 6
  • 87
  • 123