forked from EdwardBetts/FincLab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path'
81 lines (60 loc) · 3.99 KB
/
'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"""
Portfolio Class
The Portfolio class is not an abstract base class (ABC) - instead it will be normal base class. This means that it can be instantiated and thus is useful as a "first go" Portfolio object when testing out new strategies. Other Portfolios can be derived from it and override sections to add more complexity.
The Porfolio is designed to handle position sizing and current holdings, but will carry out trading orders in a "dumb" manner by simply sending them directly to the brokerage with a predetermined fixed quantity size, irrespective of cash held. These are all unrealistic assumptions.
The portfolio contains the *all_positions* and *current_positions* members:
all_positions - a dictionary; it stores a list of all previous positions recorded at the timestamp of a market data event. A position is simply the quantity of the asset held. Negative positions mean the asset has been shorted.
current_positions - a dictionary that stores the current positions for the last market bar update, for each symbol.
And *holdings* members:
all_holdings - it stores the historical list of all symbol holdings
current_holdings - stores the most up to date dictionary of all symbol holdings values
# Note
Continuing in the vein of the *Event* class hierachy, a *Portfolio* object must be able to hand *SignalEvent* objects, generate *OrderEvent* objects and interpret *FillEvent* objects to update positions. Thus, it is no surprise that the *Portfolio* objects are often the largest component of event-driven systems, in terms of lines of code (LOC).
"""
import numpy as np
import pandas as pd
import datetime as dt
from math import floor # To genearte integer-valued order sizes
try:
import Queue as queue
except ImportError:
import queue
from event import FillEvent, OrderEvent
from performance import create_sharpe_ratio, create_drawdowns
class Portfolio(object):
"""
The Portfolio class handles the positions and market value of all instruments at a resolution of a "bar", i.e., secondly, minutely, 5-min, 30-min or EOD.
The initialisation of the Portfolio object requires access to the bars DataHandler, the events Event Queue, a start datetime stamp and an initial capital value (defaulting to $100,000).
The positions DataFrame stores a time-index of the quantity of positions held.
The holdings DataFrame stores the cash and total market holdings value of each symbol for a particular time-index, as well as the percentage change in portfolio total across bars.
"""
def __init__(self, bars, events, start_date, initial_capital=100000.0):
"""
Initialises the portfolio with bars and an event queue.
Also includes a starting datetime index and initial capital (USD unless otherwise stated).
Parameters:
bars - The DataHandler object with current market data
events - The Event Queue object
start_date - The start date (bar) of the portfolio
initial_capital - The starting capital in dollars
"""
self.bars = bars
self.events = events
self.symbol_list = self.bars.symbol_list
self.start_date = start_date
self.initial_capital = initial_capital
# Construct all_positions
self.all_positions = self.construct_all_positions()
# The following simply creates a dictionary for each symbol, sets the value to zero for each, using a dictionary comprehension.
self.current_positions = dict((k , v) for k, v in [(s, 0) for s in self.symbol_list] )
# Construct all_holdings
self.all_holdings = self.construct_all_holdings()
self.current_holdings = self.construct_current_holdings()
def construct_all_positions(self):
"""
Constructs the positions list using the start_date to determine when the time index will begin.
"""
d = dict( (k, v) for k, v in [(s, 0) for s in self.symbol_list] )
d['datetime'] = self.start_date
# Add the dictionary to a list
return [d]