Last active
November 18, 2020 20:46
-
-
Save evolmk/ee21f854a66541cc519b0e5f764e0c49 to your computer and use it in GitHub Desktop.
Tensor Wall Detector
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
/* | |
Tensorcharts.com Wall Detector Script v1.0.3 | |
get notified when large walls get pulled or added, usually signaling a strong move in opposite direction | |
- browser console logs. google on how to open console for your browser | |
- voice notifications (can disable) | |
- browser notifications (soon) | |
*/ | |
var SCRIPT_VERSION = "1.0.3" | |
// --------------------- Setup & Run Script --------------------------- | |
// #1. INSTALL | |
// goto SCRIPTING > NEW SCRIPT, click on this new script in left pane. | |
// paste this entire script inside window (white area) and follow #2, #3 | |
// #2. CONFIG | |
// set Name of script to something familiar at top of window. eg: WALL DETECTOR | |
// set Interval (refresh in milliseconds) at top of window. eg: 2000 | |
// optionally change variables below marked *CONFIG* | |
// #3. START/STOP SCRIPT | |
// to Run = click PLAY icon | |
// to Stop = click STOP icon | |
// *CONFIG* Minimum Wall Size to analyze & log to console (Default=49) | |
var WALL_MIN = 49 | |
// *CONFIG* Minimum Wall Size to notify via Browser Notification & Voice (Default=199, greater than WALL_MIN) | |
var WALL_MIN_NOTIFY = 199 | |
// *CONFIG* Range Of Orderbook in percent to be analyzed (Default=4) | |
var PERCENTAGE_RANGE = 3 | |
// *CONFIG* Enable Voice Notifications (true=enabled, false=disabled) *browser console still logs notifications | |
var VOICE_ENABLED = true | |
// *CONFIG* Enable Browser Notifications (true=enabled, false=disabled) | |
var BROWSER_NOTIFICATIONS_ENABLED = true | |
// Get the latest price from which the range will be calculated | |
// if trades data is empty, set prite to -1, otherwise get the most recent one | |
var lastTradePrice = trades.length>0 ? trades[0].Price : -1 | |
// Large limit order will be defined as a multiple of limit orders' median | |
var MEDIAN_MULTIPLICATOR = 1 | |
// We don't have to calculate median every cycle/run, so we keep cycles' | |
// counter and analyze distribution only every nth cycle | |
var CYCLES_LIMIT = 5 | |
if(self.cyclesCount == undefined){ | |
self.cyclesCount = 0 | |
} | |
// Notify User | |
var notify = function(data) { | |
var msg = data.wallAction + " " + data.wallSize + " " + data.wallType + " @ " + data.price | |
var msgNotification = data.wallActionSymbol + ' ' + data.wallSize + 'btc ' + data.wallType + " wall " + "@ " + data.price | |
//notify by console | |
var color = (wallAction == 'ADDED') ? '#00af5a' : '#b52e4b' | |
console.log('%c' + msgNotification, 'color: ' + color); | |
//notify by browser flash | |
if (BROWSER_NOTIFICATIONS_ENABLED && data.wallSize >= WALL_MIN_NOTIFY) { | |
browserNotification(msgNotification, '') | |
} | |
//notify by voice | |
if (VOICE_ENABLED && data.wallSize >= WALL_MIN_NOTIFY) { | |
speak(msg) | |
} | |
}; | |
// Prerun check if all required data are loaded | |
// We need to store orderbook state from previous cycle so we can | |
// compare it with the current one | |
if(lastTradePrice > 0 && self.previousOrderBook!=undefined){ | |
// setting up price range defined by upper and lower limit | |
// orderbook data is an object with price levels as keys and | |
// [amount, count] as its value | |
// get all orderBook object keys | |
var priceLevels = Object.keys(orderBook) | |
var upperLimit = lastTradePrice * (1+PERCENTAGE_RANGE/100) | |
var lowerLimit = lastTradePrice * (1-PERCENTAGE_RANGE/100) | |
// Set Min Size of Order to analyze | |
if(self.largeLimitOrderAmount==undefined || self.cyclesCount >= CYCLES_LIMIT){ | |
// reset cycles count | |
self.cyclesCount = 0 | |
self.largeLimitOrderAmount = WALL_MIN | |
console.log('Analyzing Range:', lowerLimit + ' to ' + upperLimit) | |
} | |
// Compare previous orderbook with the current one | |
for(var i = 0; i < priceLevels.length; i++){ | |
var price = priceLevels[i] | |
if (price <= upperLimit && price >= lowerLimit){ | |
var currentAmount = orderBook[price][0] | |
var previousAmount = self.previousOrderBook[price][0] | |
// if the price level was bid in previous cycle and now it's ask or vice versa, return back to the loop start | |
if((currentAmount < 0 && previousAmount > 0) || (currentAmount > 0 && previousAmount < 0)){ | |
continue | |
} | |
currentAmount = Math.abs(currentAmount) | |
previousAmount = Math.abs(previousAmount) | |
var diff = Math.abs(currentAmount - previousAmount) | |
// return back to the loop start if size differece is less than calculated largeLimitOrderAmount | |
if(diff < self.largeLimitOrderAmount){ | |
continue | |
} | |
var wallSize = Math.round(diff) | |
var wallType = price < lastTradePrice ? 'BUY' : 'SELL' | |
var wallAction = previousAmount > currentAmount ? 'REMOVED' : 'ADDED' | |
var wallActionSymbol = previousAmount > currentAmount ? '-' : '+' | |
var data = { | |
wallSize: wallSize, | |
wallType: wallType, | |
wallAction: wallAction, | |
wallActionSymbol: wallActionSymbol, | |
price: price | |
} | |
notify(data); | |
} | |
} | |
} | |
// save current orderbook as previous | |
self.previousOrderBook = Object.assign({}, orderBook); | |
self.cyclesCount++; |
added instructions for SETUP & CONFIG
fixed buy/sell wall inversion
working on a complete overhaul & optimization now that i have a feel for Tensor's capabilities
i'll repost to group when v1.1.0 is released, a stable minor version
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
added wallType based on price, eg:
146 sell wall detected at 7320