Skip to content

Commit

Permalink
BUG: Position cost basis was calculated incorrectly for Futures
Browse files Browse the repository at this point in the history
For futures, we need to divide the position’s commission by the
contract size to get a per-unit commission in order to properly update
the position’s cost basis.
  • Loading branch information
Jean Bredeche committed Apr 20, 2017
1 parent b680db9 commit aabb914
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
35 changes: 35 additions & 0 deletions tests/test_perf_tracking.py
Expand Up @@ -2056,6 +2056,41 @@ def test_position_values_and_exposures(self):
self.assertEqual(100 + 200 + 300000 + 400000, pos_stats.gross_exposure)
self.assertEqual(100 - 200 + 300000 - 400000, pos_stats.net_exposure)

def test_cost_basis(self):
dt = pd.Timestamp("2015-12-10 15:00", tz='UTC')

equity_pos = perf.Position(
self.EQUITY1,
amount=10,
last_sale_date=dt,
cost_basis=10,
last_sale_price=11,
)

future_pos = perf.Position(
self.FUTURE3,
amount=10,
last_sale_date=dt,
cost_basis=10,
last_sale_price=11,
)

self.assertEqual(10, equity_pos.cost_basis)

# send a $5 commission to the equity position. Spread out over 10
# shares, that bumps the cost basis by $0.50.
equity_pos.adjust_commission_cost_basis(self.EQUITY1, 5)
self.assertEqual(10.5, equity_pos.cost_basis)

self.assertEqual(10, future_pos.cost_basis)

# send a $5k commission to the futures position. since self.FUTURE3
# has a contract size (multipler) of 1000, this should result in a
# $10.5 updated cost basis. (5000 / 1000 = $5, spread out over 10
# contracts, is $0.50 extra per contract).
future_pos.adjust_commission_cost_basis(self.FUTURE3, 5000)
self.assertEqual(10.5, future_pos.cost_basis)

def test_update_positions(self):
pt = perf.PositionTracker(self.env.asset_finder, None)
dt = pd.Timestamp("2014/01/01 3:00PM")
Expand Down
6 changes: 5 additions & 1 deletion zipline/finance/performance/position.py
Expand Up @@ -173,7 +173,11 @@ def adjust_commission_cost_basis(self, asset, cost):
return

prev_cost = self.cost_basis * self.amount
new_cost = prev_cost + cost
if isinstance(asset, Future):
cost_to_use = cost / asset.multiplier
else:
cost_to_use = cost
new_cost = prev_cost + cost_to_use
self.cost_basis = new_cost / self.amount

def __repr__(self):
Expand Down

0 comments on commit aabb914

Please sign in to comment.