-
-
Save shoemoney/95e6c7c3615b570bc1554063649c69eb to your computer and use it in GitHub Desktop.
bybit.js
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 { WebsocketClient } = require("bybit-api") | |
const API_KEY = "key goes here" | |
const PRIVATE_KEY = "replace me" | |
const wsConfig = { | |
key: API_KEY, | |
secret: PRIVATE_KEY, | |
/* | |
The following parameters are optional: | |
*/ | |
// defaults to false == testnet. Set to true for livenet. | |
livenet: true, | |
// NOTE: to listen to multiple markets (spot vs inverse vs linear vs linearfutures) at once, make one WebsocketClient instance per market | |
// defaults to inverse: | |
// market: "inverse", | |
market: "perpetual", | |
// market: "linear", | |
// market: "spot", | |
// how long to wait (in ms) before deciding the connection should be terminated & reconnected | |
// pongTimeout: 1000, | |
// how often to check (in ms) that WS connection is still alive | |
// pingInterval: 10000, | |
// how long to wait before attempting to reconnect (in ms) after connection is closed | |
// reconnectTimeout: 500, | |
// config options sent to RestClient (used for time sync). See RestClient docs. | |
// restOptions: { }, | |
// config for axios used for HTTP requests. E.g for proxy support | |
// requestOptions: { } | |
// override which URL to use for websocket connections | |
// wsUrl: 'wss://stream.bytick.com/realtime' | |
} | |
const ws = new WebsocketClient(wsConfig) | |
// subscribe to multiple topics at once | |
// ws.subscribe(["position", "execution", "trade"]) | |
// ws.subscribe("trade.BTCUSD") | |
ws.subscribe("orderBookL2_25.BTCUSD") | |
// and/or subscribe to individual topics on demand | |
// ws.subscribe("kline.BTCUSD.1m") | |
// Listen to events coming from websockets. This is the primary data source | |
ws.on("update", (data) => { | |
console.log("update", JSON.stringify(data)) | |
}) | |
// Optional: Listen to websocket connection open event (automatic after subscribing to one or more topics) | |
ws.on("open", ({ wsKey, event }) => { | |
console.log("connection open for websocket with ID: " + wsKey) | |
}) | |
// Optional: Listen to responses to websocket queries (e.g. the response after subscribing to a topic) | |
ws.on("response", (response) => { | |
console.log("response", response) | |
}) | |
// Optional: Listen to connection close event. Unexpected connection closes are automatically reconnected. | |
ws.on("close", () => { | |
console.log("connection closed") | |
}) | |
// Optional: Listen to raw error events. | |
// Note: responses to invalid topics are currently only sent in the "response" event. | |
ws.on("error", (err) => { | |
console.error("ERR", err) | |
}) | |
const someData = [ | |
{ open: 10, high: 20, low: 5, close: 11 }, | |
{ open: 11, high: 25, low: 9, close: 20 }, | |
{ open: 5, high: 29, low: 4, close: 20 }, | |
{ open: 8, high: 32, low: 5, close: 31 }, | |
{ open: 9, high: 31, low: 3, close: 30 }, | |
{ open: 10, high: 29, low: 5, close: 15 }, | |
{ open: 10, high: 26, low: 5, close: 9 }, | |
] | |
const mySma = sma(someData, 7, "close") | |
console.log({ mySma }) | |
function sma(dataRaw, time_period, parameter) { | |
let data = extractData(dataRaw, parameter) | |
if (time_period >= data.length) { | |
return ( | |
data.reduce( | |
(accumulator, currentValue) => accumulator + currentValue, | |
0 | |
) / data.length | |
) | |
} else { | |
let nData = data.slice(time_period * -1) | |
return ( | |
nData.reduce( | |
(accumulator, currentValue) => accumulator + currentValue, | |
0 | |
) / time_period | |
) | |
} | |
} | |
function atr(rawData, timePeriod) { | |
// first, we need a data set of only the highs and lows | |
let highs = extractData(rawData, "high") | |
let lows = extractData(rawData, "low") | |
let closes = extractData(rawData, "close") | |
// Get the True Range | |
// True Range Formula = MAX of (high-low; High-PreviousClose; //PreviousCLose-Low) | |
// Create an array of all True Range Values | |
let trueRange = [] | |
for (let i = 1; i - 1 < rawData.length - 1; i++) { | |
let tr1 = highs[i] - lows[i] | |
let tr2 = Math.abs(highs[i] - closes[i - 1]) | |
let tr3 = Math.abs(closes[i - 1] - lows[i]) | |
trueRange.push(Math.max(tr1, tr2, tr3)) | |
} | |
// use the array of True Range Values to get the Simple Moving //Average of the true range, ie., ATR | |
if (timePeriod >= trueRange.length) { | |
// if the timePeriod is //greater then the entire dataset, just return the average of the //whole set | |
return ( | |
trueRange.reduce( | |
(accumulator, currentValue) => accumulator + currentValue, | |
0 | |
) / trueRange.length | |
) | |
} else { | |
let nData = trueRange.slice(timePeriod * -1) | |
return ( | |
nData.reduce( | |
(accumulator, currentValue) => accumulator + currentValue, | |
0 | |
) / timePeriod | |
) | |
} | |
} | |
function extractData(dataObj, key) { | |
closeData = [] | |
dataObj.forEach((obj) => { | |
closeData.push(obj[key]) | |
}) | |
return closeData | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment