Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can sell more coins than what you have... without warning or raising an exception #2

Open
c0indev3l opened this issue Nov 29, 2023 · 3 comments

Comments

@c0indev3l
Copy link

c0indev3l commented Nov 29, 2023

Hi,

I think the following code should raises an error or at least display a warning...

import coin2086

columns = ['datetime', 'trade_side', 'cryptocurrency', 'quantity', 'price', 'base_currency']  # price = prix unitaire
data = []
data.append(['2013-01-01 00:00:00', 'BUY', 'BTC', 10, 10.0, 'EUR'])
data.append(['2023-01-01 00:00:00', 'SELL', 'BTC', 11, 15_000.0, 'EUR'])
trades = pd.DataFrame(data, columns=columns)
trades["amount"] = trades["quantity"] * trades["price"]
trades["fee"] = trades["amount"] * 0.0005
display(trades)

year = 2023
allowance = 305  # EUR
form2086, taxable_profit = coin2086.compute_taxable_pnls(trades, year=year)
print(f"Total taxable profit for year {year}: {taxable_profit:.2f} euros")
if taxable_profit > allowance:
    expected_tax = (taxable_profit - allowance) * 0.3
    print(f"Expected tax amount: {expected_tax:.2f} euros")
    print(f"Fill form 2086 with the information below" )
else:
    print(f"Your profit is below {allowance} euros, your do not have to report")
  
display(form2086)

Kind regards

@c0indev3l
Copy link
Author

c0indev3l commented Nov 29, 2023

Maybe adding something like

def diff(trades):
  return trades[trades["trade_side"] == "BUY"].groupby("cryptocurrency")["quantity"].sum().reindex(trades["cryptocurrency"].unique()).fillna(0) - trades[trades["trade_side"] == "SELL"].groupby("cryptocurrency")["quantity"].sum().reindex(trades["cryptocurrency"].unique()).fillna(0)

def verify(trades):
  trades_diff = diff(trades)
  neg = trades_diff[trades_diff < 0]
  assert (trades_diff >= 0).all(), f"You can't sell more coins than what you have. See\n{neg}"

should be considered

@c0indev3l c0indev3l changed the title Can sell more coins than you have... without warning or raising an exception Can sell more coins than what you have... without warning or raising an exception Nov 29, 2023
@fandre90
Copy link
Owner

Thank you for detecting this bug and opening an issue. It looks like you are right, this is a missing check. Selling more coins than you own can happen on exchanges that support short sells, but coin2086 explicitly does not support this use case, and I have no idea of the tax treatment of such events.

I will have a look at it and add a check to prevent negative balances at any point in time, not just on average.

@c0indev3l
Copy link
Author

c0indev3l commented Dec 1, 2023

Hi @fandre90 ,

You are right ! this check shouldn't be made "on average" but at "any point in time"...
Here is an implementation idea for such a check

display(trades)
portfolio = trades[["cryptocurrency", "quantity", "trade_side"]].copy()
display(portfolio)
portfolio["sign"] = portfolio["trade_side"].map({"BUY": 1, "SELL": -1})
portfolio["signed_quantity"] = portfolio["quantity"] * portfolio["sign"]
pivoted_trades = pd.pivot_table(portfolio.reset_index(), values="signed_quantity", columns="cryptocurrency", index="index").fillna(0)
display(pivoted_trades)
display(pivoted_trades.cumsum())
display(pivoted_trades.cumsum() >= 0)
display((pivoted_trades.cumsum() >= 0).all())
display((pivoted_trades.cumsum() >= 0).all().all())
assert (pivoted_trades.cumsum() >= 0).all().all(), f"You can't sell more coins than what you have. See\n{pivoted_trades.cumsum()}"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants