Skip to content

Commit 68d42d7

Browse files
committed
Update README.md
1 parent f5d8b64 commit 68d42d7

File tree

1 file changed

+17
-94
lines changed

1 file changed

+17
-94
lines changed

README.md

Lines changed: 17 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Algotrader
1+
![algotrader](https://i.imgur.com/gVbBwgh.png)
22
#### *Simple algorithmic stock and option trading for Node.js.*
33

44
[![npm package](https://nodei.co/npm/algotrader.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/algotrader/)
@@ -58,12 +58,11 @@
5858
- [Robinhood](#robinhood)
5959
- [Getting started](#robinhood)
6060
- [Multi-factor authentication](#mfa)
61-
- [Saving & loading a user](#saving--loading-a-user)
62-
- [Automatic re-authentication](Automatic-re-authentication)
63-
- [Get a user's portfolio](#get-a-users-portfolio)
64-
- [Placing an order](#placing-an-order)
65-
- [Options](#options)
66-
- [Option chains](#option-chains)
61+
- [Saving & loading a user](#saving--loading-a-user)
62+
- [Get a user's portfolio](#get-a-users-portfolio)
63+
- [Placing an order](#placing-an-order)
64+
- [Options](#options)
65+
- [Option chains](#option-chains)
6766
- Algorithm Library
6867
- [Scheduler](#scheduler)
6968
- Data Library
@@ -190,43 +189,6 @@ User.load()
190189

191190
However, authentication tokens issued by Robinhood expire after 24 hours. Version 1.4.5 takes this into account and [```User.isAuthenticated()```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#User) will return ```false``` if the token has expired. Make sure to check for this and re-authenticate if necessary. When re-authenticating, you will need to provide a password either through CLI or when calling [```User.authenticate()```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#User) as the first parameter.
192191

193-
194-
##### Automatic re-authentication
195-
196-
You can use [```User.reauthenticate```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#User) function to re-authenticate the user automatically when the authentication token is expired (after 24 hours). To do this you have to use securely saved refresh token.
197-
198-
You can save and restore a user data including a refresh token using [```User.serialize```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#User) (right after user has been authenticated) and [```User.deserialize```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#User) functions.
199-
200-
**Note:** [```User.safe```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#User) does not save a refresh token by security reason.
201-
202-
```js
203-
const authenticatedUser; // In state right after `authenticate` called, but not after `load`.
204-
const data = authenticatedUser.serialize();
205-
206-
// Save the data in your secure storage
207-
// superSecureStorage.save(userId, data);
208-
```
209-
210-
```js
211-
// Restore the data from your secure storage
212-
// const data = superSecureStorage.load(userId);
213-
214-
User.deserialize(data)
215-
.then(restoredUser => {
216-
if(!restoredUser.isAuthenticated())
217-
restoredUser.reauthenticate()
218-
.then(myUser => {
219-
// Now you can use your user
220-
// Don't forget to save it
221-
// superSecureStorage.save(userId, data);
222-
}).catch(error => {
223-
// Make sure to always catch possible errors.
224-
// You probably need to re-authenticate using username and password here.
225-
});
226-
}
227-
);
228-
```
229-
230192
#### Get a user's portfolio
231193
There are a good amount of query functions that you can run on the user's portfolio. Using your [```User```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#User) instance, you can grab the portfolio using [```User.getPortfolio```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#User) which returns a new [```Portfolio```](https://github.com/Ladinn/algotrader/blob/master/docs/ROBINHOOD.md#Portfolio) object.
232194
```js
@@ -377,53 +339,25 @@ Here is an example of how you would sort an option chain by strike price and exp
377339
```js
378340
const moment = require('moment');
379341

380-
// As of writing, QQQ share prices were $165.37.
381-
// Next option expiration is 02/01/2019.
382-
383342
const qqq = await Instrument.getBySymbol('QQQ');
384343
const quote = await qqq.getQuote(user);
385344
const chain = await OptionInstrument.getChain(user, qqq, 'call');
386345
const expirations = await OptionInstrument.getExpirations(user, qqq);
387346
// Returns an array of expiration dates [ 2019-02-01T00:00:00.000Z, 2019-02-08T00:00:00.000Z, ...
388347

389-
// Create a new array with options expiring on the next expiration date
390-
let optionsExpiringNext = [];
391-
392348
const nextExpiration = moment(expirations[0]);
393349

350+
let optionsExpiringNext = [];
351+
394352
chain.forEach(option => {
395353
let thisExpiration = moment(option.getExpiration());
396354
if (thisExpiration.isSame(nextExpiration)) {
397355
optionsExpiringNext.push(option);
398356
}
399357
});
400358

401-
// Filter out the option contracts with strike prices higher than the last trade price:
402-
let inTheMoneyCalls = optionsExpiringNext.filter(x => {
403-
return x.getStrikePrice() < quote.getLast();
404-
});
405359

406-
// Since Algotrader provides option chains ordered by strike price (low-high), we can
407-
// use the last element in the array to get the contract with the highest
408-
// strike price: the $165 call expiring on Feb 1st.
409-
let optionToBuy = inTheMoneyCalls[inTheMoneyCalls.length - 1];
410-
411-
OptionInstrument {
412-
url: 'https://api.robinhood.com',
413-
tradability: 'tradable',
414-
strikePrice: 165,
415-
state: 'active',
416-
type: 'put',
417-
symbol: 'QQQ',
418-
minTicks: { cutoff_price: '0.00', below_tick: '0.01', above_tick: '0.01' },
419-
instrumentURL: 'https://api.robinhood.com/options/instruments/c8fbe71b-5fc5-4741-9b30-004e31bf89a6/',
420-
ids:
421-
{ chain: '1c9d052c-165d-43a3-878d-3a0a0ca1ab49',
422-
option: 'c8fbe71b-5fc5-4741-9b30-004e31bf89a6' },
423-
dates:
424-
{ expiration: 2019-02-01T00:00:00.000Z,
425-
created: 2018-12-13T03:14:20.947Z,
426-
updated: 2018-12-13T03:14:20.947Z } }
360+
427361
```
428362

429363
---
@@ -436,39 +370,28 @@ For scheduling tasks, running backtests, and paper-trading, the algorithm librar
436370

437371
Using the [```Scheduler```](https://github.com/Ladinn/algotrader/blob/master/docs/ALGORITHM.md#scheduler) class, you'll be able to define exactly when you want a function to run using the following methods:
438372

439-
- ```onMarketOpen(offset)```
373+
- ```Scheduler.onMarketOpen(offset, f)```
440374
- Runs every morning when the NYSE opens. (Typically 9:30 AM EST)
441375
- Offset is in milliseconds and can be positive (after) or negative (before).
442-
- ```onMarketClose(offset)```
376+
- ```Scheduler.onMarketClose(offset, f)```
443377
- Runs every afternoon when the NYSE closes. (Typically 4:00 PM EST)
444378
- Offset is in milliseconds and can be positive (after) or negative (before).
445-
- ```every(minutes, extended)```
379+
- ```Scheduler.every(minutes, extended, f)```
446380
- Runs every ```x``` minutes during market hours or during typical extended trading hours. (9 AM EST - 6 PM EST)
447381

448-
But first, you'll need to create a new instance of the Scheduler. Here's an easy example that runs a function 5 minutes before the market opens and another one every 30 minutes during regular trading hours:
382+
Here's an easy example that runs a function 5 minutes before the market opens and another one every 30 minutes during regular trading hours:
449383

450384
```js
451385
const Scheduler = algotrader.Algorithm.Scheduler;
452386

453-
const openingTask = new Scheduler(function run() {
454-
console.log("Running!");
387+
Scheduler.onMarketOpen(-5 * 60000, () => {
388+
// Function to run five minutes before the market opens
455389
});
456390

457-
openingTask.onMarketOpen(-5 * 60000).then(nextDate => {
458-
// This is optional, but returns a promise with the next invocation time
391+
Scheduler.every(30, false, () => {
392+
// Function to run every 1/2 hour
459393
});
460394
```
461-
```js
462-
const Scheduler = algotrader.Algorithm.Scheduler;
463-
464-
const halfHourTask = new Scheduler(function run() {
465-
console.log("Running!");
466-
});
467-
468-
halfHourTask.every(30, false);
469-
```
470-
To cancel a task, just call ```cancel``` after it has been scheduled.
471-
472395
For documentation on all Scheduler functions, visit the [```Algorithm Library Docs.```](https://github.com/Ladinn/algotrader/blob/master/docs/ALGORITHM.md#scheduler)
473396

474397
---

0 commit comments

Comments
 (0)