def test_generate_positions_report(self): # Arrange report_provider = ReportProvider() order1 = self.order_factory.market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), ) order2 = self.order_factory.market( AUDUSD_SIM.symbol, OrderSide.SELL, Quantity(100000), ) fill1 = TestStubs.event_order_filled( order1, instrument=AUDUSD_SIM, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), fill_price=Price("1.00010"), ) fill2 = TestStubs.event_order_filled( order2, instrument=AUDUSD_SIM, position_id=PositionId("P-123457"), strategy_id=StrategyId("S", "001"), fill_price=Price("1.00010"), ) position1 = Position(fill1) position1.apply(fill2) position2 = Position(fill1) position2.apply(fill2) positions = [position1, position2] # Act report = report_provider.generate_positions_report(positions) # Assert self.assertEqual(2, len(report)) self.assertEqual("position_id", report.index.name) self.assertEqual(position1.id.value, report.index[0]) self.assertEqual("AUD/USD", report.iloc[0]["symbol"]) self.assertEqual("BUY", report.iloc[0]["entry"]) self.assertEqual(100000, report.iloc[0]["peak_quantity"]) self.assertEqual(1.0001, report.iloc[0]["avg_open"]) self.assertEqual(1.0001, report.iloc[0]["avg_close"]) self.assertEqual(UNIX_EPOCH, report.iloc[0]["opened_time"]) self.assertEqual(UNIX_EPOCH, report.iloc[0]["closed_time"]) self.assertEqual(0, report.iloc[0]["realized_points"]) self.assertEqual(0, report.iloc[0]["realized_return"])
def test_generate_positions_report(self): # Arrange order1 = self.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) order2 = self.order_factory.market( AUDUSD_SIM.id, OrderSide.SELL, Quantity.from_int(100000), ) fill1 = TestStubs.event_order_filled( order1, instrument=AUDUSD_SIM, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00010"), ) fill2 = TestStubs.event_order_filled( order2, instrument=AUDUSD_SIM, position_id=PositionId("P-123457"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00010"), ) position1 = Position(instrument=AUDUSD_SIM, fill=fill1) position1.apply(fill2) position2 = Position(instrument=AUDUSD_SIM, fill=fill1) position2.apply(fill2) positions = [position1, position2] # Act report = ReportProvider.generate_positions_report(positions) # Assert assert len(report) == 2 assert report.index.name == "position_id" assert report.index[0] == position1.id.value assert report.iloc[0]["instrument_id"] == "AUD/USD.SIM" assert report.iloc[0]["entry"] == "BUY" assert report.iloc[0]["side"] == "FLAT" assert report.iloc[0]["peak_qty"] == "100000" assert report.iloc[0]["avg_px_open"] == "1.00010" assert report.iloc[0]["avg_px_close"] == "1.00010" assert report.iloc[0]["ts_opened"] == UNIX_EPOCH assert report.iloc[0]["ts_closed"] == UNIX_EPOCH assert report.iloc[0]["realized_points"] == "0.00000" assert report.iloc[0]["realized_return"] == "0.00000"
def test_flatten_all_positions(self): # Arrange strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), clock=self.clock, uuid_factory=self.uuid_factory, logger=self.logger, ) self.exec_engine.register_strategy(strategy) order1 = strategy.order_factory.market( USDJPY_FXCM, OrderSide.BUY, Quantity(100000), ) order2 = strategy.order_factory.market( USDJPY_FXCM, OrderSide.BUY, Quantity(100000), ) strategy.submit_order(order1) strategy.submit_order(order2) filled1 = TestStubs.event_order_filled( order1, position_id=PositionId("B-USD/JPY-1"), strategy_id=strategy.id, ) filled2 = TestStubs.event_order_filled( order2, position_id=PositionId("B-USD/JPY-2"), strategy_id=strategy.id, ) position1 = Position(filled1) position2 = Position(filled2) # Act strategy.flatten_all_positions(USDJPY_FXCM) # Assert self.assertTrue(order1 in strategy.execution.orders()) self.assertTrue(order2 in strategy.execution.orders()) self.assertEqual(OrderState.FILLED, strategy.execution.orders()[0].state()) self.assertEqual(OrderState.FILLED, strategy.execution.orders()[1].state()) self.assertEqual(PositionSide.FLAT, strategy.execution.positions()[0].side) self.assertEqual(PositionSide.FLAT, strategy.execution.positions()[1].side) self.assertTrue(position1.id in strategy.execution.position_closed_ids()) self.assertTrue(position2.id in strategy.execution.position_closed_ids()) self.assertTrue(strategy.execution.is_completely_flat())
def nautilus_objects() -> List[Any]: """A list of nautilus instances for testing serialization""" instrument = TestInstrumentProvider.default_fx_ccy("AUD/USD") position_id = PositionId("P-001") buy = TestExecStubs.limit_order() buy_submitted, buy_accepted, buy_filled = _make_order_events( buy, instrument=instrument, position_id=position_id, trade_id=TradeId("BUY"), ) sell = TestExecStubs.limit_order(order_side=OrderSide.SELL) _, _, sell_filled = _make_order_events( sell, instrument=instrument, position_id=position_id, trade_id=TradeId("SELL"), ) open_position = Position(instrument=instrument, fill=buy_filled) closed_position = Position(instrument=instrument, fill=buy_filled) closed_position.apply(sell_filled) return [ TestDataStubs.ticker(), TestDataStubs.quote_tick_5decimal(), TestDataStubs.trade_tick_5decimal(), TestDataStubs.bar_5decimal(), TestDataStubs.venue_status_update(), TestDataStubs.instrument_status_update(), TestEventStubs.component_state_changed(), TestEventStubs.trading_state_changed(), TestEventStubs.betting_account_state(), TestEventStubs.cash_account_state(), TestEventStubs.margin_account_state(), # ORDERS TestEventStubs.order_accepted(buy), TestEventStubs.order_rejected(buy), TestEventStubs.order_pending_update(buy_accepted), TestEventStubs.order_pending_cancel(buy_accepted), TestEventStubs.order_filled( order=buy, instrument=instrument, position_id=open_position.id, ), TestEventStubs.order_canceled(buy_accepted), TestEventStubs.order_expired(buy), TestEventStubs.order_triggered(buy), # POSITIONS TestEventStubs.position_opened(open_position), TestEventStubs.position_changed(open_position), TestEventStubs.position_closed(closed_position), ]
def test_calculate_pnl_for_inverse1(self): # Arrange order = self.order_factory.market( XBTUSD_BITMEX.id, OrderSide.SELL, Quantity.from_int(100000), ) fill = TestStubs.event_order_filled( order, instrument=XBTUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("10000.00"), ) position = Position(instrument=XBTUSD_BITMEX, fill=fill) # Act pnl = position.calculate_pnl( avg_px_open=Price.from_str("10000.00"), avg_px_close=Price.from_str("11000.00"), quantity=Quantity.from_int(100000), ) # Assert self.assertEqual(Money(-0.90909091, BTC), pnl) self.assertEqual(Money(-0.90909091, BTC), position.unrealized_pnl(Price.from_str("11000.00"))) self.assertEqual(Money(-0.00750000, BTC), position.realized_pnl) self.assertEqual(Money(9.09090909, BTC), position.notional_value(Price.from_str("11000.00")))
def test_calculate_pnl_for_long_position_win(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.id, OrderSide.BUY, Quantity.from_int(12), ) fill = TestStubs.event_order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("10500.00"), ) position = Position(instrument=BTCUSDT_BINANCE, fill=fill) # Act pnl = position.calculate_pnl( avg_px_open=Price.from_str("10500.00"), avg_px_close=Price.from_str("10510.00"), quantity=Quantity.from_int(12), ) # Assert self.assertEqual(Money(120.00000000, USDT), pnl) self.assertEqual(Money(-126.00000000, USDT), position.realized_pnl) self.assertEqual( Money(120.00000000, USDT), position.unrealized_pnl(Price.from_str("10510.00")), ) self.assertEqual(Money(-6.00000000, USDT), position.total_pnl(Price.from_str("10510.00"))) self.assertEqual([Money(126.00000000, USDT)], position.commissions())
def test_can_flush(self): # Arrange order1 = self.strategy.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position1_id = self.strategy.position_id_generator.generate() self.database.add_order(order1, self.strategy.id, position1_id) order1_filled = TestStubs.event_order_filled(order1, fill_price=Price( 1.00000, 5)) position1 = Position(position1_id, order1_filled) self.database.update_order(order1) self.database.add_position(position1, self.strategy.id) order2 = self.strategy.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position2_id = self.strategy.position_id_generator.generate() self.database.add_order(order2, self.strategy.id, position2_id) order2_working = TestStubs.event_order_working(order2) order2.apply(order2_working) self.database.update_order(order2) # Act self.database.reset() self.database.flush()
def position(number=1, entry_price=None) -> Position: if entry_price is None: entry_price = Price("1.00000") generator = PositionIdGenerator(id_tag_trader=IdTag("001")) for _i in range(number): generator.generate(TestStubs.symbol_audusd_fxcm()) order_factory = OrderFactory( strategy_id=StrategyId("S", "001"), id_tag_trader=IdTag("001"), id_tag_strategy=IdTag("001"), clock=LiveClock(), ) order = order_factory.market( TestStubs.symbol_audusd_fxcm(), OrderSide.BUY, Quantity(100000), ) position_id = PositionId(TestStubs.symbol_audusd_fxcm().value) order_filled = TestStubs.event_order_filled( order, position_id=position_id, fill_price=entry_price, ) position = Position(event=order_filled) return position
def test_calculate_pnl_for_inverse2(self): # Arrange order = self.order_factory.market( ETHUSD_BITMEX.symbol, OrderSide.SELL, Quantity(100000), ) fill = TestStubs.event_order_filled( order, instrument=ETHUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), fill_price=Price("375.95"), ) position = Position(fill) # Act pnl = position.calculate_pnl( Price("375.95"), Price("365.50"), Quantity(100000), # xrate=Decimal("0.0294337") # Currently not handling quanto settlement ) # Assert self.assertEqual(Money(1582.66, USD), position.unrealized_pnl(Price("370.00"))) self.assertEqual(Money(100000.00, USD), position.notional_value(Price("370.00")))
def test_calculate_pnl_for_short_position_loss(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.symbol, OrderSide.SELL, Quantity("10"), ) fill = TestStubs.event_order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), fill_price=Price("10500.00"), ) position = Position(fill) # Act pnl = position.calculate_pnl( Price("10500.00"), Price("10670.50"), Quantity("10.000000"), ) # Assert self.assertEqual(Money("-1705.00000000", USDT), pnl) self.assertEqual(Money("-1705.00000000", USDT), position.unrealized_pnl(Price("10670.50"))) self.assertEqual(Money("-105.00000000", USDT), position.realized_pnl) self.assertEqual([Money("105.00000000", USDT)], position.commissions()) self.assertEqual(Money("105.00000000", USDT), position.commission) self.assertEqual(Money("106705.00000000", USDT), position.notional_value(Price("10670.50")))
def test_update_position_when_not_already_exists_logs(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) self.database.add_order(order) position_id = PositionId("P-1") fill = TestStubs.event_order_filled( order, instrument=AUDUSD_SIM, position_id=position_id, last_px=Price.from_str("1.00000"), ) position = Position(instrument=AUDUSD_SIM, fill=fill) # Act self.database.update_position(position) # Assert assert True # No exception raised
def test_serialize_and_deserialize_position_opened_events(self): # Arrange order = self.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) fill = TestEventStubs.order_filled( order, instrument=AUDUSD_SIM, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00001"), ) position = Position(instrument=AUDUSD_SIM, fill=fill) uuid = UUID4() event = PositionOpened.create(position, fill, uuid, 0) # Act serialized = self.serializer.serialize(event) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == event
def test_add_position(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000), ) self.database.add_order(order) position_id = PositionId("P-1") fill = TestStubs.event_order_filled( order, instrument=AUDUSD_SIM, position_id=position_id, last_px=Price("1.00000"), ) position = Position(fill=fill) # Act self.database.add_position(position) # Assert self.assertEqual(position, self.database.load_position(position.id))
def test_position_opened_event_to_from_dict_and_str_repr(self): # Arrange order = self.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) fill = TestStubs.event_order_filled( order, instrument=AUDUSD_SIM, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00001"), ) position = Position(instrument=AUDUSD_SIM, fill=fill) uuid = UUID4() event = PositionOpened.create(position, fill, uuid, 0) # Act, Assert assert PositionOpened.from_dict(PositionOpened.to_dict(event)) == event assert ( str(event) == "PositionOpened(instrument_id=AUD/USD.SIM, position_id=P-123456, account_id=SIM-000, from_order=O-19700101-000000-000-001-1, strategy_id=S-001, entry=BUY, side=LONG, net_qty=100_000, quantity=100_000, peak_qty=100_000, currency=USD, avg_px_open=1.00001, avg_px_close=None, realized_points=0, realized_return=0.00000, realized_pnl=-2.00 USD, unrealized_pnl=0.00 USD, ts_opened=0, ts_last=0, ts_closed=0, duration_ns=0)" # noqa ) assert ( repr(event) == f"PositionOpened(trader_id=TESTER-000, strategy_id=S-001, instrument_id=AUD/USD.SIM, position_id=P-123456, account_id=SIM-000, from_order=O-19700101-000000-000-001-1, strategy_id=S-001, entry=BUY, side=LONG, net_qty=100_000, quantity=100_000, peak_qty=100_000, currency=USD, avg_px_open=1.00001, avg_px_close=None, realized_points=0, realized_return=0.00000, realized_pnl=-2.00 USD, unrealized_pnl=0.00 USD, ts_opened=0, ts_last=0, ts_closed=0, duration_ns=0, event_id={uuid})" # noqa )
def test_calculate_pnl_for_long_position_loss(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.id, OrderSide.BUY, Quantity.from_int(12), ) fill = TestEventStubs.order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("10500.00"), ) position = Position(instrument=BTCUSDT_BINANCE, fill=fill) # Act pnl = position.calculate_pnl( avg_px_open=Price.from_str("10500.00"), avg_px_close=Price.from_str("10480.50"), quantity=Quantity.from_int(10), ) # Assert assert pnl == Money(-195.00000000, USDT) assert position.realized_pnl == Money(-126.00000000, USDT) assert position.unrealized_pnl(Price.from_str("10480.50")) == Money( -234.00000000, USDT) assert position.total_pnl(Price.from_str("10480.50")) == Money( -360.00000000, USDT) assert position.commissions() == [Money(126.00000000, USDT)]
def test_calculate_pnl_for_short_position_loss(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.id, OrderSide.SELL, Quantity.from_str("10"), ) fill = TestEventStubs.order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("10500.00"), ) position = Position(instrument=BTCUSDT_BINANCE, fill=fill) # Act pnl = position.calculate_pnl( Price.from_str("10500.00"), Price.from_str("10670.50"), Quantity.from_str("10.000000"), ) # Assert assert pnl == Money(-1705.00000000, USDT) assert position.unrealized_pnl(Price.from_str("10670.50")) == Money( -1705.00000000, USDT) assert position.realized_pnl == Money(-105.00000000, USDT) assert position.commissions() == [Money(105.00000000, USDT)] assert position.notional_value(Price.from_str("10670.50")) == Money( 106705.00000000, USDT)
def test_can_add_position(self): # Arrange order = self.strategy.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order, self.strategy.id, position_id) order_filled = TestStubs.event_order_filled(order, fill_price=Price( 1.00000, 5)) position = Position(position_id, order_filled) # Act self.database.add_position(position, self.strategy.id) # Assert self.assertTrue(self.database.position_exists_for_order(order.id)) self.assertTrue(self.database.position_exists(position.id)) self.assertTrue(position.id in self.database.get_position_ids()) self.assertTrue(position.id in self.database.get_positions()) self.assertTrue( position.id in self.database.get_positions_open(self.strategy.id)) self.assertTrue(position.id in self.database.get_positions_open()) self.assertTrue(position.id not in self.database.get_positions_closed( self.strategy.id)) self.assertTrue( position.id not in self.database.get_positions_closed())
def test_load_position(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), ) position_id = PositionId('P-1') self.cache.add_order(order, position_id) order_filled = TestStubs.event_order_filled( order, instrument=AUDUSD_SIM, position_id=PositionId('P-1'), fill_price=Price("1.00000"), ) position = Position(order_filled) self.cache.add_position(position) # Act result = self.cache.load_position(position.id) # Assert self.assertEqual(position, result)
def test_calculate_pnl_for_long_position_loss(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.symbol, OrderSide.BUY, Quantity(12), ) fill = TestStubs.event_order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), fill_price=Price("10500.00"), ) position = Position(fill) # Act pnl = position.calculate_pnl( avg_open=Price("10500.00"), avg_close=Price("10480.50"), quantity=Quantity(10), ) # Assert self.assertEqual(Money("-195.00000000", USDT), pnl) self.assertEqual(Money("-126.00000000", USDT), position.realized_pnl) self.assertEqual(Money("-234.00000000", USDT), position.unrealized_pnl(Price("10480.50"))) self.assertEqual(Money("-360.00000000", USDT), position.total_pnl(Price("10480.50"))) self.assertEqual([Money("126.00000000", USDT)], position.commissions()) self.assertEqual(Money("126.00000000", USDT), position.commission)
def test_load_position(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) position_id = PositionId("P-1") self.cache.add_order(order, position_id) fill = TestStubs.event_order_filled( order, instrument=AUDUSD_SIM, position_id=PositionId("P-1"), last_px=Price.from_str("1.00000"), ) position = Position(instrument=AUDUSD_SIM, fill=fill) self.cache.add_position(position) # Act result = self.cache.load_position(position.id) # Assert self.assertEqual(position, result)
def test_calculate_pnl_for_inverse1(self): # Arrange order = self.order_factory.market( XBTUSD_BITMEX.symbol, OrderSide.SELL, Quantity(100000), ) fill = TestStubs.event_order_filled( order, instrument=XBTUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), fill_price=Price("10000.00"), ) position = Position(fill) # Act pnl = position.calculate_pnl( Price("10000.00"), Price("11000.00"), Quantity(100000), ) # Assert self.assertEqual(Money(-10000.00, USD), pnl) self.assertEqual(Money(-10000.00, USD), position.unrealized_pnl(Price("11000.00"))) self.assertEqual(Money(0.00, USD), position.realized_pnl) self.assertEqual(Money(0.00, USD), position.commission) self.assertEqual(Money(100000.00, USD), position.notional_value(Price("11000.00")))
def test_calculate_unrealized_pnl_for_long_inverse(self): # Arrange order = self.order_factory.market( XBTUSD_BITMEX.id, OrderSide.BUY, Quantity.from_int(100000), ) fill = TestStubs.event_order_filled( order, instrument=XBTUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("10500.00"), ) position = Position(XBTUSD_BITMEX, fill) # Act pnl = position.unrealized_pnl(Price.from_str("11505.60")) # Assert self.assertEqual(Money(0.83238969, BTC), pnl) self.assertEqual(Money(-0.00714286, BTC), position.realized_pnl) self.assertEqual([Money(0.00714286, BTC)], position.commissions())
def test_calculate_unrealized_pnl_for_short(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.symbol, OrderSide.SELL, Quantity("5.912000"), ) fill = TestStubs.event_order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), fill_price=Price("10505.60"), ) position = Position(fill) pnl = position.unrealized_pnl(Price("10407.15")) # Assert self.assertEqual(Money("582.03640000", USDT), pnl) self.assertEqual(Money("-62.10910720", USDT), position.realized_pnl) self.assertEqual([Money("62.10910720", USDT)], position.commissions()) self.assertEqual(Money("62.10910720", USDT), position.commission)
def test_load_order_when_position_in_database_returns_position(self): # Arrange self.database.add_instrument(AUDUSD_SIM) order = self.strategy.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) self.database.add_order(order) position_id = PositionId("P-1") fill = TestStubs.event_order_filled( order, instrument=AUDUSD_SIM, position_id=position_id, last_px=Price.from_str("1.00000"), ) position = Position(instrument=AUDUSD_SIM, fill=fill) self.database.add_position(position) # Act result = self.database.load_position(position_id) # Assert assert result == position
def test_unrealized_pnl_when_insufficient_data_for_xrate_returns_none( self): # Arrange state = AccountState( account_id=AccountId("BITMEX", "01234"), account_type=AccountType.MARGIN, base_currency=BTC, reported=True, balances=[ AccountBalance( BTC, Money(10.00000000, BTC), Money(0.00000000, BTC), Money(10.00000000, BTC), ), AccountBalance( ETH, Money(20.00000000, ETH), Money(0.00000000, ETH), Money(20.00000000, ETH), ), ], info={}, event_id=uuid4(), updated_ns=0, timestamp_ns=0, ) self.exec_engine.process(state) order = self.order_factory.market( ETHUSD_BITMEX.id, OrderSide.BUY, Quantity.from_int(100), ) self.exec_engine.cache.add_order(order, PositionId.null()) self.exec_engine.process(TestStubs.event_order_submitted(order)) self.exec_engine.process(TestStubs.event_order_accepted(order)) fill = TestStubs.event_order_filled( order=order, instrument=ETHUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("376.05"), ) self.exec_engine.process(fill) position = Position(instrument=ETHUSD_BITMEX, fill=fill) self.portfolio.update_position( TestStubs.event_position_opened(position)) # Act result = self.portfolio.unrealized_pnls(BITMEX) # # Assert self.assertEqual({}, result)
def test_serialize_and_deserialize_position_events_closed( self, position_func): instrument = TestInstrumentProvider.default_fx_ccy("GBPUSD") open_order = self.order_factory.market( instrument.id, OrderSide.BUY, Quantity.from_int(100000), ) open_fill = TestStubs.event_order_filled( open_order, instrument=instrument, position_id=PositionId("P-3"), strategy_id=StrategyId("S-1"), last_px=Price.from_str("1.00000"), ) close_order = self.order_factory.market( instrument.id, OrderSide.SELL, Quantity.from_int(100000), ) close_fill = TestStubs.event_order_filled( close_order, instrument=instrument, position_id=PositionId("P-3"), strategy_id=StrategyId("S-1"), last_px=Price.from_str("1.20000"), ) position = Position(instrument=instrument, fill=open_fill) position.apply(close_fill) event = position_func(position=position) self._test_serialization(obj=event)
def test_calculate_unrealized_pnl_for_short_inverse(self): # Arrange order = self.order_factory.market( XBTUSD_BITMEX.id, OrderSide.SELL, Quantity.from_int(1250000), ) fill = TestStubs.event_order_filled( order, instrument=XBTUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("15500.00"), ) position = Position(XBTUSD_BITMEX, fill) # Act pnl = position.unrealized_pnl(Price.from_str("12506.65")) # Assert self.assertEqual(Money(19.30166700, BTC), pnl) self.assertEqual(Money(-0.06048387, BTC), position.realized_pnl) self.assertEqual([Money(0.06048387, BTC)], position.commissions())
def test_load_positions_cache_when_one_position_in_database(self): # Arrange order1 = self.strategy.order_factory.stop_market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) self.database.add_order(order1) position_id = PositionId('P-1') order1.apply(TestStubs.event_order_submitted(order1)) order1.apply(TestStubs.event_order_accepted(order1)) order1.apply(TestStubs.event_order_working(order1)) order1.apply( TestStubs.event_order_filled( order1, instrument=AUDUSD_SIM, position_id=position_id, fill_price=Price("1.00001"), )) position = Position(order1.last_event) self.database.add_position(position) # Act result = self.database.load_positions() # Assert self.assertEqual({position.id: position}, result)
def test_load_positions_cache_when_one_position_in_database(self): # Arrange self.database.add_instrument(AUDUSD_SIM) order1 = self.strategy.order_factory.stop_market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), Price.from_str("1.00000"), ) self.database.add_order(order1) position_id = PositionId("P-1") order1.apply(TestStubs.event_order_submitted(order1)) order1.apply(TestStubs.event_order_accepted(order1)) order1.apply( TestStubs.event_order_filled( order1, instrument=AUDUSD_SIM, position_id=position_id, last_px=Price.from_str("1.00001"), )) position = Position(instrument=AUDUSD_SIM, fill=order1.last_event) self.database.add_position(position) # Act result = self.database.load_positions() # Assert assert result == {position.id: position}
def test_calculate_pnl_when_given_position_side_flat_returns_zero(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.id, OrderSide.BUY, Quantity.from_int(12), ) fill = TestStubs.event_order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("10500.00"), ) position = Position(instrument=BTCUSDT_BINANCE, fill=fill) # Act result = position.calculate_pnl( Price.from_str("10500.00"), Price.from_str("10500.00"), Quantity.from_int(100000), ) # Assert self.assertEqual(Money(0, USDT), result)