Exemplo n.º 1
0
    def __init__(self):
        self._future_date = date.today() + timedelta(5)

        self._rh = Robinhood()
        self._rh.login(username=USERNAME,
                       password=PASSWORD,
                       qr_code=MFA)
 def __init__(self, name: str = 'pyrh_adapter'):
     super().__init__(name, ['pyrh_request', 'trade'])
     self.rbn = Robinhood()
     self.logged_in = False
     self.client_req = Queue()
     self.requests = Queue()
     self.request_lock = Lock()
Exemplo n.º 3
0
def get_paginated_results(
        client: Robinhood, url: str,
        **kwargs: Any) -> Generator[Dict[str, Any], None, None]:
    page = client.get(url, **kwargs)
    yield from page['results']
    while page['next']:
        page = client.get(page['next'])
        yield from page['results']
Exemplo n.º 4
0
 def __init__(self, username, pwd, rsi=5):
     self.rh = Robinhood()
     self.rh.login(username=username, password=pwd)
     self.rsiPeriod = rsi
     self.enteredPosition = False
     self.s = sched.scheduler(time.time, time.sleep)
     self.data = np.array([])
     self.closePrices = []
Exemplo n.º 5
0
def rh_setup():
    load_dotenv(verbose=True)
    rh_user = os.getenv("ROBINHOOD_USERNAME")
    rh_pass = os.getenv("ROBINHOOD_PASSWORD")
    rh_qr = os.getenv("ROBINHOOD_QR")
    rh = Robinhood()
    rh.login(username=rh_user, password=rh_pass, qr_code=rh_qr)

    return rh
Exemplo n.º 6
0
def test_bad_logout():
    """logout without logging in"""
    if not LOGIN_OK:
        pytest.xfail("cannot test without valid user/passwd")
    rh_obj = Robinhood()
    with pytest.warns(UserWarning):
        req = rh_obj.logout()

    assert req.status_code != 200
Exemplo n.º 7
0
def login():
    load_dotenv()
    try:
        rh = load_session()
    except InvalidCacheFile:
        rh = Robinhood(username=os.getenv("username"),
                       password=os.getenv("password"))
        rh.login()
        dump_session(rh)  # so you don't have to do mfa again
    return rh
Exemplo n.º 8
0
def login(email: str, password: str, mfa_secret: str) -> Robinhood:
    client = Robinhood(email, password)
    totp = pyotp.TOTP(mfa_secret)

    # We do this, because we don't want to modify the underlying API library
    # excessively to support this. Therefore, we monkey-patch our way to
    # success.
    with mock_stdin(totp.now()):
        client.login()

    return client
Exemplo n.º 9
0
def test_intstruments(config=CONFIG):
    """test `instruments` endpoint"""
    # TODO: this test is bad, just repeat of code inside endpoint
    params = {"query": CONFIG.get("FETCH", "test_ticker")}
    headers = {"User-Agent": CONFIG.get("FETCH", "user_agent")}
    address = Robinhood().endpoints["instruments"]
    res = requests.get(address, headers=headers, params=params)
    res.raise_for_status()
    hard_data = res.json()["results"]

    data = Robinhood().instruments(CONFIG.get("FETCH", "test_ticker"))

    assert data == hard_data
Exemplo n.º 10
0
def test_logout(config=CONFIG):
    """make sure logout works"""
    if not LOGIN_OK:
        pytest.xfail("cannot test without valid user/passwd")
    rh_obj = Robinhood()
    assert rh_obj.login(
        username=config.get("LOGIN", "username"),
        password=config.get("LOGIN", "password"),
    )
    assert rh_obj.auth_token is not None
    req = rh_obj.logout()

    assert req.status_code == 200
Exemplo n.º 11
0
    def __init__(self, logger: logging.Logger):
        """Authenticates Robinhood object and gathers the portfolio information to store it in a variable.

        Args:
            logger: Takes the class ``logging.Logger`` as an argument.
        """
        rh = Robinhood()
        rh.login(username=env.robinhood_user,
                 password=env.robinhood_pass,
                 qr_code=env.robinhood_qr)
        raw_result = rh.positions()
        self.logger = logger
        self.result = raw_result['results']
        self.rh = rh
Exemplo n.º 12
0
def create_robinhood_instance(username=None, password=None):
    try:
        if not username:
            username = os.getenv("USERNAME")

        if not password:
            password = os.getenv("PASSWORD")

        rh = Robinhood()
        rh.login(username, password)

        return rh
    except Exception:
        logger.error("Failed to login, exiting...")
        sys.exit()
Exemplo n.º 13
0
def test_get_news(config=CONFIG):
    """test `get_news` endpoint"""
    test_ticker = CONFIG.get("FETCH", "test_ticker")
    raw_news = helpers.fetch_REST_directly("news", test_ticker, config)
    get_news = Robinhood().get_news(test_ticker)

    assert get_news == raw_news
Exemplo n.º 14
0
def test_login_badpass(config=CONFIG):
    """try to login with bad creds"""
    if not LOGIN_OK:
        pytest.xfail("cannot test without valid user/passwd")
    bad_pass = "******"
    with pytest.raises(RH_exception.LoginFailed):
        Robinhood().login(username=config.get("LOGIN", "username"), password=bad_pass)
Exemplo n.º 15
0
def robinhood() -> None:
    """Gets investment details from robinhood API."""
    if not all([env.robinhood_user, env.robinhood_pass, env.robinhood_qr]):
        logger.warning("Robinhood username, password or QR code not found.")
        support.no_env_vars()
        return

    sys.stdout.write("\rGetting your investment details.")
    rh = Robinhood()
    rh.login(username=env.robinhood_user,
             password=env.robinhood_pass,
             qr_code=env.robinhood_qr)
    raw_result = rh.positions()
    result = raw_result["results"]
    stock_value = watcher(rh, result)
    speaker.speak(text=stock_value)
Exemplo n.º 16
0
    def main(self, stock, action, quantity):
        username = ""
        password = ""

        rh = Robinhood()
        rh.login(username=username, password=password)

        instrument = rh.instruments(stock)[0]

        if (action == "buy"):
            rh.place_buy_order(instrument, quantity)
            self.enteredTrade = True

        if (action == "sell"):
            rh.place_sell_order(instrument, quantity)
            self.enteredTrade = False
Exemplo n.º 17
0
def test_get_historical_data(config=CONFIG):
    headers = {"User-Agent": CONFIG.get("FETCH", "user_agent")}

    address = Robinhood().endpoints["historicals"]
    res = requests.get(
        address,
        headers=headers,
        params={
            "symbols": ",".join([CONFIG.get("FETCH", "test_ticker")]).upper(),
            "interval": "day",
            "span": "year",
            "bounds": "regular",
        },
    )

    hard_data = res.json()["results"]

    data = Robinhood().get_historical_quotes(
        [CONFIG.get("FETCH", "test_ticker")], "day", "year")

    assert data == hard_data
Exemplo n.º 18
0
    def addRobinhood(self):
        rh = Robinhood()
        if self.RobinHoodUser:

            rh.login(username=self.RobinHoodUser,
                     password=self.RobinHoodPassword)
            rh.print_quote("AAPL")
        else:
            print("You must set your Robinhood passwords up in init")
Exemplo n.º 19
0
 def rh_pull_orders_history(user_id, passwd):
     pyrh_rb = Robinhood()
     pyrh_rb.login(username=user_id, password=passwd, challenge_type="sms")
     past_orders = RhWrapper.rh_pull_all_history_orders(pyrh_rb)
     # keep past orders in reverse chronological order
     past_orders_sorted = sorted(past_orders, key=itemgetter('last_transaction_at'), reverse=True)
     orders_saved_to_db = 0
     for order in past_orders_sorted:
         # check if order already in db
         if order['state'] == 'filled':
             obj = robinhood_stock_order_history.objects.filter(timestamp=dateutil.parser.parse(order['last_transaction_at']))
             if not obj:
                 obj                 = robinhood_stock_order_history()
                 obj.order_type      = order['side']
                 obj.price           = order['average_price']
                 obj.shares          = order['cumulative_quantity']
                 obj.symbol, name    = RhWrapper.rh_pull_symbol_from_instrument_url(order['instrument'])
                 obj.state           = order['state']
                 obj.timestamp       = dateutil.parser.parse(order['last_transaction_at'])
                 obj.save()
                 orders_saved_to_db = orders_saved_to_db + 1
         else:
             continue
     logging.error('orders_saved_to_db: ' + str(orders_saved_to_db))
Exemplo n.º 20
0
 def get(self, request):
     #return HttpResponse(request.user.id)
     #env = environ.Env(DEBUG=(bool, False))
     # reading .env file
     #environ.Env.read_env()
     currentUser = Account.objects.get(user=request.user)
     my_trader = Robinhood()
     my_trader.login(username=currentUser.rhoodID,
                     password=currentUser.rhoodPWD,
                     qr_code=currentUser.rhQ)
     data = my_trader.portfolios()
     my_trader.logout()
     return HttpResponse(data)
     context = {}
     return render(request, self.template_name, context)
Exemplo n.º 21
0
def test_cancel_bad_order_id():
    """cancel a naughty order id"""
    bad_id = "1234Dx"
    if not LOGIN_OK:
        pytest.xfail("cannot test without valid user/passwd")
    rh_obj = Robinhood()
    rh_obj.login(
        username=CONFIG.get("LOGIN", "username"),
        password=CONFIG.get("LOGIN", "password"),
    )
    with pytest.raises(ValueError):
        rh_obj.cancel_order(bad_id)
Exemplo n.º 22
0
def test_login_happypath(config=CONFIG):
    """try to log in to robinhood"""
    global LOGIN_OK

    if (not config.get("LOGIN", "username")) or (not config.get("LOGIN", "password")):
        LOGIN_OK = False
        pytest.xfail("no login credentials given")

    try:
        LOGIN_OK = Robinhood().login(
            username=config.get("LOGIN", "username"),
            password=config.get("LOGIN", "password"),
        )
    except Exception as err_msg:
        LOGIN_OK = False
        raise err_msg

    assert LOGIN_OK
Exemplo n.º 23
0
class TestURLWrapper:
    """make sure get_url returns expected behavior"""

    base_url = "https://api.robinhood.com/"
    rh_obj = Robinhood()

    def test_url_endpoint(self):
        """fetch url directly"""
        global TEST_URL_RESULT

        req = requests.get(self.base_url)
        req.raise_for_status()

        TEST_URL_RESULT = req.json()

    def test_get_url(self):
        """fetch url with get_url"""
        data = self.rh_obj.get_url(self.base_url)
        assert data == TEST_URL_RESULT
Exemplo n.º 24
0
def fetch_REST_directly(endpoint_name, arg_string, config):
    """fetch REST endpoint (instead of ?arg1=val1&arg2=val2)

    Args:
        endpoint_name (str): endpoint name in RH class
        arg_string (str): additional args to pass onto endpoint
        config (:obj:`configparser.ConfigParser`, optional): config for args

    Returns:
        (:obj:`dict`) JSON-parsed data from Robinhood endpoint

    """
    rh_object = Robinhood()
    address = rh_object.endpoints[endpoint_name]

    address = address + arg_string + "/"
    headers = {"User-Agent": config.get("FETCH", "user_agent")}
    req = requests.get(address, headers=headers)
    req.raise_for_status()
    return req.json()
Exemplo n.º 25
0
def login(username=False, password=False, device_token=False, force=False):
    global my_trader

    if not username:
        username = config.get('user')
        password = config.get('password')
        device_token = config.get('token')

    if not password:
        password = getpass.getpass()

    try:
        my_trader = Robinhood(username=username,
                              password=password,
                              device_token=device_token)
        print(my_trader)

    except Exception as ex:
        raise ex
        print("Password incorrect. Please try again")
        login(username, force)
Exemplo n.º 26
0
class TestFundamentalsHelpers:
    """wrapper to test fundamental architecture in order"""

    test_ticker = CONFIG.get("FETCH", "test_ticker")
    fake_ticker = CONFIG.get("FETCH", "fake_ticker")
    rh_obj = Robinhood()

    def test_fundamental_endpoint(self, config=CONFIG):
        """get raw data from Robinhood to test against"""
        global TEST_FUNDAMENTAL

        TEST_FUNDAMENTAL = helpers.fetch_REST_directly("fundamentals",
                                                       self.test_ticker,
                                                       config)
        TEST_FUNDAMENTAL["volume"] = "OVERWRITE"  # flaky value

    @flaky
    def test_validate_fundamental(self):
        """validate fetcher"""
        data = self.rh_obj.get_fundamentals(self.test_ticker)
        data["volume"] = "OVERWRITE"  # flaky value
        assert data == TEST_FUNDAMENTAL

    def test_validate_fail_fundamental(self):
        """validate bad-path exception"""
        with pytest.raises(NameError):
            data = self.rh_obj.get_fundamentals(self.fake_ticker)

    @flaky
    def test_validate_fundamental_wrapper(self):
        main_data = self.rh_obj.fundamentals(self.test_ticker)
        wrapped_data = self.rh_obj.fundamentals(self.test_ticker)

        main_data["volume"] = "OVERWRITE"  # flaky value
        wrapped_data["volume"] = "OVERWRITE"  # flaky value

        assert wrapped_data == main_data
        assert wrapped_data == TEST_FUNDAMENTAL
Exemplo n.º 27
0
class RobinhoodHelper:
    def __init__(self):
        self._future_date = date.today() + timedelta(5)

        self._rh = Robinhood()
        self._rh.login(username=USERNAME,
                       password=PASSWORD,
                       qr_code=MFA)

    def fetch_news(self, stock):
        stock_to_search = stock
        clean_stock_list = []
        if(self.is_time_to_reauthenticate(date.today())):
            self._rh.login(username=USERNAME,
                           password=PASSWORD,
                           qr_code=MFA)

        try:
            news = self._rh.get_news(stock_to_search)
            info_results = news["results"]

            for i in info_results:
                stock_price = self.format_decimal_price(stock)
                stock_info = StockInfo(i["uuid"], i["title"], i["source"], i["published_at"],
                                       i["preview_text"].replace("\n\n", ""), i["url"], stock_to_search, stock_price)
                clean_stock_list.append(stock_info)
            print(stock_to_search + " = " + str(clean_stock_list[0]))
        except Exception as e:
            print("Error: ", e, "Occurred.")
            print("Skipping...")
            print()
        return clean_stock_list

    def is_time_to_reauthenticate(self, now):
        if(now == self._future_date):
            self._future_date = date.today() + timedelta(5)
            return True
        return False

    def format_decimal_price(self, stock):
        TWOPLACES = decimal.Decimal(10) ** -2
        price = str(self._rh.last_trade_price(stock)[0][0])

        return str(decimal.Decimal(price).quantize(TWOPLACES))
Exemplo n.º 28
0
    def __init__(self, credentials: str) -> None:
        self._ext_equity = 0.0

        # Set up connection to Robinhood's API.
        self._rh = Robinhood()
        self._rh.login(**read_credentials(credentials))
Exemplo n.º 29
0
class TheHood:
    """
    A wrapper for producing the kinds of transactions and calls on my Robinhood
    portfolio I'm looking for.
    """
    def __init__(self, credentials: str) -> None:
        self._ext_equity = 0.0

        # Set up connection to Robinhood's API.
        self._rh = Robinhood()
        self._rh.login(**read_credentials(credentials))

    @property
    def extended_hours_equity(self) -> float:
        """
        Keep track of the extended equity and prevent its setting to NoneType.

        Returns:
            The current extended equity.
        """
        return self._ext_equity

    @extended_hours_equity.setter
    def extended_hours_equity(self, new_equity: Union[float, None]) -> None:
        """
        Keep track of the extended equity and prevent its setting to NoneType.

        Returns:
            The current extended equity.
        """
        if type(new_equity) is not float:
            pass
        else:
            self._ext_equity = new_equity

    @retry
    def total_dollar_equity(self) -> Tuple[float, float, float]:
        """
        Get values that explain the current monetary value of my account.

        Returns:
            A tuple containing today's closing equity in my account, followed by the
            previous day's closing value and the current extended / after-hours value.
        """
        self.extended_hours_equity = self._rh.extended_hours_equity()
        return self._rh.equity(), self._rh.equity_previous_close(
        ), self.extended_hours_equity

    @retry
    def account_potential(self) -> float:
        """
        Get the total account potential for comparison against the total account value.
        I define account potential as the sum of all stocks' current worth plus the
        absolute value of any losses.

        Returns:
            A float representing the account potential.
        """
        stocks = self._rh.securities_owned()['results']
        potential_sum = float(self._rh.portfolios()['withdrawable_amount'])
        for stock in stocks:
            # Make quantity a float as the API may change when I buy fractional shares.
            quantity = float(stock['quantity'])
            buy_price = float(stock['average_buy_price'])
            potential_sum += quantity * buy_price
        return potential_sum

    @retry
    def dividend_payments(self, since: str = '') -> float:
        """
        If there are dividend payments, I want to graph a sum in Grafana.

        Args:
            since: the date since we should allow the summation of dividends. For
                   instance, you may wish to set this to the past year.

        Returns:
            A float representing the sum of dividend payments to my account.
        """
        dividends: Dict = self._rh.dividends()['results']
        dividend_sum = 0.0
        for dividend in dividends:
            if dividend['state'] == 'paid':
                if since and not (datetime.fromisoformat(
                        dividend['paid_at'][:-1]) >
                                  datetime.fromisoformat(since)):
                    continue
                dividend_sum += float(dividend['amount'])
        return dividend_sum
Exemplo n.º 30
0
    It then compares the price of the stock at a given moment with the initial bought value
    If it's lower than some threshold, it will automatically sell 
"""

import sys, time

sys.path.append('./pyrh')
from pyrh import Robinhood

from dotenv import load_dotenv
load_dotenv()
import os
USERNAME = os.getenv("RH_USERNAME")
PASSWORD = os.getenv("RH_PASSWORD")

rh = Robinhood(username=USERNAME, password=PASSWORD)
rh.login()

# Set how much you're willing to loss
PRICE_DIFF_LIMIT = -100

# How many seconds to wait before polling
REFRESH_TIME = 1800


def fetch_json_by_url(rh, url):
    return rh.session.get(url).json()


def get_current_positions(rh):
    positions = rh.positions()