Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
commission is correctly set on the Position entities.
"""
ph = PositionHandler()
# Asset 1
asset1 = EquityMock(1, exchange='NYSE')
dt1 = pd.Timestamp('2015-05-06')
trans_pos_1 = Transaction(
asset1, quantity=75, dt=dt1, price=483.45,
order_id=1, commission=0.0
)
ph.transact_position(trans_pos_1)
ph.update_commission(asset1, 15.97)
# Asset 2
asset2 = EquityMock(2, exchange='NYSE')
dt2 = pd.Timestamp('2015-05-07')
trans_pos_2 = Transaction(
asset2, quantity=250, dt=dt2, price=142.58,
order_id=2, commission=0.0
)
ph.transact_position(trans_pos_2)
ph.update_commission(asset2, 8.35)
# Check all total values
self.assertEqual(ph.total_book_cost(), 71928.07)
self.assertEqual(ph.total_market_value(), 71903.75)
self.assertEqual(ph.total_unr_gain(), -24.31999999999971)
self.assertEqual(ph.total_unr_perc_gain(), -0.03381155646190282)
def test_transact_position_current_position(self):
"""
Tests the 'transact_position' method for a transaction
with a current asset and checks that all objects are
set correctly.
"""
# Create the PositionHandler, Transaction and
# carry out a transaction
ph = PositionHandler()
asset = EquityMock(1, exchange='NYSE')
dt = pd.Timestamp('2015-05-06')
transaction_long = Transaction(
asset, quantity=100, dt=dt, price=960.0,
order_id=123, commission=26.83
)
transaction_long_again = Transaction(
asset, quantity=200, dt=dt, price=990.0,
order_id=234, commission=18.53
)
ph.transact_position(transaction_long)
ph.transact_position(transaction_long_again)
# Check that the position object is set correctly
pos = ph.positions[asset]
self.assertEqual(pos.quantity, 300)
self.assertEqual(pos.direction, 1.0)
self.assertEqual(pos.book_cost_ps, 980.1512000000001)
self.assertEqual(pos.book_cost, 294045.36000000004)
def test_position_short_long_excess_cover(self):
"""
Tests that the quantity and book cost are
correctly calculated for an initial short
position with an additional long transaction
in the same asset, where the long position
is in excess of the short position.
"""
asset = EquityMock(1, exchange='NYSE')
position = Position(
asset, quantity=-100, book_cost_ps=700.0,
current_trade_price=700.0
)
dt = pd.Timestamp('2015-05-06')
transaction = Transaction(
asset, quantity=175, dt=dt, price=873.0,
order_id=123, commission=None
)
position.update(transaction)
self.assertEqual(position.quantity, 75)
self.assertEqual(position.book_cost_ps, 873.0)
self.assertEqual(position.direction, 1.0)
self.assertEqual(position.current_trade_price, 873.0)
self.assertEqual(position.market_value, 65475.0)
self.assertEqual(position.unr_gain, 0.0)
self.assertEqual(position.unr_perc_gain, 0.0)
def test_update_for_incorrect_asset(self):
"""
Tests that the 'update' method, when provided
with a transaction with an asset that does not
match the position's asset, raises an Exception.
"""
asset1 = EquityMock(1, exchange='NYSE')
asset2 = EquityMock(2, exchange='NYSE')
position = Position(
asset1, quantity=100, book_cost_ps=950.0,
current_trade_price=950.0
)
dt = pd.Timestamp('2015-05-06')
transaction = Transaction(
asset2, quantity=50, dt=dt, price=960.0,
order_id=123, commission=None
)
with self.assertRaises(Exception):
position.update(transaction)
def test_transact_position_new_position(self):
"""
Tests the 'transact_position' method for a transaction
with a brand new asset and checks that all objects are
set correctly.
"""
# Create the PositionHandler, Transaction and
# carry out a transaction
ph = PositionHandler()
asset = EquityMock(1, exchange='NYSE')
dt = pd.Timestamp('2015-05-06')
transaction = Transaction(
asset, quantity=100, dt=dt, price=960.0,
order_id=123, commission=26.83
)
ph.transact_position(transaction)
# Check that the position object is set correctly
pos = ph.positions[asset]
self.assertEqual(pos.quantity, 100)
self.assertEqual(pos.direction, 1.0)
self.assertEqual(pos.book_cost_ps, 960.2683000000001)
self.assertEqual(pos.book_cost, 96026.83)
def test_holdings_to_console_for_two_positions(self):
"""
Tests the 'holdings_to_console' console output for
two Position entities within the Portfolio.
"""
start_dt = pd.Timestamp('2017-10-05 08:00:00', tz=pytz.UTC)
asset1_dt = pd.Timestamp('2017-10-06 08:00:00', tz=pytz.UTC)
asset2_dt = pd.Timestamp('2017-10-07 08:00:00', tz=pytz.UTC)
update_dt = pd.Timestamp('2017-10-08 08:00:00', tz=pytz.UTC)
asset1 = EquityMock("AAA Inc.", "AAA", "NYSE", tax_exempt=False)
asset2 = EquityMock("BBB Inc.", "BBB", "NYSE", tax_exempt=False)
port = Portfolio(start_dt)
port.subscribe_funds(start_dt, 100000.0)
tn_asset1 = Transaction(
asset=asset1, quantity=100, dt=asset1_dt,
price=567.0, order_id=1, commission=15.78
)
port.transact_asset(tn_asset1)
tn_asset2 = Transaction(
asset=asset2, quantity=100, dt=asset2_dt,
price=123.0, order_id=2, commission=7.64
)
port.transact_asset(tn_asset2)
test_str = "\x1b[1;36m\nPortfolio Holdings | None - None\n\n" \
"\x1b[0m*======================================================" \
"============================================*\n" \
"| Holding | Quantity | Price | Change | Book Cost " \
"| Market Value | Unrealised Gain | \n" \
"*======================================================" \
"============================================*\n" \
zcm = ZeroBrokerCommission()
broker = SimulatedBroker(
start_dt, exchange,
account_id=1234,
initial_funds=cash,
broker_commission=zcm
)
bpid = "2222"
broker.create_portfolio(bpid)
broker.subscribe_funds_to_portfolio(bpid, cash)
tn1 = Transaction(
assets[0], 100, start_dt, price=45.78,
order_id=1, commission=0.0
)
tn2 = Transaction(
assets[1], 200, start_dt, price=26.32,
order_id=2, commission=0.0
)
tn3 = Transaction(
assets[2], -100, start_dt, price=62.432,
order_id=3, commission=0.0
)
broker.portfolios[bpid].transact_asset(tn1)
broker.portfolios[bpid].transact_asset(tn2)
broker.portfolios[bpid].transact_asset(tn3)
# Create portfolio construction model
ewpcm = EqualWeightPCM(
start_dt, broker, bpid,
transaction_cost_model=zcm
)
def test_update_commission(self):
"""
Tests the 'update_commission' method to ensure
commission is correctly set on the Position entities.
"""
ph = PositionHandler()
# Asset 1
asset1 = EquityMock(1, exchange='NYSE')
dt1 = pd.Timestamp('2015-05-06')
trans_pos_1 = Transaction(
asset1, quantity=75, dt=dt1, price=483.45,
order_id=1, commission=0.0
)
ph.transact_position(trans_pos_1)
ph.update_commission(asset1, 15.97)
# Asset 2
asset2 = EquityMock(2, exchange='NYSE')
dt2 = pd.Timestamp('2015-05-07')
trans_pos_2 = Transaction(
asset2, quantity=250, dt=dt2, price=142.58,
order_id=2, commission=0.0
)
ph.transact_position(trans_pos_2)
ph.update_commission(asset2, 8.35)
# Check all total values
self.assertEqual(ph.total_book_cost(), 71928.07)
def test_position_short_long_insufficient_cover(self):
"""
Tests that the quantity and book cost are
correctly calculated for an initial short
position with an additional long transaction
in the same asset, where the long does not
completely eliminate the position.
"""
asset = EquityMock(1, exchange='NYSE')
position = Position(
asset, quantity=-100, book_cost_ps=950.0,
current_trade_price=950.0
)
dt = pd.Timestamp('2015-05-06')
transaction = Transaction(
asset, quantity=50, dt=dt, price=960.0,
order_id=123, commission=None
)
position.update(transaction)
self.assertEqual(position.quantity, -50)
self.assertEqual(position.book_cost_ps, 950.0)
self.assertEqual(position.direction, -1.0)
self.assertEqual(position.current_trade_price, 960.0)
self.assertEqual(position.market_value, -48000.0)
self.assertEqual(position.unr_gain, -500.0)
self.assertEqual(position.unr_perc_gain, -1.0526315789473684)
)
position.update(transaction)
self.assertEqual(position.quantity, 400)
self.assertEqual(position.book_cost_ps, 2.25)
# First short
dt = pd.Timestamp('2015-05-08')
transaction = Transaction(
asset, quantity=-100, dt=dt, price=3.5,
order_id=123, commission=None
)
position.update(transaction)
self.assertEqual(position.quantity, 300)
self.assertEqual(position.book_cost_ps, 2.25)
# Final long
dt = pd.Timestamp('2015-05-09')
transaction = Transaction(
asset, quantity=100, dt=dt, price=4.0,
order_id=123, commission=None
)
position.update(transaction)
self.assertEqual(position.quantity, 400)
self.assertEqual(position.book_cost_ps, 2.6875)
self.assertEqual(position.direction, 1.0)
self.assertEqual(position.current_trade_price, 4.0)
self.assertEqual(position.market_value, 1600.0)
self.assertEqual(position.unr_gain, 525.0)
self.assertEqual(position.unr_perc_gain, 48.837209302325576)