From c75cbec2a304aecd7bde1073a8e6376d5ac95468 Mon Sep 17 00:00:00 2001 From: DJ Nieto Date: Fri, 9 Apr 2021 03:43:41 -0600 Subject: [PATCH 1/4] A line was joined on accident --- gamestonk_terminal/oanda/oanda_functions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gamestonk_terminal/oanda/oanda_functions.py b/gamestonk_terminal/oanda/oanda_functions.py index 8843d337526..caa303b77c1 100644 --- a/gamestonk_terminal/oanda/oanda_functions.py +++ b/gamestonk_terminal/oanda/oanda_functions.py @@ -52,7 +52,8 @@ def list_orders(accountID, state="ALL", count="50"): "state": state, "count": count } - request = orders.OrderList(accountID, parameters) response = client.request(request) + request = orders.OrderList(accountID, parameters) + response = client.request(request) for i in range(0, int(count), 1): try: order_id = response["orders"][i]["id"] From 8857dcb604742b3979850c45f8ee5473f5350204 Mon Sep 17 00:00:00 2001 From: DJ Nieto Date: Sat, 10 Apr 2021 02:58:22 -0600 Subject: [PATCH 2/4] Added functions for oanda --- gamestonk_terminal/oanda/oanda_controller.py | 77 ++++- gamestonk_terminal/oanda/oanda_functions.py | 334 +++++++++++++++++-- 2 files changed, 375 insertions(+), 36 deletions(-) diff --git a/gamestonk_terminal/oanda/oanda_controller.py b/gamestonk_terminal/oanda/oanda_controller.py index 4befdbd1c10..ebb446063be 100644 --- a/gamestonk_terminal/oanda/oanda_controller.py +++ b/gamestonk_terminal/oanda/oanda_controller.py @@ -1,5 +1,6 @@ import argparse # import matplotlib.pyplot as plt +from typing import List from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn from gamestonk_terminal import feature_flags as gtff @@ -17,17 +18,22 @@ class OandaController: "help", "q", "quit", - "hist", "price", "summary", - "list"] + "list", + "orderbook", + "positionbook", + "limitorder", + "cancel", + "positions", + "closetrade", + "trades", + "pending"] def __init__( self, -# instrument:str, ): """Construct Data""" -# self.instrument = instrument self.oanda_parser = argparse.ArgumentParser(add_help=False, prog="fx") self.oanda_parser.add_argument( "cmd", @@ -39,13 +45,21 @@ class OandaController: """Print help""" print("\nForex Mode:") - print("\t help \t show this menu again") - print("\t q \t quit this menu and goes back to main menu") - print("\t quit \t quit to abandon program") + print("help \t show this menu again") + print("q \t quit this menu and goes back to main menu") + print("quit \t quit to abandon program") print("") - print("\t price \t shows price for selected instrument") - print("\t summary shows account summary") - print("\t list \t list orders") + print("price \t shows price for selected instrument") + print("summary shows account summary") + print("list \t list order history") + print("trades \t list open trades") + print("orderbook \t print orderbook") + print("positionbook \t print positionbook") + print("limitorder \t place limit order -u # of units -p price") + print("cancel \t cancel a pending order by ID -i order ID") + print("pending \t get information on pending up to 25 pending orders") + print("positions \t Get open positions") + print("closetrade \t Close a trade by id") def switch(self, an_input: str): """Process and dispatch input @@ -72,20 +86,49 @@ class OandaController: """Process Quit command - exit the program""" return True - def call_price(self, _): + def call_price(self, other_args: List[str]): """Process Price Command""" - try: - oanda_functions.get_fx_price(account, instrument) - except NameError as e: - print(e) + oanda_functions.get_fx_price(account, other_args) def call_summary(self, _): """Process account summary command""" oanda_functions.get_account_summary(account) - def call_list(self, _): + def call_orderbook(self, other_args: List [str]): + """Process Oanda Order Book""" + oanda_functions.get_order_book(other_args) + + def call_positionbook(self, other_args: List [str]): + """Process Oanda Position Book""" + oanda_functions.get_position_book(other_args) + + def call_list(self, other_args: List [str]): """Process list orders command""" - oanda_functions.list_orders(account) + oanda_functions.list_orders(account, other_args) + + def call_limitorder(self, other_args: List [str]): + """Place market order""" + oanda_functions.create_limit_order(account, other_args) + + def call_cancel(self, other_args: List [str]): + """Cancel pending order by ID""" + oanda_functions.cancel_pending_order(account, other_args) + + def call_positions(self, _): + """Get Open Positions""" + oanda_functions.get_open_positions(account) + + def call_pending(self, _): + """See up to 25 pending orders""" + oanda_functions.get_pending_orders(account) + + def call_closetrade(self, other_args: List [str]): + """Close a trade by id""" + oanda_functions.close_trade(account, other_args) + + def call_trades(self, _): + """List open trades""" + oanda_functions.get_open_trades(account) def menu(): diff --git a/gamestonk_terminal/oanda/oanda_functions.py b/gamestonk_terminal/oanda/oanda_functions.py index caa303b77c1..e93f6f1a3f3 100644 --- a/gamestonk_terminal/oanda/oanda_functions.py +++ b/gamestonk_terminal/oanda/oanda_functions.py @@ -1,24 +1,51 @@ import argparse from oandapyV20 import API +from typing import List import oandapyV20.endpoints.pricing as pricing import oandapyV20.endpoints.accounts as accounts import oandapyV20.endpoints.orders as orders +import oandapyV20.endpoints.instruments as instruments +import oandapyV20.endpoints.positions as positions +import oandapyV20.endpoints.trades as trades +from oandapyV20.exceptions import V20Error from gamestonk_terminal import config_terminal as cfg +from gamestonk_terminal.helper_funcs import parse_known_args_and_warn client = API(access_token=cfg.OANDA_TOKEN, environment="live") account = cfg.OANDA_ACCOUNT -def get_fx_price(accountID, instrument): - parameters = { - "instruments": instrument - } - request = pricing.PricingInfo(accountID=accountID, params=parameters) - response = client.request(request) - bid = response["prices"][0]["bids"][0]["price"] - ask = response["prices"][0]["asks"][0]["price"] - print(instrument + " Bid: " + bid) - print(instrument + " Ask: " + ask) +def get_fx_price(accountID, other_args: List[str]): + parser = argparse.ArgumentParser( + add_help=False, + prog="getfxprice", + description="Get price for forex", + ) + parser.add_argument( + "-i", + "--instrument", + dest="instrument", + action="store", + required=True + ) + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + try: + parameters = { + "instruments": ns_parser.instrument + } + request = pricing.PricingInfo(accountID=accountID, params=parameters) + response = client.request(request) + bid = response["prices"][0]["bids"][0]["price"] + ask = response["prices"][0]["asks"][0]["price"] + print(ns_parser.instrument + " Bid: " + bid) + print(ns_parser.instrument + " Ask: " + ask) + except V20Error as e: + print(e) + except NameError as e: + print(e) def get_account_summary(accountID): @@ -47,14 +74,44 @@ def get_account_summary(accountID): print(f"Margin Closeout Position Value: {margin_closeout_position_value}") -def list_orders(accountID, state="ALL", count="50"): +def list_orders(accountID, other_args: List [str]): + parser = argparse.ArgumentParser( + add_help=False, + prog="listorders", + description="List order history", + ) + parser.add_argument( + "-s", + "--state", + dest="state", + action="store", + default="ALL", + required=False + ) + parser.add_argument( + "-c", + "--count", + dest="count", + action="store", + default=50, + required=False + ) + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + parameters = { - "state": state, - "count": count +# "state": ns_parser.state, +# "count": ns_parser.count, } + if ns_parser.state is not None: + parameters["state"] = ns_parser.state + if ns_parser.count is not None: + parameters["count"] = ns_parser.count + request = orders.OrderList(accountID, parameters) response = client.request(request) - for i in range(0, int(count), 1): + for i in range(0, int(ns_parser.count), 1): try: order_id = response["orders"][i]["id"] instrument = response["orders"][i]["instrument"] @@ -67,12 +124,251 @@ def list_orders(accountID, state="ALL", count="50"): print(f"Units: {units}") print(f"Order State: {order_state}") print(f"Order Type: {order_type}") - print("") - except KeyError as e: - print(f"Key error: {e} not found \n") + print("-"*30) + except KeyError: continue - except IndexError as e: - print(e) + except IndexError: break +def get_order_book(other_args: List [str]): + parser = argparse.ArgumentParser( + add_help=False, + prog="get_order_book", + description="Get Order book", + ) + parser.add_argument( + "-i", + "--instrument", + dest="instrument", + action="store", + required=True + ) + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + parameters = { + "bucketWidth": 0.1 + } + request = instruments.InstrumentsOrderBook(instrument=ns_parser.instrument, params=parameters) + response = client.request(request) + + for i in range(400, 700, 1): + order_instrument = response["orderBook"]["instrument"] + price = response["orderBook"]["buckets"][i]["price"] + short_count_percent = response["orderBook"]["buckets"][i]["shortCountPercent"] + long_count_percent = response["orderBook"]["buckets"][i]["longCountPercent"] + print(f"Instrument: {order_instrument}") + print(f"Price: {price}") + print(f"Short count percent: {short_count_percent}") + print(f"Long count percent: {long_count_percent}") + print("-"*30) + + +def get_position_book(other_args: List [str]): + parser = argparse.ArgumentParser( + add_help=False, + prog="get_position_book ", + description="Get Position Book", + ) + parser.add_argument( + "-i", + "--instrument", + dest="instrument", + action="store", + required=True + ) + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + parameters = { + "bucketWidth": 0.1 + } + request = instruments.InstrumentsPositionBook (instrument=ns_parser.instrument, params=parameters) + response = client.request(request) + + for i in range(200,400,1): + order_instrument = response["positionBook"]["instrument"] + price = response["positionBook"]["buckets"][i]["price"] + short_count_percent = response["positionBook"]["buckets"][i]["shortCountPercent"] + long_count_percent = response["positionBook"]["buckets"][i]["longCountPercent"] + print(f"Instrument: {order_instrument}") + print(f"Price: {price}") + print(f"Short count percent: {short_count_percent}") + print(f"Long count percent: {long_count_percent}") + print("-"*30) + + +def create_limit_order(accountID, instrument, other_args: List[str]): + parser = argparse.ArgumentParser( + add_help=False, + prog="create_limit_order", + description="Create limit order", + ) + parser.add_argument( + "-u", + "--unit", + dest="units", + action="store", + type=int, + default=0, + required=True, + ) + parser.add_argument( + "-p", + "--price", + dest="price", + action="store", + type=float, + required=True, + ) + + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + data = { + "order":{ + "price": ns_parser.price, + "instrument": instrument, + "units": ns_parser.units, + "type": "LIMIT", + "timeInForce":"GTC", + "positionFill": "DEFAULT" + } + } + request = orders.OrderCreate(accountID, data) + response = client.request(request) + print(response) + + +def cancel_pending_order(accountID, other_args: List[str]): + parser = argparse.ArgumentParser( + add_help=False, + prog="cancelpendingorder", + description="Cancel Pending Order", + ) + parser.add_argument( + "-i", + "--id", + dest="orderID", + action="store", + type=str, + required=True, + ) + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + try: + request = orders.OrderCancel(accountID, ns_parser.orderID) + client.request(request) + except V20Error as e: + print(e) + + +def get_pending_orders(accountID): + request = orders.OrdersPending(accountID) + response = client.request(request) + for i in range(0,25,1): + try: + order_id = response["orders"][i]["id"] + instrument = response["orders"][i]["instrument"] + price = response["orders"][i]["price"] + units = response["orders"][i]["units"] + create_time = response["orders"][i]["createTime"] + time_in_force = response["orders"][i]["timeInForce"] + print(f"Order ID: {order_id}") + print(f"Instrument: {instrument}") + print(f"Price: {price}") + print(f"Units: {units}") + print(f"Time created: {create_time}") + print(f"Time in force: {time_in_force}") + print("-"*30) + except IndexError: + break + + +def get_open_positions(accountID): + request = positions.OpenPositions(accountID) + response = client.request(request) + for i in range(0,100,1): + try: + instrument = response["positions"][i]["instrument"] + long_units = response["positions"][i]["long"]["units"] + long_pl = response["positions"][i]["long"]["pl"] + long_upl = response["positions"][i]["long"]["unrealizedPL"] + short_units = response["positions"][i]["short"]["units"] + short_pl = response["positions"][i]["short"]["pl"] + short_upl = response["positions"][i]["short"]["unrealizedPL"] + print(f"Instrument: {instrument}\n") + print(f"Long Units: {long_units}") + print(f"Long P/L: {long_pl}") + print(f"Long Unrealized P/L: {long_upl}\n") + print(f"Short Units: {short_units}") + print(f"Short P/L: {short_pl}") + print(f"Short Unrealized P/L: {short_upl}") + print("-"*30+"\n") + except IndexError: + break + + +def get_open_trades(accountID): + request = trades.OpenTrades(accountID) + response = client.request(request) + for i in range (0,100,1): + try: + order_id = response["trades"][i]["id"] + instrument = response["trades"][i]["instrument"] + initial_units = response["trades"][i]["initialUnits"] + current_units = response["trades"][i]["currentUnits"] + price = response["trades"][i]["price"] + unrealized_pl = response["trades"][i]["unrealizedPL"] + print(f"Order ID: {order_id}\n") + print(f"Instrument: {instrument}") + print(f"Initial Units: {initial_units}") + print(f"Current Units: {current_units}") + print(f"Price: {price}") + print(f"Unrealized P/L: {unrealized_pl}") + print("-"*30+"\n") + except IndexError: + break + + + + + + +def close_trade(accountID, other_args: List[str]): + parser = ArgumentParser( + add_help = False, + prog="close_trade", + description="close a trade", + ) + parser.add_argument( + "-i", + "--id", + dest="orderID", + action="store", + type=str, + required=True, + ) + parser.add_argument( + "-u", + "--units", + dest="units", + action="store", + type=str, + required=False, + ) + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + data={ + "units": ns_parser.units, + } + try: + request = trades.TradeClose(accountID, ns_parser.orderID, data) + response = client.request(request) + except V20Error as e: + print(e) From 52ed3cd97401bfe8c3baa973a98ce258742942e4 Mon Sep 17 00:00:00 2001 From: DJ Nieto Date: Thu, 15 Apr 2021 21:34:35 -0600 Subject: [PATCH 3/4] Updating oanda --- gamestonk_terminal/oanda/oanda_controller.py | 74 ++++--- gamestonk_terminal/oanda/oanda_functions.py | 222 +++++++++++-------- 2 files changed, 169 insertions(+), 127 deletions(-) diff --git a/gamestonk_terminal/oanda/oanda_controller.py b/gamestonk_terminal/oanda/oanda_controller.py index ebb446063be..8794f2f4656 100644 --- a/gamestonk_terminal/oanda/oanda_controller.py +++ b/gamestonk_terminal/oanda/oanda_controller.py @@ -1,5 +1,4 @@ import argparse -# import matplotlib.pyplot as plt from typing import List from prompt_toolkit.completion import NestedCompleter from gamestonk_terminal.helper_funcs import get_flair, parse_known_args_and_warn @@ -28,16 +27,18 @@ class OandaController: "positions", "closetrade", "trades", - "pending"] + "candles", + "pending", + ] def __init__( self, - ): + ): """Construct Data""" self.oanda_parser = argparse.ArgumentParser(add_help=False, prog="fx") self.oanda_parser.add_argument( - "cmd", - choices=self.CHOICES, + "cmd", + choices=self.CHOICES, ) @staticmethod @@ -57,9 +58,10 @@ class OandaController: print("positionbook \t print positionbook") print("limitorder \t place limit order -u # of units -p price") print("cancel \t cancel a pending order by ID -i order ID") - print("pending \t get information on pending up to 25 pending orders") + print("pending \t get information on pending orders") print("positions \t Get open positions") print("closetrade \t Close a trade by id") + print("candles \t show candles") def switch(self, an_input: str): """Process and dispatch input @@ -72,7 +74,9 @@ class OandaController: """ (known_args, other_args) = self.oanda_parser.parse_known_args(an_input.split()) - return getattr(self, "call_" + known_args.cmd, lambda: "command not recognized!")(other_args) + return getattr( + self, "call_" + known_args.cmd, lambda: "command not recognized!" + )(other_args) def call_help(self, _): """Process Help Command""" @@ -94,23 +98,23 @@ class OandaController: """Process account summary command""" oanda_functions.get_account_summary(account) - def call_orderbook(self, other_args: List [str]): + def call_orderbook(self, other_args: List[str]): """Process Oanda Order Book""" oanda_functions.get_order_book(other_args) - def call_positionbook(self, other_args: List [str]): + def call_positionbook(self, other_args: List[str]): """Process Oanda Position Book""" oanda_functions.get_position_book(other_args) - def call_list(self, other_args: List [str]): + def call_list(self, other_args: List[str]): """Process list orders command""" oanda_functions.list_orders(account, other_args) - def call_limitorder(self, other_args: List [str]): - """Place market order""" + def call_limitorder(self, other_args: List[str]): + """Place limit order""" oanda_functions.create_limit_order(account, other_args) - def call_cancel(self, other_args: List [str]): + def call_cancel(self, other_args: List[str]): """Cancel pending order by ID""" oanda_functions.cancel_pending_order(account, other_args) @@ -122,39 +126,41 @@ class OandaController: """See up to 25 pending orders""" oanda_functions.get_pending_orders(account) - def call_closetrade(self, other_args: List [str]): + def call_closetrade(self, other_args: List[str]): """Close a trade by id""" oanda_functions.close_trade(account, other_args) + def call_candles(self, _): + oanda_functions.show_candles(account) + def call_trades(self, _): """List open trades""" oanda_functions.get_open_trades(account) def menu(): - """Oanda Menu""" - oanda_controller = OandaController() - oanda_controller.call_help(None) - while True: - if session and gtff.USE_PROMPT_TOOLKIT: - completer = NestedCompleter.from_nested_dict( - {c: None for c in oanda_controller.CHOICES} - ) + """Oanda Menu""" + oanda_controller = OandaController() + oanda_controller.call_help(None) + while True: + if session and gtff.USE_PROMPT_TOOLKIT: + completer = NestedCompleter.from_nested_dict( + {c: None for c in oanda_controller.CHOICES} + ) - an_input = session.prompt( + an_input = session.prompt( f"{get_flair()} (fx)> ", completer=completer, - ) - else: - an_input = input(f"{get_flair()} (fx)> ") + ) + else: + an_input = input(f"{get_flair()} (fx)> ") - try: - process_input = oanda_controller.switch(an_input) + try: + process_input = oanda_controller.switch(an_input) - if process_input is not None: - return process_input - - except SystemExit: - print("The command selected doesn't exit\n") - continue + if process_input is not None: + return process_input + except SystemExit: + print("The command selected doesn't exit\n") + continue diff --git a/gamestonk_terminal/oanda/oanda_functions.py b/gamestonk_terminal/oanda/oanda_functions.py index e93f6f1a3f3..fa3db84bca5 100644 --- a/gamestonk_terminal/oanda/oanda_functions.py +++ b/gamestonk_terminal/oanda/oanda_functions.py @@ -10,6 +10,10 @@ import oandapyV20.endpoints.trades as trades from oandapyV20.exceptions import V20Error from gamestonk_terminal import config_terminal as cfg from gamestonk_terminal.helper_funcs import parse_known_args_and_warn +import pandas as pd +import matplotlib.pyplot as plt +import mplfinance as mpf +import matplotlib.dates as mdates client = API(access_token=cfg.OANDA_TOKEN, environment="live") account = cfg.OANDA_ACCOUNT @@ -22,20 +26,14 @@ def get_fx_price(accountID, other_args: List[str]): description="Get price for forex", ) parser.add_argument( - "-i", - "--instrument", - dest="instrument", - action="store", - required=True + "-i", "--instrument", dest="instrument", action="store", required=True ) ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return try: - parameters = { - "instruments": ns_parser.instrument - } + parameters = {"instruments": ns_parser.instrument} request = pricing.PricingInfo(accountID=accountID, params=parameters) response = client.request(request) bid = response["prices"][0]["bids"][0]["price"] @@ -74,42 +72,32 @@ def get_account_summary(accountID): print(f"Margin Closeout Position Value: {margin_closeout_position_value}") -def list_orders(accountID, other_args: List [str]): +def list_orders(accountID, other_args: List[str]): parser = argparse.ArgumentParser( add_help=False, prog="listorders", description="List order history", ) parser.add_argument( - "-s", - "--state", - dest="state", - action="store", - default="ALL", - required=False + "-s", "--state", dest="state", action="store", default="ALL", required=False ) parser.add_argument( - "-c", - "--count", - dest="count", - action="store", - default=50, - required=False + "-c", "--count", dest="count", action="store", default=50, required=False ) ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return parameters = { -# "state": ns_parser.state, -# "count": ns_parser.count, + # "state": ns_parser.state, + # "count": ns_parser.count, } if ns_parser.state is not None: parameters["state"] = ns_parser.state if ns_parser.count is not None: parameters["count"] = ns_parser.count - request = orders.OrderList(accountID, parameters) + request = orders.OrderList(accountID, parameters) response = client.request(request) for i in range(0, int(ns_parser.count), 1): try: @@ -124,34 +112,30 @@ def list_orders(accountID, other_args: List [str]): print(f"Units: {units}") print(f"Order State: {order_state}") print(f"Order Type: {order_type}") - print("-"*30) + print("-" * 30) except KeyError: continue except IndexError: break -def get_order_book(other_args: List [str]): +def get_order_book(other_args: List[str]): parser = argparse.ArgumentParser( add_help=False, prog="get_order_book", description="Get Order book", ) parser.add_argument( - "-i", - "--instrument", - dest="instrument", - action="store", - required=True + "-i", "--instrument", dest="instrument", action="store", required=True ) ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return - parameters = { - "bucketWidth": 0.1 - } - request = instruments.InstrumentsOrderBook(instrument=ns_parser.instrument, params=parameters) + parameters = {"bucketWidth": 0.1} + request = instruments.InstrumentsOrderBook( + instrument=ns_parser.instrument, params=parameters + ) response = client.request(request) for i in range(400, 700, 1): @@ -163,79 +147,83 @@ def get_order_book(other_args: List [str]): print(f"Price: {price}") print(f"Short count percent: {short_count_percent}") print(f"Long count percent: {long_count_percent}") - print("-"*30) + print("-" * 30) -def get_position_book(other_args: List [str]): +def get_position_book(other_args: List[str]): parser = argparse.ArgumentParser( add_help=False, prog="get_position_book ", description="Get Position Book", ) parser.add_argument( - "-i", - "--instrument", - dest="instrument", - action="store", - required=True - ) + "-i", "--instrument", dest="instrument", action="store", required=True + ) ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return - parameters = { - "bucketWidth": 0.1 - } - request = instruments.InstrumentsPositionBook (instrument=ns_parser.instrument, params=parameters) + parameters = {"bucketWidth": 0.1} + request = instruments.InstrumentsPositionBook( + instrument=ns_parser.instrument, params=parameters + ) response = client.request(request) - for i in range(200,400,1): + for i in range(200, 400, 1): order_instrument = response["positionBook"]["instrument"] price = response["positionBook"]["buckets"][i]["price"] - short_count_percent = response["positionBook"]["buckets"][i]["shortCountPercent"] + short_count_percent = response["positionBook"]["buckets"][i][ + "shortCountPercent" + ] long_count_percent = response["positionBook"]["buckets"][i]["longCountPercent"] print(f"Instrument: {order_instrument}") print(f"Price: {price}") print(f"Short count percent: {short_count_percent}") print(f"Long count percent: {long_count_percent}") - print("-"*30) + print("-" * 30) -def create_limit_order(accountID, instrument, other_args: List[str]): +def create_limit_order(accountID, other_args: List[str]): parser = argparse.ArgumentParser( - add_help=False, - prog="create_limit_order", - description="Create limit order", + add_help=False, + prog="create_limit_order", + description="Create limit order", ) parser.add_argument( - "-u", - "--unit", - dest="units", - action="store", - type=int, - default=0, - required=True, + "-u", + "--unit", + dest="units", + action="store", + type=int, + default=0, + required=True, ) parser.add_argument( - "-p", - "--price", - dest="price", - action="store", - type=float, - required=True, + "-p", + "--price", + dest="price", + action="store", + type=float, + required=True, ) + parser.add_argument( + "-i", + "--instrument", + dest="instrument", + action="store", + required=True) ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return data = { - "order":{ + "order": { "price": ns_parser.price, - "instrument": instrument, + "instrument": ns_parser.instrument, "units": ns_parser.units, "type": "LIMIT", - "timeInForce":"GTC", - "positionFill": "DEFAULT" + "timeInForce": "GTC", + "positionFill": "DEFAULT", } } request = orders.OrderCreate(accountID, data) @@ -250,12 +238,12 @@ def cancel_pending_order(accountID, other_args: List[str]): description="Cancel Pending Order", ) parser.add_argument( - "-i", - "--id", - dest="orderID", - action="store", - type=str, - required=True, + "-i", + "--id", + dest="orderID", + action="store", + type=str, + required=True, ) ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: @@ -270,7 +258,7 @@ def cancel_pending_order(accountID, other_args: List[str]): def get_pending_orders(accountID): request = orders.OrdersPending(accountID) response = client.request(request) - for i in range(0,25,1): + for i in range(len(response["orders"])): try: order_id = response["orders"][i]["id"] instrument = response["orders"][i]["instrument"] @@ -284,7 +272,7 @@ def get_pending_orders(accountID): print(f"Units: {units}") print(f"Time created: {create_time}") print(f"Time in force: {time_in_force}") - print("-"*30) + print("-" * 30) except IndexError: break @@ -292,7 +280,7 @@ def get_pending_orders(accountID): def get_open_positions(accountID): request = positions.OpenPositions(accountID) response = client.request(request) - for i in range(0,100,1): + for i in range(0, 100, 1): try: instrument = response["positions"][i]["instrument"] long_units = response["positions"][i]["long"]["units"] @@ -303,12 +291,12 @@ def get_open_positions(accountID): short_upl = response["positions"][i]["short"]["unrealizedPL"] print(f"Instrument: {instrument}\n") print(f"Long Units: {long_units}") - print(f"Long P/L: {long_pl}") + print(f"Total Long P/L: {long_pl}") print(f"Long Unrealized P/L: {long_upl}\n") print(f"Short Units: {short_units}") - print(f"Short P/L: {short_pl}") + print(f"Total Short P/L: {short_pl}") print(f"Short Unrealized P/L: {short_upl}") - print("-"*30+"\n") + print("-" * 30 + "\n") except IndexError: break @@ -316,7 +304,7 @@ def get_open_positions(accountID): def get_open_trades(accountID): request = trades.OpenTrades(accountID) response = client.request(request) - for i in range (0,100,1): + for i in range(len(response["trades"])): try: order_id = response["trades"][i]["id"] instrument = response["trades"][i]["instrument"] @@ -328,20 +316,16 @@ def get_open_trades(accountID): print(f"Instrument: {instrument}") print(f"Initial Units: {initial_units}") print(f"Current Units: {current_units}") - print(f"Price: {price}") + print(f"Entry Price: {price}") print(f"Unrealized P/L: {unrealized_pl}") - print("-"*30+"\n") + print("-" * 30 + "\n") except IndexError: break - - - - def close_trade(accountID, other_args: List[str]): parser = ArgumentParser( - add_help = False, + add_help=False, prog="close_trade", description="close a trade", ) @@ -364,11 +348,63 @@ def close_trade(accountID, other_args: List[str]): ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return - data={ + data = { "units": ns_parser.units, - } + } try: request = trades.TradeClose(accountID, ns_parser.orderID, data) response = client.request(request) except V20Error as e: print(e) + + +def show_candles(accountID): + parameters = { + "granularity": "D" + } + try: + request = instruments.InstrumentsCandles("EUR_USD", params=parameters) + response = client.request(request) + process_response(response) + oanda_fix_date(".temp_candles.csv") + df = pd.read_csv(".candles.csv") + df["Datetime"] = pd.to_datetime(df["Datetime"]) + df.set_index(pd.DatetimeIndex(df["Datetime"]), inplace=True) + print(df) +# dvalues = df[["Open", "High", "Low", "Close"]].values.tolist() +# pdates = mdates.date2num(data.index) +# ohlc = [ ppdates[i] + dvalues[i] for i in range(len(pdates))] +# plt.style.use("fivethirtyeight") +# fix, ax = plt.subplots(figsize = (12, 6)) +# mpf.candlestick_ohlc(ax, ohlc[-50:], width=0.4) +# ax.set_xlabel("Date") +# ax.set_ylabel("Price") +# ax.set_title("Chart for EUR_USD") +# ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d')) +# fig.autofmt_xdate() + mpf.plot(df, type="candlestick") +# plt.show() + + except Exception as e: + print(e) + + +def process_response(response): + with open(".temp_candles.csv", 'w') as out: + for i in range(len(response["candles"])): + time = response["candles"][i]["time"] + o = response["candles"][i]["mid"]["o"] + h = response["candles"][i]["mid"]["h"] + l = response["candles"][i]["mid"]["l"] + c = response["candles"][i]["mid"]["c"] + out.write(str(time) + "," + str(o) + "," + str(h) + "," + str(l) + "," + str(c) + "\n") + + +def oanda_fix_date(file): + with open(file, 'r') as candle_file: + lines = candle_file.readlines() + with open(".candles.csv", 'w') as out: + out.write("Datetime, Open, High, Low, Close\n") + for line in lines: + with open(".candles.csv", "a") as output: + output.write(line[:10] + " " + line[11:19] + line[30:]) From f533563f1df9778fbe95961d94f20c12b0ccff8e Mon Sep 17 00:00:00 2001 From: DJ Nieto Date: Thu, 15 Apr 2021 22:40:30 -0600 Subject: [PATCH 4/4] ? --- terminal.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/terminal.py b/terminal.py index 56783314efd..c17d47b359c 100644 --- a/terminal.py +++ b/terminal.py @@ -32,6 +32,8 @@ from gamestonk_terminal.portfolio import port_controller from gamestonk_terminal.cryptocurrency import crypto_controller from gamestonk_terminal.screener import screener_controller from gamestonk_terminal.oanda import oanda_controller +from gamestonk_terminal.portfolio_optimization import po_controller + # import warnings @@ -90,6 +92,7 @@ def main(): "pa", "crypto", "ra", + "po", "fx", ] menu_parser.add_argument("opt", choices=choices)