liveBook · Manning

Cost basis

As explained in Build a Robo-Advisor with Python (From Scratch)

Cost basis is the tax-accounting value assigned to an investment for determining taxable gain or loss when it is disposed of.

Cost basis is the tax-accounting value assigned to an investment. It sets the reference point for taxable gains or losses when the investment is sold: a lower basis produces a larger gain at the same sale price, while a higher basis produces a smaller gain or a larger loss. In portfolio projections, basis is therefore separate from current value and expected return. section 8.1 section 14.1.1

Treat cost basis as a state variable for each asset. A taxable-account model can begin with both a starting value and an initial basis, alongside return, payout, capital-gains tax rate, ordinary-income tax rate, and turnover. When holdings are sold and reinvested, the model assumes the average-cost method for tax purposes, so basis must remain part of the asset record rather than being inferred from value alone. section 8.1

Tax-loss harvesting lowers basis

Suppose an ETF bought for $100,000 falls to $95,000. Selling it realizes a $5,000 loss; at a 20% tax rate, that loss can offset $1,000 of current tax. Reinvesting the $95,000 proceeds in a similar ETF preserves roughly the same exposure, but the replacement position has a $95,000 basis. If it later sells for $150,000, the realized gain is $55,000 and tax is $11,000 at 20%, versus a $50,000 gain and $10,000 tax had the original ETF been held. The benefit is deferring the $1,000 payment, not eliminating it. section 14.1.1

The value of a lower basis depends on timing. Realizing a loss can free cash from a current tax bill, while the reduced basis creates a future tax liability. With the future tax rate held constant, the economic benefit of the deferral depends on how long the later payment is postponed and the discount rate used to value that future payment. section 14.1.1

Listing 8.1 Defining the Asset() class
class Asset():
    def __init__(self, avg_ret=0.08, payout_rate=0.0, tax_rate_payout=0.2,  #1
                 tax_rate_cap_gains=0.2, tax_rate_ord_inc=0.35,  
                 turnover_rate=0, starting_value=500000, cost_basis=500000):
        self.avg_ret = avg_ret
        self.payout_rate = payout_rate
        self.tax_rate_payout = tax_rate_payout
        self.tax_rate_cap_gains = tax_rate_cap_gains
        self.tax_rate_ord_inc = tax_rate_ord_inc
        self.turnover_rate = turnover_rate
        self.starting_value = starting_value
        self.cost_basis = cost_basis
    def IRA_value(self, horizon=30):
        pretax_value = self.starting_value * (1+self.avg_ret)**horizon
        aftertax_value = pretax_value * (1-self.tax_rate_ord_inc)
        return aftertax_value
    def Taxable_value(self, horizon=30):
        curr_cost_basis = self.cost_basis
        curr_value = self.starting_value
        for year in range(1, horizon+1):
            taxes_div = self.payout_rate * curr_value * self.tax_rate_payout
            taxes_cap_gain = (self.turnover_rate * curr_value
                              * self.tax_rate_cap_gains)
            curr_cost_basis += ((self.payout_rate * curr_value)   #2
                               + (self.turnover_rate * curr_value)
                               - (taxes_div + taxes_cap_gain))
            curr_value = (curr_value * (1+self.avg_ret) 
                          - (taxes_div + taxes_cap_gain))
        aftertax_value = (curr_value 
                          - (curr_value - curr_cost_basis) 
                          * self.tax_rate_cap_gains)
        return aftertax_value
    def Taxable_minus_IRA(self, horizon=30):
        difference = (self.Taxable_value(horizon) - self.IRA_value(horizon) 
                      - self.starting_value * self.tax_rate_ord_inc)  #3
        return difference        
   
    def Roth_value(self, horizon=30):
        aftertax_value = self.starting_value * (1+self.avg_ret)**horizon
        return aftertax_value  

Use the Asset class as a compact implementation pattern: store cost_basis beside starting_value and tax assumptions, then compare projected IRA and taxable values. section 8.1

How Build a Robo-Advisor with Python (From Scratch) covers it

How deep it goes
Defines basis operationally and works through its change after a loss-harvesting trade, without detailing tax-lot rules beyond average cost.
Examples
Uses a $100,000 ETF falling to $95,000 and later selling at $150,000, plus an Asset class with a cost_basis parameter.
What it assumes
Assumes familiarity with investment returns and taxes while introducing basis through explicit asset inputs and numerical gains.
What you can do after
Evaluate/understand how realizing a loss lowers replacement basis and shifts tax from the present to a later sale.
How it connects
Connects cost basis to capital gains, taxable accounts, tax-loss harvesting, tax deferral, and asset location.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build a Robo-Advisor with Python (From Scratch). The section links point to the parts of the book it draws on.