Skip to content

Instantly share code, notes, and snippets.

@evolmk
Last active November 18, 2020 20:46
Show Gist options
  • Save evolmk/ee21f854a66541cc519b0e5f764e0c49 to your computer and use it in GitHub Desktop.
Save evolmk/ee21f854a66541cc519b0e5f764e0c49 to your computer and use it in GitHub Desktop.
Tensor Wall Detector
/*
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++;
@evolmk
Copy link
Author

evolmk commented Jun 2, 2018

added wallType based on price, eg:
146 sell wall detected at 7320

@evolmk
Copy link
Author

evolmk commented Jun 2, 2018

added instructions for SETUP & CONFIG

@evolmk
Copy link
Author

evolmk commented Jun 2, 2018

fixed buy/sell wall inversion

@evolmk
Copy link
Author

evolmk commented Jun 2, 2018

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