Last active
March 18, 2019 07:53
-
-
Save treypeng/a9141c2b293c52dfe366c1134f5bc55d to your computer and use it in GitHub Desktop.
Script to detect darth maul candles from bitmex 1h interval data
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
require('./util'); | |
const Candler = require('./candle-db'); | |
const ATR_LENGTH = 24; | |
const SMA_LENGTH = 24; | |
let trs = []; // series. needed by atr() function. | |
// Open the database, cut down version to save size, contains only 2019 1h candle data | |
let candler = new Candler('./bitmex-xbt-1h-2019-only.db'); | |
// Get H1 xbtusd candles from 2019 year open | |
let candles = candler.get_range('bitmex', '1h', 'btcusd', date(2019,1,1), Date.now()); | |
// Go through each of the candles, starting from the first one at 00:00 on 1st January 2019 | |
for (let i=0; i < candles.length; i++) | |
{ | |
// Current ATR for this candle | |
let a = atr( candles, i, ATR_LENGTH ); | |
// Let's also compute the SMA(24) of the close price: | |
let s = sma ( (candles.slice(0, i + 1)).map ( e => e.close ), SMA_LENGTH ); | |
// uncomment this line to see the atr and sma for this H1 candle: | |
// console.log(`atr = ${a}, sma = ${s} timestamp = ${strdate(candles[i].timestamp)}`); | |
let dm = is_darth_maul( candles[i], a, s ); | |
if (dm) | |
{ | |
console.log(`\n🚨 The Sith will rule the galaxy: ${strdate(candles[i].timestamp)}`); | |
console.log( candles[i] ); | |
} | |
} | |
function is_darth_maul(candle, current_atr, current_sma) | |
{ | |
const DARTH_MAUL_RANGE = 1.0; // wicks that are +100% outside the ATR band's range | |
// The way this works is we compute an ATR 'band' using the SMA of the close | |
// price and the ATR of the current candle | |
let atr_upper_band = current_sma + current_atr; | |
let atr_lower_band = current_sma - current_atr; | |
let band_range = atr_upper_band - atr_lower_band; | |
// Now we see by how much (if at all) the wicks extended through the band's range | |
let upper_wick_dev = candle.high - atr_upper_band; | |
let lower_wick_dev = atr_lower_band - candle.low; | |
// if either wick inside the band, it's definitely not a Darth Maul, return | |
if (upper_wick_dev < 0 || lower_wick_dev < 0) | |
return false; | |
// Ok, they both exceeded the band, but by what factor? | |
let upper_factor = upper_wick_dev / band_range; | |
let lower_factor = lower_wick_dev / band_range; | |
// Make sure they both did, upside or downside only doesn't count | |
if (upper_factor >= DARTH_MAUL_RANGE && lower_factor >= DARTH_MAUL_RANGE) | |
return true; | |
return false; | |
} | |
// Function to compute ATR | |
function atr(candles, index, length) | |
{ | |
// Get the current candle | |
let candle0 = candles[index]; | |
// Get the previous candle | |
let candle1 = (index >= 0) ? candles[index-1] : null; | |
// not sure if I need to do this or can use candle0 alone :thonking: | |
if (!candle1) return; | |
// First, let's calculate the True Range, from the PineScript documentation: | |
// max(high - low, abs(high - close[1]), abs(low - close[1])) | |
let tr = Math.max( candle0.high - candle0.low, | |
Math.max( | |
Math.abs(candle0.high - candle1.close), | |
Math.abs(candle0.low - candle1.close) | |
) | |
); | |
// Save our ongoing series of True Ranges | |
trs.push(tr) | |
// Now return the simple-moving-average of them (see util.js): | |
return sma( trs, length ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment