Skip to content

Commit 94321b1

Browse files
committed
Add logger module.
1 parent 1cfabea commit 94321b1

10 files changed

+118
-49
lines changed

calculateFloatTurnover.js

+7-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
Example usage: node float GPRO 77930000 2017-01-04
88
*/
9-
const log = console.log;
9+
const log = require('./src/logger.js');
1010
const rp = require('request-promise');
1111
const config = require('./config.js')
1212
const parseRawData = require('./src/parseRawData.js');
@@ -18,7 +18,7 @@ const startDate = process.argv[4];
1818
const reverse = process.argv[5] === 'reverse' ? true : false;
1919

2020
const fetchDataForOneStock = (ticker) => new Promise((resolve, reject) => {
21-
log('Getting: ', '\x1b[34m', ticker, '\x1b[0m');
21+
log(info, `Getting: \x1b[34m${ticker}\x1b[0m`);
2222
return rp({ // Request data for this stock.
2323
uri: 'https://www.alphavantage.co/query',
2424
json: true,
@@ -106,7 +106,9 @@ fetchDataForOneStock(ticker)
106106
return [day.date, day.v];
107107
});
108108
return volumeByDate;
109-
}).then(volumeByDate => {
109+
})
110+
.then(volumeByDate => {
110111
const result = getFloatTurnovers(volumeByDate, totalFloat, startDate, reverse);
111-
log(result);
112-
}).catch(e => console.log(`Error: ${e}`));
112+
log('info', result);
113+
})
114+
.catch(e => log('warn', e, e.stack));

config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
module.exports = {
2-
API_KEY : "U9RKMXCNKJZOWNFR"
2+
API_KEY : 'U9RKMXCNKJZOWNFR',
3+
logLevels: ['info', 'warn', 'critical', 'debug']
34
}

findOuterPivotsOnLowerVolume.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const filterResults = require('./src/filterResults.js');
3535
const printToScreen = require('./src/printResults.js');
3636
const writeToCsv = require('./src/writeCSV.js');
3737
const throttle = createThrottle(1, 1900);
38-
const log = console.log;
38+
const log = require('./src/logger.js');
3939
const data = require('./src/stockData.js');
4040

4141
// Date is passed in from command line in format 'YYYY-MM-DD'.
@@ -60,14 +60,14 @@ const filter = process.argv[2] ? [
6060
await throttle();
6161
return await fetchStock(ticker);
6262
} catch (err) {
63-
log(err);
63+
log('warn', err);
6464
}
6565
});
6666

6767
Promise.all(tickerRequests)
6868
.then(() => {
69-
log(`\n\x1b[31m Fetch complete. \x1b[0m`);
70-
log('Retries: ', data.retries);
69+
log('info', '\n\x1b[31m Fetch complete. \x1b[0m');
70+
log('info', `Retries: ${data.retries}`);
7171
})
7272
.then(() => {
7373
if (data.retries.length) {
@@ -78,7 +78,7 @@ const filter = process.argv[2] ? [
7878
}
7979
})
8080
.then(() => {
81-
log('\n\x1b[31m' + 'Retries complete.' + '\x1b[0m');
81+
log('info', '\n\x1b[31m Retries complete.\x1b[0m');
8282

8383
let results;
8484

@@ -87,23 +87,23 @@ const filter = process.argv[2] ? [
8787
}
8888
else {
8989
results = data.allSignals;
90-
log('\n\x1b[31m' + 'No search filter provided. All results: ' + '\x1b[0m' + '\n');
90+
log('info', '\n\x1b[31m' + 'No search filter provided. All results: ' + '\x1b[0m' + '\n');
9191
}
9292

9393
if (results.length) {
94-
log('\n\x1b[31m' + 'Search Results:' + '\x1b[0m');
94+
log('info', '\n\x1b[31m' + 'Search Results:' + '\x1b[0m');
9595
printToScreen(results);
9696
writeToCsv(results);
9797

9898
if(every(results, allResultsShort) || every(results, allResultsLong)) {
99-
log('\n\x1b[32m' + 'All results agree. This has been a reliable signal about next trading day for the market' + '\x1b[0m');
99+
log('info', '\n\x1b[32m' + 'All results agree. This has been a reliable signal about next trading day for the market' + '\x1b[0m');
100100
}
101101
}
102102
else {
103-
log('\n\x1b[31m' + 'No results.' + '\x1b[0m');
103+
log('info', '\n\x1b[31m' + 'No results.' + '\x1b[0m');
104104
}
105105
})
106-
.catch(e => log(e));
106+
.catch(e => log('warn', e));
107107
})();
108108

109109

scrapeFloat.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ const createThrottle = require('./src/createThrottle.js')
33
const throttle = createThrottle(1, 4000);
44
const tickers = require('./stockList.js');
55
const fs = require('fs');
6-
const log = console.log;
6+
const log = require('.logger.js');
77

88
// Retreives financial data from Yahoo Finance, scrapes the float for a ticker, and returns it as a tuple.
99
const scrapeFloat = (ticker) => new Promise((resolve, reject) => {
10-
console.log(`Scraping float for ${ticker}...`);
10+
log('info', `Scraping float for ${ticker}...`);
1111
return rp({
1212
uri: `https://finance.yahoo.com/quote/${ticker}/key-statistics/`,
1313
json: true,
@@ -16,7 +16,7 @@ const scrapeFloat = (ticker) => new Promise((resolve, reject) => {
1616
const searchTerm = 'floatShares":{"raw":';
1717
const floatIdx = response.indexOf(searchTerm);
1818
if (floatIdx < 0) {
19-
log(`Search term ${searchTerm} not found in response.`)
19+
log('info', `Search term ${searchTerm} not found in response.`)
2020
}
2121
const startIdx = floatIdx + searchTerm.length;
2222
const endIdx = startIdx + 20;
@@ -26,7 +26,7 @@ const scrapeFloat = (ticker) => new Promise((resolve, reject) => {
2626
resolve([ticker, parseInt(float)]);
2727
})
2828
.catch(err => {
29-
log(`error scraping float for ${ticker}: ${JSON.stringify(error)}`);
29+
log('warn', `error scraping float for ${ticker}: ${JSON.stringify(error)}`);
3030
})
3131
});
3232

@@ -41,10 +41,10 @@ const getAllFloats = (tickers) => {
4141
for (const floatEntry of results) {
4242
floatMap[floatEntry[0]] = floatEntry[1];
4343
}
44-
log(`floatMap: ${JSON.stringify(floatMap)}`);
44+
log('info', `floatMap: ${JSON.stringify(floatMap)}`);
4545
return floatMap;
4646
})
47-
.catch(e => log(`Error: ${e}`));
47+
.catch(e => log('warn', `Error getting all floats: ${e}`));
4848
};
4949

5050
async function main() {
@@ -57,7 +57,7 @@ async function main() {
5757
const stringifiedData = JSON.stringify(fileObj);
5858
fs.writeFileSync('./floats.json', stringifiedData);
5959
} catch (e) {
60-
console.log(e);
60+
log('warn', e);
6161
}
6262
}
6363

src/diskUtils.js

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
const fs = require('fs');
22
const folderPath = 'stockData';
33
const daysBetween = require('./daysBetween.js');
4+
const log = require('./logger.js');
45

56

67
/**
78
Initializes the local stock data folder if it doesn't yet exist.
89
*/
9-
function initDataFolder() {
10-
if (!fs.existsSync(folderPath)){
11-
console.log(`${folderPath} folder doesn't exist. Creating...`);
12-
fs.mkdirSync(folderPath, (err) => {
13-
if (err) console.log(err);
10+
function initDataFolder(path) {
11+
if (!fs.existsSync(path)) {
12+
log('info', `${path} folder doesn't exist. Creating...`);
13+
fs.mkdirSync(path, (err) => {
14+
if (err) log('warn', err);
1415
});
1516
}
1617
}
@@ -24,7 +25,7 @@ function readStockDataFromDisk(ticker) {
2425
const filePath = `${folderPath}/${ticker}.json`;
2526
try {
2627
const data = fs.readFileSync(filePath, 'utf8');
27-
console.log(`Local data found for ${ticker}.`);
28+
log('info', `Local data found for ${ticker}.`);
2829
return JSON.parse(data);
2930
}
3031
catch (err) {
@@ -40,7 +41,7 @@ function readStockDataFromDisk(ticker) {
4041
*/
4142
function writeStockDataToDisk(ticker, incomingData, existingData) {
4243

43-
initDataFolder();
44+
initDataFolder(folderPath);
4445

4546
const filePath = `${folderPath}/${ticker}.json`;
4647
const now = new Date();
@@ -53,13 +54,13 @@ function writeStockDataToDisk(ticker, incomingData, existingData) {
5354
// If we're creating the file for the first time.
5455
if (!fs.existsSync(filePath)) {
5556
try {
56-
console.log(`${ticker} - ${filePath} doesn't exist. Creating...`);
57+
log('info', `${ticker} - ${filePath} doesn't exist. Creating...`);
5758
const stringifiedData = JSON.stringify(writeObject);
5859
fs.writeFileSync(filePath, stringifiedData);
59-
console.log(`${ticker} - Wrote data to disk.`);
60+
log('info', `${ticker} - Wrote data to disk.`);
6061
return incomingData;
6162
} catch (err) {
62-
console.log(`${ticker} - Error creating new file: `, err);
63+
log('warn', `${ticker} - Error creating new file: `, err);
6364
}
6465
}
6566
// Otherwise, we're appending data to existing file.
@@ -71,18 +72,18 @@ function writeStockDataToDisk(ticker, incomingData, existingData) {
7172
const sliceAfterIdx = incomingData.findIndex(day => day.date === lastDateRetrievedForExistingData);
7273
if (sliceAfterIdx > 0) {
7374
const newData = incomingData.slice(sliceAfterIdx + 1);
74-
console.log(`${ticker} - Got ${newData.length} entries. Applying partial update.`);
75+
log('info', `${ticker} - Got ${newData.length} entries. Applying partial update.`);
7576
writeObject.data = existingData.concat(newData);
7677
}
7778
}
7879
try {
7980
const stringifiedData = JSON.stringify(writeObject);
80-
console.log(`File for ${ticker} exists. Updating...`);
81+
log('info', `File for ${ticker} exists. Updating...`);
8182
fs.writeFileSync(filePath, stringifiedData);
82-
console.log(`${ticker} - Updated data on disk.`);
83+
log('info', `${ticker} - Updated data on disk.`);
8384
return writeObject.data;
8485
} catch (err) {
85-
console.log(`${ticker} - Error updating existing data on disk: `, err);
86+
log('warn', `${ticker} - Error updating existing data on disk: `, err);
8687
}
8788
}
8889
}

src/fetchDataForOneStock.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ const buildHeatmap = require('./buildHeatMap');
66
const findHits = require('./findHits.js');
77
const buildSignals = require('./buildSignals.js');
88
const daysBetween = require('./daysBetween.js');
9-
const log = console.log;
9+
const log = require('./logger.js');
1010
const data = require('./stockData.js');
1111
const diskUtils = require('./diskUtils');
1212

1313
// Requests data for one stock ticker with a promise.
1414
const fetchDataForOneStock = (ticker) => new Promise((resolve, reject) => {
1515

16-
log('Getting: ', '\x1b[34m', ticker, '\x1b[0m');
16+
log('info', `Getting: \x1b[34m'${ticker}\x1b[0m`);
1717
const queryString = {
1818
apikey: config.API_KEY,
1919
function: 'TIME_SERIES_DAILY',
@@ -34,11 +34,11 @@ const fetchDataForOneStock = (ticker) => new Promise((resolve, reject) => {
3434
} catch (e) {
3535
// If we have no local data for this ticker, retrieve complete history.
3636
if (e.code === 'ENOENT') {
37-
log(`${ticker} - No local data.`);
37+
log('info', `${ticker} - No local data.`);
3838
queryString.outputsize = 'full';
3939
}
4040
else {
41-
log(`${ticker} - Error reading data from disk: `, e);
41+
log('warn', `${ticker} - Error reading data from disk: ${e}`);
4242
}
4343
}
4444

@@ -50,8 +50,8 @@ const fetchDataForOneStock = (ticker) => new Promise((resolve, reject) => {
5050
transform: parseRawData
5151
})
5252
.then(parsedData => {
53-
log('Got: ', '\x1b[34m', ticker, '\x1b[0m');
54-
console.log(`${ticker} - Retrieved ${parsedData.length} entries.`)
53+
log('info', `Got: \x1b[34m${ticker}\x1b[0m`);
54+
log('info', `${ticker} - Retrieved ${parsedData.length} entries.`)
5555
// Append to data stored locally.
5656
const localData = localFile ? localFile.data : null;
5757
parsedData = diskUtils.writeStockDataToDisk(ticker, parsedData, localData);
@@ -76,7 +76,7 @@ const fetchDataForOneStock = (ticker) => new Promise((resolve, reject) => {
7676
})
7777
.catch(err => {
7878
// Tell user if something went wrong.
79-
log('\n' + '\x1b[31m' + 'Ticker: ' + ticker + '\n' + 'Error: ' + '\x1b[0m' + '\n' + err);
79+
log('warn', `\n\x1b[31mTicker: ${ticker}\nError: \x1b[0m\n${err}`);
8080
// Add ticker to retry list.
8181
data.retries.push(ticker);
8282
reject(err);

src/findHits.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
const daysBetween = require('./daysBetween.js');
22
const data = require('./stockData.js');
3+
const log = require('./logger.js');
34

45
// A 'hit' is a pivot near the same price range as the current pivot.
56
// Finds and stores all prior hits, recent hits, and recent hits on decreasing volume.
67
// Scans an array of pivots for a single ticker.
78
function findHits(ticker, direction, pivots) {
89
if (!['long', 'short'].includes(direction)) {
9-
return console.error('Must specify "long" or "short".');
10+
return log('warn', 'Must specify "long" or "short".');
1011
}
1112
const pivot = direction === 'long' ? 'l' : 'h';
1213

src/logger.js

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
const fs = require('fs');
2+
const config = require('../config.js');
3+
const folderPath = 'logs';
4+
let logFolderExists = false;
5+
6+
7+
const logger = (level, message, extra) => {
8+
// Filter out any logging levels not set in config file.
9+
if (!config.logLevels.includes(level)) {
10+
return;
11+
}
12+
// Create the log files folder if it doesn't exist.
13+
initLogFolder(folderPath);
14+
15+
// Format the message.
16+
const output = format(level, message, extra);
17+
// Write to screen.
18+
console.log(output);
19+
// Write to file.
20+
const date = new Date().toISOString().slice(0, 10);
21+
const fileName = `${date}.txt`;
22+
const filePath = `${folderPath}/${fileName}`;
23+
// Create a file with today's date if it doesn't exist.
24+
if (!fs.existsSync(filePath)) {
25+
console.log(`${filePath} doesn't exist. Creating...`);
26+
fs.writeFileSync(filePath, '', 'utf8');
27+
}
28+
fs.appendFile(filePath, output, (err) => {
29+
if (err) {
30+
console.error(err);
31+
}
32+
});
33+
};
34+
35+
36+
// Creates the folder at folderPath if it doesn't yet exist.
37+
function initLogFolder(path) {
38+
if (logFolderExists) {
39+
return;
40+
}
41+
if (!fs.existsSync(path)) {
42+
console.log(`Logs folder doesn't exist. Creating...`);
43+
fs.mkdirSync(path, (err) => {
44+
if (err) {
45+
return console.error(err);
46+
};
47+
});
48+
logFolderExists = true;
49+
}
50+
}
51+
52+
53+
// Handles formatting for log messages.
54+
function format(level, message, extra) {
55+
const now = new Date().toISOString();
56+
let formattedOutput = `${now}::${level.toUpperCase()}::${message}\n`;
57+
if (extra !== undefined) {
58+
formattedOutput += `${extra}\n`;
59+
}
60+
return formattedOutput;
61+
};
62+
63+
64+
module.exports = logger;

src/parseRawData.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const log = require('./logger.js');
12
// Takes a parsed JSON object, and transforms it.
23
// (Passed as the 'transform' option to request-promise.)
34
function parseRawData (stock) {
@@ -22,8 +23,7 @@ function parseRawData (stock) {
2223
return transformed.reverse();
2324
}
2425
catch (error) {
25-
console.log('Transform error. Got:');
26-
console.log(error);
26+
log('warn', `Transform error: ${error}`);
2727
}
2828
}
2929
module.exports = parseRawData;

0 commit comments

Comments
 (0)