Allow direct orderbook export from degiro paexport to portfolio load command (#2091)

* redirect paexport to holdings/portfolio folder

* allow name change on export

* centralize default holdings path in helper

* create default folder for degiro orderbook

* refresh and unrestrict choices

* update degiro help

* fix linting

* remove unused import

* move logic to model
This commit is contained in:
montezdesousa
2022-07-20 08:46:40 +01:00
committed by GitHub
parent f05676b79a
commit d474bcc0f8
6 changed files with 59 additions and 30 deletions

View File

@@ -316,7 +316,9 @@ class DegiroController(BaseController):
@log_start_end(log=logger)
def call_paexport(self, other_args: List[str]):
"""Export transactions for Portfolio Analysis Menu into CSV format."""
"""Export transactions for Portfolio menu into csv format. The transactions
file is exported to the portfolio/holdings folder and can be loaded directly
in the Portfolio menu."""
# PARSING ARGS
parser = argparse.ArgumentParser(

View File

@@ -3,6 +3,7 @@ import datetime
import logging
import math
from typing import List, Union
from pathlib import Path
# IMPORTATION THIRDPARTY
import pandas as pd
@@ -22,7 +23,9 @@ from degiro_connector.trading.models.trading_pb2 import (
# IMPORTATION INTERNAL
import openbb_terminal.config_terminal as config
from openbb_terminal.rich_config import console
from openbb_terminal.decorators import log_start_end
from openbb_terminal.portfolio import portfolio_helper
# pylint: disable=no-member
# pylint: disable=no-else-return
@@ -438,3 +441,24 @@ class DegiroModel:
portfolio_df = portfolio_df.set_index("Date")
return portfolio_df
@staticmethod
@log_start_end(log=logger)
def export_data(portfolio_df: pd.DataFrame, export: str):
# In this scenario the path was provided, e.g. --export pt.csv, pt.jpg
if "." in export:
if export.endswith("csv"):
filename = export
# In this scenario we use the default filename
else:
console.print("Wrong export file specified.\n")
else:
now = datetime.datetime.now()
filename = f"{now.strftime('%Y%m%d_%H%M%S')}_paexport_degiro.csv"
file_path = Path(str(portfolio_helper.DEFAULT_HOLDINGS_PATH), filename)
portfolio_df.to_csv(file_path)
console.print(f"Saved file: {file_path}\n")

View File

@@ -1,7 +1,6 @@
# IMPORTATION THIRDPARTY
import logging
from argparse import Namespace
from pathlib import Path
# IMPORTATION THIRDPARTY
import pandas as pd
@@ -21,7 +20,6 @@ from openbb_terminal.decorators import check_api_key
# IMPORTATION INTERNAL
from openbb_terminal.helper_funcs import (
export_data,
print_rich_table,
)
from openbb_terminal.portfolio.brokers.degiro.degiro_model import DegiroModel
@@ -507,17 +505,15 @@ class DegiroView:
)
if portfolio_df is not None:
print_rich_table(
df=portfolio_df,
headers=list(portfolio_df.columns),
show_index=True,
title="Degiro Transactions",
)
export_data(
export_type=ns_parser.export,
dir_path=str(Path(__file__).parent.parent.parent.absolute()),
func_name="paexport",
df=portfolio_df,
)
degiro_model.export_data(portfolio_df, ns_parser.export)
else:
console.print("Error while fetching or processing Transactions.")

View File

@@ -96,9 +96,7 @@ class PortfolioController(BaseController):
super().__init__(queue)
self.file_types = ["xlsx", "csv"]
self.DEFAULT_HOLDINGS_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), "..", "..", "portfolio", "holdings")
)
self.DEFAULT_HOLDINGS_PATH = portfolio_helper.DEFAULT_HOLDINGS_PATH
self.DATA_HOLDINGS_FILES = {
filepath.name: filepath
@@ -135,17 +133,30 @@ class PortfolioController(BaseController):
)
if session and obbff.USE_PROMPT_TOOLKIT:
choices: dict = {c: {} for c in self.controller_choices}
choices["load"] = {c: None for c in self.DATA_HOLDINGS_FILES}
choices["bench"] = {c: None for c in portfolio_helper.BENCHMARK_LIST}
choices["alloc"] = {c: None for c in self.AGGREGATION_METRICS}
choices["metric"] = {c: None for c in self.VALID_METRICS}
self.choices = choices
self.update_choices()
choices["support"] = self.SUPPORT_CHOICES
choices["about"] = self.ABOUT_CHOICES
def update_choices(self):
self.completer = NestedCompleter.from_nested_dict(choices)
self.DEFAULT_HOLDINGS_PATH = portfolio_helper.DEFAULT_HOLDINGS_PATH
self.DATA_HOLDINGS_FILES = {
filepath.name: filepath
for file_type in self.file_types
for filepath in Path(self.DEFAULT_HOLDINGS_PATH).rglob(f"*.{file_type}")
if filepath.is_file()
}
choices: dict = {c: {} for c in self.controller_choices}
choices["load"] = {c: None for c in self.DATA_HOLDINGS_FILES}
choices["bench"] = {c: None for c in portfolio_helper.BENCHMARK_LIST}
choices["alloc"] = {c: None for c in self.AGGREGATION_METRICS}
choices["metric"] = {c: None for c in self.VALID_METRICS}
self.choices = choices
choices["support"] = self.SUPPORT_CHOICES
choices["about"] = self.ABOUT_CHOICES
self.completer = NestedCompleter.from_nested_dict(choices)
def print_help(self):
"""Print help"""
@@ -237,6 +248,7 @@ class PortfolioController(BaseController):
# [info]Reports:[/info]
# ar annual report for performance of a given portfolio
console.print(text=help_text, menu="Portfolio")
self.update_choices()
def custom_reset(self):
"""Class specific component of reset command"""
@@ -284,7 +296,6 @@ class PortfolioController(BaseController):
"-f",
"--file",
type=str,
choices=self.DATA_HOLDINGS_FILES,
dest="file",
required="-h" not in other_args,
help="The file to be loaded",
@@ -336,7 +347,6 @@ class PortfolioController(BaseController):
console.print(
f"[bold]Risk Free Rate:[/bold] {self.portfolio.risk_free_rate}"
)
console.print()
@log_start_end(log=logger)

View File

@@ -251,6 +251,10 @@ PERIODS_DAYS = {
"10y": 10 * 12 * 21,
}
DEFAULT_HOLDINGS_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), "..", "..", "portfolio", "holdings")
)
def is_ticker(ticker: str) -> bool:
"""Determine whether a string is a valid ticker
@@ -426,13 +430,6 @@ def get_info_from_ticker(ticker: str) -> list:
filename = "tickers_info.csv"
# Direct file to openbb_terminal\portfolio
DEFAULT_HOLDINGS_PATH = os.path.abspath(
os.path.join(
os.path.dirname(__file__), "..", "..", "openbb_terminal", "portfolio"
)
)
file_path = Path(str(DEFAULT_HOLDINGS_PATH), filename)
if file_path.is_file() and os.stat(file_path).st_size > 0:

View File