OpenBB-finance / OpenBB

Investment Research for Everyone, Everywhere.
https://openbb.co
Other
33.54k stars 3.06k forks source link

[FR] Make it possible to have "jobs" - a group of commands that can be called by calling a single command #83

Closed CosminIvanov closed 3 years ago

CosminIvanov commented 3 years ago

What's the problem of not having this feature? It is likely that people want to do the same things everyday. Let's say they first start by seeing the top gainers of yesterday, orders on fidelity and the news. They would need to do those steps every day. Having to type only one command for everything would make their work a lot faster.

Describe the solution you would like There are three solutions that I think can both be implemented:

CosminIvanov commented 3 years ago

I am waiting for your comments and ideas. I may start working on it sometime during the next 2 weeks if no one else does it.

shadycuz commented 3 years ago

Could you give an example of a group of commands you would turn into a job and the value proposition besides just being shorter?

Also I think workflow describes what your asking for better.

CosminIvanov commented 3 years ago

In any case I would do a general_discovery and analyze_stock General discovery: give me everything tranding on reddit, twitter, orders, news Analyze stock: picks stock I wanted, run through some basic strategies, give me sentiment from a multitude of platforms.

Those two steps may be combined later in a separate program.

EDIT: This is how I see interaction with the program in the future. Having to type every single command is not that user friendly. Not user friendly for average joe, not user friendly for a programmer that wants to automate some stuff.

aia commented 3 years ago

See https://github.com/aia/GamestonkTerminal/tree/main/gamestonk_terminal/papermill

aia commented 3 years ago

Initial code is now merged into the main branch.

clothespin commented 3 years ago

So, it doesn't actually work yet because the current terminal input loop doesn't support running in something other than a tty, but because the terminal runs in a loop taking a line of text as input and interpreting it, it can in principle be scripted (at least on Linux) using the same techniques used for other scripting languages like python, perl, or bash. A sample script might look like the following:

#!/usr/bin/env python /path/to/terminal.py
load -t GME -s 2021-01-01
export -f /path/to/reports/report.csv -F csv

Which would load data for GME since the start of the year and then export it to a csv file. The OS takes care of feeding each line to the interpreter over stdin and feeding EOF once done. Since the terminal exits when it sees an EOF, that's good enough to enable a batch scripting workflow, although ideally we'd want to actually catch that exception for a cleaner exit vs just letting the unhandled EofError kill the terminal.

clothespin commented 3 years ago

Hmm, on trying out a couple things, input redirection in bash with < almost works with a script.

Test script (test.gme):

load -t GME -s 2020-01-01
export

Output:

clothespin@marshawn:~/GamestonkTerminal$ python ./terminal.py <test.gme

Welcome to Didier's Gamestonk Terminal

What do you want to do?
   help        help to see this menu again
   quit        to abandon the program

   clear       clear a specific stock ticker from analysis
   load        load a specific stock ticker for analysis
   view        view and load a specific stock ticker for technical analysis

Stock: ?
Market CLOSED.

Menus:
   disc        discover trending stocks,     e.g. map, sectors, high short interest
   mill        papermill menu,           menu to generate notebook reports
   sen         sentiment of the market,      from: reddit, stocktwits, twitter

> Loading Daily GME stock with starting period 2020-01-01 for analysis.

What do you want to do?
   help        help to see this menu again
   quit        to abandon the program

   clear       clear a specific stock ticker from analysis
   load        load a specific stock ticker for analysis
   view        view and load a specific stock ticker for technical analysis
   export      export the currently loaded dataframe to a file or stdout

Daily Stock: GME (from 2020-01-01)
Market CLOSED.

Menus:
   disc        discover trending stocks,     e.g. map, sectors, high short interest
   mill        papermill menu,           menu to generate notebook reports
   sen         sentiment of the market,      from: reddit, stocktwits, twitter
   res         research web page,            e.g.: macroaxis, yahoo finance, fool
   fa          fundamental analysis,         e.g.: income, balance, cash, earnings
   ta          technical analysis,           e.g.: ema, macd, rsi, adx, bbands, obv
   dd          in-depth due-diligence,       e.g.: news, analyst, shorts, insider, sec
   pred        prediction techniques,        e.g.: regression, arima, rnn, lstm, prophet

> date,1. open,2. high,3. low,4. close,5. adjusted close,6. volume,7. dividend amount,8. split coefficient
2020-01-02,6.14,6.47,6.07,6.31,6.31,4453598.0,0.0,1.0
2020-01-03,6.21,6.25,5.835,5.88,5.88,3543933.0,0.0,1.0
...snip...
2021-03-09,217.71,249.85,208.5101,246.9,246.9,39099331.0,0.0,1.0
What do you want to do?
   help        help to see this menu again
   quit        to abandon the program

   clear       clear a specific stock ticker from analysis
   load        load a specific stock ticker for analysis
   view        view and load a specific stock ticker for technical analysis
   export      export the currently loaded dataframe to a file or stdout

Daily Stock: GME (from 2020-01-01)
Market CLOSED.

Menus:
   disc        discover trending stocks,     e.g. map, sectors, high short interest
   mill        papermill menu,           menu to generate notebook reports
   sen         sentiment of the market,      from: reddit, stocktwits, twitter
   res         research web page,            e.g.: macroaxis, yahoo finance, fool
   fa          fundamental analysis,         e.g.: income, balance, cash, earnings
   ta          technical analysis,           e.g.: ema, macd, rsi, adx, bbands, obv
   dd          in-depth due-diligence,       e.g.: news, analyst, shorts, insider, sec
   pred        prediction techniques,        e.g.: regression, arima, rnn, lstm, prophet

> Traceback (most recent call last):
  File "./terminal.py", line 502, in <module>
    main()
  File "./terminal.py", line 381, in main
    as_input = input("> ")
EOFError: EOF when reading a line

That's almost useful already, all that is needed is to

  1. Catch the EOF exception and exit successfully (if we made it to EOF, we interpreted all the input).
  2. Use os.isatty(sys.stdin) to detect when the terminal is being run in batch mode and turn off all helper text and the terminal prompt string, so all that is printed to stdout is the data requested.

and we can run the terminal as an interpreter in batch mode against a prewritten script.

clothespin commented 3 years ago

Took a look at implementing this today but it looks like the addition of prompt_toolkit breaks this workflow, I get

Warning: Input is not a terminal (fd=0).

Welcome to Gamestonk Terminal 🚀

Traceback (most recent call last):
  File "/usr/lib/python3.7/asyncio/selector_events.py", line 251, in _add_reader
    key = self._selector.get_key(fd)
  File "/usr/lib/python3.7/selectors.py", line 192, in get_key
    raise KeyError("{!r} is not registered".format(fileobj)) from None
KeyError: '0 is not registered'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "terminal.py", line 214, in <module>
    main()
  File "terminal.py", line 81, in main
    as_input = session.prompt(f"{get_flair()}> ", completer=completer)
  File "/home/ian/.local/lib/python3.7/site-packages/prompt_toolkit/shortcuts/prompt.py", line 1013, in prompt
    return self.app.run(set_exception_handler=set_exception_handler)
  File "/home/ian/.local/lib/python3.7/site-packages/prompt_toolkit/application/application.py", line 849, in run
    self.run_async(pre_run=pre_run, set_exception_handler=set_exception_handler)
  File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "/home/ian/.local/lib/python3.7/site-packages/prompt_toolkit/application/application.py", line 815, in run_async
    return await _run_async2()
  File "/home/ian/.local/lib/python3.7/site-packages/prompt_toolkit/application/application.py", line 791, in _run_async2
    result = await _run_async()
  File "/home/ian/.local/lib/python3.7/site-packages/prompt_toolkit/application/application.py", line 721, in _run_async
    read_from_input
  File "/usr/lib/python3.7/contextlib.py", line 112, in __enter__
    return next(self.gen)
  File "/home/ian/.local/lib/python3.7/site-packages/prompt_toolkit/input/vt100.py", line 170, in _attached_input
    loop.add_reader(fd, callback_wrapper)
  File "/usr/lib/python3.7/asyncio/selector_events.py", line 324, in add_reader
    return self._add_reader(fd, callback, *args)
  File "/usr/lib/python3.7/asyncio/selector_events.py", line 254, in _add_reader
    (handle, None))
  File "/usr/lib/python3.7/selectors.py", line 359, in register
    self._selector.register(key.fd, poller_events)
PermissionError: [Errno 1] Operation not permitted

I'll look into how other projects that use prompt_toolkit handle this.

aia commented 3 years ago

Both DD and Econ have been working very well for a while. Closing.

DidierRLopes commented 2 years ago

@CosminIvanov took some time, we needed that magic xmas sparkle... ✨

How is this looking? image

Also, multiple inline commands + autocompletion image

DidierRLopes commented 2 years ago

Merged https://github.com/GamestonkTerminal/GamestonkTerminal/pull/1041 :)