quant-zero
Version:
Node-Quant is a powerful Node.js package for developing and testing quantitative trading strategies in cryptocurrency markets, offering tools for backtesting and performance analysis.
984 lines (944 loc) • 27 kB
JavaScript
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// src/lib/ChartingSystem.ts
var ChartingSystem = class {
transform(rawData) {
return rawData;
}
};
// src/lib/Indicator.ts
import { EventEmitter } from "events";
// src/types.ts
var CryptoPair = /* @__PURE__ */ ((CryptoPair2) => {
CryptoPair2["BTCUSDT"] = "BTC/USDT";
CryptoPair2["ETHUSDT"] = "ETH/USDT";
CryptoPair2["SOLUSDT"] = "SOL/USDT";
CryptoPair2["BNBUSDT"] = "BNB/USDT";
CryptoPair2["LTCUSDT"] = "LTC/USDT";
CryptoPair2["DOGEUSDT"] = "DOGE/USDT";
return CryptoPair2;
})(CryptoPair || {});
var TimelineEvents = /* @__PURE__ */ ((TimelineEvents2) => {
TimelineEvents2["PROVIDED"] = "provided";
TimelineEvents2["FED"] = "fed";
TimelineEvents2["GENERATED"] = "generated";
return TimelineEvents2;
})(TimelineEvents || {});
var NumberReturnType = /* @__PURE__ */ ((NumberReturnType3) => {
NumberReturnType3["RELATIVE"] = "relative";
NumberReturnType3["FIXED"] = "fixed";
return NumberReturnType3;
})(NumberReturnType || {});
var OrderType = /* @__PURE__ */ ((OrderType2) => {
OrderType2["MARKET"] = "market";
OrderType2["LIMIT"] = "limit";
OrderType2["STOP"] = "stop";
return OrderType2;
})(OrderType || {});
var PositionType = /* @__PURE__ */ ((PositionType3) => {
PositionType3["LONG"] = "long";
PositionType3["SHORT"] = "short";
return PositionType3;
})(PositionType || {});
var TRADE_KEY = /* @__PURE__ */ ((TRADE_KEY2) => {
TRADE_KEY2["ID"] = "id";
TRADE_KEY2["isOpen"] = "isOpen";
TRADE_KEY2["isClosed"] = "isClosed";
TRADE_KEY2["PL"] = "PL";
TRADE_KEY2["TP"] = "TP";
TRADE_KEY2["SL"] = "SL";
TRADE_KEY2["positionSize"] = "size";
TRADE_KEY2["leverage"] = "leverage";
TRADE_KEY2["drawdown"] = "drawdown";
TRADE_KEY2["openPrice"] = "openPrice";
TRADE_KEY2["closePrice"] = "closePrice";
TRADE_KEY2["fee"] = "fee";
TRADE_KEY2["pair"] = "pair";
TRADE_KEY2["blockChainTrack"] = "blockChainTrack";
TRADE_KEY2["orderType"] = "orderType";
TRADE_KEY2["positionType"] = "positionType";
TRADE_KEY2["timestamp"] = "timestamp";
return TRADE_KEY2;
})(TRADE_KEY || {});
var DataSourceType = /* @__PURE__ */ ((DataSourceType2) => {
DataSourceType2["PRICE"] = "price";
DataSourceType2["FACTOR"] = "factor";
return DataSourceType2;
})(DataSourceType || {});
var TimeFrame = /* @__PURE__ */ ((TimeFrame2) => {
TimeFrame2["SECOND"] = "1s";
TimeFrame2["MINUTE"] = "1m";
TimeFrame2["TWO_MINUTES"] = "2m";
TimeFrame2["THREE_MINUTES"] = "3m";
TimeFrame2["FIVE_MINUTES"] = "5m";
TimeFrame2["TEN_MINUTES"] = "10m";
TimeFrame2["FIFTEEN_MINUTES"] = "15m";
TimeFrame2["THIRTY_MINUTES"] = "30m";
TimeFrame2["FORTY_FIVE_MINUTES"] = "45m";
TimeFrame2["HOUR"] = "1h";
TimeFrame2["TWO_HOURS"] = "2h";
TimeFrame2["THREE_HOURS"] = "3h";
TimeFrame2["FOUR_HOURS"] = "4h";
TimeFrame2["DAY"] = "1d";
TimeFrame2["WEEK"] = "1w";
TimeFrame2["MONTH"] = "1M";
return TimeFrame2;
})(TimeFrame || {});
// src/lib/Indicator.ts
var Indicator = class extends EventEmitter {
data = [];
name;
key;
description;
constructor({ name, key, description }) {
super();
this.name = name;
this.key = key;
this.description = description;
}
// Provides the first sample of data if not already provided
provide(data) {
if (this.data.length === 0 && data.length > 0) {
this.data = data;
this.emit("provided" /* PROVIDED */, this.data);
}
}
// Feeds new data in
feed(data) {
this.data.push(data);
this.emit("fed" /* FED */, data);
}
// Generates the result
generate() {
return null;
}
clear() {
this.data = [];
}
on(event, listener) {
return super.on(event, listener);
}
};
// src/lib/Logger.ts
import chalk from "chalk";
var Logger = class {
success(payload) {
console.log(chalk.green(payload));
}
debug(payload) {
console.log(payload);
}
info(payload) {
console.log(chalk.cyan(payload));
}
warn(payload) {
console.log(chalk.yellow(payload));
}
error(payload) {
console.log(chalk.red(payload));
}
};
var logger = new Logger();
// src/lib/Strategy.ts
import fs2 from "fs";
import path2 from "path";
// src/utils/dataInstaller.ts
import fs from "fs";
import path from "path";
// src/exchange.ts
import ccxt from "ccxt";
var exchange = new ccxt.binance();
var exchange_default = exchange;
// src/utils/dataInstaller.ts
async function downloadPairData(pair, timeFrame, dataLength, dataFolderPath) {
const fileName = `${pair.replace("/", "_")}_${dataLength}_${timeFrame}.json`;
const filePath = path.join(dataFolderPath, fileName);
if (fs.existsSync(filePath)) {
console.log(
`Data for ${pair} with length ${dataLength} already exists. Returning existing data.`
);
const existingData = fs.readFileSync(filePath, "utf-8");
return { path: filePath, data: JSON.parse(existingData) };
}
console.log(`Installing ${dataLength} candles for ${pair}.`);
const fetchedData = await exchange_default.fetchOHLCV(
pair,
timeFrame,
void 0,
dataLength,
{
paginate: true
}
);
fs.writeFileSync(filePath, JSON.stringify(fetchedData, null, 2));
return { path: filePath, data: fetchedData };
}
// src/utils/parseOHLCV.ts
var parseIntoRows = (data) => {
const timestamps = [];
const opens = [];
const highs = [];
const lows = [];
const closes = [];
const volumes = [];
data.forEach((candle) => {
timestamps.push(candle[0]);
opens.push(candle[1]);
highs.push(candle[2]);
lows.push(candle[3]);
closes.push(candle[4]);
volumes.push(candle[5]);
});
return { timestamps, opens, highs, lows, closes, volumes };
};
// src/charting/CandleSticks.ts
var CandleSticks = class extends ChartingSystem {
transform(rawData) {
const { opens, highs, lows, closes, timestamps, volumes } = parseIntoRows(rawData);
return {
open: opens,
high: highs,
low: lows,
close: closes,
timestamp: timestamps,
volume: volumes
};
}
};
// src/charting/HeikenAishi.ts
import ta from "technicalindicators";
// src/charting/Renko.ts
import ta2 from "technicalindicators";
// src/utils/generateId.ts
import crypto from "crypto";
var generateMD5Id = () => {
const seed = Math.random().toString();
return crypto.createHash("md5").update(seed).digest("hex");
};
// src/utils/maths/pl.ts
function calcPL(currentClose, openPrice, positionType) {
return positionType === "long" /* LONG */ ? 100 * ((currentClose - openPrice) / openPrice) : 100 * ((openPrice - currentClose) / openPrice);
}
// src/lib/Trade.ts
var Trade = class {
id;
tradeData;
constructor(options) {
this.id = generateMD5Id();
this.tradeData = /* @__PURE__ */ new Map([
["id" /* ID */, this.id],
["size" /* positionSize */, options.positionSize],
["leverage" /* leverage */, options.leverage],
["TP" /* TP */, options.TP],
["SL" /* SL */, options.SL],
["PL" /* PL */, 0],
["drawdown" /* drawdown */, 0],
["closePrice" /* closePrice */, void 0],
["openPrice" /* openPrice */, void 0],
["isClosed" /* isClosed */, false],
["fee" /* fee */, void 0],
["blockChainTrack" /* blockChainTrack */, void 0],
["timestamp" /* timestamp */, Date.now()],
["pair" /* pair */, options.pair],
["orderType" /* orderType */, options.orderType],
["positionType" /* positionType */, options.positionType],
["isOpen" /* isOpen */, options.open ?? false]
]);
}
open() {
if (!this.tradeData.get("isClosed" /* isClosed */)) {
this.tradeData.set("isOpen" /* isOpen */, true);
}
}
close() {
this.tradeData.set("isOpen" /* isOpen */, false);
}
updateTP(TP) {
this.tradeData.set("TP" /* TP */, TP);
}
updateSL(SL) {
this.tradeData.set("SL" /* SL */, SL);
}
getData() {
return Object.fromEntries(this.tradeData);
}
onUpdate(update, updates) {
if (this.tradeData.get("isClosed" /* isClosed */)) return;
const currentClose = Number(update.at(4) ?? 0);
if (!currentClose || currentClose === 0) return;
const openPrice = this.tradeData.get("openPrice" /* openPrice */);
const positionType = this.tradeData.get("positionType" /* positionType */);
if (!openPrice) {
this.tradeData.set("openPrice" /* openPrice */, currentClose);
return;
}
const pl = calcPL(currentClose, openPrice, positionType);
this.tradeData.set("PL" /* PL */, pl);
this.tradeData.set("closePrice" /* closePrice */, currentClose);
const currentDrawdown = this.tradeData.get("drawdown" /* drawdown */);
if (pl < currentDrawdown) {
this.tradeData.set("drawdown" /* drawdown */, pl);
}
}
getFootprint() {
}
};
// src/managers/TradeManager.ts
var TradeManager = class {
trades = /* @__PURE__ */ new Map();
strategy;
constructor(strategy) {
this.strategy = strategy;
}
onUpdate(update, updates) {
for (const trade of this.trades.values()) {
if (!trade.getData()["isClosed" /* isClosed */]) {
trade.onUpdate(update, updates);
}
}
}
getTrade(id) {
return this.trades.get(id) || null;
}
getTrades() {
return Array.from(this.trades.values());
}
createTrade(options) {
const trade = new Trade({
orderType: options.orderType,
pair: this.strategy.strategyOptions.pair,
positionSize: options.size,
positionType: options.positionType,
leverage: options.leverage ?? 1,
open: options.open ?? false,
SL: options.riskOptions?.SL,
TP: options.riskOptions?.TP,
isLive: false
});
this.trades.set(trade.id, trade);
return trade;
}
getTradeHistory() {
const trades = this.getTrades();
return trades.filter(async (trade) => {
const tradeData = await trade.getData();
return tradeData["isClosed" /* isClosed */];
});
}
closeTrade(tradeId) {
this.getTrade(tradeId)?.close();
}
clear() {
this.trades = /* @__PURE__ */ new Map();
}
};
// src/utils/maths/alpha.ts
function calcAlpha(r, rf = 0, beta, rm) {
return r - rf - beta * (rm - rf);
}
// src/utils/maths/beta.ts
function calcBeta(covariance, variance) {
return covariance / variance;
}
// src/utils/maths/covariance.ts
function calcCovariance(returns, marketReturn) {
const meanReturn = returns.reduce((sum, r) => sum + r, 0) / returns.length;
return returns.reduce(
(cov, r) => cov + (r - meanReturn) * (marketReturn - meanReturn),
0
) / returns.length;
}
// src/utils/maths/sharpeE.ts
function calcSharpeE(E, rp, rf = 0, sp) {
return E * (rp - rf) / sp;
}
// src/utils/maths/variance.ts
function calcVariance(returns) {
const meanReturn = returns.reduce((sum, r) => sum + r, 0) / returns.length;
return returns.reduce((varSum, r) => varSum + Math.pow(r - meanReturn, 2), 0) / returns.length;
}
// src/utils/maths/standarddev.ts
function calcStddev(returns) {
return Math.sqrt(calcVariance(returns));
}
// src/utils/getAvgMarketReturn.ts
async function getAvgMarketReturn(pair, timeFrame, dataLength) {
const data = await exchange_default.fetchOHLCV(
pair,
timeFrame,
void 0,
dataLength,
{ paginate: true }
);
let totalReturn = 0;
for (let i = 1; i < data.length; i++) {
const prevCandle = data[i - 1];
const currCandle = data[i];
if (!prevCandle || !currCandle) continue;
const prevClose = Number(prevCandle[4]);
const currClose = Number(currCandle[4]);
const returnPct = (currClose - prevClose) / prevClose * 100;
totalReturn += returnPct;
}
return totalReturn / (data.length - 1);
}
// src/lib/Strategy.ts
var Strategy = class {
name;
data = [];
strategyOptions;
tradeManager;
indicators = /* @__PURE__ */ new Map();
pairDataPath = "";
constructor(strategyOptions) {
const {
name,
dataLength = 100,
timeFrame = "1m" /* MINUTE */,
chartType = new CandleSticks(),
indicators = [],
simulationOptions,
pair
} = strategyOptions;
this.name = strategyOptions.name;
this.strategyOptions = {
name,
dataLength,
timeFrame,
chartType,
indicators,
simulationOptions: simulationOptions ?? { pair },
pair
};
this.tradeManager = new TradeManager(this);
}
async loadData() {
const { pair, timeFrame, dataLength } = this.strategyOptions;
const dataFolderPath = path2.join(process.cwd(), "data");
if (!fs2.existsSync(dataFolderPath)) {
fs2.mkdirSync(dataFolderPath);
}
const { path: pairDataPath, data } = await downloadPairData(
pair,
timeFrame,
dataLength,
dataFolderPath
);
this.pairDataPath = pairDataPath;
this.data = data;
}
provideAllIndicators() {
this.strategyOptions.indicators.forEach(
(indicator) => indicator.provide(this.data)
);
}
feedAllIndicators(data) {
this.strategyOptions.indicators.forEach((indicator) => indicator.feed(data));
}
async backtest({}) {
const results = {
alpha: 0,
beta: 0,
maxDrawdown: 0,
maxProfit: 0,
percentageProfitable: 0,
return: 0,
profitFactor: 0,
sharpeE: 0,
tradeCount: 0,
reportData: {
data: [],
trades: []
}
};
await Promise.all([this.internalStart(), this.onStart(this.data)]);
for (const update of this.data) {
await Promise.all([
this.internalUpdate(update, this.data),
this.onUpdate(update, this.data)
]);
}
const tradeHistory = this.tradeManager.getTradeHistory();
results.tradeCount = tradeHistory.length;
results.reportData.trades = tradeHistory;
if (tradeHistory.length === 0) {
return results;
}
const returns = tradeHistory.map((trade) => {
const { ["PL" /* PL */]: pl = 0, ["leverage" /* leverage */]: leverage = 1 } = trade.getData();
return pl * leverage;
});
const totalPL = returns.reduce((sum, r) => sum + r, 0);
const profitableTrades = returns.filter((r) => r > 0);
const lossTrades = returns.filter((r) => r < 0);
results.return = totalPL;
results.percentageProfitable = profitableTrades.length / returns.length * 100;
results.maxDrawdown = Math.min(...returns);
results.maxProfit = Math.max(...returns);
const grossProfit = profitableTrades.reduce((sum, r) => sum + r, 0);
const grossLoss = Math.abs(lossTrades.reduce((sum, r) => sum + r, 0));
results.profitFactor = grossLoss !== 0 ? grossProfit / grossLoss : grossProfit;
const averageReturn = totalPL / returns.length;
const riskFreeRate = 0;
const marketReturn = await getAvgMarketReturn(
this.strategyOptions.pair,
"1M" /* MONTH */,
60
// 5 years * 12 months
);
const covariance = calcCovariance(returns, marketReturn) || 0;
const variance = calcVariance(returns) || 0;
const standardDeviation = calcStddev(returns);
results.beta = calcBeta(covariance, variance);
results.alpha = calcAlpha(
averageReturn,
riskFreeRate,
results.beta,
marketReturn
);
results.sharpeE = calcSharpeE(
averageReturn,
results.return,
riskFreeRate,
standardDeviation
);
results.reportData.data.push({
name: `${this.strategyOptions.pair.replaceAll("/", "_")}_${this.strategyOptions.timeFrame}`,
type: "price" /* PRICE */,
data: this.data
});
this.indicators.forEach((indicatorData, indicatorKey) => {
results.reportData.data.push({
name: indicatorKey,
type: "factor" /* FACTOR */,
data: indicatorData
});
});
return results;
}
internalStart() {
this.strategyOptions.indicators.forEach((indicator) => {
indicator.clear();
});
}
async internalUpdate(update, updates) {
this.feedAllIndicators(update);
await Promise.all(
this.strategyOptions.indicators.map(async (indicator) => {
this.indicators.set(indicator.key, await indicator.generate());
})
);
this.tradeManager.onUpdate(update, updates);
}
live() {
}
onStart(updates) {
}
onUpdate(update, updates) {
}
};
// src/managers/Report/ReportManager.ts
import Express from "express";
import path3 from "path";
var ReportManager = class {
app = Express();
PORT = 2555;
viewsPath;
constructor() {
this.viewsPath = new URL("./", import.meta.url).pathname;
this.initializeApp();
}
initializeApp() {
this.app.use(Express.json());
this.app.set("views", this.viewsPath);
this.app.use(Express.static(this.viewsPath));
this.app.listen(this.PORT, () => {
console.log(`Report server listening on port ${this.PORT}`);
});
}
generateReport(strategy, reportData) {
const reportId = generateMD5Id();
const { trades, data } = reportData;
const reportRouter = Express.Router();
const priceData = data.filter((e) => e.type === "price" /* PRICE */);
const factorData = data.filter((e) => e.type === "factor" /* FACTOR */);
reportRouter.get("/price-data", (_, res) => {
res.json(priceData);
});
reportRouter.get("/factor-data", (_, res) => {
res.json(factorData);
});
reportRouter.get("/trade-data", (_, res) => {
res.json(trades);
});
reportRouter.get("/", (_, res) => {
const buildPath = path3.join(this.viewsPath, "performance/dist/index.html").replace("\\C", "C");
res.sendFile(buildPath);
});
this.app.use(`/${reportId}`, reportRouter);
console.log(
`Report for ${strategy.name}: http://localhost:${this.PORT}/${reportId}`
);
}
};
// src/indicators/index.ts
var indicators_exports = {};
__export(indicators_exports, {
ADX: () => ADX,
ATR: () => ATR,
BB: () => BB,
EMA: () => EMA,
ForceIndex: () => ForceIndex,
IchimokuCloud: () => IchimokuCloud,
MACD: () => MACD,
RSI: () => RSI,
SMA: () => SMA,
StockRSI: () => StockRSI,
VWAP: () => VWAP,
VolumeProfile: () => VolumeProfile,
WEMA: () => WEMA
});
// src/indicators/EMA.ts
import ta3 from "technicalindicators";
var EMA = class extends Indicator {
period = 9;
constructor(key, options) {
super({
name: "EMA",
key,
description: "Exponential Moving Average."
});
if (options.period) this.period = options.period;
}
generate() {
const values = this.data.map((update) => update[4]).filter((value) => value !== void 0);
const ema = ta3.EMA.calculate({
period: this.period,
values
});
return ema;
}
};
// src/indicators/SMA.ts
import ta4 from "technicalindicators";
var SMA = class extends Indicator {
period = 9;
constructor(key, options) {
super({
name: "SMA",
key,
description: "Simple Moving Average."
});
if (options.period) this.period = options.period;
}
generate() {
const values = this.data.map((update) => update[4]).filter((value) => value !== void 0);
const sma = ta4.SMA.calculate({
period: this.period,
values
});
return sma;
}
};
// src/indicators/ATR.ts
import ta5 from "technicalindicators";
var ATR = class extends Indicator {
period = 14;
constructor(key, options) {
super({
name: "ATR",
key,
description: "Average True Range."
});
if (options.period) this.period = options.period;
}
generate() {
const { highs, lows, closes } = parseIntoRows(this.data);
const atr = ta5.ATR.calculate({
period: this.period,
high: highs,
low: lows,
close: closes
});
return atr;
}
};
// src/indicators/RSI.ts
import ta6 from "technicalindicators";
var RSI = class extends Indicator {
period = 14;
constructor(key, options) {
super({
name: "RSI",
key,
description: "Relative Strength Index."
});
if (options.period) this.period = options.period;
}
generate() {
const values = this.data.map((update) => update[4]).filter((value) => value !== void 0);
const rsi = ta6.RSI.calculate({
period: this.period,
values
});
return rsi;
}
};
// src/indicators/MACD.ts
import ta7 from "technicalindicators";
var MACD = class extends Indicator {
fastPeriod = 12;
slowPeriod = 26;
signalSmoothing = 9;
MAType = "SMA";
MAOscillatorType = "SMA";
constructor(key, options) {
super({
name: "MACD",
key,
description: "Moving Average Convergence/Divergence."
});
if (options.fastPeriod) this.fastPeriod = options.fastPeriod;
if (options.slowPeriod) this.slowPeriod = options.slowPeriod;
if (options.signalSmoothing) this.signalSmoothing = options.signalSmoothing;
if (options.MAOscillatorType)
this.MAOscillatorType = options.MAOscillatorType;
if (options.MAType) this.MAType = options.MAType;
}
generate() {
const values = this.data.map((update) => update[4]).filter((value) => value !== void 0);
const macd = ta7.MACD.calculate({
fastPeriod: this.fastPeriod,
slowPeriod: this.slowPeriod,
SimpleMAOscillator: this.MAOscillatorType === "SMA" ? true : false,
SimpleMASignal: this.MAType === "SMA" ? true : false,
signalPeriod: this.signalSmoothing,
values
});
return macd;
}
};
// src/indicators/StochRSI.ts
import ta8 from "technicalindicators";
var StockRSI = class extends Indicator {
dPeriod = 9;
kPeriod = 12;
rsiPeriod = 14;
stochasticPeriod = 16;
constructor(key, options) {
super({
name: "Bollinger Bands",
key,
description: "Boillinger Bands."
});
if (options.dPeriod) this.dPeriod = options.dPeriod;
if (options.kPeriod) this.kPeriod = options.kPeriod;
if (options.rsiPeriod) this.rsiPeriod = options.rsiPeriod;
if (options.stochasticPeriod)
this.stochasticPeriod = options.stochasticPeriod;
}
generate() {
const values = this.data.map((update) => update[4]).filter((value) => value !== void 0);
const stochRSI = ta8.StochasticRSI.calculate({
values,
dPeriod: this.dPeriod,
kPeriod: this.kPeriod,
rsiPeriod: this.rsiPeriod,
stochasticPeriod: this.stochasticPeriod
});
return stochRSI;
}
};
// src/indicators/BB.ts
import ta9 from "technicalindicators";
var BB = class extends Indicator {
period = 9;
stdDev = 1;
constructor(key, options) {
super({
name: "Bollinger Bands",
key,
description: "Boillinger Bands."
});
if (options.period) this.period = options.period;
if (options.stdDev) this.stdDev = options.stdDev;
}
generate() {
const values = this.data.map((update) => update[4]).filter((value) => value !== void 0);
const bb = ta9.BollingerBands.calculate({
values,
period: this.period,
stdDev: this.stdDev
});
return bb;
}
};
// src/indicators/IchimokuCloud.ts
import ta10 from "technicalindicators";
var IchimokuCloud = class extends Indicator {
basePeriod = 9;
conversionPeriod = 12;
spanPeriod = 16;
displacement = 21;
constructor(key, options) {
super({
name: "Ichimoku Cloud",
key,
description: "Ichimoku Cloud."
});
if (options.basePeriod) this.basePeriod = options.basePeriod;
if (options.conversionPeriod)
this.conversionPeriod = options.conversionPeriod;
if (options.spanPeriod) this.spanPeriod = options.spanPeriod;
if (options.displacement) this.displacement = options.displacement;
}
generate() {
const { highs, lows } = parseIntoRows(this.data);
const ichimoku = ta10.IchimokuCloud.calculate({
basePeriod: this.basePeriod,
conversionPeriod: this.conversionPeriod,
spanPeriod: this.spanPeriod,
displacement: this.displacement,
high: highs,
low: lows
});
return ichimoku;
}
};
// src/indicators/WEMA.ts
import ta11 from "technicalindicators";
var WEMA = class extends Indicator {
period = 9;
constructor(key, options) {
super({
name: "Weighted Exponential Moving Average",
key,
description: "Weighted Exponential Moving Average."
});
if (options.period) this.period = options.period;
}
generate() {
const values = this.data.map((update) => update[4]).filter((value) => value !== void 0);
const wema = ta11.WEMA.calculate({
period: this.period,
values
});
return wema;
}
};
// src/indicators/ADX.ts
import ta12 from "technicalindicators";
var ADX = class extends Indicator {
period = 9;
constructor(key, options) {
super({
name: "ADX",
key,
description: "Trend Strength."
});
if (options.period) this.period = options.period;
}
generate() {
const { closes, highs, lows } = parseIntoRows(this.data);
const adx = ta12.ADX.calculate({
period: this.period,
close: closes,
high: highs,
low: lows
});
return adx;
}
};
// src/indicators/VolumeProfile.ts
import ta13 from "technicalindicators";
var VolumeProfile = class extends Indicator {
numberOfBars = 20;
constructor(key, options) {
super({
name: "Volume Profile",
key,
description: "Volume Profile."
});
if (options.numberOfBars) this.numberOfBars = options.numberOfBars;
}
generate() {
const { closes, highs, lows, opens, volumes } = parseIntoRows(this.data);
const volumeProfile = ta13.VolumeProfile.calculate({
close: closes,
high: highs,
low: lows,
open: opens,
volume: volumes,
noOfBars: this.numberOfBars
});
return volumeProfile;
}
};
// src/indicators/VWAP.ts
import ta14 from "technicalindicators";
var VWAP = class extends Indicator {
constructor(key) {
super({
name: "VWAP",
key,
description: "Volume-weighted Average Price."
});
}
generate() {
const { closes, highs, lows, opens, timestamps, volumes } = parseIntoRows(
this.data
);
const vwap = ta14.VWAP.calculate({
close: closes,
high: highs,
low: lows,
volume: volumes
});
return vwap;
}
};
// src/indicators/ForceIndex.ts
import ta15 from "technicalindicators";
var ForceIndex = class extends Indicator {
period = 9;
constructor(key, options) {
super({
name: "ForceIndex",
key,
description: "Force Index."
});
if (options.period) this.period = options.period;
}
generate() {
const { closes, volumes } = parseIntoRows(this.data);
const forceIndex = ta15.ForceIndex.calculate({
period: this.period,
close: closes,
volume: volumes
});
return forceIndex;
}
};
export {
ChartingSystem,
CryptoPair,
DataSourceType,
Indicator,
indicators_exports as Indicators,
Logger,
NumberReturnType,
OrderType,
PositionType,
ReportManager,
Strategy,
TRADE_KEY,
TimeFrame,
TimelineEvents,
Trade,
TradeManager,
logger
};
//# sourceMappingURL=index.js.map