-
Install deps:
npm i
-
Start server:
npm run start
-
Check lint:
npm run lint
-
Run sercice tests:
npm run test
-
Endpoint to get OHLCV:
GET http://localhost:8989?market=BTC-DOGE&exchange=bittrex
Last active
May 19, 2018 01:50
-
-
Save fernandojunior/5339c4aed789b7842696aaa8821339bc to your computer and use it in GitHub Desktop.
ohlcv challenge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
{ | |
"extends": "standard" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node_modules/ | |
package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const bodyParser = require('body-parser') | |
const routes = require('./routes') | |
const PORT = 8989 | |
const app = express() | |
app.use(bodyParser.json()) | |
app.use(bodyParser.urlencoded({ extended: true })) | |
app.use(routes) | |
app.listen(PORT, () => { | |
console.log(`OHLCV Server endpoint listening on http://localhost:${PORT}/. Query paramters: { exchange='bittrex', market='USDT-BTC' } `) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "test", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "./node_modules/mocha/bin/mocha service.test.js", | |
"start": "node index.js", | |
"lint": "eslint *.js" | |
}, | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"body-parser": "^1.18.3", | |
"dateformat": "^3.0.3", | |
"express": "^4.16.3", | |
"mathjs": "^4.2.2", | |
"request": "^2.86.0", | |
"request-promise": "^4.2.2" | |
}, | |
"devDependencies": { | |
"eslint": "^4.19.1", | |
"eslint-config-standard": "^11.0.0", | |
"eslint-plugin-import": "^2.12.0", | |
"eslint-plugin-node": "^6.0.1", | |
"eslint-plugin-promise": "^3.7.0", | |
"eslint-plugin-standard": "^3.1.0", | |
"mocha": "^5.1.1" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const express = require('express') | |
const { getOhlcv } = require('./service') | |
const routes = express() | |
// TODO use APIDOC for REST API doc | |
routes.get('/', async (req, res) => { | |
// TODO use ExpressValidator to verify query params | |
res.send(await getOhlcv(req.query)) | |
}) | |
module.exports = routes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const dateFormat = require('dateformat') | |
const math = require('mathjs') | |
const { getExchangeData, addTwoZeroPad, getSecondsFromTimestamp } = require('./utils') | |
function filterDataByTimestamp (data, timeStamp) { | |
return data.filter((item) => (item.TimeStamp.includes(timeStamp))) | |
} | |
async function getOhlcv ({ exchange = 'bittrex', market = 'USDT-BTC' }) { | |
const { result: data } = await getExchangeData({ exchange, market }) | |
let [ year, month, day, hour, min ] = dateFormat(new Date(), 'UTC:yyyy,mm,dd,HH,MM').split(',') | |
min = parseInt(min) - 1 // last minute before current | |
let lastMinTimestamp = `${year}-${month}-${day}T${hour}:${addTwoZeroPad(min)}` | |
// const lastMinTimestamp = '2018-05-16T20:04' | |
let filtered = filterDataByTimestamp(data, lastMinTimestamp) | |
// find last minute with data ? | |
// while (filtered.length === 0) { | |
// lastMinTimestamp = `${year}-${month}-${day}T${hour}:${addTwoZeroPad(--min)}` | |
// filtered = filterDataByTimestamp(data, lastMinTimestamp) | |
// } | |
console.info(`Registrated data in last min: length = ${filtered.length}, lastMinute = ${lastMinTimestamp}`) | |
let open, high, low, close, volume, time | |
if (filtered.length > 0) { | |
const sortedByTimestamp = filtered.sort((a, b) => (getSecondsFromTimestamp(a) - getSecondsFromTimestamp(b))) | |
const prices = filtered.map((item) => (parseFloat(item.Price))) | |
const quantities = filtered.map((item) => (parseFloat(item.Quantity))) | |
open = sortedByTimestamp[0].Price | |
high = math.max(prices) | |
low = math.min(prices) | |
close = sortedByTimestamp[sortedByTimestamp.length - 1].Price | |
volume = quantities.reduce((a, b) => (a + b)) | |
time = new Date(`${lastMinTimestamp}:00Z`).getTime() / 1000 | |
} | |
return { open, high, low, close, volume, time } | |
} | |
module.exports = { getOhlcv } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const assert = require('assert') | |
const { getOhlcv } = require('./service') | |
describe('test getOhlcv function', () => { // eslint-disable-line | |
['open', 'high', 'low', 'close', 'volume', 'time'].forEach((prop) => { | |
it(`should an object with the ${prop} prop`, async () => { // eslint-disable-line | |
assert.equal(Object.keys(await getOhlcv({})).includes(prop), true) | |
}) | |
}) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const request = require('request-promise') | |
function addTwoZeroPad (n) { | |
return typeof n === 'string' ? n : ('0' + n).slice(-2) | |
} | |
function getSecondsFromTimestamp (item) { | |
return parseFloat(item.TimeStamp.split(':')[2]) | |
} | |
const exchangeApiUrls = { | |
bittrex: ({ market }) => (`https://bittrex.com/api/v1.1/public/getmarkethistory?market=${market}`) | |
} | |
function getExchangeApiUrl ({ exchange, market }) { | |
return exchangeApiUrls[exchange]({ market }) | |
} | |
async function getExchangeData (options) { | |
const url = getExchangeApiUrl(options) | |
console.info(`Requesting ${url}`) | |
return JSON.parse(await request(url)) | |
} | |
module.exports = { addTwoZeroPad, getSecondsFromTimestamp, getExchangeData } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment