Web Integration in Finance with Python
Web Integration in Finance with Python
Web Integration
I have been quoted saying that, in the future, all companies will be
Internet companies. I still believe that. More than ever, really.
— Andrew Grove
The Internet, or the Web, has evolved from some separate world into
something that is everywhere and in everything. It has become a technol-
ogy platform enabling a multitude of different use cases. From a finance
perspective, the following seem particularly noteworthy:
Data provision/gathering
Web technology allows the provision of data and the gathering thereof in a
simplified manner and generally at reduced costs; it also speeds up in general all
associated processes. Large financial data providers, like Bloomberg and
Thomson Reuters, rely heavily on the Web and related technologies to provide
the financial world with data in real time.
Trading/buying/selling
Using the Web also facilitates trading of financial securities; even private
investors today have access to professional trading facilities (e.g., online
brokers like Interactive Brokers) and can trade securities in real time.
Application providing
Models like Software-as-a-Service (SaaS) allow both small companies, like
startups, and large ones to provide applications in an efficient manner; even the
smallest outfit can today reach a global target audience at very little cost. Large
corporations benefit from web technologies, for example, when they use them
to provide internal applications that are accessible and usable via any standard
web browser, instead of installing such applications on hundreds or even
thousands of different machines.
Communication
Of course, the Web facilitates communication within organizations and across
organizations; the majority of today’s business and financial communication has
moved from paper to the Web.
Commoditization/scalability
Recent web technologies also allow for better virtualization, making web
servers and servers in general a commodity that everybody can rent at rather
low variable costs and that is easily scalable when requirements change;
computing power and storage capacity become more and more comparable to
electricity, which we are all used to getting from the plug sockets at home.
Again, Python for the Web is a broad topic in itself that cannot be cov-
ered by a single chapter in this book. However, this chapter is able to
cover a number of important topics from a finance perspective. In partic-
ular, it covers:
Web protocols
The first section shows how to transfer files via FTP and how to access
websites via HTTP .
Web plotting
Web technologies generally allow for better interactivity and for better real-time
support than standard approaches, for example, for plotting data; the second
section introduces the plotting library Bokeh to generate interactive web plots
and to realize real-time plotting of financial data.
Web applications
One of Python ’s strengths is its powerful web frameworks to develop web-
based applications; one that is really Pythonic and that has become quite
popular recently is Flask . This chapter illustrates techniques for developing
web-based applications using this framework.
Web services
Web services have become an important aspect of web-enabled applications; the
last section shows how to develop a simple web service for the valuation of
European options on the VSTOXX volatility index.
Web Basics
This section gives a rather brief overview of selected Python libraries for
working with web technologies and protocols. Several topics, like the han-
dling of email functionality with Python , are not touched upon.
ftplib
The File Transfer Protocol ( FTP ) is, as the name suggests, a protocol
to transfer files over the Web.[50] Python provides a dedicated library to
work with FTP called ftplib :
In what follows, we will connect to an FTP server, log in, transfer a file to
the server, transfer it back to the local machine, and delete the file on the
server. First, the connection:
Not every FTP server is password protected, but this one is:
For the FTP file transfer to follow, we have to open the file for reading:
This open file can now be written, choosing here binary transfer, by the
STOR command in combination with the target filename:
Let us have a look at the directory of the FTP server. Indeed, the file was
transferred:
In [7]: [Link]('LIST')
Again, we choose binary transfer, and we use the RETR command for re-
trieving the file from the FTP server:
Since we do not need the file on the server anymore, we can delete it:
In [10]: [Link]('[Link]')
In [11]: [Link]('LIST')
In [12]: [Link]()
In the local directory there are now two files, the one that was generated
locally and the one generated by retrieving the file from the server:
<<<<<<< HEAD
Out[13]: insgesamt 156
-rw------- 1 1000 1000 77824 Sep 15 08:14 array_ftp.npy
-rw------- 1 1000 1000 80080 Sep 15 08:14 [Link]
=======
Out[13]: insgesamt 156
-rw------- 1 1000 1000 77824 Sep 29 17:05 array_ftp.npy
-rw------- 1 1000 1000 80080 Sep 29 17:05 [Link]
>>>>>>> 798603793467fffcd06a9df88edf091e339dec37
All that has happened so far was done without encryption (i.e., was fully
insecure). Both login information and data were transferred in readable
form. However, for most applications such operations should be en-
crypted so others are not able to read the data and/or steal the login infor-
mation and do even worse things.
ftplib can connect to FTP servers securely via the function FTP_TLS .
Once such a secure connection is established, all other operations remain
the same:
In [17]: ftps.prot_p()
In [18]: [Link]('LIST')
httplib
Another important protocol, if not the most important one on the Web, is
the HyperText Transfer Protocol ( HTTP ).[51] This protocol is used
whenever a ( HTML -based) web page is displayed in the browser. The
Python library to work with HTTP is called httplib :
Equipped with the response object, we can now read the content as
follows:
In [25]: content = [Link]()
content[:100]
# first 100 characters of the file
Once you have the content of a particular web page, there are many po-
tential use cases. You might want to look up certain information, for ex-
ample. You might know that you can find the email address on the page
by looking for E (in this very particular case). Since content is a string
object, you can apply the find method to look for E :[52]
Out[26]: 2071
Equipped with the index value for the information you are looking for,
you can inspect the subsequent characters of the object:
Once you are finished, you should again close the connection to the
server:
In [28]: [Link]()
urllib
There is another Python library that supports the use of different web
protocols. It is called urllib . There is also a related library called
urllib2 . Both libraries are designed to work with arbitrary web re-
sources, in the spirit of the “uniform” in URL (uniform resource locator).
[53] A standard use case, for example, is to retrieve files, like CSV data
files, via the Web. Begin by importing urllib :
With the connection established, read out the content by calling the read
method on the connection object:
The result in this case is historical stock price information for Yahoo!
itself:
As result, there is a string object that can be inserted into the preceding
URL string to complete it:
In [36]: params
Out[36]: 'a=05&s=MSFT&b=1&c=2014'
Equipped with this new URL string, establish a connection and read the
data from the connection:
The result again is stock price data, this time for more dates and for
Microsoft:
A brief inspection of the content of the saved file shows that we have in-
deed retrieved and saved the same content as before:
This section starts with generating static plots, then proceeds to interac-
tive plots to finally arrive at real-time plotting.
Static Plots
First, a brief benchmark example using the pandas library based on a fi-
nancial time series from the Yahoo! Finance API, as used in the previous
section:
As shown in Chapter 6, using pandas makes data retrieval from the Web
in general quite convenient. We do not even have to use additional li-
braries, such as urllib —almost everything happens under the hood.
The following retrieves historical stock price quotes for Microsoft Inc.
and stores the data in a DataFrame object:
pandas accepts column names as parameter values for the x and y co-
ordinates. The result is shown in Figure 14-1:
Graphics and plots like Figure 14-1 can of course also be used in a web
context. For example, it is straightforward to save plots generated with
matplotlib as files in the PNG ( Portable Network Graphics ) format
and to include such files in a website. However, recent web technologies
typically also provide interactivity, like panning or zooming.
In [49]: [Link](
data['Date'],
# x coordinates
data['Close'],
# y coordinates
color='#0066cc',
# set a color for the line
legend='MSFT',
# attach a legend label
title='Historical Stock Quotes',
# plot title
x_axis_type='datetime',
# datetime information on x-axis
tools = ''
)
[Link]()
Interactive Plots
The next step is to add interactivity to the web-based plot. Available inter-
activity elements (“tools”) include:
pan
Supports panning of the plot (like panning with a movie camera); i.e., moving
the plot (including x and y coordinates) relative to the fixed plotting frame
wheel_zoom
Enables zooming into the plot by using the mouse wheel
box_zoom
Enables zooming into the plot by marking a box with the mouse
reset
Resets the original/default view of the plot
previewsave
Generates a static (bitmap) version of the plot that can be saved in PNG format
In [50]: bp.output_file("../images/msft_2.html",
title="Bokeh Example (Interactive)")
[Link](
data['Date'],
data['Close'],
color='#0066cc',
legend='MSFT',
title='Historical Stock Quotes',
x_axis_type = "datetime",
tools = 'pan, wheel_zoom, box_zoom, reset, previewsave'
# adding a list of interactive tools
)
[Link]()
The output of this code is shown as Figure 14-3, where the panning func-
tion is used to move the plot within the plotting frame (compare this with
Figure 14-2).
In principle, all the features shown so far can also be implemented by us-
ing matplotlib . In fact, the interactive tools shown for Bokeh are avail-
able by default with matplotlib when you plot into a separate window.
Figure 14-4 shows a zoomed and panned version of the pandas plot in
Figure 14-1 in a separate ( Python -controlled) window. However, in con-
trast to Bokeh , matplotlib cannot “export” this functionality to be in-
cluded in a separate, standalone graphics file.[55]
Figure 14-3. Screenshot of HTML-based Bokeh plot with interactive elements
Figure 14-4. Screenshot of pandas/matplotlib-based plot with interactive elements
Real-Time Plots
Real-time FX data
Our first example is based on a JSON API for, among others, FX rates.
Some imports first:
The API we use is from OANDA, an FX online broker. This broker offers
an API sandbox that provides random/dummy data that resembles real
exchange rates. Our example is based on the EUR–USD exchange rate (cf.
the API guide):
To connect to the API we use the requests library whose aim is to im-
prove the interface for “humans” when interacting with web resources:
With the open connection, data in JSON format is simply read by calling
the method json on the connection object:
Unfortunately, the data is not yet completely in the format we would like
it to have. Therefore, we transform it a bit. The following code takes only
the first element of the list object stored under the key “prices.” The re-
sulting object is a standard dict object:
In [55]: data = data['prices'][0]
data
$ bokeh-server
With the server running in the background, let us implement the real-
time data update routine:
In [59]: bp.output_notebook("default")
[Link](ticks['time'], ticks['bid'],
x_axis_type='datetime', legend=instrument)
<[Link] at 0x7fdb7e1b2e10>
We need to get access to our current plot (i.e., the most recently generated
plot). Calling the function curplot returns the object we are looking for:
In [60]: [Link]()
In [61]: [Link]().renderers
The glyph attribute of the object contains the type of the Glyph object—
in this case, as expected, a Line object:
In [63]: [Link]
With the rendering object, we can access its data source directly:
In [64]: renderer.data_source
In [65]: renderer.data_source.data
In [66]: ds = renderer.data_source
This is the object that we will work with and that is to be updated when-
ever new data arrives. The following while loop runs for a predeter-
mined period of time only. During the loop, a new request object is gener-
ated and the JSON data is read. The new data is appended to the existing
DataFrame object. The x and y coordinates of the rendering object are
updated and then stored to the current session:
Figure 14-5 shows the output of the plotting exercise—i.e., a static snap-
shot of a real-time plot. This approach and the underlying technology of
course have many interesting application areas, both in finance, with its
focus today on real-time, high-frequency data, and far beyond.
Figure 14-5. Screenshot of real-time Bokeh plot via Bokeh Server (exchange rate)
The second example uses real-time, high-frequency stock price data. First,
make sure to correctly direct the output (i.e., in this case to the Bokeh
server for the real-time plot):
In [68]: bp.output_notebook("default")
Chapter 6 provides an example based on the data source and API that we
use in what follows. It is the stock price API for intraday real-time data
provided by Netfonds, a Norwegian online broker. The API and web ser-
vice, respectively, have the following basic URL format:
In [69]: url1 = '[Link]
url2 = 'date=%s%s%s&paper=%s.O&csv_format=csv'
url = url1 + url2
In [71]: y, m, d, sym
Out[72]: '[Link]
rmat=csv'
Equipped with the right URL string, retrieving data is only one line of
code away:
The details of what follows are known from the previous example. First,
the initial plot:
In [74]: [Link](data['time'], data['bid'],
x_axis_type='datetime', legend=sym)
# intial plot
Third, the while loop updating the financial data and the plot per loop:
If the Python world were to be divided into continents, there might be,
among others, the science and finance content, the system administration
continent, and for sure the web development continent. Although not re-
ally transparent, it is highly probable that the web development conti-
nent, to stay with this concept, might be one of the largest when it comes
to people (developers) populating it and houses (applications) built on it.
One of the major reasons for Python being strong in web development is
the availability of different high-level, full-stack frameworks. As the
Python web page states:
A web application may use a combination of a base HTTP applica-
tion server, a storage mechanism such as a database, a template
engine, a request dispatcher, an authentication module and an
AJAX toolkit. These can be individual components or be provided
together in a high-level framework.
Django
Flask
Pyramid/Pylons
TurboGears
Zope
It is safe to say that there is not a single framework that is best suited for
everybody and every different application type.[56] All have their
strengths (and sometimes weaknesses), and often it is more a matter of
taste (regarding architecture, style, syntax, APIs, etc.) what framework is
chosen.
Pythonic
Application development with Flask is really Pythonic , with a lot of the
web-related details being taken care of behind the scenes.
Compactness
It is not too complex and can therefore be learned quite rapidly; it is based
mainly on standard components and libraries widely used elsewhere.
Documentation
It is well documented, with both an online HTML version and a PDF with
around 300 pages available at the time of this writing.[57]
The basic idea is to build a web-based application for which traders can
register that provides one central chat room to exchange ideas and talk
markets. The main screen shall allow a user who is logged in to type in
text that is, after pushing a button, added to the timeline, indicating who
added the comment and when this happened. The main screen also
shows all the historical entries in descending order (from newest to
oldest).
Data Modeling
$ mkdir tradechat
$ mkdir tradechat/static
$ mkdir tradechat/templates
To store data—both for registered users and for comments made in the
chat room—we use SQLite3 (cf. [Link] and
[Link] as a database. Two different
tables are needed that can be generated by the SQL schema presented in
Example 14-1, the details of which we do not discuss here. You should
store this under the filename [Link] in the main directory of the ap-
plication, tradechat .
The SQL schema is a main input for the Python/Flask application to fol-
low. We will go through the single elements step by step to finally arrive
at the complete Python script to be stored under [Link] in the
main directory, tradechat .
# Tradechat
#
# A simple example for a web-based chat room
# based on Flask and SQLite3.
#
import os
import datetime as dt
from sqlite3 import dbapi2 as sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash
Having provided the path and filename of the database, the function
connect_db connects to the database and returns the connection object:
def connect_db():
''' Connects to the TC database.'''
rv = [Link]([Link]['DATABASE'])
rv.row_factory = [Link]
return rv
Flask uses an object called g to store global data and other objects. For
example, web applications serving large numbers of users make it neces-
sary to connect regularly to databases. It would be inefficient to instanti-
ate a connection object every time a database operation has to be exe-
cuted. One can rather store such a connection object in the attribute
sqlite_db of the g object. The function get_db makes use of this ap-
proach in that a new database connection is opened only when there is no
connection object stored in the g object already:
def get_db():
''' Opens a new connection to the TC database. '''
if not hasattr(g, 'sqlite_db'):
# open only if none exists yet
g.sqlite_db = connect_db()
return g.sqlite_db
At least once, we need to create the tables in the database. Calling the
function init_db for a second time will delete all information previously
stored in the database (according to the SQL schema used):
def init_db():
''' Creates the TC database tables.'''
with app.app_context():
db = get_db()
with app.open_resource('[Link]', mode='r') as f:
[Link]().executescript([Link]())
# creates entries and users tables
[Link]()
The function close_db closes the database connection if one exists in the
g object. For the first time (and for sure not the last time), we encounter
a Flask function decorator, i.e., @app.teardown_appcontext . This deco-
rator ensures that the respective function is called whenever the applica-
tion context tears down—that is, roughly speaking, when the execution of
the application is terminated by the user or by an error/exception:
@app.teardown_appcontext
def close_db(error):
''' Closes the TC database at the end of the request. '''
if hasattr(g, 'sqlite_db'):
g.sqlite_db.close()
Core functionality
Once users have registered or logged in again, they should be able to add
comments in the chat room. The function add_entry stores the comment
text, the username of the user who commented, and the exact time (to the
second) of the posting. The function also checks whether the user is
logged in or not:
@[Link]('/add', methods=['POST'])
def add_entry():
''' Adds entry to the TC database. '''
if not [Link]('logged_in'):
abort(401)
db = get_db()
now = [Link]()
[Link]('insert into comments (comment, user, time) values (?, ?, ?)',
[[Link]['text'], [Link]['USERNAME'], str(now)[:-7]])
[Link]()
flash('Your comment was successfully added.')
return redirect(url_for('show_entries'))
Finally, to end the session, the user must log out. This is what the function
logout supports:
@[Link]('/logout')
def logout():
''' Logs out the current user. '''
[Link]('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
# main routine
if __name__ == '__main__':
init_db() # comment out if data in current
# TC database is to be kept
[Link]()
Putting all these pieces together, we end up with the Python script
shown as Example 14-2.
Example 14-2. Python script embodying the core of the Tradechat application
# Tradechat
#
# A simple example for a web-based chat room
# based on Flask and SQLite3.
#
import os
import datetime as dt
from sqlite3 import dbapi2 as sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
render_template, flash
# the application object from the main Flask class
app = Flask(__name__)
def connect_db():
''' Connects to the TC database.'''
rv = [Link]([Link]['DATABASE'])
rv.row_factory = [Link]
return rv
def get_db():
''' Opens a new connection to the TC database. '''
if not hasattr(g, 'sqlite_db'):
# open only if none exists yet
g.sqlite_db = connect_db()
return g.sqlite_db
def init_db():
''' Creates the TC database tables.'''
with app.app_context():
db = get_db()
with app.open_resource('[Link]', mode='r') as f:
[Link]().executescript([Link]())
# creates entries and users tables
[Link]()
@app.teardown_appcontext
def close_db(error):
''' Closes the TC database at the end of the request. '''
if hasattr(g, 'sqlite_db'):
g.sqlite_db.close()
@[Link]('/')
def show_entries():
''' Renders all entries of the TC database. '''
db = get_db()
query = 'select comment, user, time from comments order by id desc'
cursor = [Link](query)
comments = [Link]()
return render_template('show_entries.html', comments=comments)
@[Link]('/add', methods=['POST'])
def add_entry():
''' Adds entry to the TC database. '''
if not [Link]('logged_in'):
abort(401)
db = get_db()
now = [Link]()
[Link]('insert into comments (comment, user, time) values (?, ?, ?)',
[[Link]['text'], [Link]['USERNAME'], str(now)[:-7]])
[Link]()
flash('Your comment was successfully added.')
return redirect(url_for('show_entries'))
@[Link]('/logout')
def logout():
''' Logs out the current user. '''
[Link]('logged_in', None)
flash('You were logged out')
return redirect(url_for('show_entries'))
# main routine
if __name__ == '__main__':
init_db() # comment out if data in current
# TC database is to be kept
[Link]()
SECURITY
Although the example in this section illustrates the basic design of a web applica-
tion in Python with Flask , it barely addresses security issues, which are of para-
mount importance when it comes to web applications. However, Flask and other
web frameworks provide complete tool sets to tackle typical security issues (e.g.,
encryption) with due diligence.
Templating
Templating to generate HTML pages works pretty similarly. The major dif-
ference is that the string object “resembles” an HTML document (or a
part thereof) and has commands for replacements and also, for example,
ways of controlling the flow when rendering the template (e.g., the for
loop). Missing information is added during the rendering procedure, as
we added the integers to the string object in the previous examples.
Consider now the following string object, containing partly standard
HTML code and some template-specific code:
In [82]: t = Template(templ)
This Template object has a method called render to make valid HTML
code out of the template and some input values—in this case, some num-
bers via the parameter numbers :
In [84]: html
Out[84]: u'<!doctype html>\n Just print out <b>numbers</b> provided to the temp
late.\n <br><br>\n \n 0\n \n 1\n \n 2\n \n 3\n \n
4\n '
Of course, templating involves much more than this simple example can
illustrate (e.g., inheritance). More details can be found at
[Link] However, the templates for the Tradechat applica-
tion already include a number of important aspects. Specifically, we need
the following templates:
[Link]
Defines the basic layout from which the other templates inherit
[Link]
The template for the user registration page
[Link]
The corresponding template for the user login
show_entries.html
The main page showing the comments in the chat room and, if the user is
logged in, the text field for writing and posting comments
Example 14-3 shows the template containing the basic layout and some
meta-information (like the site title). This is the template all other tem-
plates inherit from.
<!doctype html>
<title>Tradechat</title>
<link rel=stylesheet type=text/css
href="{{ url_for('static', filename='[Link]') }}">
<div class=page>
<h1>Tradechat</h1>
<div class=metanav>
{% if not session.logged_in %}
<a href="{{ url_for('login') }}">log in</a><br>
<a href="{{ url_for('register') }}">register</a>
{% else %}
<a href="{{ url_for('logout') }}">log out</a>
{% endif %}
</div>
{% for message in get_flashed_messages() %}
<div class=flash>{{ message }}</div>
{% endfor %}
{% block body %}{% endblock %}
</div>
Figure 14-7 shows a screenshot of the main page after starting the appli-
cation for the first time. No users are registered (or logged in, of course).
No comments have been posted yet.
Figure 14-7. Screenshot of “empty” home page of Tradechat
Example 14-4 provides the templating code for the user registration page.
Here, forms are used to allow users to provide information to the page
via the POST method.
{% extends "[Link]" %}
{% block body %}
<h2>Register</h2>
{% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
<form action="{{ url_for('register') }}" method=post>
<dl>
<dd><font size="-1">Username</font>
<dd><input type=text name=username>
<dd><font size="-1">Password</font>
<dd><input type=password name=password>
<dd><input type=submit value=Register>
</dl>
</form>
{% endblock %}
The templating code for the login page, as shown in Example 14-5, is
pretty similar to the code for the registration page. Again, the user can
provide login information via a form.
{% extends "[Link]" %}
{% block body %}
<h2>Login</h2>
{% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
<form action="{{ url_for('login') }}" method=post>
<dl>
<dd><font size="-1">Username</font>
<dd><input type=text name=username>
<dd><font size="-1">Password</font>
<dd><input type=password name=password>
<dd><input type=submit value=Login>
</dl>
</form>
{% endblock %}
The login page, as shown in Figure 14-9, not only looks pretty similar to
the registration page but also provides mainly the same functionality.
Figure 14-9. Screenshot of Tradechat login page
Finally, Example 14-6 provides the templating code for the main page.
This template does mainly two things:
Enables commenting
If the user is logged in, a text field and a Post button are shown to allow the
user to post comments.
Displays comments
All comments found in the database are displayed in reverse chronological
order (newest first, oldest last).
Example 14-6. Template for Tradechat main page with chat room comments
{% extends "[Link]" %}
{% block body %}
{% if session.logged_in %}
<form action="{{ url_for('add_entry') }}" method=post class=add-comment>
<dl>
<dd>What's up?
<dd><textarea name=text rows=3 cols=40></textarea>
<dd><input type=submit value=Post>
</dl>
</form>
{% endif %}
<ul class=comments>
{% for comment in comments %}
<li>{{ [Link]|safe }}
<font size="-2">({{ [Link] }} @ {{ [Link] }})</font>
{% else %}
<li><em>No comments so far.</em>
{% endfor %}
</ul>
{% endblock %}
Once a user is logged in and has posted some comments, the main page
shows the text field and the Post button as well as all comments stored
in the database (cf. Figure 14-10).
Styling
Today’s standard when it comes to the styling of web pages and web-
based applications is CSS ( Cascading Style Sheets ). If you take a
closer look at the single templates, you will find in many places parame-
terizations like class=comments or class=add-comment . Without a cor-
responding CSS file, these parameterizations are essentially
meaningless.
This style information is the final ingredient defining the look of the
Tradechat application and explaining why, for example, the “Tradechat”
heading is displayed in blue (namely, due to the line a, h1, h2 { color:
#0066cc; } ).
.page { margin: 2em auto; width: 35em; border: 1px solid #ccc;
padding: 0.8em; background: white; }
.comments { list-style: none; margin: 0; padding: 0; }
.comments li { margin: 0.8em 1.2em; }
.comments li h2 { margin-left: -1em; }
.add-comment { color: #0066cc; font-size: 0.7em; border-bottom: 1px solid #ccc;
.add-comment dl { font-weight: bold; }
.metanav { text-align: right; font-size: 0.8em; padding: 0.3em;
margin-bottom: 1em; background: #fafafa; }
.flash { color: #b9b9b9; font-size: 0.7em; }
.error { color: #ff4629; font-size: 0.7em; padding: 0.5em; }
If you have followed every step, your tradechat directory should now
contain the same files listed here:
In [86]: import os
for path, dirs, files in [Link]('../python/tradechat'):
print path
for f in files:
print f
Out[86]: ../python/tradechat
[Link]
[Link]
[Link]
../python/tradechat/static
[Link]
../python/tradechat/templates
[Link]
[Link]
[Link]
show_entries.html
You can now run the main script from the shell as follows and start the
application:
$ python [Link]
You can then access the application via your web browser at
[Link] Click on register to register as a user, and after
having provided a username and a password you will be able to post
your comments.
Web Services
The last topic in this chapter—and a very interesting and important one—
is web services. Web services provide a simple and efficient means to ac-
cess server-based functionality via web protocols. For example, one of the
web services with the highest traffic is the Google search functionality.
We are used to visiting [Link] and typing some words of
interest into the search/text input field provided on the website.
However, what happens after you press the Return key or push the
Search button is that the page translates all the information it has (from
the search field and maybe your personal preferences) into a more or less
complex URL .
Such a URL could, for example, take on the form
[Link] When you click this
link or copy it into your web browser, Google Search returns those five
search results ( num=5 ) that the engine considers the best matches given
the words provided ( q=Yves+Python ). Your web browser then displays
something similar to Figure 14-11.
Vt
The time t value of the volatility index (for example, the VSTOXX)
θV
The long-run mean of the volatility index
κV
The rate at which Vt reverts to 𝜃
ΣV
The volatility of the volatility (“vol-vol”)
θV, κV, and ΣV
Assumed to be constant and positive
Zt
A standard Brownian motion
Based on this model, Gruenbichler and Longstaff (1996) derive the for-
mula provided in Equation 14-2 for the value of a European call option. In
the formula, D(T) is the appropriate discount factor. The parameter 𝜁 de-
notes the expected premium for volatility risk, while is the com-
plementary noncentral 𝜒2 distribution.
#
# Valuation of European volatility call options
# in Gruenbichler-Longstaff (1996) model
# square-root diffusion framework
# -- semianalytical formula
#
from [Link] import ncx2
import numpy as np
Parameters
==========
V0 : float
current volatility level
kappa : float
mean reversion factor
theta : float
long-run mean of volatility
sigma : float
volatility of volatility
zeta :
volatility risk premium
T : float
time-to-maturity
r : float
risk-free short rate
K : float
strike price of the option
Returns
=======
value : float
net present value of volatility call option
'''
D = [Link](-r * T) # discount factor
# variables
alpha = kappa * theta
beta = kappa + zeta
gamma = 4 * beta / (sigma ** 2 * (1 - [Link](-beta * T)))
nu = 4 * alpha / sigma ** 2
lamb = gamma * [Link](-beta * T) * V0
cx1 = 1 - [Link](gamma * K, nu + 4, lamb)
cx2 = 1 - [Link](gamma * K, nu + 2, lamb)
cx3 = 1 - [Link](gamma * K, nu, lamb)
Example 14-9. Python script for volatility option valuation and web service helper
function
#
# Valuation of European volatility options
# in Gruenbichler-Longstaff (1996) model
# square-root diffusion framework
# -- parameter dictionary & web service function
#
from vol_pricing_formula import calculate_option_value
# model parameters
PARAMS={
'V0' : 'current volatility level',
'kappa' : 'mean reversion factor',
'theta' : 'long-run mean of volatility',
'sigma' : 'volatility of volatility',
'zeta' : 'factor of the expected volatility risk premium',
'T' : 'time horizon in years',
'r' : 'risk-free interest rate',
'K' : 'strike'
}
def get_option_value(data):
''' A helper function for web service. '''
errorline = 'Missing parameter %s (%s)\n'
errormsg = ''
for para in PARAMS:
if not data.has_key(para):
# check if all parameters are provided
errormsg += errorline % (para, PARAMS[para])
if errormsg != '':
return errormsg
else:
result = calculate_option_value(
float(data['V0']),
float(data['kappa']),
float(data['theta']),
float(data['sigma']),
float(data['zeta']),
float(data['T']),
float(data['r']),
float(data['K'])
)
return str(result)
Furthermore, for our core WSGI application to follow, we need the func-
tion get_option_value that we defined earlier:
The only thing that remains is to implement the WSGI application (func-
tion) itself. This function might in our case look as follows:
To be better able to serve this function (e.g., via a local web server), we
put the function into a separate WSGI script and add the serving function-
ality to it. Example 14-10 shows the code of this script, called
vol_pricing.py .
Example 14-10. Python script for volatility option valuation and web service helper
function
#
# Valuation of European volatility options
# in Gruenbichler-Longstaff (1996) model
# square-root diffusion framework
# -- WSGI application for web service
#
from vol_pricing_service import get_option_value
from [Link] import Request, Response
from [Link] import run_simple
Being in the right subdirectory ( volservice ), you can now start the ap-
plication by executing the following command via the shell or command-
line interface:
$ python vol_pricing.py
* Running on [Link]
This fires up a separate Python process that serves the WSGI application.
Using urllib , we can now access the “full power” of the web service.
Copying the URL in your web browser and pressing the Return key yields
something like the result shown in Figure 14-12.
However, usually you want to use a web service quite a bit differently—
for example, from a scripting environment like IPython . To this end, we
can use the functionality the urllib library provides:
In [94]: urlval = urlpara % (25, 2.0, 20, 1.0, 0.0, 1.5, 0.02, 22.5)
urlval
Out[94]: '[Link]
eta=0.0&T=1.5&r=0.02&K=22.5'
Out[95]: 0.202937705934
With such a web service, you can of course do multiple calls to calculate
multiple option values quite easily:
In [96]: %%time
urlpara = '[Link]
urlpara += '&theta=25&sigma=1.0&zeta=0.0&T=1&r=0.02&K=%s'
strikes = [Link](20, 30, 50)
results = []
for K in strikes:
[Link](float([Link](urlpara % K).read()))
results = [Link](results)
In [97]: results
One advantage of this approach is that you do not use your local re-
sources to get the results, but rather the resources of a web server—
which might also use, for example, parallelization techniques. Of course,
in our example all is local and the web service uses the local computing
resources. Figure 14-13 shows the valuation results graphically, conclud-
ing this section:
Figure 14-13. Value of European volatility call option for different strikes
W E B S E RV I C E S A R C H I T E C T U R E
The web services architecture is often a powerful and efficient alternative to the
provision of Python -based analytical functionality, or even whole applications.
This holds true for the Internet as well as for models where private networks are
used. This architecture also simplifies updates and maintenance, since such ser-
vices are generally provided in a centralized fashion.
Conclusions
This chapter first illustrates some basic techniques with regard to the
most common communication protocols (mainly FTP and HTTP ). It also
shows how to implement interactive web plotting, how to interface in real
time with web-based financial data APIs (e.g., JSON -based) and how to vi-
sualize such high frequency data in real time with Bokeh . These basic
tools and techniques are helpful in almost any context.
However, the Python ecosystem also provides a number of powerful,
high level frameworks to develop even complex web applications in rapid
fashion. We use Flask , a framework which has gained some popularity
recently, to implement a simple chat room for traders with simple user
administration (registration and login). All elements of a typical web ap-
plication—core functionality in Python , templating with Jinja2 , and
styling with CSS —are illustrated.
Finally, the last section in this chapter addresses the important topic of
web services. Using the Werkzeug library for a somewhat simplified han-
dling of WSGI applications, we implement a web-based pricing service for
volatility options based on the model and formula of Gruenbichler and
Longstaff (1996).
Further Reading
The following web resources are helpful with regard to the topics covered
in this chapter:
[52] This example is for illustration purposes only. In general, you would want to
use specialized libraries such as lxml or Beautiful Soup .
[53]
There are alternatives to these libraries, like Requests , that come with a more
modern API.
[54] For more information on interactive plots with matplotlib , refer to the
library’s home page.
[55] The majority of graphics formats matplotlib can export to are static by na-
ture (i.e., bitmaps). A counterexample is graphics in SVG ( Scalable Vector
Graphics ) format, which can be programmed in JavaScript/ECMAScript . The
library’s website provides some examples of how to do this.
[58] The example application is called Flaskr and represents a microblog applica-
tion. Our example is, more or less, a mixture between Flaskr and Minitwit , an-
other Flask example application resembling a simple Twitter clone.
[59]
See also the larger case study about volatility options presented in Chapter 19.