[![Build Status](https://travis-ci.org/sanko/Finance-Robinhood.svg?branch=master)](https://travis-ci.org/sanko/Finance-Robinhood)
# NAME

Finance::Robinhood - Trade Stocks and ETFs with Commission Free Brokerage Robinhood

# SYNOPSIS

    use Finance::Robinhood;

    my $rh = Finance::Robinhood->new();

    my $token = $rh->login($user, $password); # Store it for later

    $rh->quote('MSFT');
    Finance::Robinhood::quote('AAPL');
    # ????
    # Profit

# Examples

Some people have really only be reading this to get an automated stock trading
bot up and running. If that's you, the quickest way to get in without a load
of looking through documentation would be to move over to any of the example
scripts that I've included with this distributio:

- `eg/buy.pl`

    Buy stocks from the command line

        buy.pl -username=getMoney -password=*** -symbol=MSFT -quantity=2000

    Currently only market orders are supported but adding all the different limit
    order types is really rather simple. I might update it myself if I find a
    round tuit somewhere this summer. Might even add a sell script...

- `eg/export_orders.pl`

    Export your entire Robinhood order history to a CSV file from the command line

        buy -username=getMoney -password=*** -output=Robinhood.csv

    You can dump the CSV to STDOUT by leaving `-output` undefined.

Both scripts provide help when called without arguments. In addition to those
examples, you should check out the unofficial documentation of Robinhood
trade's API. Find it on github:
[https://github.com/sanko/Finance-Robinhood/blob/master/API.md](https://github.com/sanko/Finance-Robinhood/blob/master/API.md)

# DESCRIPTION

Finance::Robinhood allows you to buy, sell, and gather information related to
stocks and ETFs traded in the U.S commission free. Before we get into how,
please read the [Legal](https://metacpan.org/pod/LEGAL) section below. It's really important.

Okay. This package is organized into very easy to understand parts:

- Orders to buy and sell are created in [Finance::Robinhood::Order](https://metacpan.org/pod/Finance::Robinhood::Order). If
you're looking to make this as simple as possible, go check out the
[cheat sheet](https://metacpan.org/pod/Finance::Robinhood::Order#Order-Cheat-Sheet). You'll find
recipes for market, limit, as well as stop loss and stop limit order types.
- Quote information can be accessed with [Finance::Robinhood::Quote](https://metacpan.org/pod/Finance::Robinhood::Quote).
- Account information is handled by [Finance::Robinhood::Account](https://metacpan.org/pod/Finance::Robinhood::Account). If
you'd like to view or edit any of the information Robinhood has on you, start
there.
- Individual securities are represented by
[Finance::Robinhood::Instrument](https://metacpan.org/pod/Finance::Robinhood::Instrument) objects. Gathering quote and fundamental
information is only the beginning.
- [Finance::Robinhood::Watchlist](https://metacpan.org/pod/Finance::Robinhood::Watchlist) objects represent persistant lists of
securities you'd like to keep track of. Organize your watchlists by type!

If you're looking to just buy and sell without lot of reading, head over to
the [Finance::Robinhood::Order](https://metacpan.org/pod/Finance::Robinhood::Order) and pay special attention to the
[order cheat sheet](https://metacpan.org/pod/Finance::Robinhood::Order#Order-Cheat-Sheet) and apply
what you learn to the `eg/buy.pl` example script.

# METHODS

Finance::Robinhood wraps a powerfully capable API which has many options.
There are parts of this package that are object oriented (because they require
persistant login information) and others which may also be used functionally
(because they do not require login information). I've attempted to organize
everything according to how and when they are used... Let's start at the very
beginning: let's log in!

# Logging In

Robinhood requires an authorization token for most API calls. To get this
token, you must either pass it as an argument to `new( ... )` or log in with
your username and password.

## `new( ... )`

    # Passing the token is the preferred way of handling authorization
    my $rh = Finance::Robinhood->new( token => ... );

This would create a new Finance::Robinhood object ready to go.

    # Requires ->login(...) call :(
    my $rh = Finance::Robinhood->new( );

Without arguments, a new Finance::Robinhood object is created without account
information. Before you can buy or sell or do almost anything else, you must
[log in manually](#login).

On the bright side, for future logins, you can store the authorization token
and use it rather than having to pass your username and password around
anymore.

## `login( ... )`

    my $token = $rh->login($user, $password);
    # Save the token somewhere

Logging in allows you to buy and sell securities with your Robinhood account.
You must do this if you do not have an authorization token.

If login was successful, a valid token is returned and may also be had by
calling `token( )`. The token should be kept secret and stored for use in
future calls to `new( ... )`.

## `token( )`

If you logged in with a username/password combo but later decided you might
want to securely store authorization info to pass to `new( ... )` next time.
Get the authorization token here.

## `logout( )`

    my $token = $rh->login($user, $password);
    # ...do some stuff... buy... sell... idk... stuff... and then...
    $rh->logout( ); # Goodbye!

Logs you out of Robinhood by forcing the token returned by `login(...)` or
passed to `new(...)` to expire.

_Note_: This will log you out _everywhere_ because Robinhood generates a
single authorization token per account at a time! All logged in clients will
be logged out. This is good in rare case your device or the token itself is
stolen.

## `forgot_password( ... )`

    Finance::Robinhood::forgot_password('contact@example.com');

It happens. This requests a password reset email to be sent from Robinhood.

## `change_password( ... )`

    Finance::Robinhood::change_password( $username, $password, $token );

When you've forgotten your password, the email Robinhood send contains a link
to an online form where you may change your password. That link has a token
you may use here to change the password as well.

# User Information

Brokerage firms must collect a lot of information about their customers due to
IRS and SEC regulations. They also keep data to identify you internally.
Here's how to access all of the data you entered when during registration and
beyond.

## `user_id( )`

    my $user_id = $rh->user_id( );

Returns the ID Robinhood uses to identify this particular account. You could
also gather this information with the `user_info( )` method.

## `user_info( )`

    my %info = $rh->user_info( );
    say 'My name is ' . $info{first_name} . ' ' . $info{last_name};

Returns very basic information (name, email address, etc.) about the currently
logged in account as a hash.

## `basic_info( )`

This method grabs basic but more private information about the user including
their date of birth, marital status, and the last four digits of their social
security number.

## `additional_info( )`

This method grabs information about the user that the SEC would like to know
including any affiliations with publicly traded securities.

## `employment_info( )`

This method grabs information about the user's current employment status and
(if applicable) current job.

## `investment_profile( )`

This method grabs answers about the user's investment experience gathered by
the survey performed during registration.

## `identity_mismatch( )`

Returns a paginated list of identification information.

# Accounts

A user may have access to more than a single Robinhood account. Each account
is represented by a Finance::Robinhood::Account object internally. Orders to
buy and sell securities require an account object. The object also contains
information about your financial standing.

For more on how to use these objects, please see the
Finance::Robinhood::Account docs.

## `accounts( ... )`

This method returns a paginated list of Finance::Robinhood::Account objects
related to the currently logged in user.

_Note_: Not sure why the API returns a paginated list of accounts. Perhaps
in the future a single user will have access to multiple accounts?

# Financial Instruments

Financial Instrument is a fancy term for any equity, asset, debt, loan, etc.
but we'll strictly be referring to securities (stocks and ETFs) as financial
instruments.

We use blessed Finance::Robinhood::Instrument objects to represent securities
in order transactions, watchlists, etc. It's how we'll refer to a security so
looking over the documentation found in Finance::Robinhood::Instrument would
be a wise thing to do.

## `instrument( ... )`

    my $msft = $rh->instrument('MSFT');
    my $msft = Finance::Robinhood::instrument('MSFT');

When a single string is passed, only the exact match for the given symbol is
returned as a Finance::Robinhood::Instrument object.

    my $msft = $rh->instrument({id => '50810c35-d215-4866-9758-0ada4ac79ffa'});
    my $msft = Finance::Robinhood::instrument({id => '50810c35-d215-4866-9758-0ada4ac79ffa'});

If a hash reference is passed with an `id` key, the single result is returned
as a Finance::Robinhood::Instrument object. The unique ID is how Robinhood
identifies securities internally.

    my $results = $rh->instrument({query => 'solar'});
    my $results = Finance::Robinhood::instrument({query => 'solar'});

If a hash reference is passed with a `query` key, results are returned as a
hash reference with cursor keys (`next` and `previous`). The matching
securities are Finance::Robinhood::Instrument objects which may be found in
the `results` key as a list.

    my $results = $rh->instrument({cursor => 'cD04NjQ5'});
    my $results = Finance::Robinhood::instrument({cursor => 'cD04NjQ5'});

Results to a query may generate more than a single page of results. To gather
them, use the `next` or `previous` values.

    my $results = $rh->instrument( );
    my $results = Finance::Robinhood::instrument( );

Returns a sample list of top securities as Finance::Robinhood::Instrument
objects along with `next` and `previous` cursor values.

# Orders

Now that you've [logged in](#logging-in) and
[found the particular stock](#financial-instruments) you're interested in,
you probably want to buy or sell something. You do this by placing orders.

Orders are created by using the constructor found in Finance::Robinhood::Order
directly so have a look at the documentation there (especially the small cheat
sheet).

Once you've place the order, you'll want to keep track of them somehow. To do
this, you may use either of the following methods.

## `locate_order( ... )`

    my $order = $rh->locate_order( $order_id );

Returns a blessed Finance::Robinhood::Order object related to the buy or sell
order with the given id if it exits.

## `list_orders( ... )`

    my $orders = $rh->list_orders( );

Requests a list of all orders ordered from newest to oldest. Executed and even
canceled orders are returned in a `results` key as Finance::Robinhood::Order
objects. Cursor keys `next` and `previous` may also be present.

    my $more_orders = $rh->list_orders({ cursor => $orders->{next} });

You'll likely generate more than a hand full of buy and sell orders which
would generate more than a single page of results. To gather them, use the
`next` or `previous` values.

# Quotes and Historical Data

If you're doing anything beyond randomly choosing stocks with a symbol
generator, you'll want to know a little more. Robinhood provides access to
both current and historical data on securities.

## `quote( ... )`

    my %msft = $rh->quote('MSFT');
    my $swa  = Finance::Robinhood::quote('LUV');

    my $quotes = $rh->quote('AAPL', 'GOOG', 'MA');
    my $quotes = Finance::Robinhood::quote('LUV', 'JBLU', 'DAL');

Requests current information about a security which is returned as a
Finance::Robinhood::Quote object. If `quote( ... )` is given a list of
symbols, the objects are returned as a paginated list.

This function has both functional and object oriented forms. The functional
form does not require an account and may be called without ever logging in.

## `historicals( ... )`

    # Snapshots of basic quote data for every five minutes of the previous day
    my $msft = $rh->historicals('MSFT', '5minute', 'day');

You may retrieve historical quote data with this method. The first argument is
a symbol. The second is an interval time and must be either `5minute`,
`10minute`, `day`, or `week`.

The third argument is a span of time indicating how far into the past you
would like to retrieve and may be one of the following: `day`, `week`,
`year`, or `5year`.

So, to get five years of weekly historical data for Apple, you would write...

    my $iHist = $rh->historicals('AAPL', 'week', '5year');
    my $gates = Finance::Robinhood::historicals('MSFT', 'week', '5year');

This method returns a list of hashes which in turn contain the following keys:

- `begins_at` - A DateTime object indicating the timestamp of this block
of data.
- `close_price` - The most recent close price during this interval.
- `high_price` - The most recent high price during this interval.
- `interpolated` - Indicates whether the data was a statistical estimate.
This is a boolean value.
- `low_price` - The most recent low price during this interval.
- `open_price` - The most recent open price during this interval.
- `volume` - The trading volume during this interval.

Note that if you already have a Finance::Robinhood::Instrument object, you may
want to just call the object's `historicals( $interval, $span )` method which
wraps this.

This function has both functional and object oriented forms. The functional
form does not require an account and may be called without ever logging in.

# Informational Cards and Notifications

TODO

## `cards( )`

    my $cards = $rh->cards( );

Returns the informational cards the Robinhood apps display. These are links to
news, typically. Currently, these are returned as a paginated list of hashes
which look like this:

    {   action => "robinhood://web?url=https://finance.yahoo.com/news/spotify-agreement-win-artists-company-003248363.html",
        call_to_action => "View Article",
        fixed => bless(do{\(my $o = 0)}, "JSON::Tiny::_Bool"),
        icon => "news",
        message => "Spotify Agreement A 'win' For Artists, Company :Billboard Editor",
        relative_time => "2h",
        show_if_unsupported => 'fix',
        time => "2016-03-19T00:32:48Z",
        title => "Reuters",
        type => "news",
        url => "https://api.robinhood.com/notifications/stack/4494b413-33db-4ed3-a9d0-714a4acd38de/",
    }

\* Please note that the `url` provided by the API is incorrect! Rather than
`"https://api.robinhood.com/notifications/stack/4494b413-33db-4ed3-a9d0-714a4acd38de/"`,
it should be
`<"https://api.robinhood.com/**midlands/**notifications/stack/4494b413-33db-4ed3-a9d0-714a4acd38de/"`>.

# Dividends

TODO

## `dividends( )`

Gathers a paginated list of dividends due (or recently paid) for your account.

`results` currently contains a list of hashes which look a lot like this:

    { account => "https://api.robinhood.com/accounts/XXXXXXXX/",
      amount => 0.23,
      id => "28a46be1-db41-4f75-bf89-76c803a151ef",
      instrument => "https://api.robinhood.com/instruments/39ff611b-84e7-425b-bfb8-6fe2a983fcf3/",
      paid_at => undef,
      payable_date => "2016-04-25",
      position => "1.0000",
      rate => "0.2300000000",
      record_date => "2016-02-29",
      url => "https://api.robinhood.com/dividends/28a46be1-db41-4f75-bf89-76c803a151ef/",
      withholding => "0.00",
    }

# Watchlists

You can keep track of a list of securities by adding them to a watchlist. The
watchlist used by the official Robinhood apps and preloaded with popular
securities is named 'Default'. You may create new watchlists for
organizational reasons but the official apps currently only display the
'Default' watchlist.

Each watchlist is represented by a Finance::Robinhood::Watchlist object.
Please read the docs for that package to find out how to add and remove
individual securities.

## `watchlist( ... )`

    my $hotlist = $rh->watchlist( 'Blue_Chips' );

Returns a blessed Finance::Robinhood::Watchlist if the watchlist with the
given name exists.

## `create_watchlist( ... )`

    my $watchlist = $rh->create_watchlist( 'Energy' );

You can create new Finance::Robinhood::Watchlist objects with this. Here, your
code would create a new one named "Energy".

Note that only alphanumeric characters and understore are allowed in watchlist
names. No whitespace, etc.

## `delete_watchlist( ... )`

    my $watchlist = $rh->create_watchlist( 'Energy' );
    $rh->delete_watchlist( $watchlist );

    $rh->create_watchlist( 'Energy' );
    $rh->delete_watchlist( 'Energy' );

You may remove a watchlist with this method. The argument may either be a
Finance::Robinhood::Watchlist object or the name of the watchlist as a string.

If you clobber the watchlist named 'Default', it will be recreated with
popular securities the next time you open any of the official apps.

## `watchlists( ... )`

    my $watchlists = $rh->watchlists( );

Returns all your current watchlists as a paginated list of
Finance::Robinhood::Watchlists.

    my $more = $rh->watchlists( { cursor => $watchlists->{next} } );

In case where you have more than one page of watchlists, use the `next` and
`previous` cursor strings.

# LEGAL

This is a simple wrapper around the API used in the official apps. The author
provides no investment, legal, or tax advice and is not responsible for any
damages incurred while using this software. Neither this software nor its
author are affiliated with Robinhood Financial LLC in any way.

For Robinhood's terms and disclosures, please see their website at http://robinhood.com/

# LICENSE

Copyright (C) Sanko Robinson.

This library is free software; you can redistribute it and/or modify
it under the terms found in the Artistic License 2.

Other copyrights, terms, and conditions may apply to data transmitted through
this module. Please refer to the [LEGAL](https://metacpan.org/pod/LEGAL) section.

# AUTHOR

Sanko Robinson <sanko@cpan.org>
