You are on page 1of 22

+

Python (Part 2)

Edward Khon
ekhon@virtu.com
+
Our Best Friends

n Official Python documentation


n https://docs.python.org/2/

n Google
n https://www.google.com

n Most important thing is to know what to search for


+
How do we use Python in Virtu?

n FS Dev

n Ops Scripts

n Coreops and Systems

n Trading and Strategy Dev


n Prodscripts (Jython)
n Simulators (Jython)
n Trading analysis (Pandas etc.)
n Stats 1.0 (Python CGI)
+
List Slicing

>>> mylist
['p', 'i', 'n', 'e', 'a', 'p', 'p', 'l', 'e']
>>> mylist[2:]
['n', 'e', 'a', 'p', 'p', 'l', 'e']
>>> mylist[:5]
['p', 'i', 'n', 'e', 'a']
>>> mylist[-2:]
['l', 'e']
>>> mylist[:-2]
['p', 'i', 'n', 'e', 'a', 'p', 'p']
>>> mylist[3:-2]
['e', 'a', 'p', 'p']
>>> mylist[::2]
['p', 'n', 'a', 'p', 'e']
>>> mylist[::-1]
['e', 'l', 'p', 'p', 'a', 'e', 'n', 'i', 'p']
+
List Comprehensions

n Concise way to create lists based on some rule


>>> squares = []

>>> for x in range(10):

... squares.append(x**2)

...
>>> squares

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

n Equivalent list comprehension:


>>> squares = [x**2 for x in range(10)]
+
List Comprehensions

n Can also be nested


>>> matrix = [[0,1,2,3], [4,5,6,7], [8,9,10,11]]
>>> flattened = []
>>> for row in matrix:
... for i in row:
... flattened.append(i)
...
>>> flattened
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

n Equivalent list comprehension:


>>> flattened = [i for row in matrix for i in row]
+
List Comprehensions

n Conditionals can be used to filter results


>>> vowels = "aeiou"
>>> sentence = "The quick brown fox jumps over the lazy dog"
>>> no_vowels = "".join(l for l in sentence if not l in vowels)
>>>
>>> no_vowels
'Th qck brwn fx jmps vr th lzy dg'

n There are also other comprehensions: set, generator,


dictionary
+
File I/O

n File reading
n Loading a CSV configuration file
n Analyzing a log file

n File writing
n Producing configuration files
n Writing to a log file
n Transforming the contents of an existing file

n f = open(filename, mode)
n E.g. open(/prod/file.txt, r)
n Modes: r for reading, w for writing, r+ for both, a for
appending
n w erases the contents of the file if one exists
+
Operating on files

n f.read()
n Returns the entire contents of the file as a String

n f.readline()
n Reads the next line of the file

n Files can be iterated over:


>>> for line in f:
... print line

n f.write(This is the first line.\n)

n Remember to call f.close() to free up resource when done, or


wrap in a with block
+
Regular Expressions (Regex)

n Extremely useful concept used for matching on text


n Can be used for advanced find and replace and extracting data

n A search pattern is specified in the Regex syntax


n Specifies what to look for in strings

n Functionality accessed in Python through the re module


n https://docs.python.org/2/library/re.html

n Also used in many of our applications


n Sentry
n Eagle Eye
+
Regex Examples

>>> import re
>>> re.findall("\d+", "S0m3 c0mb1n4t10n 0f 13773rs and numb3rs")
['0', '3', '0', '1', '4', '10', '0', '13773', '3']
>>> re.match(".*(DE\d{10})", "The German ISIN is DE0124315323").group(1)
'DE0124315323'
>>> symbols = "AAPL, GOOG, TSE:1570, OSE:NK2M6, SGX:INN6, CLZ5"
>>> re.findall("[A-Z0-9]+[FGHJKMNQUVXZ]\d", symbols)
['NK2M6', 'INN6', 'CLZ5']
>>> re.findall("[A-Z0-9]+:?[A-Z0-9]+[FGHJKMNQUVXZ]\d", symbols)
['OSE:NK2M6', 'SGX:INN6', 'CLZ5']
+
Classes

n Classes are blueprints for encapsulating methods and fields


n Keeps data relating one entity together
n Facilitates computation and tracking of these related sets of data

n Objects are concrete instances of a class


n Created by calling a Classs constructor

n Can be subclassed, Python support multiple inheritance

n Use the self keyword for accessing fields and methods from
within an object
+
Classes Example
class Strategy:
def __init__(self, name, mark_price, multiplier=1):
self.name = name
self.multiplier = multiplier
self.mark_price = mark_price
self.pnl = 0
self.volume = 0
self.position = 0

def print_status(self):
print "%s PNL: %s Volume: %s Position: %s" % (self.name, self.pnl, self.volume, self.position)

def trade(self, is_buy, symbol, shares, price):


self.pnl += shares * (self.mark_price - price) * self.multiplier * (1 if is_buy else -1)
self.volume += shares
self.position += shares if is_buy else -shares
self.mark(price)
print "%s %s %s shares of %s at %s" % (self.name, ("bought" if is_buy else "sold"), shares, symbol, price)
+
Classes Example

strat1 = Strategy("strat-aapl", 100, 1) strat-aapl PNL: 0 Volume: 0 Position: 0


strat2 = Strategy("strat-nikkei", 16250, 1000) strat-nikkei PNL: 0 Volume: 0 Position: 0
strat-aapl bought 1000 shares of AAPL at 99.99
strat1.print_status() strat-nikkei sold 10 shares of OSE:NK2U6 at 16350
strat2.print_status() strat-aapl sold 1000 shares of AAPL at 100.01
strat-nikkei bought 10 shares of OSE:NK2U6 at 16340
strat1.trade(True, "AAPL", 1000, 99.99) strat-aapl PNL: 20.0 Volume: 2000 Position: 0
strat2.trade(False, "OSE:NK2U6", 10, 16350) strat-nikkei PNL: 100000 Volume: 20 Position: 0
strat1.trade(False, "AAPL", 1000, 100.01)
strat2.trade(True, "OSE:NK2U6", 10, 16340)

strat1.print_status()
strat2.print_status()
+
Built-ins

n Functions that are always available


n No need to import a module

n Used often so worth memorizing


n You could implement them yourself in Python, but potentially
lower performance

n Only scratching the surface here


n https://docs.python.org/2/library/functions.html
+
Useful Built-ins

>>> max(5, 8, -1)


n max()/min() 8
n Can pass in multiple arguments or a >>> abs(2), abs(-3.125)
list (2, 3.125)
>>> sum([1, 2, 3, 5])
n abs()
11
>>> round(2.3), round(3.7)
n sum()
(2.0, 4.0)
>>> all([2 == 3, 2 + 2 == 4])
n round()
False

n all() >>> all([2 == 2, 2 + 2 == 4])


True

n any() >>> any([2 == 3, 2 + 2 == 4])


True
n range() >>> range(2, 12, 3)
[2, 5, 8, 11]
+
Useful Built-ins

>>> set([1, 2, 3, 1, 1, 3])


n set() set([1, 2, 3])
n Removes duplicates >>> int(2.9), float(1)
(2, 1.0)
n Type casts >>> bool(0), bool(32), bool('')
n int(), bool(), float() (False, True, False)
>>> map(round, [1.3, -2, 2.8])
n int() truncates instead of rounding
[1.0, -2.0, 3.0]

n map() >>> def increment(x): return x + 1


...
n Applies a function to every
>>> map(increment, [1, 3, 4])
element
[2, 4, 5]
+
Useful Built-ins

>>> len("hello")
n len() 5
>>> len(["i", "t", "s", "m", "e"])
n enumerate() 5
>>> list(enumerate(["a", "b", "c"]))
n type() [(0, 'a'), (1, 'b'), (2, 'c')]
n Returns what kind of object a >>> type("Python")
variable is <type 'str'>
>>> type([1,2,3])
n isinstance() <type 'list'>

n For testing if a variable matches a >>> strat = Strategy("strat-msft", 100, 1)

specific type >>> type(strat), isinstance(strat, Strategy)


(<type 'instance'>, True)
+
Assertions

n Used as a safety check crash if this state isnt what I


expected

n We use many assertions in the strategy code

n Try using them in prodscripts too to catch issues early

n When used in prodscripts you can find the failed asssert


message in strategy.log
Traceback (most recent call last):
File "nse-bigmak-test.py", line 200, in <module>
assert thresholdBalance > 0.5, "Bal. thresh. must be >0.5 got %s" % thresholdBalance
AssertionError: Bal. thresh. must be >0.5 got 0.25
+
Exceptions

n Sometimes crashing isnt the best way to deal with errors

n Say you want to open a file and read it, but even if it doesnt
its okay for your project
try:
f = open("myfile.txt", "r")
# Do something with the file
except IOError as e:
print "I/O error %s: %s" % (e.errno, e.strerror)

print "Still alive!"


+
Exceptions

n You can catch multiple exceptions with one except statement


n except (RuntimeError, TypeError, NameError):

n Multiple except statements can be used to handle each


exception differently

n Exceptions should be used carefully and rarely


n Complicate control flow
n Can hide real issues

n NEVER do this (we wont let you check it in):


try:
configureStrategy(bigmak) # or any other code
except:
pass
+
Good Practices

n Organize your code into methods, classes, and modules


n Better organization (easier debugging!), facilitates code-reuse

n CamelCase or under_scores
n Up to you, but be consistent
n Prodscripts plug into Java classes which are in CamelCase, so that
choice might be obvious

n Check if code exists before re-inventing the wheel


(prodscript.py, produtil.py, base.py etc.)

n Comment your code if it isnt obvious

You might also like