コード例 #1
0
def run_test(input_csv, expected_out_csv):
  lots = lot.load_lots(input_csv)
  out = wash.perform_wash(lots, progress_logger.NullLogger())
  expected = lot.load_lots(expected_out_csv)
  out.sort(cmp=wash.cmp_by_buy_date)
  expected.sort(cmp=wash.cmp_by_buy_date)
  if out != expected:
    print "Test failed:", input_csv
    print "Got result:"
    lot.print_lots(out)
    print "\nExpected:"
    lot.print_lots(expected)
  else:
    print "Test passed:", input_csv
コード例 #2
0
ファイル: wash.py プロジェクト: kbloom/wash-sale-calculator
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--out_file')
    parser.add_argument('-w', '--do_wash', metavar='in_file')
    parser.add_argument('-q', '--quiet', action="store_true")
    parser.add_argument('-m',
                        '--merge_split_lots',
                        action="store_true",
                        help='''Any split lots are merged back together at end.
                      This makes it easier to match the output to the input
                      lots, but can cause the buy-dates to be slightly
                      incorrect since a lot can only have a single buy date.
                      In this mode, some wash sale lots may have a loss that
                      is greater than the adjustment amount, instead of being
                      identical, i.e., only part of the loss in the lot is
                      actually a wash sale. This is expected in this mode..''')
    parser.add_argument(
        '-r',
        '--adjust_for_dollar_rounding',
        action="store_true",
        help='''Some tax software packages will round the basis,
                      proceeds and adjustment to calculate the total loss (or
                      profit). This can cause problems for wash sales which
                      instead of having a loss of $0 may now have a profit of
                      $1, which results in a warning about a wash sale lot with
                      a profit. Fix this by slightly modifying the adjustment
                      amount so that the final loss will be $0 in such cases.
                      It is safe to use this option with the merge_split_lots
                      option.''')
    parsed = parser.parse_args()

    if parsed.do_wash:
        lots = lot.load_lots(open(parsed.do_wash))
        lot.print_lots(lots, False)
        if parsed.quiet:
            logger = progress_logger.NullLogger()
        else:
            logger = progress_logger.TermLogger()
        out = perform_wash(lots, logger)

        # merge split lots back together, if asked.
        if parsed.merge_split_lots:
            out = lot.merge_split_lots(out)

        # make the adjustment safe for whole-dollar rounding arithmentic
        if parsed.adjust_for_dollar_rounding:
            lot.adjust_for_dollar_rounding(out)

        # readable text output
        print 'output:'
        lot.print_lots(out,
                       merged=parsed.merge_split_lots,
                       rounded_dollars=parsed.adjust_for_dollar_rounding)

        # CSV text output
        if parsed.out_file:
            print 'Saving final lots to', parsed.out_file
            lot.save_lots(out, open(parsed.out_file, 'w'))
コード例 #3
0
def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('-o', '--out_file')
  parser.add_argument('-w', '--do_wash', metavar='in_file')
  parser.add_argument('-q', '--quiet', action="store_true")
  parser.add_argument('-m', '--merge_split_lots', action="store_true",
                      help='''Any split lots are merged back together at end.
                      This makes it easier to match the output to the input
                      lots, but can cause the buy-dates to be slightly
                      incorrect since a lot can only have a single buy date.
                      In this mode, some wash sale lots may have a loss that
                      is greater than the adjustment amount, instead of being
                      identical, i.e., only part of the loss in the lot is
                      actually a wash sale. This is expected in this mode..''')
  parser.add_argument('-r', '--adjust_for_dollar_rounding', action="store_true",
                      help='''Some tax software packages will round the basis,
                      proceeds and adjustment to calculate the total loss (or
                      profit). This can cause problems for wash sales which
                      instead of having a loss of $0 may now have a profit of
                      $1, which results in a warning about a wash sale lot with
                      a profit. Fix this by slightly modifying the adjustment
                      amount so that the final loss will be $0 in such cases.
                      It is safe to use this option with the merge_split_lots
                      option.''')
  parsed = parser.parse_args()

  if parsed.do_wash:
    lots = lot.load_lots(open(parsed.do_wash))
    lot.print_lots(lots, False)
    if parsed.quiet:
      logger = progress_logger.NullLogger()
    else:
      logger = progress_logger.TermLogger()
    out = perform_wash(lots, logger)

    # merge split lots back together, if asked.
    if parsed.merge_split_lots:
      out = lot.merge_split_lots(out)

    # make the adjustment safe for whole-dollar rounding arithmentic
    if parsed.adjust_for_dollar_rounding:
      lot.adjust_for_dollar_rounding(out)

    # readable text output
    print 'output:'
    lot.print_lots(out, merged=parsed.merge_split_lots,
                   rounded_dollars=parsed.adjust_for_dollar_rounding)

    # CSV text output
    if parsed.out_file:
      print 'Saving final lots to', parsed.out_file
      lot.save_lots(out, open(parsed.out_file, 'w'))
コード例 #4
0
def run_test(input_csv, expected_out_csv, merge_split_lots=False,
        rounded_dollars=False):
  lots = lot.load_lots(open(input_csv))
  out = wash.perform_wash(lots, progress_logger.NullLogger())
  out.sort(cmp=wash.cmp_by_buy_date)

  # merge split lots back together, if asked.
  if merge_split_lots:
    out = lot.merge_split_lots(out)

  # make the adjustment safe for whole-dollar rounding arithmentic
  if rounded_dollars:
    lot.adjust_for_dollar_rounding(out)

  # Sort both out and expected the same way, so we can compare them.
  out.sort(cmp=wash.cmp_by_buy_date)
  out_csv = StringIO.StringIO()
  lot.save_lots(out, out_csv)

  expected = lot.load_lots(open(expected_out_csv))
  expected.sort(cmp=wash.cmp_by_buy_date)
  expected_csv = StringIO.StringIO()
  lot.save_lots(expected, expected_csv)

  # Report pass/fail
  mods = "(merged split-lots) " if merge_split_lots else ""
  mods += "(safe for whole-dollar arithmetic) " if rounded_dollars else ""
  # lot.__eq__ compares all members, including original_form_position
  # and will also include any future internal data members. So, to compare
  # the test vs expected, we use the output CSV file for both, which should
  # be invariant.
  if out_csv.getvalue() != expected_csv.getvalue():
    print "****\n%sTest failed: %s" % (mods, input_csv)
    print "Got result:"
    print out_csv.getvalue()
    print "\nExpected output:", expected_out_csv
    print expected_csv.getvalue()
  else:
    print "%sTest passed: %s" % (mods, input_csv)
コード例 #5
0
ファイル: wash.py プロジェクト: fberger/wash-sale-calculator
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--out_file')
    parser.add_argument('-w', '--do_wash', metavar='in_file')
    parser.add_argument('-q', '--quiet', action="store_true")
    parsed = parser.parse_args()

    if parsed.do_wash:
        lots = lot.load_lots(parsed.do_wash)
        lot.print_lots(lots)
        if parsed.quiet:
            logger = progress_logger.NullLogger()
        else:
            logger = progress_logger.TermLogger()
        out = perform_wash(lots, logger)
        print 'output:'
        lot.print_lots(out)
        if parsed.out_file:
            print 'Saving final lots to', parsed.out_file
            lot.save_lots(out, parsed.out_file)
コード例 #6
0
ファイル: wash.py プロジェクト: koff75/wash-sale-calculator
def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('-o', '--out_file')
  parser.add_argument('-w', '--do_wash', metavar='in_file')
  parser.add_argument('-q', '--quiet', action="store_true")
  parsed = parser.parse_args()

  if parsed.do_wash:
    lots = lot.load_lots(parsed.do_wash)
    lot.print_lots(lots)
    if parsed.quiet:
      logger = progress_logger.NullLogger()
    else:
      logger = progress_logger.TermLogger()
    out = perform_wash(lots, logger)
    print 'output:'
    lot.print_lots(out)
    if parsed.out_file:
      print 'Saving final lots to', parsed.out_file
      lot.save_lots(out, parsed.out_file)