mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-05 08:51:20 +00:00
Co-authored-by: jmaslek <jmaslek11@gmail.com> Co-authored-by: Chavithra <chavithra@gmail.com> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> Co-authored-by: Didier Rodrigues Lopes <dro.lopes@campus.fct.unl.pt> * improve user experience phase 1 * add difflib replacement * implement auto-complete on discovery menu * auoto-complete, difflib,jump through menus with cd * Updating tests : terminal * improve navigation on gst * add q command to terminal.py * usage instructions * Updating tests : terminal * fix cd command * vars updated * show menu when user is going through menus * allow user to forget the intiail / on scripting * terminal to accept text file with configuration * refactor -n to -l and clean code * add all commands to the tests_stocks_disc * remove fds from disc since we have search on stocks/ and stocks/sia * hopefully fix tests * skip test * fix completer type and calling menu after command for stocks/disc * show help menu when moving forward/backwards in menus * skip test * skip test - bug fix * add reset, help and quit to choices * improve stocks/disc controller * refactor sia menu * UX improvements for sia menu * improve ux design * refactor ca controller * fix infinite loop * improve ux on dps controller * Add capability of going back from a menu going into a menu * Ux economy (#1056) * First round of UX improvements on economy menu * Do fred menu + sample tests file * revert to > on menu * rename jobs file to .gst * remove cd option * improve return * final refactoring of disc_controller * fix ca,dps,sia,disc,stocks and terminal controllers * work on ba_controller menu * fix reset and try_except * UX on screener controller * fix for full reset name * Ux etfs (#1059) * Refactor ETF menu for new UX * Add couple more examples to test * r->reset * Clean up switch * gov menu refactored * fix reset issue * 80% of refactoring options and pricing/payoff menu is done * improve payoff controller * minor fix * fix: refactor pred and ta stocks controller * fix: refactor fa(and fmp) controllers * fix: refactored dd controller (still missing .gst tests) * fix infinite loop bug * refactor options controller * add tests for payoff and pricing * fix reset for options * UX Upgrade for Crypto controller(s) (#1049) * refactor crypto controller * refactor crypto/defi controller * added simple test and fixes not returning queue in commands * Clean up unused functions / iex load (#1047) * Clean up unused functions and adjust iex load function to not depend on dates * Had an incorrect tab on s_start definition * wrong default arg * regenerate pytest yml * Comment out parametrization * Tests : Stocks > Discovery (#1050) * Updating tests : stocks/discovery/ark * Updating tests : stocks/discovery/fidelity * Updating tests : stocks/discovery/fidelity * Updating tests : stocks/discovery/fidelity * Updating tests : stocks/discovery/seeking_alpha * Updating tests : stocks/discovery/seeking_alpha * Updating tests : stocks/discovery/shortinterest * Updating tests : stocks/discovery/shortinterest * Updating tests : stocks/discovery/seeking_alpha * Updating tests : stocks/discovery/shortinterest * Updating tests : stocks/discovery/disc_controller * Updating tests : stocks/dd * Updating tests : stocks/fa * Updating tests : stocks/discovery/financedatabase * Updating tests : stocks/discovery/finnhub * Updating tests : stocks/discovery/geekofwallstreet * Updating tests : stocks/discovery/marketbeat * Updating tests : stocks/discovery/nasdaq * Updating tests : stocks / discovery / yahoofinance * Updating tests : black * Updating tests : unused import * Updating tests : stocks/discovery/ark * Tests : Stocks > Doc + Helpers + Government (#1051) * Updating tests : stocks/government/controller * Updating tests : stocks/government * Updating tests : conftest * Updating tests : stocks > government * Updating tests : stocks/government * Updating tests : docs * Tests : Stocks > Insider (#1054) * Updating tests : stocks > helper * Updating tests : doc * Updating tests : clean stocks > fa > av * Updating tests : stocks/insider/controller * Updating tests : stocks/insider/business insider * Updating tests : stocks/insider/finviz * Updating tests : stocks/insider/openinsider * Updating tests : stocks/insider/controller * Updating tests : black * Updating tests : stocks/insider/controller * Tests : Stocks > Backtesting + Behavioural Analysis (#1057) * Updating tests : add __init__ files * Updating tests : stocsk/behavioural_analysis * Updating tests : black * Updating tests : stocks/backtesting * Updating tests : stocks/backtesting * fix: converted top to limit arguments * fix: refactor disc controller, updated docs * fix: refactor dd_controller and docs * fix: refactor nft controller and docs * fix: pass test temporarily, onchain controller refactor, docs * fix: overview controller refactor, fix quit command * fix: linting issues * fix: refacot ta controller * fix: refactor pred controller * fix: linting * fix: crypto controller * fix: added tests, updated all controlers * fix: menu print renamed from stocks to crypto controller, added tests * fix: fix faster function execution * Fix annoying pylint C0201 error * fix: renamed commands to long format * DISC Cleanup (#1058) * Get rid/cleanup of marketbeat functions * Get rid of last unused disc function + fix related tests * fix test * Dividend History Chart (#1053) * Dividend History Chart * changed to default number 10 * changed divs flag default to false * updating the expected result for test_fa_controller. * else statement * fix: added load on dd * fix: added autocompletion in all commands with argument choices * fix: linting * Workflows + Stocks > Insider (#1061) * Updating code : stocks/insider remove unused file * Updating workflows : tests - set mypy==0.910 * fix: linting * Fixing Linting (#1062) * Updating code : fixing linting mypy message = Too many arguments for <lambda> * Updating workflows : allow newest mypy version * Updating code : apply black * Updating code : black * fix: updated predict controller help to match stocks * Ux: portfolio (#1063) * First step of portfolio UX * Add all broker controllers to UX stuff * UX Improvement for PO Co-authored-by: Didier Rodrigues Lopes <dro.lopes@campus.fct.unl.pt> * UX Improvement for resources (#1064) Co-authored-by: Didier Rodrigues Lopes <dro.lopes@campus.fct.unl.pt> * UX: stock/bt (#1065) * UX: stocks>qa (#1068) * fix mypy lambda * skip tests for now * remove unused paths.py * rename tests/simulator to tests/e2e * refactor options/screener menu * UX : move `gst` files location * fix stocks_controller * UX upgrade of the Forex menu (#1048) * Add basic forex menu test * Add forex routes to terminal paths * Remove commands from paths because they're not menus * WIP Refactor forex controller * refactor crypto controller * Remove commented code * Improve user output with printed text * Add "help" back to the list of choices * Enable the command queue for the forex controller * refactor crypto/defi controller * Fix candle chart blocking the terminal * Black * Return help and reset to the list of known args * added simple test and fixes not returning queue in commands * Add currency codes loading to the av_model * Return the queue in edge cases (when commands don't process) * Split select into to and from to enable autocompletion * Style text output * Stop printing help after the execution of every command * Update test scenarios * Black * fix: converted top to limit arguments * fix: refactor disc controller, updated docs * Delete oanda the old view file that was moved into the oanda menu * fix: refactor dd_controller and docs * fix: refactor nft controller and docs * fix: pass test temporarily, onchain controller refactor, docs * fix: overview controller refactor, fix quit command * fix: linting issues * fix: refacot ta controller * fix: refactor pred controller * fix: linting * fix: crypto controller * fix: added tests, updated all controlers * fix: menu print renamed from stocks to crypto controller, added tests * fix: fix faster function execution * Implement basic UX improvement of the oanda controller * Update the forex controller * Fix annoying pylint C0201 error * Add latest convention changes to the forex controller * fix: renamed commands to long format * fix: added load on dd * Merge the latest updates of the controller design * fix: added autocompletion in all commands with argument choices * fix: linting * fix: linting * fix: updated predict controller help to match stocks * Update the forex menu e2e test scripts * Add check_non_negative_float helper * Update the controller with the latest changes to the convention * Update the currency pair loading mechanism * Move data models logic to the models file * Update update oanda views to be interact with the models * Upgrade oanda controller * Remove raw stocks ba and eda code from the forex menu * Update "help wanted" banner for ba and eda in forex menu * Remove remainders of stocks ba and eda from forex context * Improve typing, docstrings and error messages * Remove stocks ba and eda code that was merged from other ux branches * Add fixes that prevented incorrect argument handling * Remove -argument from the candles call If there is an expected agr `-g` and you put an incorrect argument `-argument` the difflib will interpret `argument` as `g` Co-authored-by: jose-donato <zmcdonato@gmail.com> Co-authored-by: Didier Rodrigues Lopes <dro.lopes@campus.fct.unl.pt> * fix reset for menus that require ticker * UX improvement on research menu * skip insider controller test * initial refactoring of insider_controller * improve insider controller ux part 2 * finish refactoring ins controller ux menu * fix bug of when commands in queue have args * skip test * comment test stuff * UX: stocks>qa (#1071) * refactor return self.queue * fix return None * minor fix * minor tabulate fix * Get rid of leading '/' in terminal and add some newlines on quits. (#1074) * Get rid of leading '/' in terminal and add some newlines on quits. * print crypto help on menu entry * looks like a format issue here... * newlines on quit * remove unnecessary line break * fix pylint issue * refactor * refactor * allow portfolio optimization to quit context * add exit at end of scripts * improve dd_controller * test ux in stocks/dd menu * Ux upgrade for reports context (#1075) * Refactor reports and upgrade them with the latest controller convention * Add test scenarios for the reports context * test ux stocks/ta * ux branch scripts/ta * improvement on main param * Upgrades for the UX upgrade for the fa and fa/fmp menus (#1076) * Change --num to --limit * Remove inconsistent/unreliable functions from the choices list * Improve docstring compliance with numpy doc format * Fix hardcoded class id in dcf scrapper * Fix annoying pylint error in discordbot that was blocking the hook * Add test scenarios for the fa and fa/fmp menus * Fix forgotten replacement of --num to --limit * Fix tests * Return some excluded commands to the choices list * Fix dd report to reflect the updates * Fix set function not returning the queue * Update gst test files * fix exit on ca from another submenu * fix changes of options/screener * fix dps controller * fix fa when running out of AV calls * Fix TVL plot locking interpreter during defi test * Add exception handling for broken coingecko scrapper * skip fa/av test that fails * fix dps tests Co-authored-by: Chavithra PARANA <chavithra@gmail.com> Co-authored-by: jmaslek <jmaslek11@gmail.com> Co-authored-by: jose-donato <zmcdonato@gmail.com> Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com>
462 lines
13 KiB
Python
462 lines
13 KiB
Python
"""Oanda View."""
|
|
__docformat__ = "numpy"
|
|
|
|
from typing import Dict, Union
|
|
|
|
import matplotlib.pyplot as plt
|
|
import matplotlib.ticker as mticker
|
|
import mplfinance as mpf
|
|
import pandas as pd
|
|
import pandas_ta as ta
|
|
import seaborn as sns
|
|
|
|
from gamestonk_terminal import config_plot as cfgPlot
|
|
from gamestonk_terminal import feature_flags as gtff
|
|
from gamestonk_terminal.helper_funcs import (
|
|
plot_autoscale,
|
|
)
|
|
|
|
from gamestonk_terminal.forex.oanda.oanda_model import (
|
|
cancel_pending_order_request,
|
|
close_trades_request,
|
|
fx_price_request,
|
|
account_summary_request,
|
|
open_positions_request,
|
|
open_trades_request,
|
|
orderbook_plot_data_request,
|
|
pending_orders_request,
|
|
positionbook_plot_data_request,
|
|
order_history_request,
|
|
create_order_request,
|
|
get_candles_dataframe,
|
|
get_calendar_request,
|
|
)
|
|
|
|
|
|
def get_fx_price(account: str, instrument: Union[str, None]):
|
|
"""View price for loaded currency pair.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda account ID
|
|
instrument : Union[str, None]
|
|
Instrument code or None
|
|
"""
|
|
data = fx_price_request(accountID=account, instrument=instrument)
|
|
if data and data is not None and "prices" in data:
|
|
bid = data["prices"][0]["bids"][0]["price"]
|
|
ask = data["prices"][0]["asks"][0]["price"]
|
|
print(f"{instrument if instrument else ''}" + " Bid: " + bid)
|
|
print(f"{instrument if instrument else ''}" + " Ask: " + ask)
|
|
print("")
|
|
else:
|
|
print("No data was retrieved.\n")
|
|
|
|
|
|
def get_account_summary(accountID: str):
|
|
"""Print Oanda account summary.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
"""
|
|
df_summary = account_summary_request(accountID)
|
|
if df_summary is not False and not df_summary.empty:
|
|
print(df_summary.to_string(index=False, header=False))
|
|
else:
|
|
print("No data was retrieved.\n")
|
|
|
|
|
|
def get_order_book(accountID: str, instrument: str):
|
|
"""
|
|
Plot the orderbook for the instrument if Oanda provides one.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
instrument : str
|
|
The loaded currency pair
|
|
"""
|
|
df_orderbook_data = orderbook_plot_data_request(
|
|
accountID=accountID, instrument=instrument
|
|
)
|
|
if df_orderbook_data is not False and not df_orderbook_data.empty:
|
|
pd.set_option("display.max_rows", None)
|
|
# HELP WANTED!
|
|
# TODO:
|
|
# An early contributor left "magic constants" in this function
|
|
# help is needed to figure out the rationale behind these or
|
|
# refactor it to not include the magic numbers.
|
|
df_orderbook_data = df_orderbook_data.take(range(527, 727, 1))
|
|
book_plot(df_orderbook_data, instrument, "Order Book")
|
|
print("")
|
|
else:
|
|
print("No data was retrieved.\n")
|
|
|
|
|
|
def get_position_book(accountID: str, instrument: str):
|
|
"""Plot a position book for an instrument if Oanda provides one.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
instrument : str
|
|
The loaded currency pair
|
|
"""
|
|
df_positionbook_data = positionbook_plot_data_request(
|
|
accountID=accountID, instrument=instrument
|
|
)
|
|
if df_positionbook_data is not False and not df_positionbook_data.empty:
|
|
pd.set_option("display.max_rows", None)
|
|
# HELP WANTED!
|
|
# TODO:
|
|
# An early contributor left "magic constants" in this function
|
|
# help is needed to figure out the rationale behind these or
|
|
# refactor it to not include the magic numbers.
|
|
df_positionbook_data = df_positionbook_data.take(range(219, 300, 1))
|
|
book_plot(df_positionbook_data, instrument, "Position Book")
|
|
print("")
|
|
else:
|
|
print("No data was retrieved.\n")
|
|
|
|
|
|
def list_orders(accountID: str, order_state: str, order_count: int):
|
|
"""List order history.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
order_state : str
|
|
Filter orders by a specific state ("PENDING", "CANCELLED", etc.)
|
|
order_count : int
|
|
Limit the number of orders to retrieve
|
|
"""
|
|
df_order_list = order_history_request(order_state, order_count, accountID)
|
|
if df_order_list is not False and not df_order_list.empty:
|
|
print(df_order_list)
|
|
print("")
|
|
else:
|
|
print("No data was retrieved.\n")
|
|
|
|
|
|
def create_order(accountID: str, instrument: str, price: int, units: int):
|
|
"""Create a buy/sell order.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
instrument : str
|
|
The loaded currency pair
|
|
price : int
|
|
The price to set for the limit order.
|
|
units : int
|
|
The number of units to place in the order request.
|
|
"""
|
|
df_orders = create_order_request(price, units, instrument, accountID)
|
|
if df_orders is not False and not df_orders.empty:
|
|
print(df_orders.to_string(index=False))
|
|
print("")
|
|
else:
|
|
print("No data was returned from Oanda.\n")
|
|
|
|
|
|
def cancel_pending_order(accountID: str, orderID: str):
|
|
"""Cancel a Pending Order.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
orderID : str
|
|
The pending order ID to cancel.
|
|
"""
|
|
order_id = cancel_pending_order_request(orderID, accountID)
|
|
if order_id is not False and order_id is not None:
|
|
print(f"Order {order_id} canceled.")
|
|
print("")
|
|
else:
|
|
print("No data was returned from Oanda.\n")
|
|
|
|
|
|
def get_open_positions(accountID: str):
|
|
"""Get information about open positions.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
"""
|
|
df_positions = open_positions_request(accountID)
|
|
if df_positions is not False and not df_positions.empty:
|
|
print(df_positions.to_string(index=False))
|
|
print("")
|
|
else:
|
|
print("No data was returned from Oanda.\n")
|
|
|
|
|
|
def get_pending_orders(accountID: str):
|
|
"""Get information about pending orders.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
"""
|
|
df_pending = pending_orders_request(accountID)
|
|
if df_pending is not False and not df_pending.empty:
|
|
print(df_pending.to_string(index=False))
|
|
print("")
|
|
elif df_pending is not False and df_pending.empty:
|
|
print("No pending orders.\n")
|
|
else:
|
|
print("No data was returned from Oanda.\n")
|
|
|
|
|
|
# Pylint raises no-member error because the df_trades can be either
|
|
# a dataframe or a boolean (False) value that has no .empty and no .to_string
|
|
# pylint: disable=no-member
|
|
def get_open_trades(accountID: str):
|
|
"""View open trades.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
"""
|
|
df_trades = open_trades_request(accountID)
|
|
if df_trades is not False and not df_trades.empty:
|
|
print(df_trades.to_string(index=False))
|
|
print("")
|
|
elif df_trades is not False and df_trades.empty:
|
|
print("No trades were found.\n")
|
|
else:
|
|
print("No data was returned from Oanda.\n")
|
|
|
|
|
|
def close_trade(accountID: str, orderID: str, units: Union[int, None]):
|
|
"""Close a trade.
|
|
|
|
Parameters
|
|
----------
|
|
accountID : str
|
|
Oanda user account ID
|
|
orderID : str
|
|
ID of the order to close
|
|
units : Union[int, None]
|
|
Number of units to close. If empty default to all.
|
|
"""
|
|
df_trades = close_trades_request(orderID, units, accountID)
|
|
if df_trades is not False and not df_trades.empty:
|
|
print(df_trades.to_string(index=False))
|
|
print("")
|
|
elif df_trades is not False and df_trades.empty:
|
|
print("No trades were found.\n")
|
|
else:
|
|
print("No data was returned from Oanda.\n")
|
|
|
|
|
|
def show_candles(
|
|
instrument: str,
|
|
granularity: str,
|
|
candlecount: int,
|
|
additional_charts: Dict[str, bool],
|
|
):
|
|
"""Show candle chart.
|
|
|
|
Parameters
|
|
----------
|
|
instrument : str
|
|
The loaded currency pair
|
|
granularity : str, optional
|
|
Data granularity
|
|
candlecount : int, optional
|
|
Limit for the number of data points
|
|
additional_charts : Dict[str, bool]
|
|
A dictionary of flags to include additional charts
|
|
"""
|
|
df_candles = get_candles_dataframe(instrument, granularity, candlecount)
|
|
if df_candles is not False and not df_candles.empty:
|
|
plots_to_add, legends, subplot_legends = add_plots(
|
|
df_candles, additional_charts
|
|
)
|
|
|
|
if gtff.USE_ION:
|
|
plt.ion()
|
|
|
|
_, ax = mpf.plot(
|
|
df_candles,
|
|
type="candle",
|
|
style="charles",
|
|
volume=True,
|
|
scale_padding={"left": 0.3, "right": 1, "top": 0.8, "bottom": 0.8},
|
|
returnfig=True,
|
|
addplot=plots_to_add,
|
|
)
|
|
|
|
ax[0].set_title(f"{instrument} {granularity}")
|
|
if len(legends) > 0:
|
|
ax[0].legend(legends)
|
|
# pylint: disable=C0200
|
|
for i in range(0, len(subplot_legends), 2):
|
|
ax[subplot_legends[i]].legend(subplot_legends[i + 1])
|
|
|
|
print("")
|
|
|
|
|
|
def calendar(instrument: str, days: int):
|
|
"""View calendar of significant events.
|
|
|
|
Parameters
|
|
----------
|
|
instrument : str
|
|
The loaded currency pair
|
|
days : int
|
|
Number of days in advance
|
|
"""
|
|
df_calendar = get_calendar_request(days, instrument)
|
|
if df_calendar is not False and not df_calendar.empty:
|
|
print(df_calendar.to_string(index=False))
|
|
print("")
|
|
elif df_calendar is not False and df_calendar.empty:
|
|
print("No calendar records were found.\n")
|
|
else:
|
|
print("No data was returned from Oanda.\n")
|
|
|
|
|
|
# Utilities
|
|
|
|
|
|
def add_plots(df: pd.DataFrame, additional_charts: Dict[str, bool]):
|
|
"""Add additional plots to the candle chart.
|
|
|
|
Parameters
|
|
----------
|
|
df : pd.DataFrame
|
|
The source data
|
|
additional_charts : Dict[str, bool]
|
|
A dictionary of flags to include additional charts
|
|
|
|
Returns
|
|
-------
|
|
Tuple
|
|
Tuple of lists containing the plots, legends and subplot legends
|
|
"""
|
|
panel_number = 2
|
|
plots_to_add = []
|
|
legends = []
|
|
subplot_legends = []
|
|
|
|
if additional_charts["ad"]:
|
|
ad = ta.ad(df["High"], df["Low"], df["Close"], df["Volume"])
|
|
ad_plot = mpf.make_addplot(ad, panel=panel_number)
|
|
plots_to_add.append(ad_plot)
|
|
subplot_legends.extend([panel_number * 2, ["AD"]])
|
|
panel_number += 1
|
|
|
|
if additional_charts["bbands"]:
|
|
bbands = ta.bbands(df["Close"])
|
|
bbands = bbands.drop("BBB_5_2.0", axis=1)
|
|
bbands_plot = mpf.make_addplot(bbands, panel=0)
|
|
plots_to_add.append(bbands_plot)
|
|
legends.extend(["Lower BBand", "Middle BBand", "Upper BBand"])
|
|
|
|
if additional_charts["cci"]:
|
|
cci = ta.cci(df["High"], df["Low"], df["Close"])
|
|
cci_plot = mpf.make_addplot(cci, panel=panel_number)
|
|
plots_to_add.append(cci_plot)
|
|
subplot_legends.extend([panel_number * 2, ["CCI"]])
|
|
panel_number += 1
|
|
|
|
if additional_charts["ema"]:
|
|
ema = ta.ema(df["Close"])
|
|
ema_plot = mpf.make_addplot(ema, panel=0)
|
|
plots_to_add.append(ema_plot)
|
|
legends.append("10 EMA")
|
|
|
|
if additional_charts["rsi"]:
|
|
rsi = ta.rsi(df["Close"])
|
|
rsi_plot = mpf.make_addplot(rsi, panel=panel_number)
|
|
plots_to_add.append(rsi_plot)
|
|
subplot_legends.extend([panel_number * 2, ["RSI"]])
|
|
panel_number += 1
|
|
|
|
if additional_charts["obv"]:
|
|
obv = ta.obv(df["Close"], df["Volume"])
|
|
obv_plot = mpf.make_addplot(obv, panel=panel_number)
|
|
plots_to_add.append(obv_plot)
|
|
subplot_legends.extend([panel_number * 2, ["OBV"]])
|
|
panel_number += 1
|
|
|
|
if additional_charts["sma"]:
|
|
sma_length = [20, 50]
|
|
for length in sma_length:
|
|
sma = ta.sma(df["Close"], length=length)
|
|
sma_plot = mpf.make_addplot(sma, panel=0)
|
|
plots_to_add.append(sma_plot)
|
|
legends.append(f"{length} SMA")
|
|
|
|
if additional_charts["vwap"]:
|
|
vwap = ta.vwap(df["High"], df["Low"], df["Close"], df["Volume"])
|
|
vwap_plot = mpf.make_addplot(vwap, panel=0)
|
|
plots_to_add.append(vwap_plot)
|
|
legends.append("vwap")
|
|
|
|
return plots_to_add, legends, subplot_legends
|
|
|
|
|
|
def book_plot(df: pd.DataFrame, instrument: str, book_type: str):
|
|
"""Plot the order book for a given instrument.
|
|
|
|
Parameters
|
|
----------
|
|
df : pd.DataFrame
|
|
Order book data
|
|
instrument : str
|
|
The loaded currency pair
|
|
book_type : str
|
|
Order book type
|
|
"""
|
|
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=cfgPlot.PLOT_DPI)
|
|
df = df.apply(pd.to_numeric)
|
|
df["shortCountPercent"] = df["shortCountPercent"] * -1
|
|
axis_origin = max(
|
|
abs(max(df["longCountPercent"])), abs(max(df["shortCountPercent"]))
|
|
)
|
|
ax.set_xlim(-axis_origin, +axis_origin)
|
|
|
|
sns.set_style(style="darkgrid")
|
|
|
|
sns.barplot(
|
|
x="longCountPercent",
|
|
y="price",
|
|
data=df,
|
|
label="Count Percent",
|
|
color="green",
|
|
orient="h",
|
|
)
|
|
|
|
sns.barplot(
|
|
x="shortCountPercent",
|
|
y="price",
|
|
data=df,
|
|
label="Prices",
|
|
color="red",
|
|
orient="h",
|
|
)
|
|
|
|
ax.invert_yaxis()
|
|
plt.title(f"{instrument} {book_type}")
|
|
plt.xlabel("Count Percent")
|
|
plt.ylabel("Price")
|
|
sns.despine(left=True, bottom=True)
|
|
ax.yaxis.set_major_locator(mticker.MultipleLocator(5))
|
|
if gtff.USE_ION:
|
|
plt.ion()
|
|
plt.show()
|