diff --git a/src/investir/cli.py b/src/investir/cli.py index d167f6c..d1b9e6b 100644 --- a/src/investir/cli.py +++ b/src/investir/cli.py @@ -18,6 +18,7 @@ ) from investir.logging import configure_logger from investir.parser import ParserFactory +from investir.prettytable import OutputFormat from investir.taxcalculator import TaxCalculator from investir.transaction import Acquisition, Disposal, Transaction from investir.trhistory import TrHistory @@ -72,6 +73,12 @@ def __init__(self, opt1: str, opt2: str) -> None: ] +OutputFormatOpt = Annotated[ + OutputFormat, + typer.Option("--output", "-o", help="Output format."), +] + + def abort(message: str) -> None: logger.critical(message) raise typer.Exit(code=1) @@ -230,7 +237,7 @@ def main_callback( # noqa: PLR0913 @app.command("orders") -def orders_command( +def orders_command( # noqa: PLR0913 files: FilesArg, tax_year: TaxYearOpt = None, ticker: TickerOpt = None, @@ -240,6 +247,7 @@ def orders_command( disposals_only: Annotated[ bool, typer.Option("--disposals", help="Show only disposals.") ] = False, + output_format: OutputFormatOpt = OutputFormat.TEXT, ) -> None: """ Show share buy/sell orders. @@ -257,7 +265,7 @@ def orders_command( filters = create_filters(tax_year=tax_year, ticker=ticker, tr_type=tr_type) if table := tr_hist.get_orders_table(filters): - print(table.to_string(leading_nl=config.logging_enabled)) + print(table.to_string(output_format, leading_nl=config.logging_enabled)) @app.command("dividends") @@ -265,6 +273,7 @@ def dividends_command( files: FilesArg, tax_year: TaxYearOpt = None, ticker: TickerOpt = None, + output_format: OutputFormatOpt = OutputFormat.TEXT, ) -> None: """ Show share dividends paid out. @@ -272,7 +281,7 @@ def dividends_command( tr_hist, _ = parse(files) filters = create_filters(tax_year=tax_year, ticker=ticker) if table := tr_hist.get_dividends_table(filters): - print(table.to_string(leading_nl=config.logging_enabled)) + print(table.to_string(output_format, leading_nl=config.logging_enabled)) @app.command("transfers") @@ -285,6 +294,7 @@ def transfers_command( withdrawals_only: Annotated[ bool, typer.Option("--withdrawals", help="Show only withdrawals.") ] = False, + output_format: OutputFormatOpt = OutputFormat.TEXT, ) -> None: """ Show cash deposits and cash withdrawals. @@ -303,22 +313,26 @@ def transfers_command( filters = create_filters(tax_year=tax_year, amount_op=amount_op) if table := tr_hist.get_transfers_table(filters): - print(table.to_string(leading_nl=config.logging_enabled)) + print(table.to_string(output_format, leading_nl=config.logging_enabled)) @app.command("interest") -def interest_command(files: FilesArg, tax_year: TaxYearOpt = None) -> None: +def interest_command( + files: FilesArg, + tax_year: TaxYearOpt = None, + output_format: OutputFormatOpt = OutputFormat.TEXT, +) -> None: """ Show interest earned on cash. """ tr_hist, _ = parse(files) filters = create_filters(tax_year=tax_year) if table := tr_hist.get_interest_table(filters): - print(table.to_string(leading_nl=config.logging_enabled)) + print(table.to_string(output_format, leading_nl=config.logging_enabled)) @app.command("capital-gains") -def capital_gains_command( +def capital_gains_command( # noqa: PLR0913 files: FilesArg, gains_only: Annotated[ bool, typer.Option("--gains", help="Show only capital gains.") @@ -328,6 +342,7 @@ def capital_gains_command( ] = False, tax_year: TaxYearOpt = None, ticker: TickerOpt = None, + output_format: OutputFormatOpt = OutputFormat.TEXT, ) -> None: """ Show capital gains report. @@ -335,6 +350,12 @@ def capital_gains_command( if gains_only and losses_only: raise MutuallyExclusiveOption("--gains", "--losses") + if output_format != OutputFormat.TEXT and tax_year is None: + raise click.exceptions.UsageError( + f"The {output_format.value} format requires the option " + f"--tax-year to be used" + ) + _, tax_calculator = parse(files) tax_year = Year(tax_year) if tax_year else None ticker = Ticker(ticker) if ticker else None @@ -354,10 +375,16 @@ def capital_gains_command( if table: print(end="\n" if tax_year_idx == 0 and config.logging_enabled else "") - print(boldify(f"Capital Gains Tax Report {tax_year_short_date(tax_year)}")) - print(tax_year_full_date(tax_year)) - print(table.to_string(leading_nl=True)) - print(summary) + + if output_format == OutputFormat.TEXT: + print( + boldify(f"Capital Gains Tax Report {tax_year_short_date(tax_year)}") + ) + print(tax_year_full_date(tax_year)) + print(table.to_string(output_format)) + print(summary) + else: + print(table.to_string(output_format, leading_nl=False)) @app.command("holdings") @@ -367,6 +394,7 @@ def holdings_command( show_gain_loss: Annotated[ bool, typer.Option("--show-gain-loss", help="Show unrealised gain/loss.") ] = False, + output_format: OutputFormatOpt = OutputFormat.TEXT, ) -> None: """ Show current holdings. @@ -374,7 +402,7 @@ def holdings_command( _, tax_calculator = parse(files) ticker = Ticker(ticker) if ticker else None if table := tax_calculator.get_holdings_table(ticker, show_gain_loss): - print(table.to_string(leading_nl=config.logging_enabled)) + print(table.to_string(output_format, leading_nl=config.logging_enabled)) def main() -> None: diff --git a/src/investir/prettytable.py b/src/investir/prettytable.py index 445529b..35eb883 100644 --- a/src/investir/prettytable.py +++ b/src/investir/prettytable.py @@ -1,6 +1,7 @@ from collections.abc import Callable from datetime import date from decimal import Decimal +from enum import Enum from typing import Any import prettytable @@ -8,6 +9,13 @@ from investir.utils import boldify, unboldify +class OutputFormat(str, Enum): + TEXT = "text" + CSV = "csv" + JSON = "json" + HTML = "html" + + def date_format(format: str) -> Callable[[str, Any], str]: def _date_format(_field, val) -> str: if isinstance(val, date): @@ -31,12 +39,41 @@ def _decimal_format(_field, val) -> str: class PrettyTable(prettytable.PrettyTable): def __init__(self, *args, **kwargs) -> None: - kwargs["field_names"] = list(map(lambda f: boldify(f), kwargs["field_names"])) - super().__init__(*args, **kwargs) + self.hrules = prettytable.HEADER + self.vrules = prettytable.NONE + self.invisible_fields: set[str] = set() + + def hide_field(self, field_name: str) -> None: + self.invisible_fields.add(field_name) + + def to_string(self, output_format: OutputFormat, leading_nl: bool = True) -> str: + self._apply_formatting(output_format == OutputFormat.TEXT) + + leading = "\n" if leading_nl else "" + trailing = "\n" if output_format == OutputFormat.TEXT else "" + + fields = [ + f for f in self.field_names if unboldify(f) not in self.invisible_fields + ] + + kwargs: dict[str, Any] = {"fields": fields} + if output_format == OutputFormat.JSON: + kwargs["default"] = str + + table_str = self.get_formatted_string(output_format.value, **kwargs) + + if output_format == OutputFormat.CSV: + table_str = table_str.rstrip() + + return f"{leading}{table_str}{trailing}" + + def _apply_formatting(self, bold_titles: bool) -> None: + if bold_titles: + self.field_names = list(map(lambda f: boldify(f), self.field_names)) for f in self.field_names: - plain_f = unboldify(f) + plain_f = unboldify(f) if bold_titles else f match plain_f.split()[0].strip(), plain_f.split()[-1]: case ("Date", _) | (_, "Date"): @@ -53,21 +90,5 @@ def __init__(self, *args, **kwargs) -> None: case _: self.align[f] = "l" - self.hrules = prettytable.HEADER - self.vrules = prettytable.NONE - self.invisible_fields: set[str] = set() - - def hide_field(self, field_name: str) -> None: - self.invisible_fields.add(field_name) - - def to_string(self, leading_nl: bool = True) -> str: - nl = "\n" if leading_nl else "" - - fields = [ - f for f in self.field_names if unboldify(f) not in self.invisible_fields - ] - - return f"{nl}{self.get_string(fields=fields)}\n" - def __bool__(self) -> bool: return len(self.rows) > 0 diff --git a/tests/test_cli.py b/tests/test_cli.py index cf05e2d..bc4bdfb 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -109,6 +109,31 @@ def _execute( # Holdings ("holdings", "holdings"), ("holdings --ticker SWKS", "holdings_swks"), + # Output formats + ("orders --output text", "orders"), + ("orders --output csv", "orders_csv"), + ("orders --output json", "orders_json"), + ("orders --output html", "orders_html"), + ("dividends --output text", "dividends"), + ("dividends --output csv", "dividends_csv"), + ("dividends --output json", "dividends_json"), + ("dividends --output html", "dividends_html"), + ("interest --output text", "interest"), + ("interest --output csv", "interest_csv"), + ("interest --output json", "interest_json"), + ("interest --output html", "interest_html"), + ("transfers --output text", "transfers"), + ("transfers --output csv", "transfers_csv"), + ("transfers --output json", "transfers_json"), + ("transfers --output html", "transfers_html"), + ("capital-gains --output text", "capital_gains"), + ("capital-gains --tax-year 2022 --output csv", "capital_gains_csv"), + ("capital-gains --tax-year 2022 --output json", "capital_gains_json"), + ("capital-gains --tax-year 2022 --output html", "capital_gains_html"), + ("holdings --output text", "holdings"), + ("holdings --output csv", "holdings_csv"), + ("holdings --output json", "holdings_json"), + ("holdings --output html", "holdings_html"), ] @@ -210,6 +235,13 @@ def test_capital_gains_command_mutually_exclusive_filters(execute): assert result.exit_code != EX_OK +def test_capital_gains_command_tax_year_required(execute): + result = execute(["capital-gains", "--output", "json", DATA_FILE]) + assert not result.stdout + assert "Usage:" in result.stderr + assert result.exit_code != EX_OK + + def test_invocation_without_any_argument(execute): result = execute([], global_opts=[]) assert not result.stderr diff --git a/tests/test_cli/capital_gains_csv b/tests/test_cli/capital_gains_csv new file mode 100644 index 0000000..9e0d5b5 --- /dev/null +++ b/tests/test_cli/capital_gains_csv @@ -0,0 +1,5 @@ +Disposal Date,Identification,Security Name,ISIN,Quantity,Cost (£),Proceeds (£),Gain/loss (£) +2022-09-20,Section 104,Amazon,US0231351067,48.31896981,3493.12,4941.53,1448.41 +2022-10-14,Section 104,Microsoft,US5949181045,1.32642,324.7926690016643403072609590,319.76,-5.0326690016643403072609590 +2022-12-16,Section 104,Skyworks,US83088M1027,8.30000000,1094.155192117222311059989321,979.69,-114.465192117222311059989321 +2023-03-03,Section 104,Skyworks,US83088M1027,2.10000000,277.2021570417068497862623581,312.95,35.7478429582931502137376419 diff --git a/tests/test_cli/capital_gains_html b/tests/test_cli/capital_gains_html new file mode 100644 index 0000000..8fd1ea0 --- /dev/null +++ b/tests/test_cli/capital_gains_html @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Disposal DateIdentificationSecurity NameISINQuantityCost (£)Proceeds (£)Gain/loss (£)
20/09/2022Section 104AmazonUS023135106748.318969813493.124941.531448.41
14/10/2022Section 104MicrosoftUS59491810451.32642000324.79319.76-5.03
16/12/2022Section 104SkyworksUS83088M10278.300000001094.16979.69-114.47
03/03/2023Section 104SkyworksUS83088M10272.10000000277.20312.9535.75
diff --git a/tests/test_cli/capital_gains_json b/tests/test_cli/capital_gains_json new file mode 100644 index 0000000..686eaae --- /dev/null +++ b/tests/test_cli/capital_gains_json @@ -0,0 +1,52 @@ +[ + [ + "Disposal Date", + "Identification", + "Security Name", + "ISIN", + "Quantity", + "Cost (\u00a3)", + "Proceeds (\u00a3)", + "Gain/loss (\u00a3)" + ], + { + "Cost (\u00a3)": "3493.12", + "Disposal Date": "2022-09-20", + "Gain/loss (\u00a3)": "1448.41", + "ISIN": "US0231351067", + "Identification": "Section 104", + "Proceeds (\u00a3)": "4941.53", + "Quantity": "48.31896981", + "Security Name": "Amazon" + }, + { + "Cost (\u00a3)": "324.7926690016643403072609590", + "Disposal Date": "2022-10-14", + "Gain/loss (\u00a3)": "-5.0326690016643403072609590", + "ISIN": "US5949181045", + "Identification": "Section 104", + "Proceeds (\u00a3)": "319.76", + "Quantity": "1.32642", + "Security Name": "Microsoft" + }, + { + "Cost (\u00a3)": "1094.155192117222311059989321", + "Disposal Date": "2022-12-16", + "Gain/loss (\u00a3)": "-114.465192117222311059989321", + "ISIN": "US83088M1027", + "Identification": "Section 104", + "Proceeds (\u00a3)": "979.69", + "Quantity": "8.30000000", + "Security Name": "Skyworks" + }, + { + "Cost (\u00a3)": "277.2021570417068497862623581", + "Disposal Date": "2023-03-03", + "Gain/loss (\u00a3)": "35.7478429582931502137376419", + "ISIN": "US83088M1027", + "Identification": "Section 104", + "Proceeds (\u00a3)": "312.95", + "Quantity": "2.10000000", + "Security Name": "Skyworks" + } +] diff --git a/tests/test_cli/dividends_csv b/tests/test_cli/dividends_csv new file mode 100644 index 0000000..c53dd45 --- /dev/null +++ b/tests/test_cli/dividends_csv @@ -0,0 +1,7 @@ +Date,Security Name,ISIN,Ticker,Net Amount (£),Widthheld Amount (£) +2022-02-12,Apple,US0378331005,AAPL,1.37,0.2391180000 +2022-03-09,Microsoft,US5949181045,MSFT,3.44,0.6073200000 +2022-03-15,Skyworks,US83088M1027,SWKS,2.50,0.4430620000 +2022-05-13,Microsoft,US5949181045,MSFT,4.12,0.7230000000 +2022-06-08,Apple,US0378331005,AAPL,1.64,0.2825940000 +,,,,13.07,2.29 diff --git a/tests/test_cli/dividends_html b/tests/test_cli/dividends_html new file mode 100644 index 0000000..ce7eedd --- /dev/null +++ b/tests/test_cli/dividends_html @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateSecurity NameISINTickerNet Amount (£)Widthheld Amount (£)
12/02/2022AppleUS0378331005AAPL1.370.24
09/03/2022MicrosoftUS5949181045MSFT3.440.61
15/03/2022SkyworksUS83088M1027SWKS2.500.44
13/05/2022MicrosoftUS5949181045MSFT4.120.72
08/06/2022AppleUS0378331005AAPL1.640.28
13.072.29
diff --git a/tests/test_cli/dividends_json b/tests/test_cli/dividends_json new file mode 100644 index 0000000..38669de --- /dev/null +++ b/tests/test_cli/dividends_json @@ -0,0 +1,58 @@ +[ + [ + "Date", + "Security Name", + "ISIN", + "Ticker", + "Net Amount (\u00a3)", + "Widthheld Amount (\u00a3)" + ], + { + "Date": "2022-02-12", + "ISIN": "US0378331005", + "Net Amount (\u00a3)": "1.37", + "Security Name": "Apple", + "Ticker": "AAPL", + "Widthheld Amount (\u00a3)": "0.2391180000" + }, + { + "Date": "2022-03-09", + "ISIN": "US5949181045", + "Net Amount (\u00a3)": "3.44", + "Security Name": "Microsoft", + "Ticker": "MSFT", + "Widthheld Amount (\u00a3)": "0.6073200000" + }, + { + "Date": "2022-03-15", + "ISIN": "US83088M1027", + "Net Amount (\u00a3)": "2.50", + "Security Name": "Skyworks", + "Ticker": "SWKS", + "Widthheld Amount (\u00a3)": "0.4430620000" + }, + { + "Date": "2022-05-13", + "ISIN": "US5949181045", + "Net Amount (\u00a3)": "4.12", + "Security Name": "Microsoft", + "Ticker": "MSFT", + "Widthheld Amount (\u00a3)": "0.7230000000" + }, + { + "Date": "2022-06-08", + "ISIN": "US0378331005", + "Net Amount (\u00a3)": "1.64", + "Security Name": "Apple", + "Ticker": "AAPL", + "Widthheld Amount (\u00a3)": "0.2825940000" + }, + { + "Date": "", + "ISIN": "", + "Net Amount (\u00a3)": "13.07", + "Security Name": "", + "Ticker": "", + "Widthheld Amount (\u00a3)": "2.29" + } +] diff --git a/tests/test_cli/holdings_csv b/tests/test_cli/holdings_csv new file mode 100644 index 0000000..f68eee7 --- /dev/null +++ b/tests/test_cli/holdings_csv @@ -0,0 +1,6 @@ +Security Name,ISIN,Cost (£),Quantity,Current Value (£),Gain/Loss (£),Weight (%) +SMT,GB00BLDYK618,2196.812045454545454545454546,162.00000000,,n/a,n/a +Microsoft,US5949181045,882.3464985164979278272490710,3.62439184,,n/a,n/a +Apple,US0378331005,301.699341785252128650422842,3.00000000,,n/a,n/a +Skyworks,US83088M1027,301.0770951964634031790966809,2.295943596,,n/a,n/a +PayPal,US70450Y1038,249.59,4.13171759,,n/a,n/a diff --git a/tests/test_cli/holdings_html b/tests/test_cli/holdings_html new file mode 100644 index 0000000..10c5123 --- /dev/null +++ b/tests/test_cli/holdings_html @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Security NameISINCost (£)Quantity
SMTGB00BLDYK6182196.81162.00000000
MicrosoftUS5949181045882.353.62439184
AppleUS0378331005301.703.00000000
SkyworksUS83088M1027301.082.29594360
PayPalUS70450Y1038249.594.13171759
diff --git a/tests/test_cli/holdings_json b/tests/test_cli/holdings_json new file mode 100644 index 0000000..daa3368 --- /dev/null +++ b/tests/test_cli/holdings_json @@ -0,0 +1,56 @@ +[ + [ + "Security Name", + "ISIN", + "Cost (\u00a3)", + "Quantity", + "Current Value (\u00a3)", + "Gain/Loss (\u00a3)", + "Weight (%)" + ], + { + "Cost (\u00a3)": "2196.812045454545454545454546", + "Current Value (\u00a3)": null, + "Gain/Loss (\u00a3)": "n/a", + "ISIN": "GB00BLDYK618", + "Quantity": "162.00000000", + "Security Name": "SMT", + "Weight (%)": "n/a" + }, + { + "Cost (\u00a3)": "882.3464985164979278272490710", + "Current Value (\u00a3)": null, + "Gain/Loss (\u00a3)": "n/a", + "ISIN": "US5949181045", + "Quantity": "3.62439184", + "Security Name": "Microsoft", + "Weight (%)": "n/a" + }, + { + "Cost (\u00a3)": "301.699341785252128650422842", + "Current Value (\u00a3)": null, + "Gain/Loss (\u00a3)": "n/a", + "ISIN": "US0378331005", + "Quantity": "3.00000000", + "Security Name": "Apple", + "Weight (%)": "n/a" + }, + { + "Cost (\u00a3)": "301.0770951964634031790966809", + "Current Value (\u00a3)": null, + "Gain/Loss (\u00a3)": "n/a", + "ISIN": "US83088M1027", + "Quantity": "2.295943596", + "Security Name": "Skyworks", + "Weight (%)": "n/a" + }, + { + "Cost (\u00a3)": "249.59", + "Current Value (\u00a3)": null, + "Gain/Loss (\u00a3)": "n/a", + "ISIN": "US70450Y1038", + "Quantity": "4.13171759", + "Security Name": "PayPal", + "Weight (%)": "n/a" + } +] diff --git a/tests/test_cli/interest_csv b/tests/test_cli/interest_csv new file mode 100644 index 0000000..70d1153 --- /dev/null +++ b/tests/test_cli/interest_csv @@ -0,0 +1,7 @@ +Date,Amount (£) +2021-10-15,1.70 +2022-01-15,1.59 +2022-04-15,1.61 +2022-07-15,1.58 +2023-01-15,1.81 +,8.29 diff --git a/tests/test_cli/interest_html b/tests/test_cli/interest_html new file mode 100644 index 0000000..d162844 --- /dev/null +++ b/tests/test_cli/interest_html @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateAmount (£)
15/10/20211.70
15/01/20221.59
15/04/20221.61
15/07/20221.58
15/01/20231.81
8.29
diff --git a/tests/test_cli/interest_json b/tests/test_cli/interest_json new file mode 100644 index 0000000..a45f38f --- /dev/null +++ b/tests/test_cli/interest_json @@ -0,0 +1,30 @@ +[ + [ + "Date", + "Amount (\u00a3)" + ], + { + "Amount (\u00a3)": "1.70", + "Date": "2021-10-15" + }, + { + "Amount (\u00a3)": "1.59", + "Date": "2022-01-15" + }, + { + "Amount (\u00a3)": "1.61", + "Date": "2022-04-15" + }, + { + "Amount (\u00a3)": "1.58", + "Date": "2022-07-15" + }, + { + "Amount (\u00a3)": "1.81", + "Date": "2023-01-15" + }, + { + "Amount (\u00a3)": "8.29", + "Date": "" + } +] diff --git a/tests/test_cli/orders_csv b/tests/test_cli/orders_csv new file mode 100644 index 0000000..c6926cb --- /dev/null +++ b/tests/test_cli/orders_csv @@ -0,0 +1,22 @@ +Date,Security Name,ISIN,Ticker,Total Cost (£),Net Proceeds (£),Quantity,Price (£),Fees (£) +2021-04-07,Apple,US0378331005,AAPL,1940.99,,20.13713692,96.15219917767733984300683794,4.76 +2021-06-05,Apple,US0378331005,AAPL,998.48,,9.09199546,109.3280352341926928326908777,4.47 +2021-06-11,Microsoft,US5949181045,MSFT,2715.44,,15.00246544,180.1863840854146970126264793,12.20 +2021-08-12,Skyworks,US83088M1027,SWKS,1497.76,,11.21263989,132.9793888529135666373389612,6.71 +2021-08-25,Microsoft,US5949181045,MSFT,,2939.35,13.00246544,227.0707823546424284900848773,13.13 +2021-08-26,SMT,GB00BLDYK618,SMT,2386.66,,176.00000000,13.49295454545454545454545455,11.90 +2021-09-01,Skyworks,US83088M1027,SWKS,,152.47,1.245848877,122.9763921037751996946255625,0.74 +2021-09-13,SMT,GB00BLDYK618,SMT,,1228.97,88.00000000,13.96556818181818181818181818,0.00 +2021-09-13,SMT,GB00BLDYK618,SMT,443.65,,34.00000000,13.02558823529411764705882353,0.78 +2021-09-26,SMT,GB00BLDYK618,SMT,482.67,,40.00000000,12.05275,0.56 +2021-11-02,Apple,US0378331005,AAPL,,3643.81,26.22913238,139.2859644410395857706979174,9.54 +2022-01-27,Skyworks,US83088M1027,SWKS,,177.34,1.245848877,142.9788181283563495960032077,0.79 +2022-04-10,PayPal,US70450Y1038,PYPL,249.59,,4.13171759,60.05492742305264866856497808,1.46 +2022-05-12,Microsoft,US5949181045,MSFT,843.26,,2.95081184,284.0946984949064051471340172,4.95 +2022-07-09,Amazon,US0231351067,AMZN,3464.02,,48.31896981,71.26931748630341918293476961,20.36 +2022-09-20,Amazon,US0231351067,AMZN,,4912.43,48.31896981,102.2689436349967578085663660,29.10 +2022-09-28,Skyworks,US83088M1027,SWKS,499.95,,3.97500146,125.0339163397439355909066760,2.94 +2022-10-14,Microsoft,US5949181045,MSFT,,317.88,1.32642,241.0699476787141327784562959,1.88 +2022-12-16,Skyworks,US83088M1027,SWKS,,973.95,8.30000000,118.0349397590361445783132530,5.74 +2023-03-03,Skyworks,US83088M1027,SWKS,,311.13,2.10000000,149.0238095238095238095238095,1.82 +,,,,15522.47,14657.33,,,133.83 diff --git a/tests/test_cli/orders_html b/tests/test_cli/orders_html new file mode 100644 index 0000000..1f60656 --- /dev/null +++ b/tests/test_cli/orders_html @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateSecurity NameISINTickerTotal Cost (£)Net Proceeds (£)QuantityPrice (£)Fees (£)
07/04/2021AppleUS0378331005AAPL1940.9920.1371369296.154.76
05/06/2021AppleUS0378331005AAPL998.489.09199546109.334.47
11/06/2021MicrosoftUS5949181045MSFT2715.4415.00246544180.1912.20
12/08/2021SkyworksUS83088M1027SWKS1497.7611.21263989132.986.71
25/08/2021MicrosoftUS5949181045MSFT2939.3513.00246544227.0713.13
26/08/2021SMTGB00BLDYK618SMT2386.66176.0000000013.4911.90
01/09/2021SkyworksUS83088M1027SWKS152.471.24584888122.980.74
13/09/2021SMTGB00BLDYK618SMT1228.9788.0000000013.970.00
13/09/2021SMTGB00BLDYK618SMT443.6534.0000000013.030.78
26/09/2021SMTGB00BLDYK618SMT482.6740.0000000012.050.56
02/11/2021AppleUS0378331005AAPL3643.8126.22913238139.299.54
27/01/2022SkyworksUS83088M1027SWKS177.341.24584888142.980.79
10/04/2022PayPalUS70450Y1038PYPL249.594.1317175960.051.46
12/05/2022MicrosoftUS5949181045MSFT843.262.95081184284.094.95
09/07/2022AmazonUS0231351067AMZN3464.0248.3189698171.2720.36
20/09/2022AmazonUS0231351067AMZN4912.4348.31896981102.2729.10
28/09/2022SkyworksUS83088M1027SWKS499.953.97500146125.032.94
14/10/2022MicrosoftUS5949181045MSFT317.881.32642000241.071.88
16/12/2022SkyworksUS83088M1027SWKS973.958.30000000118.035.74
03/03/2023SkyworksUS83088M1027SWKS311.132.10000000149.021.82
15522.4714657.33133.83
diff --git a/tests/test_cli/orders_json b/tests/test_cli/orders_json new file mode 100644 index 0000000..3f36a31 --- /dev/null +++ b/tests/test_cli/orders_json @@ -0,0 +1,244 @@ +[ + [ + "Date", + "Security Name", + "ISIN", + "Ticker", + "Total Cost (\u00a3)", + "Net Proceeds (\u00a3)", + "Quantity", + "Price (\u00a3)", + "Fees (\u00a3)" + ], + { + "Date": "2021-04-07", + "Fees (\u00a3)": "4.76", + "ISIN": "US0378331005", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "96.15219917767733984300683794", + "Quantity": "20.13713692", + "Security Name": "Apple", + "Ticker": "AAPL", + "Total Cost (\u00a3)": "1940.99" + }, + { + "Date": "2021-06-05", + "Fees (\u00a3)": "4.47", + "ISIN": "US0378331005", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "109.3280352341926928326908777", + "Quantity": "9.09199546", + "Security Name": "Apple", + "Ticker": "AAPL", + "Total Cost (\u00a3)": "998.48" + }, + { + "Date": "2021-06-11", + "Fees (\u00a3)": "12.20", + "ISIN": "US5949181045", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "180.1863840854146970126264793", + "Quantity": "15.00246544", + "Security Name": "Microsoft", + "Ticker": "MSFT", + "Total Cost (\u00a3)": "2715.44" + }, + { + "Date": "2021-08-12", + "Fees (\u00a3)": "6.71", + "ISIN": "US83088M1027", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "132.9793888529135666373389612", + "Quantity": "11.21263989", + "Security Name": "Skyworks", + "Ticker": "SWKS", + "Total Cost (\u00a3)": "1497.76" + }, + { + "Date": "2021-08-25", + "Fees (\u00a3)": "13.13", + "ISIN": "US5949181045", + "Net Proceeds (\u00a3)": "2939.35", + "Price (\u00a3)": "227.0707823546424284900848773", + "Quantity": "13.00246544", + "Security Name": "Microsoft", + "Ticker": "MSFT", + "Total Cost (\u00a3)": null + }, + { + "Date": "2021-08-26", + "Fees (\u00a3)": "11.90", + "ISIN": "GB00BLDYK618", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "13.49295454545454545454545455", + "Quantity": "176.00000000", + "Security Name": "SMT", + "Ticker": "SMT", + "Total Cost (\u00a3)": "2386.66" + }, + { + "Date": "2021-09-01", + "Fees (\u00a3)": "0.74", + "ISIN": "US83088M1027", + "Net Proceeds (\u00a3)": "152.47", + "Price (\u00a3)": "122.9763921037751996946255625", + "Quantity": "1.245848877", + "Security Name": "Skyworks", + "Ticker": "SWKS", + "Total Cost (\u00a3)": null + }, + { + "Date": "2021-09-13", + "Fees (\u00a3)": "0.00", + "ISIN": "GB00BLDYK618", + "Net Proceeds (\u00a3)": "1228.97", + "Price (\u00a3)": "13.96556818181818181818181818", + "Quantity": "88.00000000", + "Security Name": "SMT", + "Ticker": "SMT", + "Total Cost (\u00a3)": null + }, + { + "Date": "2021-09-13", + "Fees (\u00a3)": "0.78", + "ISIN": "GB00BLDYK618", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "13.02558823529411764705882353", + "Quantity": "34.00000000", + "Security Name": "SMT", + "Ticker": "SMT", + "Total Cost (\u00a3)": "443.65" + }, + { + "Date": "2021-09-26", + "Fees (\u00a3)": "0.56", + "ISIN": "GB00BLDYK618", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "12.05275", + "Quantity": "40.00000000", + "Security Name": "SMT", + "Ticker": "SMT", + "Total Cost (\u00a3)": "482.67" + }, + { + "Date": "2021-11-02", + "Fees (\u00a3)": "9.54", + "ISIN": "US0378331005", + "Net Proceeds (\u00a3)": "3643.81", + "Price (\u00a3)": "139.2859644410395857706979174", + "Quantity": "26.22913238", + "Security Name": "Apple", + "Ticker": "AAPL", + "Total Cost (\u00a3)": null + }, + { + "Date": "2022-01-27", + "Fees (\u00a3)": "0.79", + "ISIN": "US83088M1027", + "Net Proceeds (\u00a3)": "177.34", + "Price (\u00a3)": "142.9788181283563495960032077", + "Quantity": "1.245848877", + "Security Name": "Skyworks", + "Ticker": "SWKS", + "Total Cost (\u00a3)": null + }, + { + "Date": "2022-04-10", + "Fees (\u00a3)": "1.46", + "ISIN": "US70450Y1038", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "60.05492742305264866856497808", + "Quantity": "4.13171759", + "Security Name": "PayPal", + "Ticker": "PYPL", + "Total Cost (\u00a3)": "249.59" + }, + { + "Date": "2022-05-12", + "Fees (\u00a3)": "4.95", + "ISIN": "US5949181045", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "284.0946984949064051471340172", + "Quantity": "2.95081184", + "Security Name": "Microsoft", + "Ticker": "MSFT", + "Total Cost (\u00a3)": "843.26" + }, + { + "Date": "2022-07-09", + "Fees (\u00a3)": "20.36", + "ISIN": "US0231351067", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "71.26931748630341918293476961", + "Quantity": "48.31896981", + "Security Name": "Amazon", + "Ticker": "AMZN", + "Total Cost (\u00a3)": "3464.02" + }, + { + "Date": "2022-09-20", + "Fees (\u00a3)": "29.10", + "ISIN": "US0231351067", + "Net Proceeds (\u00a3)": "4912.43", + "Price (\u00a3)": "102.2689436349967578085663660", + "Quantity": "48.31896981", + "Security Name": "Amazon", + "Ticker": "AMZN", + "Total Cost (\u00a3)": null + }, + { + "Date": "2022-09-28", + "Fees (\u00a3)": "2.94", + "ISIN": "US83088M1027", + "Net Proceeds (\u00a3)": null, + "Price (\u00a3)": "125.0339163397439355909066760", + "Quantity": "3.97500146", + "Security Name": "Skyworks", + "Ticker": "SWKS", + "Total Cost (\u00a3)": "499.95" + }, + { + "Date": "2022-10-14", + "Fees (\u00a3)": "1.88", + "ISIN": "US5949181045", + "Net Proceeds (\u00a3)": "317.88", + "Price (\u00a3)": "241.0699476787141327784562959", + "Quantity": "1.32642", + "Security Name": "Microsoft", + "Ticker": "MSFT", + "Total Cost (\u00a3)": null + }, + { + "Date": "2022-12-16", + "Fees (\u00a3)": "5.74", + "ISIN": "US83088M1027", + "Net Proceeds (\u00a3)": "973.95", + "Price (\u00a3)": "118.0349397590361445783132530", + "Quantity": "8.30000000", + "Security Name": "Skyworks", + "Ticker": "SWKS", + "Total Cost (\u00a3)": null + }, + { + "Date": "2023-03-03", + "Fees (\u00a3)": "1.82", + "ISIN": "US83088M1027", + "Net Proceeds (\u00a3)": "311.13", + "Price (\u00a3)": "149.0238095238095238095238095", + "Quantity": "2.10000000", + "Security Name": "Skyworks", + "Ticker": "SWKS", + "Total Cost (\u00a3)": null + }, + { + "Date": "", + "Fees (\u00a3)": "133.83", + "ISIN": "", + "Net Proceeds (\u00a3)": "14657.33", + "Price (\u00a3)": "", + "Quantity": "", + "Security Name": "", + "Ticker": "", + "Total Cost (\u00a3)": "15522.47" + } +] diff --git a/tests/test_cli/transfers_csv b/tests/test_cli/transfers_csv new file mode 100644 index 0000000..aab1f14 --- /dev/null +++ b/tests/test_cli/transfers_csv @@ -0,0 +1,7 @@ +Date,Deposit (£),Withdrawal (£) +2021-03-02,6000.00, +2021-07-28,4000.00, +2022-02-24,,400.00 +2022-04-08,,100.00 +2023-01-03,2000.00, +,12000.00,500.00 diff --git a/tests/test_cli/transfers_html b/tests/test_cli/transfers_html new file mode 100644 index 0000000..6635d11 --- /dev/null +++ b/tests/test_cli/transfers_html @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DateDeposit (£)Withdrawal (£)
02/03/20216000.00
28/07/20214000.00
24/02/2022400.00
08/04/2022100.00
03/01/20232000.00
12000.00500.00
diff --git a/tests/test_cli/transfers_json b/tests/test_cli/transfers_json new file mode 100644 index 0000000..48dd438 --- /dev/null +++ b/tests/test_cli/transfers_json @@ -0,0 +1,37 @@ +[ + [ + "Date", + "Deposit (\u00a3)", + "Withdrawal (\u00a3)" + ], + { + "Date": "2021-03-02", + "Deposit (\u00a3)": "6000.00", + "Withdrawal (\u00a3)": "" + }, + { + "Date": "2021-07-28", + "Deposit (\u00a3)": "4000.00", + "Withdrawal (\u00a3)": "" + }, + { + "Date": "2022-02-24", + "Deposit (\u00a3)": "", + "Withdrawal (\u00a3)": "400.00" + }, + { + "Date": "2022-04-08", + "Deposit (\u00a3)": "", + "Withdrawal (\u00a3)": "100.00" + }, + { + "Date": "2023-01-03", + "Deposit (\u00a3)": "2000.00", + "Withdrawal (\u00a3)": "" + }, + { + "Date": "", + "Deposit (\u00a3)": "12000.00", + "Withdrawal (\u00a3)": "500.00" + } +]