Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Implementation of tax simulation

Hello all,

Wanted to share/get feedback on some work I've done in simulating taxes using the commission API. Taxes are collected the first trading day of every year. And taxes are attached as commission when I purchase one stock of IBM. I never trade IBM otherwise. I haven't tried holding anything long term, so I haven't implemented that. And I assume fixed tax rates for all time, and don't handle dividends, because doing anything else seems to be really hard. Let me know what you think!

import zipline.finance.commission

stock_to_tax = symbol('IBM')

class CombinedCommissions(commission.PerShare):  
    def __init__(self, *commissions):  
        self.commissions = commissions

    def calculate(self, transaction):  
        per_share = 0  
        total = 0  
        for c in self.commissions:  
            c_per_share, c_total = c.calculate(transaction)  
            per_share += c_per_share  
            total += c_total  
        return per_share, total

class ComputeProfitLoss(commission.PerShare):  
    def __init__(self, context):  
        self.context = context

    def calculate(self, transaction):  
        # Recording profit/loss on taxed stock SID will result in following  
        # year's taxes being  
        if transaction.sid == stock_to_tax:  
            return 0.0, 0.0  
        # This will only work for long-only portfolios If portfolio has  
        # short positions, we will want to base taxibility on existence of  
        # position alone?  
        if transaction.amount > 0:  
            return 0.0, 0.0  
        position = self.context.portfolio.positions[transaction.sid]  
        if position:  
            pl = (transaction.price - position.cost_basis)*(-transaction.amount)  
            if pl < 0:  
                self.context.loss += pl  
            else:  
                # TODO Use position date to decide long vs short term  
                self.context.short_term_gain += pl  
        return 0.0, 0.0

class ApplyTax(commission.PerShare):  
    def __init__(self, context):  
        self.context = context

    def calculate(self, transaction):  
        if transaction.sid == stock_to_tax and transaction.amount == 1:  
            st_taxable = self.context.short_term_gain + self.context.loss  
            lt_taxable = self.context.long_term_gain  
            self.context.short_term_gain = 0.0  
            self.context.long_term_gain = 0.0  
            self.context.loss = 0.0  
            if st_taxable < 0:  
                lt_taxable += st_taxable  
                st_taxable = 0  
            # Apply uniformly for all years, which is wrong  
            tax = st_taxable * 0.3 + lt_taxable * 0.15  
            if tax < 0:  
                tax = 0.0  
            log.info('Applying tax {0}'.format(tax))  
            return tax, tax  
        else:  
            return 0.0, 0.0

def apply_tax(context, data):  
    if get_datetime().month == 1:  
        order(stock_to_tax, 1)  
    else:  
        order_target_value(stock_to_tax, 0.0)

def initialize(context):  
    ...  
        if arena == 'backtest':  
        set_commission(CombinedCommissions(commission.PerShare(cost=0.0075, min_trade_cost=1.00),  
                                           ComputeProfitLoss(context),  
                                           ApplyTax(context)))  
        schedule_function(apply_tax,  
                          date_rule=date_rules.month_start(),  
                          time_rule=time_rules.market_open(minutes=30))  
    ...