From 5945e27bddc906a6f978df143d3a18d993d38f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Coelho?= <16445494+jcoelho93@users.noreply.github.com> Date: Sat, 27 Apr 2024 14:48:22 +0100 Subject: [PATCH] Add remaining operations --- README.md | 12 ++-- python_trading212/__init__.py | 8 ++- python_trading212/models.py | 57 +++++++++++---- python_trading212/trading212.py | 118 ++++++++++++++++++++++++++++---- 4 files changed, 162 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 7948737..444c894 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ trading212.create_pie( - [x] Place Market order - [x] Place Stop order - [x] Place StopLimit order -- [ ] Cancel by ID -- [ ] Fetch by ID +- [x] Cancel by ID +- [x] Fetch by ID ## Account Data @@ -76,10 +76,10 @@ trading212.create_pie( ## Historical Items - [x] Historical order data -- [ ] Paid out dividens -- [ ] Exports List -- [ ] Export csv -- [ ] Transaction list +- [x] Paid out dividens +- [x] Exports List +- [x] Export csv +- [x] Transaction list ## Disclaimer diff --git a/python_trading212/__init__.py b/python_trading212/__init__.py index 6408d13..9271bae 100644 --- a/python_trading212/__init__.py +++ b/python_trading212/__init__.py @@ -1,2 +1,8 @@ from python_trading212.trading212 import Trading212 # noqa -from python_trading212.models import Position # noqa +from python_trading212.models import ( # noqa + Position, Exchange, Instrument, + Pie, Order, AccountCash, AccountMetadata, + HistoricalOrderData, LimitOrder, MarketOrder, + StopOrder, StopLimitOrder, PaidOutDividends, + Export, Report, TransactionList +) diff --git a/python_trading212/models.py b/python_trading212/models.py index 6c96ce6..f25e822 100644 --- a/python_trading212/models.py +++ b/python_trading212/models.py @@ -122,7 +122,7 @@ class Pie(BaseModel): class Order(BaseModel): - creationTime: str + creationTime: datetime filledQuantity: float filledValue: float id: int @@ -233,16 +233,49 @@ class StopLimitOrder(BaseModel): timeValidity: str -class FilledOrder(BaseModel): - creationTime: str - filledQuantity: float - filledValue: float - id: int - limitPrice: float - quantity: float - status: str - stopPrice: float - strategy: str +class Dividend(BaseModel): + amount: int + amountInEuro: int + grossAmountPerShare: int + paidOn: str + quantity: int + reference: str ticker: str type: str - value: float + + +class PaidOutDividends(BaseModel): + items: List[Dividend] + nextPagePath: str + + +class DataIncluded(BaseModel): + includeDividends: bool + includeInterest: bool + includeOrders: bool + includeTransactions: bool + + +class Export(BaseModel): + dataIncluded: DataIncluded + downloadLink: str + reportId: int + status: str + timeFrom: datetime + timeTo: datetime + + +class Report(BaseModel): + reportId: int + + +class Transaction(BaseModel): + amount: int + dateTime: datetime + reference: str + type: str + + +class TransactionList(BaseModel): + items: List[Transaction] + nextPagePath: str diff --git a/python_trading212/trading212.py b/python_trading212/trading212.py index 21bccde..927a50a 100644 --- a/python_trading212/trading212.py +++ b/python_trading212/trading212.py @@ -5,8 +5,9 @@ from python_trading212.models import ( Position, Exchange, Instrument, Pie, Order, AccountCash, AccountMetadata, - HistoricalOrderData, LimitOrder, FilledOrder, - MarketOrder, StopOrder, StopLimitOrder + HistoricalOrderData, LimitOrder, MarketOrder, + StopOrder, StopLimitOrder, PaidOutDividends, + Export, Report, TransactionList ) @@ -181,7 +182,7 @@ def fetch_all_orders(self) -> List[Order]: orders.append(Order(**order)) return orders - def place_limit_order(self, limit_order: LimitOrder) -> FilledOrder: + def place_limit_order(self, limit_order: LimitOrder) -> Order: """Places a limit order https://t212public-api-docs.redoc.ly/#operation/placeLimitOrder @@ -190,14 +191,14 @@ def place_limit_order(self, limit_order: LimitOrder) -> FilledOrder: limit_order (LimitOrder): the limit order to place Returns: - FilledOrder: the filled order + Order: the filled order """ endpoint = self.url + "equity/orders/limit" response = self._post(endpoint, limit_order.model_dump()) - return FilledOrder(**response) + return Order(**response) - def place_market_order(self, market_order: MarketOrder) -> FilledOrder: + def place_market_order(self, market_order: MarketOrder) -> Order: """Places a market order https://t212public-api-docs.redoc.ly/#operation/placeMarketOrder @@ -206,14 +207,14 @@ def place_market_order(self, market_order: MarketOrder) -> FilledOrder: market_order (MarketOrder): the market order to place Returns: - FilledOrder: the filled order + Order: the filled order """ endpoint = self.url + "equity/orders/market" response = self._post(endpoint, market_order.model_dump()) - return FilledOrder(**response) + return Order(**response) - def place_stop_order(self, stop_order: StopOrder) -> FilledOrder: + def place_stop_order(self, stop_order: StopOrder) -> Order: """Places a stop order https://t212public-api-docs.redoc.ly/#operation/placeStopOrder @@ -222,14 +223,14 @@ def place_stop_order(self, stop_order: StopOrder) -> FilledOrder: stop_order (StopOrder): the stop order to place Returns: - FilledOrder: the filled order + Order: the filled order """ endpoint = self.url + "equity/orders/stop" response = self._post(endpoint, stop_order.model_dump()) - return FilledOrder(**response) + return Order(**response) - def place_stop_limit_order(self, stop_limit_order: StopLimitOrder) -> FilledOrder: + def place_stop_limit_order(self, stop_limit_order: StopLimitOrder) -> Order: """Places a stop limit order https://t212public-api-docs.redoc.ly/#operation/placeStopLimitOrder @@ -238,12 +239,39 @@ def place_stop_limit_order(self, stop_limit_order: StopLimitOrder) -> FilledOrde stop_limit_order (StopLimitOrder): the stop limit order to place Returns: - FilledOrder: the filled order + Order: the filled order """ endpoint = self.url + "equity/orders/stop_limit" response = self._post(endpoint, stop_limit_order.model_dump()) - return FilledOrder(**response) + return Order(**response) + + def cancel_order(self, id: int): + """Cancels an order by ID + + https://t212public-api-docs.redoc.ly/#operation/cancelOrder + + Args: + id (int): the ID of the order + """ + endpoint = self.url + f"equity/orders/{id}" + return self._delete(endpoint) + + def fetch_order_by_id(self, id: int) -> Order: + """Fetches an order by ID + + https://t212public-api-docs.redoc.ly/#operation/orderById + + Args: + id (int): the ID of the order + + Returns: + Order: the order + """ + endpoint = self.url + f"equity/orders/{id}" + response = self._get(endpoint) + + return Order(**response) def fetch_order(self, id: int) -> Order: """Fetches an order by ID @@ -349,3 +377,65 @@ def historical_order_data(self, cursor: int, ticker: str, limit: int) -> Histori response = self._get(endpoint, params) return HistoricalOrderData(**response) + + def paid_out_dividends(self, cursor: int = None, ticker: str = None, limit: int = None) -> PaidOutDividends: + """Fetch paid out dividends + + https://t212public-api-docs.redoc.ly/#operation/dividends + + Returns: + List[DividendDetails]: _description_ + """ + endpoint = self.url + "equity/dividends" + response = self._get(endpoint, { + "cursor": cursor, + "ticker": ticker, + "limit": limit + }) + + return PaidOutDividends(**response) + + def exports_list(self) -> List[Export]: + """Fetch all exports + + https://t212public-api-docs.redoc.ly/#operation/getReports + + Returns: + List[Export]: list of exports + """ + endpoint = self.url + "history/exports" + response = self._get(endpoint) + + return PaidOutDividends(**response) + + def export_csv(self, export: Export) -> Report: + """Exports a CSV + + https://t212public-api-docs.redoc.ly/#operation/requestReport + + Args: + export (Export): the export settings + + Returns: + Report: the report ID + """ + endpoint = self.url + "history/exports" + response = self._post(endpoint, export.model_dump()) + + return Report(**response) + + def transaction_list(self, cursor: str = None, limit: int = None) -> TransactionList: + """Fetch all transactions + + https://t212public-api-docs.redoc.ly/#operation/transactions + + Returns: + List[Transaction]: list of transactions + """ + endpoint = self.url + "history/transactions" + response = self._get(endpoint, { + "cursor": cursor, + "limit": limit + }) + + return TransactionList(**response)