-
Notifications
You must be signed in to change notification settings - Fork 853
/
Copy pathib_positions.py
144 lines (110 loc) · 4.09 KB
/
ib_positions.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from typing import NamedTuple
from ib_insync.ib import Position, Contract
from syscore.genutils import highest_common_factor_for_list, sign
from syscore.constants import arg_not_supplied
from sysexecution.trade_qty import tradeQuantity
class IBPositionWithExtendedAttr(NamedTuple):
account: str
contract: Contract
position: float
avgCost: float
exchange: str
@classmethod
def from_ib_position(cls, ib_position: Position, exchange: str):
return cls(
account=ib_position.account,
contract=ib_position.contract,
avgCost=ib_position.avgCost,
position=ib_position.position,
exchange=exchange,
)
def extract_fx_balances_from_account_summary(account_summary) -> dict:
relevant_tag = "TotalCashBalance"
result = extract_currency_dict_for_tag_from_account_summary(
account_summary, relevant_tag
)
return result
def extract_currency_dict_for_tag_from_account_summary(account_summary, relevant_tag):
result = dict(
[
(summary_item.currency, summary_item.value)
for summary_item in account_summary
if summary_item.tag == relevant_tag
]
)
return result
class positionsFromIB(dict):
pass
def from_ib_positions_to_dict(
raw_positions, account_id=arg_not_supplied
) -> positionsFromIB:
"""
:param raw_positions: list of positions in form Position(...)
:return: dict of positions as dataframes
"""
resolved_positions_dict = dict()
position_methods = dict(
STK=resolve_ib_stock_position,
FUT=resolve_ib_future_position,
CASH=resolve_ib_cash_position,
)
for position in raw_positions:
if account_id is not arg_not_supplied:
if position.account != account_id:
continue
asset_class = position.contract.secType
method = position_methods.get(asset_class, None)
if method is None:
# Resolve unexpected asset classes like cash rather than failing
method = resolve_ib_cash_position
# raise Exception("Can't find asset class %s in methods dict" % asset_class)
resolved_position = method(position)
asset_class_list = resolved_positions_dict.get(asset_class, [])
asset_class_list.append(resolved_position)
resolved_positions_dict[asset_class] = asset_class_list
resolved_positions_dict = positionsFromIB(resolved_positions_dict)
return resolved_positions_dict
def resolve_ib_stock_position(position):
return dict(
account=position.account,
symbol=position.contract.symbol,
multiplier=1.0,
expiry="",
exchange=position.contract.exchange,
currency=position.contract.currency,
position=position.position,
ib_contract=position.contract, ## persist to find exchanges later
)
def resolve_ib_future_position(position):
return dict(
account=position.account,
symbol=position.contract.symbol,
expiry=position.contract.lastTradeDateOrContractMonth,
multiplier=float(position.contract.multiplier),
currency=position.contract.currency,
position=position.position,
ib_contract=position.contract, ## persist to find exchanges later
)
def resolve_ib_cash_position(position):
return dict(
account=position.account,
symbol=position.contract.localSymbol,
expiry="",
multiplier=1.0,
currency=position.contract.currency,
position=position.position,
ib_contract=position.contract, ## persist to find exchanges later
)
def resolveBS_for_list(trade_list: tradeQuantity):
if len(trade_list) == 1:
return resolveBS(trade_list[0])
else:
return resolveBS_for_calendar_spread(trade_list)
def resolveBS_for_calendar_spread(trade_list: tradeQuantity):
trade = highest_common_factor_for_list(trade_list)
trade = sign(trade_list[0]) * trade
return resolveBS(trade)
def resolveBS(trade: int):
if trade < 0:
return "SELL", int(abs(trade))
return "BUY", int(abs(trade))