@neabyte/candlestick-cli
Version:
Beautiful terminal candlestick charts with real-time trading data. Create stunning ASCII art charts directly in your terminal with support for live market data, custom colors, and professional trading visualization.
1 lines • 3.1 kB
JavaScript
import{CONSTANTS,COLORS}from"../constants.js";export function fnum(t){let r;if("string"==typeof t)try{r=parseInt(t)}catch{r=parseFloat(t)}else r=t;if(!r||Math.abs(r)>=1)return Number.isInteger(r)?r.toLocaleString():r.toLocaleString(void 0,{minimumFractionDigits:CONSTANTS.PRECISION,maximumFractionDigits:CONSTANTS.PRECISION});const o=r.toFixed(18).match(/^(0\.)(0{4,})(.{4}).*$/);if(o){const[,t,r,e]=o;return`${t}⦗0×${r.length}⦘${e}`}return r.toFixed(CONSTANTS.PRECISION_SMALL)}export function hexaToRgb(t){const r=t.replace("#","");return[parseInt(r.slice(0,2),16),parseInt(r.slice(2,4),16),parseInt(r.slice(4,6),16)]}function detectTruecolorSupport(){return"true"===process.env.FORCE_COLOR||(process.env.TERM?.includes("256color")??!1)}function getGrayAnsiColor(t){return t>200?"[97m":t>150?"[37m":t>100?"[90m":"[30m"}function getDominantAnsiColor(t,r,o){return t>r&&t>o?"[91m":r>t&&r>o?"[92m":o>t&&o>r?"[94m":"[37m"}function getMixedAnsiColor(t,r,o){return t>200&&r>200?"[93m":t>200&&o>200?"[95m":r>200&&o>200?"[96m":"[37m"}function rgbToAnsi(t,r,o){if(Math.max(t,r,o)-Math.min(t,r,o)<30){return getGrayAnsiColor(Math.round((t+r+o)/3))}const e=getDominantAnsiColor(t,r,o);return"[37m"!==e?e:getMixedAnsiColor(t,r,o)}export function colorize(t,r,o,e){if(detectTruecolorSupport())return`[38;2;${r};${o};${e}m${t}[00m`;return`${rgbToAnsi(r,o,e)}${t}[00m`}export function truecolor(t,r,o,e){return colorize(t,r,o,e)}export function color(t,r){if(!r)return t;if(Array.isArray(r))return truecolor(t,...r);if("string"==typeof r&&!r.includes("m")){const o=COLORS[r];if(o)return`${o}${t}[00m`}return"string"==typeof r?`[${r}${t}[00m`:t}export function roundPrice(t){if(CONSTANTS.Y_AXIS_ROUND_MULTIPLIER>0){const r=CONSTANTS.Y_AXIS_ROUND_MULTIPLIER;t="down"===CONSTANTS.Y_AXIS_ROUND_DIR?Math.floor(t*r)/r:Math.ceil(t*r)/r}return formatPrice(t)}export function formatPrice(t){return t.toLocaleString(void 0,{minimumFractionDigits:CONSTANTS.PRECISION,maximumFractionDigits:CONSTANTS.PRECISION})}export function makeCandles(t){return Array.from(t).map(t=>({open:parseFloat(String(t.open)),high:parseFloat(String(t.high)),low:parseFloat(String(t.low)),close:parseFloat(String(t.close)),volume:parseFloat(String(t.volume||"0")),timestamp:parseFloat(String(t.timestamp||"0")),type:parseFloat(String(t.open))<parseFloat(String(t.close))?1:0}))}export function parseCandlesFromCsv(t){const r=t.trim().split("\n"),o=r[0].split(",");return r.slice(1).map(t=>{const r=t.split(","),e={};return o.forEach((t,o)=>{e[t.trim()]=r[o]?.trim()||"0"}),e}).map(t=>({open:parseFloat(String(t.open)),high:parseFloat(String(t.high)),low:parseFloat(String(t.low)),close:parseFloat(String(t.close)),volume:parseFloat(String(t.volume||"0")),timestamp:parseFloat(String(t.timestamp||"0")),type:parseFloat(String(t.open))<parseFloat(String(t.close))?1:0}))}export function parseCandlesFromJson(t){return makeCandles(JSON.parse(t))}export function convertMarketDataToCandles(t){return t.map(t=>({open:t.open,high:t.high,low:t.low,close:t.close,volume:t.volume,timestamp:t.timestamp,type:t.open<t.close?1:0}))}