Removing cash from portfolio to pay taxes

Hi All,

I'd like to make my testing more realistic by accounting for taxes. In my algorithm, I've come up with a method for determining the amount of tax due when a sale occurs. My problem is that I can't figure out how to pay the taxes.

I've tried reducing the amount of cash in my portfolio with code like this in the handle_data method:

 if context.taxes_due != None:
context.portfolio.cash = context.portfolio.cash - context.taxes_due
context.taxes_due = None


But on the next pass through handle_data, the cash is back in my portfolio. I suspect I'm missing something pretty simple here, can anyone tell me how to remove cash from my portfolio?

--Rick

13 responses

Hi Rick,

This may be doable with a custom/hack commission model. I posted a question: https://www.quantopian.com/posts/possible-to-write-a-custom-commission-model.

Grant

Hi Rick,

This is a real hack, but it seems like it might work (some additional tweaking to make it practical):

def initialize(context):
pass

set_commission(CashOut())
def handle_data(context, data):
cash = context.portfolio.cash
record(cash = cash)
order(sid(38986), 1) # VGSH
"""
Calculates a commission for a transaction based on a per
"""

def __init__(self, cost=5.0):
"""
Cost parameter is the cost of a trade, regardless of
share count. $5.00 per trade is fairly typical of discount brokers. """ # Cost needs to be floating point so that calculation using division # logic does not floor to an integer. self.cost = float(cost) def calculate(self, transaction): """ returns a tuple of: (per share commission, total transaction commission) """ if transaction.amount == 0: return 0, 0 if transaction.amount == 1: return 1000, 1000 #$1000 for testing

return abs(self.cost / transaction.amount), self.cost


The basic idea is to have a special commission when ordering exactly one share of VGSH (which should be equivalent to cash, right?). In the algorithm, this special case of ordering one share then needs to be avoided.

Additional code needs to be added to compute the tax (I used \$1000 as a placeholder).

Grant

Hi Grant,

Thanks for that response... looks like you've been digging in some code.

But despite my best efforts, I can't seem to get this to work. I've updated my code to be very simple, the calculate method just returns a tuple so that I can change the numbers and see what effect they have. So far as I can tell, the first value of the tuple works as expected. But the second value (which is of course the one I am trying to use since I know the total amount of taxes due) seems to be ignored no matter what I return. If you have any more insights, that'd be great. If not, I guess since I know the total amount due and the number of shares being traded, I could just figure out the tax due per share.

Cheers,
--Rick

Hi Rick,

How is the tax to be computed? In your original post, you have context.taxes_due, but how would one arrive at the value? Are taxes paid at the time of the transaction, or quarterly/annually?

It might be that a custom commission model is not required, if you can roll the taxes into an effective commission.

Grant

Hi Grant,

Taxes are paid at the time of the transaction based on the gain and whether it is short- or long-term. I updated the code so that the custom commission model takes the total amount due and computes the per-share tax. That seems to have things working nicely.

I guess I was hoping there'd be a much simpler way to do this, like setting the cash value in my original post, but at least I have something that works now. I really appreciate your help.

Cheers,
--Rick

Rick, it's a good question. Grant, thanks for giving that great workaround.

Unfortunately we don't have a tax model set yet. You can repurpose slippage and/or commissions to capture the taxes, but we don't have module created specifically for taxes yet.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

Hi Dan,

Yeah, I wasn't really looking for a tax model. I understand how complicated that could be. All I was looking for is a way to pull out cash based on a model of my own making.

Cheers,
--Rick

Hi Rick,

Would you mind posting the code that you ended up using? I'm curious what you did.

Grant

Sure, here's a skeleton of what I ended up with...

def initialize(context):
set_commission(TaxableTransaction(8.95, context))
# Other stuff omitted for brevity

def handle_data(context, data):
# Some code that decides if we need to order or not and calls 'order' if we do

def order(context, weight):
context.taxes_due = determine_taxes_due(context, weight)
order_target_percent(context.sid, weight)

def determine_taxes_due(context, weight):
if taxes_due > 0:
return taxes_due
return None

self.context = context
def calculate(self, transaction):
cost = self.cost
if self.context.taxes_due != None:
cost = cost + self.context.taxes_due
self.context.taxes_due = None
cost_per_share = abs(cost / transaction.amount)
return cost_per_share, 0


Hi Rick, Grant,

Thank you for the tips you've gathered here for modeling taxes. I am currently considering how to do this myself, and I was wondering if this is what you're still using? I have a few questions about your experience with this model:

• How do you handle position losses? Specifically how do you balance out gains made elsewhere? I assume you would be able to keep a running total in the context object and drain it periodically, perhaps on an annual basis. But then that leads to my next question...

• How do the taxes show up in the backtest? Is it the case that transactions occasionally look artificially bad/inflated? Or is there some other mechanism you have for managing how the backtest reports taxes? One thought I had was to keep aside a "boring" security, and never trade in that except on the first day of the year where I add in the entire tax burden.

Thanks for the excellent ideas here.

Sunil

Hello Sunil,

I haven't continued working on this. I'll leave it to others to respond.

Cheers,

Grant

This thread seems to be referenced from many other threads as the closest thing Quantopian's got to removing (or adding - can commission be negative?) cash into a portfolio during the simulation. Nobody seems to mention that it must break the accounting for the Position object. The TaxableTransaction class here removes context.taxes_due from the portfolio, but it would lead to an incorrect cost_basis in the position object if the trade is a Buy. Seems especially ironic that people want this feature so they can account for taxes, but the best hack available makes it harder to calculate taxes (because your basis is wrong).

At any rate, the code implementing commissions must be removing value from the portfolio. The accounting must be already be there. Couldn't we just have an API: context.remove_value() and/or context.add_value()? That would let people who want to model taxes do it all themselves. (Same for people who want to model periodic contribution) We don't need a "tax model", just support for the simple primitive of changing the portfolio value.

Edit: Looked into the zipline code, and it all comes down to this:

 def handle_commission(self, cost):
# Deduct from our total cash pool.