def restore(self, filename_prefix): with open('{}.prices.json'.format(filename_prefix), 'r') as fp: jsn = json.load(fp) self._prices = { Instrument.fromJson(json.loads(k)): [(p1, datetime.fromtimestamp(p2)) for p1, p2 in v] for k, v in jsn.items() } with open('{}.trades.json'.format(filename_prefix), 'r') as fp: jsn = json.load(fp) self._trades = { Instrument.fromJson(json.loads(k)): [Trade.fromJson(x) for x in v] for k, v in jsn.items() } with open('{}.active_by_inst.json'.format(filename_prefix), 'r') as fp: jsn = json.load(fp) self._active_positions_by_instrument = { Instrument.fromJson(json.loads(k)): [Position.fromJson(vv) for vv in v] for k, v in jsn.items() } with open('{}.active_by_strat.json'.format(filename_prefix), 'r') as fp: jsn = json.load(fp) self._active_positions_by_strategy = { k: { Instrument.fromJson(json.loads(kk)): Position.fromJson(vv) for kk, vv in v.items() } for k, v in jsn.items() }
def position(self, account: str, contract: Contract, position: float, avgCost: float): super().position(account, contract, position, avgCost) self._positions.append(Position(size=position, price=avgCost / position, timestamp=datetime.now(), instrument=_constructInstrument(contract), exchange=self._exchange, trades=[]))
def newPosition(self, trade: Trade): if trade.id in self._active_positions: # update position cur_pos = self._active_positions[trade.id] cur_pos.trades.append(trade) # TODO update notional/size/price etc prev_size = cur_pos.size prev_notional = cur_pos.notional prev_price = cur_pos.price cur_pos.size += trade.volume if trade.side == Side.BUY else -1 * trade.volume if (prev_size > 0 and cur_pos.size > prev_size) or ( prev_size < 0 and cur_pos.size < prev_size): # increasing position size # update average price cur_pos.price = (prev_notional + (trade.volume * trade.price)) / cur_pos.size elif (prev_size > 0 and cur_pos.size < 0) or (prev_size < 0 and cur_pos.size > 0): # decreasing position size in one direction, increasing position size in other # update realized pnl cur_pos.pnl += (prev_size * (trade.price - prev_price) ) # update realized pnl with closing position # update average price cur_pos.price = trade.price else: # decreasing position size # update realized pnl cur_pos.pnl += (trade.volume * (prev_price - trade.price) ) # update realized pnl with closing position # TODO close if side is 0 else: self._active_positions[trade.id] = Position( price=trade.price, size=trade.volume, notional=trade.volume * trade.price, instrument=trade.instrument, exchange=trade.exchange, trades=[trade]) self._instrument_positions_map[ trade.instrument] = self._active_positions[trade.id]
def newPosition(self, trade: Trade): my_order: Order = trade.my_order if trade.instrument in self._active_positions: # update position cur_pos = self._active_positions[trade.instrument] cur_pos.trades.append(trade) # TODO update notional/size/price etc prev_size: float = cur_pos.size prev_price: float = cur_pos.price prev_notional: float = prev_size * prev_price # FIXME separate maker, taker cur_pos.size = (cur_pos.size + (my_order.volume if my_order.side == Side.BUY else -1 * my_order.volume), trade.timestamp) if (prev_size > 0 and cur_pos.size > prev_size) or (prev_size < 0 and cur_pos.size < prev_size): # type: ignore # increasing position size # update average price cur_pos.price = ((prev_notional + (my_order.volume * trade.price)) / cur_pos.size, trade.timestamp) elif (prev_size > 0 and cur_pos.size < 0) or (prev_size < 0 and cur_pos.size > 0): # type: ignore # decreasing position size in one direction, increasing position size in other # update realized pnl pnl = cur_pos.pnl + (prev_size * (trade.price - prev_price)) cur_pos.pnl = (pnl, trade.timestamp) # update realized pnl with closing position # deduct from unrealized pnl cur_pos.unrealizedPnl = (cur_pos.unrealizedPnl - pnl, trade.timestamp) # update average price cur_pos.price = (trade.price, trade.timestamp) else: # decreasing position size # update realized pnl pnl = cur_pos.pnl + (prev_size * (trade.price - prev_price)) cur_pos.pnl = (pnl, trade.timestamp) # update realized pnl with closing position # deduct from unrealized pnl cur_pos.unrealizedPnl = (cur_pos.unrealizedPnl - pnl, trade.timestamp) # TODO close if side is 0 else: self._active_positions[trade.instrument] = Position(price=trade.price, size=trade.volume, timestamp=trade.timestamp, instrument=trade.instrument, exchange=trade.exchange, trades=[trade])
def newPosition(self, trade, strategy): my_order: Order = trade.my_order if trade.instrument in self._active_positions_by_instrument and \ strategy.name() in self._active_positions_by_strategy and \ trade.instrument in self._active_positions_by_strategy[strategy.name()]: # update position cur_pos = self._active_positions_by_strategy[strategy.name()][ trade.instrument] cur_pos.trades.append(trade) # TODO update notional/size/price etc prev_size: float = cur_pos.size prev_price: float = cur_pos.price prev_notional: float = prev_size * prev_price cur_pos.size = (cur_pos.size + (my_order.volume if my_order.side == Side.BUY else -1 * my_order.volume), trade.timestamp) if (prev_size >= 0 and cur_pos.size > prev_size) or ( prev_size <= 0 and cur_pos.size < prev_size): # type: ignore # increasing position size # update average price cur_pos.price = ((prev_notional + (my_order.volume * trade.price)) / cur_pos.size, trade.timestamp) elif (prev_size > 0 and cur_pos.size < 0) or ( prev_size < 0 and cur_pos.size > 0): # type: ignore # decreasing position size in one direction, increasing position size in other # update realized pnl pnl = (prev_size * (trade.price - prev_price)) cur_pos.pnl = (cur_pos.pnl + pnl, trade.timestamp ) # update realized pnl with closing position # deduct from unrealized pnl cur_pos.unrealizedPnl = (cur_pos.unrealizedPnl - pnl, trade.timestamp) # update average price cur_pos.price = (trade.price, trade.timestamp) else: # decreasing position size # update realized pnl pnl = (prev_size * (trade.price - prev_price)) cur_pos.pnl = (cur_pos.pnl + pnl, trade.timestamp ) # update realized pnl with closing position # deduct from unrealized pnl cur_pos.unrealizedPnl = (cur_pos.unrealizedPnl - pnl, trade.timestamp) # TODO close if side is 0? else: # If strategy has no positions yet, make a new dict if strategy.name() not in self._active_positions_by_strategy: self._active_positions_by_strategy[strategy.name()] = {} # if not tracking instrument yet, add if trade.instrument not in self._active_positions_by_instrument: self._active_positions_by_instrument[trade.instrument] = [] # Map position in by strategy self._active_positions_by_strategy[strategy.name()][ trade.instrument] = Position(price=trade.price, size=trade.volume, timestamp=trade.timestamp, instrument=trade.instrument, exchange=trade.exchange, trades=[trade]) # map a single position by instrument self._active_positions_by_instrument[trade.instrument].append( self._active_positions_by_strategy[strategy.name()][ trade.instrument])