@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.
2 lines ⢠3.26 kB
JavaScript
import{parseArgs}from"./parser.js";import{validateInputSource,validateData,validateDimensions,validateVolumeHeight}from"./validation.js";import{fetchData}from"./data.js";import{configureChart}from"./chart.js";import{handleChartOutput}from"./output.js";const UNKNOWN_ERROR="Unknown error";async function showBanner(){const{default:t}=await import("figlet"),e=t.textSync("Candlestick-CLI",{font:"Slant",horizontalLayout:"fitted",verticalLayout:"default"});console.log(e)}function clearSmoothly(){process.stdout.write("[?25l"),process.stdout.write("[H[J"),process.stdout.write("[?25h")}async function startWatchMode(t,e){const a=1e3*(t.interval||30);let o=0,n=Date.now(),s=null;const r=()=>{console.log("\nš Stopping watch mode..."),process.exit(0)};process.on("SIGINT",r),process.on("SIGTERM",r);process.stdout.on("resize",()=>{s&&clearTimeout(s),s=setTimeout(async()=>{try{await new Promise(t=>setTimeout(t,50));const a=e.chartData.getTerminalSize();e.updateSizeFromTerminal();const o=e.chartData.getTerminalSize(),n=await fetchData(t);e.updateCandles(n,!0),clearSmoothly();const s=`š Terminal resized: ${a.width}x${a.height} ā ${o.width}x${o.height}`;console.log(s);const r=e.chartData.visibleCandleSet.candles.length,i=e.chartData.mainCandleSet.candles.length;console.log(`šÆļø Candles: ${r}/${i} visible`),await e.draw()}catch(t){const e=t instanceof Error?t.message:UNKNOWN_ERROR;console.error(`ā Resize failed: ${e}`)}},200)}),e.disableAutoResize(),t.watch&&8===t.volumeHeight&&e.setVolumePaneHeight(12),console.log(`š Watch mode enabled - updating every ${t.interval||30} seconds`),console.log("š” Press Ctrl+C to stop watching"),console.log(""),await e.draw();const i=setInterval(async()=>{try{o++;const s=Date.now();process.stdout.write(`\rš Updating chart... (${o})`);const r=e.chartData.getTerminalSize();e.updateSizeFromTerminal();const i=e.chartData.getTerminalSize(),c=await fetchData(t);e.updateCandles(c,!0),clearSmoothly();const l=Date.now()-s,d=Date.now()-n;n=Date.now();const h=e.chartData.visibleCandleSet.candles.length,m=e.chartData.mainCandleSet.candles.length;console.log(`š Chart updated in ${l}ms (${d}ms since last update)`),console.log(`š Terminal: ${r.width}x${r.height} ā ${i.width}x${i.height}`),console.log(`šÆļø Candles: ${h}/${m} visible`),console.log(`ā° Next update in ${a/1e3} seconds`),console.log(""),await e.draw()}catch(t){const e=t instanceof Error?t.message:UNKNOWN_ERROR;console.error(`ā Update failed: ${e}`),console.error("š Retrying in next cycle...")}},a);await new Promise(t=>{process.on("exit",()=>{"undefined"!=typeof clearInterval&&clearInterval(i),t()})})}async function main(){try{const t=await parseArgs();await validateInputSource(t);const e=await fetchData(t);validateData(e),validateDimensions(t.width,t.height),validateVolumeHeight(t.volumeHeight);const a=configureChart(t,e);!0===t.watch&&t.symbol&&!t.output?await startWatchMode(t,a):await handleChartOutput(a,t)}catch(t){await showBanner();const e=t instanceof Error?t.message:UNKNOWN_ERROR;console.error(`ā Fatal error: ${e}`),process.exit(1)}}main().catch(async t=>{await showBanner(),console.error(`ā Fatal error: ${t instanceof Error?t.message:UNKNOWN_ERROR}`),process.exit(1)});