mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-28 04:52:07 +00:00
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:
@@ -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(
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
0
portfolio/holdings/paexport_degiro.csv
vendored
Normal file
0
portfolio/holdings/paexport_degiro.csv
vendored
Normal file
|
|
Reference in New Issue
Block a user