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
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'))
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'))
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)
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)