forked from nst/efx-backtest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
account.py
90 lines (66 loc) · 2.81 KB
/
account.py
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
82
83
84
85
86
87
88
89
90
#!/usr/bin/python
class Account:
def __init__(self):
self.orders = []
self.win_count = 0
self.lose_count = 0
def add_order(self, o):
self.orders.append(o)
def execute_orders_with_price_change(self, p):
for o in self.orders:
if o.status == "closed":
continue
elif o.status is None:
if o.price >= p.low and o.price <= p.high:
o.open(p.timestamp)
elif o.status == "opened":
if p.contains_price(o.stop_loss):
o.close(p.timestamp, o.stop_loss)
self.lose_count += 1
elif p.contains_price(o.take_profit):
o.close(p.timestamp, o.take_profit)
self.win_count += 1
elif o.buy_or_sell == "BUY":
if p.low <= o.stop_loss:
o.close(p.timestamp, o.stop_loss)
self.lose_count += 1
elif p.high >= o.take_profit:
o.close(p.timestamp, o.take_profit)
self.win_count += 1
elif o.buy_or_sell == "SELL":
if p.high >= o.stop_loss:
o.close(p.timestamp, o.stop_loss)
self.lose_count += 1
elif p.low <= o.take_profit:
o.close(p.timestamp, o.take_profit)
self.win_count += 1
def exposure(self):
opened_orders = filter(lambda o:o.status == "opened", self.orders)
return sum(map(lambda o:o.amount, opened_orders))
def pnl_realized(self):
n = 0.0
for o in filter(lambda o:o.status == "closed", self.orders):
n += o.pnl()
return n
def pnl_unrealized_with_price(self, price):
n = 0.0
for o in self.opened_orders():
if o.buy_or_sell == "BUY":
n += o.price - price.close
elif o.buy_or_sell == "SELL":
n += price.close - o.price
else:
print "--", o.buy_or_sell
raise Exception
return n * 10000
def trades_count(self):
return len(filter(lambda o:o.status != None, self.orders))
def opened_orders(self):
return filter(lambda o:o.status == "opened", self.orders)
def closed_orders(self):
return filter(lambda o:o.status == "closed", self.orders)
def opened_or_closed_orders(self):
return filter(lambda o:o.status == "opened" or o.status == "closed", self.orders)
def latest_closed_order(self):
l = self.closed_orders()
return l[-1] if len(l) > 0 else None