npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@selmecir/fifo-capital-gains-js

v0.2.2

Published

Calculate your FIFO capital gains for tax-purposes with BigNumber.js

Downloads

96

Readme

FIFO Capital Gains

Calculate your FIFO capital gains for tax-purposes

Build Status NPM version Downloads Standard Version


✨ Features

  • Generate FIFO capital gains per sale
  • Ability to aggregate capital gains per civil year
  • Supports differentation of securities by using a symbol (e.g., stock ticker)

🔧 Installation

npm install --save fifo-capital-gains-js

🎬 Getting started

Let's demonstrate a simple usage by obtaining the FIFO capital gains per civil year:

const operationHistory = [
  {
    amount: 10,
    date: new Date('2020-01-01'),
    price: 100,
    symbol: 'STK1',
    type: 'BUY',
  },
  {
    amount: 10,
    date: new Date('2020-02-01'),
    price: 150,
    symbol: 'STK1',
    type: 'BUY',
  },
  {
    amount: 8,
    date: new Date('2020-03-01'),
    price: 200,
    symbol: 'STK1',
    type: 'SELL',
  },
  {
    amount: 7,
    date: new Date('2021-01-01'),
    price: 300,
    symbol: 'STK1',
    type: 'SELL',
  },
]

const capitalGainsByYear = aggregateByYear(
  calculateFIFOCapitalGains(operationHistory)
)
// {
//   2020: 800,
//   2021: 1150,
// }

Now, let's say just you want the FIFO capital gains per operation, so you can execute your custom logic:

const operationHistory = [
  {
    amount: 10,
    date: new Date('2020-01-01'),
    price: 100,
    symbol: 'STK1',
    type: 'BUY',
  },
  {
    amount: 10,
    date: new Date('2020-02-01'),
    price: 150,
    symbol: 'STK1',
    type: 'BUY',
  },
  {
    amount: 15,
    date: new Date('2020-03-01'),
    price: 200,
    symbol: 'STK1',
    type: 'SELL',
  },
]

const capitalGains = calculateFIFOCapitalGains(operationHistory)
// [
//   {
//     sale: { <-- Operation that originated the capital gains
//       amount: 15,
//       date: new Date('2020-03-01'),
//       price: 200,
//       symbol: 'STK1',
//       type: 'SELL',
//     },
//     capitalGains: 1250, <-- Capital gains = (200-100)*10 + (200-150)*5
//   },
// ]

Note: When you have multiple securities, you can use the symbol property in operations to distinguish between them.

In case you want to aggregate the capital gains by civil year, regardless of the symbols that produced them, you can use the aggregateByYear function:

const capitalGains = [
  {
    sale: {
      amount: 1,
      date: new Date('2020-01-01'),
      price: 1500,
      symbol: 'STK2',
      type: 'SELL',
    },
    capitalGains: 400,
  },
  {
    sale: {
      amount: 1,
      date: new Date('2020-06-01'),
      price: 2000,
      symbol: 'STK1',
      type: 'SELL',
    },
    capitalGains: 300,
  },
  {
    sale: {
      amount: 1,
      date: new Date('2021-01-01'),
      price: 2000,
      symbol: 'STK1',
      type: 'SELL',
    },
    capitalGains: 500,
  },
]

const capitalGainsByYear = aggregateByYear(capitalGains)
// {
//   2020: 700,
//   2021: 500,
// }

📜 API

Operations are represented using the Operation object. Its composition is the following:

interface Operation {
  /**
   * Symbol that identifies the underlying security. It is used only for differentation between
   * operations of different securities. Can be the stock ticker or any other identifier that
   * is different from other securities'.
   */
  symbol: string

  /**
   * Date when the operation took place
   */
  date: Date

  /**
   * Price of the security when the operation took place.
   * If it is a buy operation, this is the buying price; if a sell operation,
   * then this is the selling price.
   */
  price: number

  /**
   * Number of units transacted.
   */
  amount: number

  /**
   * Type of the operation
   */
  type: 'BUY' | 'SELL'
}

Capital gains are represented using the CapitalGains object, which is defined as:

interface CapitalGains {
  /**
   * Sale that triggered the capital gains
   */
  sale: Operation

  /**
   * Capital gains triggered from the sale
   */
  capitalGains: number
}

calculateFIFOCapitalGains(operationHistory: Operation[]): CapitalGains[]

This method calculates the FIFO capital gains for each sell operation in the given operation history. It separates capital gains of securities using the symbols given in each operation.

operationHistory contains the history of operations (buy and sales) to calculate the capital gains for.

This method will throw if the amount of securities of all sell operations of a given symbol exceeds the amount of securities of all buy operations for the same symbol. This indicates that there is an error in the input, since it is not possible to sell more securities than the ones bought.

Example:

const operationHistory = [
  {
    amount: 10,
    date: new Date('2020-01-01'),
    price: 100,
    symbol: 'STK1',
    type: 'BUY',
  },
  {
    amount: 10,
    date: new Date('2020-02-01'),
    price: 150,
    symbol: 'STK1',
    type: 'BUY',
  },
  {
    amount: 15,
    date: new Date('2020-03-01'),
    price: 200,
    symbol: 'STK1',
    type: 'SELL',
  },
]

const capitalGains = calculateFIFOCapitalGains(operationHistory)
// [
//   {
//     sale: { <-- Operation that originated the capital gains
//       amount: 15,
//       date: new Date('2020-03-01'),
//       price: 200,
//       symbol: 'STK1',
//       type: 'SELL',
//     },
//     capitalGains: 1250, <-- Capital gains = (200-100)*10 + (200-150)*5
//   },
// ]

aggregateByYear(saleCapitalGains: CapitalGains[]): YearlyCapitalGains

This method aggregates the capital gains generated by a sequence of sales in a yearly basis. It returns an object with the civil year as its key and the capital gains generated in the given year as its value.

saleCapitalGains is an array of capital gains generated by sell operations. It can be generated by calling calculateFIFOCapitalGains with the operation history.

Example:

const capitalGains = [
  {
    sale: {
      amount: 1,
      date: new Date('2020-01-01'),
      price: 1500,
      symbol: 'STK2',
      type: 'SELL',
    },
    capitalGains: 400,
  },
  {
    sale: {
      amount: 1,
      date: new Date('2020-06-01'),
      price: 2000,
      symbol: 'STK1',
      type: 'SELL',
    },
    capitalGains: 300,
  },
  {
    sale: {
      amount: 1,
      date: new Date('2021-01-01'),
      price: 2000,
      symbol: 'STK1',
      type: 'SELL',
    },
    capitalGains: 500,
  },
]

const capitalGainsByYear = aggregateByYear(capitalGains)
// {
//   2020: 700,
//   2021: 500,
// }

calculateSalesForNetWithdrawal(history: Operation[], options: NetSalesOptions): Operation[]

This method calculates the sales required to obtain a withdrawal amount set, given the history of purchases and sales and some settings.

const history: Operation[] = [
  {
    amount: 10,
    date: new Date('2020-01-01'),
    price: 100,
    symbol: 'STK1',
    type: 'BUY',
  },
  {
    amount: 10,
    date: new Date('2021-01-01'),
    price: 200,
    symbol: 'STK2',
    type: 'BUY',
  },
  {
    amount: 10,
    date: new Date('2021-01-01'),
    price: 200,
    symbol: 'STK1',
    type: 'BUY',
  },
]

const options: NetSalesOptions = {
  netWithdrawal: 4000,
  capitalGainsTax: 0.5,
  date: new Date('2022-01-01'),
  prices: { STK1: 300, STK2: 600 },
}

const sales = calculateSalesForNetWithdrawal(history, options))
// [
//   {
//     amount: 10,
//     date: new Date('2022-01-01'),
//     price: 300,
//     symbol: 'STK1',
//     type: 'SELL',
//   },
//   {
//     amount: 5,
//     date: new Date('2022-01-01'),
//     price: 600,
//     symbol: 'STK2',
//     type: 'SELL',
//   },
// ])

🥂 License

MIT as always