UNPKG

sql-synergy

Version:

Synergy Wave TA

401 lines (400 loc) 12.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Technicals = void 0; // const SMA = require('technicalindicators').SMA; // const EMA = require('technicalindicators').EMA; // const MACD = require('technicalindicators').MACD; const IConstants_1 = require("./IConstants"); //const sma = require('sma'); const finmath_1 = require("finmath"); class Technicals { constructor(oTickerQuotes) { this.iPC = -1; this.fO = []; this.fH = []; this.fL = []; this.fC = []; this.fD = []; this.fV = []; this.oTickerQuotes = oTickerQuotes; this.refresh(); } delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } getPeriod() { return this.oTickerQuotes.getPeriod(); } getSymbol() { return this.oTickerQuotes.getSymbol(); } setChart(iPC) { this.iPC = iPC; } getChart() { return this.iPC; } getLastDay() { let i = this.fD.length; if (i == 0) return 0; if (this.isPeriodEnd(this.fD[i - 1])) return i; i--; if (i < 1) return 0; return i; } getDate() { return this.oTickerQuotes.getColumn(IConstants_1.IConstants.DATE_TIME); } getOpen() { return this.oTickerQuotes.getColumn(IConstants_1.IConstants.OPEN); } getHigh() { return this.oTickerQuotes.getColumn(IConstants_1.IConstants.HIGH); } getLow() { return this.oTickerQuotes.getColumn(IConstants_1.IConstants.LOW); } getClose() { return this.oTickerQuotes.getColumn(IConstants_1.IConstants.CLOSE); } // getVolume(): Array<number> { // return this.oTickerQuotes.getColumn(IConstants.VOLUME); // } getCurrentPrice() { let iL = this.fD.length; if (iL == 0) return -1; return this.fC[iL - 1]; } size() { return this.fD.length; } isPeriodEnd(lDate) { return true; } getChartDate(lDate) { var i = 0; for (; i < this.fD.length; i++) if (this.fD[i] > lDate) break; i--; if (i < 0) return -1; // if (this.isPeriodEnd(this.fD[i])) // return i; if (i == 0) return -1; return i - 1; } getSmallerChartDate(lDate) { var i = 0; for (; i < this.fD.length; i++) if (this.fD[i] > lDate) break; i--; //System.out.println ( "Bigger Chart Date: " + lDate + " Smaller Chart Index: " + i ) ; return i; } static getSum(f, nDays, iIndex) { nDays--; var i = iIndex - nDays; if (i <= 0) { i = 0; iIndex = nDays; } iIndex = Math.min(iIndex, f.length - 1); var fSum = 0.0; try { for (; i <= iIndex; i++) fSum += f[i]; } catch (e) { console.error("iIndex = " + iIndex + " nDays = " + nDays + " i = " + i + " f.length = " + f.length); throw e; } return fSum; } static getHighest(f, nDays, iIndex) { nDays--; var fMax = 0.0; var i = iIndex - nDays; if (i < 0) return 0.0; for (; i <= iIndex; i++) fMax = f[i] > fMax ? f[i] : fMax; return fMax; } static getLowest(f, nDays, iIndex) { nDays--; var fMin = Number.MAX_VALUE; var i = iIndex - nDays; if (i < 0) return 0.0; for (; i <= iIndex; i++) fMin = f[i] < fMin ? f[i] : fMin; return fMin; } static cross(f, f1, nDays) { var n = f.length - 1; if (n <= nDays) return false; for (var i = n; i > (n - nDays); i--) { if (f[i] > f1[i] && f[i - 1] < f1[i - 1]) return true; } return false; } // static getPriceOscillator ( fPrice:Array<number>, n1MA:number, n2MA:number ) // { // let fShortMA:Array<number> = this.getMA ( fPrice, Math.min ( n1MA, n2MA ) ) ; // var nMax = Math.max ( n1MA, n2MA ) ; // let fLongMA:Array<number> = this.getMA ( fPrice, nMax ) ; // var n = fPrice.length ; // let f:Array<number> = new Array( n) ; // for ( var i = 0 ; i < n ; i++ ) // { // if ( i < ( nMax - 1 ) ) // f [ i ] = Number.MIN_VALUE ; // else // f [ i ] = ( fShortMA [ i ] - fLongMA [ i ] ) * 100.0 / fShortMA [ i ] ); // } // return f ; // } // static getSMA ( fPrice:Array<number>, nPeriod:number ):Array<number> // { // var n = fPrice.length ; // let fResult:Array<number> = new Array(n); // for ( var i = 0 ; i < n ; i++ ) // { // if ( i >= nPeriod ) // fResult [ i ] = ( fResult [ i - 1 ] * ( nPeriod - 1 ) + fPrice [ i ] ) / nPeriod ; // else // fResult [ i ] = this.getMA ( fPrice, nPeriod, i ) ; // } // return fResult ; // } static getMACrossOverBuySignalDay(f, iShortTerm, iLongTerm) { if (f.length < iLongTerm) return -1; let fSMA = Technicals.MOV(f, iShortTerm, 'S'); let fLMA = Technicals.MOV(f, iLongTerm, 'S'); var iDay = f.length - 1; if (fSMA[iDay] < fLMA[iDay]) return -1; while (iDay > 0 && fSMA[iDay] >= fLMA[iDay]) iDay--; return iDay + 1; } static getMACrossOverSellSignalDay(f, iShortTerm, iLongTerm) { if (f.length < iLongTerm) return -1; var fSMA = Technicals.MOV(f, iShortTerm, 'S'); var fLMA = Technicals.MOV(f, iLongTerm, 'S'); var iDay = f.length - 1; if (fSMA[iDay] > fLMA[iDay]) return -1; while (iDay > 0 && fSMA[iDay] <= fLMA[iDay]) iDay--; return iDay + 1; } // MOV ( number f [ ], var nDays, char chType, var iIndex ) // { // if ( chType == 'S' || chType == 's' ) // return getMA ( f, nDays, iIndex ) ; // if ( chType == 'E' || chType == 'e' ) // return getEMA ( f, nDays, iIndex ) ; // System.out.println ( "Technicals.java Unknown MOV Function " + chType ) ; // console.error ( "Technicals.java Unknown MOV Function " + chType ) ; // return 0 ; // } static MOV(f, nDays, chType) { if (chType == 'E' || chType == 'e') return finmath_1.ema(f, nDays); return finmath_1.sma(f, nDays); } //getMA Tested static getMA(f, nDays, iIndex) { if (iIndex < 0) return 0; var n = iIndex - nDays + 1; if (n < 0) { n = 0; nDays = iIndex + 1; } var fAverage = 0; for (var i = 0; i < nDays; i++) fAverage += f[n + i]; return fAverage / nDays; } static getColumn(f, iColumn) { return f.map(function (r) { return r[iColumn]; }); } static getHighIndex(fPrice, iFromIndex, iToIndex) { var f = 0; var h = 0; var iS = Math.min(iFromIndex, iToIndex); var iE = Math.max(iFromIndex, iToIndex); if (iS >= fPrice.length) { console.error("Error: HighIndex ??"); return -1; } for (var k = iS; k <= iE; k++) { if (f < fPrice[k]) { h = k; f = fPrice[k]; } } return h; } static getHigh(fPrice, iFromIndex, iToIndex) { var f = 0; var iS = Math.min(iFromIndex, iToIndex); var iE = Math.max(iFromIndex, iToIndex); if (iS >= fPrice.length) { console.error("Error: HighIndex ??"); return -1; } for (var k = iS; k <= iE; k++) f = Math.max(f, fPrice[k]); return f; } static getLowIndex(fPrice, iFromIndex, iToIndex) { var f = Number.MAX_VALUE; var h = 0; var iS = Math.min(iFromIndex, iToIndex); var iE = Math.max(iFromIndex, iToIndex); if (iS >= fPrice.length) { console.error("Error: LowIndex ??"); return -1; } for (var k = iS; k <= iE; k++) { if (f > fPrice[k]) { h = k; f = fPrice[k]; } } return h; } static getLow(fPrice, iFromIndex, iToIndex) { var f = Number.MAX_VALUE; var iS = Math.min(iFromIndex, iToIndex); var iE = Math.max(iFromIndex, iToIndex); if (iS >= fPrice.length) { console.error("Error: HighIndex ??"); return -1; } for (var k = iS; k <= iE; k++) f = Math.min(f, fPrice[k]); return f; } LLV(fPrice, nDays) { return this.getLowestLow(fPrice, nDays, this.size() - 1); } HHV(fPrice, nDays) { return this.getHighestHigh(fPrice, nDays, this.size() - 1); } getHighestHigh(fPrice, nDays, nIndex) { var n = nIndex - nDays; var nMax = nDays; if (n < 0) { n = 0; nMax = nIndex + 1; } var f = 0; for (var k = 0; k < nMax; k++) f = Math.max(f, fPrice[n + k]); return f; } getLowestLow(fPrice, nDays, nIndex) { var n = nIndex - nDays; var nMax = nDays; if (n < 0) { n = 0; nMax = nIndex + 1; } var f = Number.MAX_VALUE; for (var k = 0; k < nMax; k++) f = Math.min(f, fPrice[n + k]); return f; } static getIntersectionPredictions(f, fSignal) { let oSB = ""; var i = 0; var n = f.length; while (i < n && f[i] == Number.MIN_VALUE || fSignal[i] == Number.MIN_VALUE) i++; for (i++; i < n; i++) { if (f[i - 1] < fSignal[i - 1] && f[i] > fSignal[i]) // Buy oSB += ("" + i + "," + (fSignal[i] - .10)) + "\n"; else if (f[i - 1] > fSignal[i - 1] && f[i] < fSignal[i]) // Sell oSB += ("" + (-i) + "," + (fSignal[i] + .10) + "\n"); } return oSB; } getLowStick(iDay) { return this.getDownStick(iDay); } getUpStick(iDay) { if (iDay >= this.fD.length) return 0.0; return this.fH[iDay] - Math.max(this.fO[iDay], this.fC[iDay]); } getDownStick(iDay) { if (iDay >= this.fD.length) return 0.0; return Math.min(this.fO[iDay], this.fC[iDay]) - this.fL[iDay]; } getBody(iDay) { if (iDay >= this.fD.length) return 0.0; return Math.abs(this.fO[iDay] - this.fC[iDay]); } getHeight(iDay) { if (iDay >= this.fD.length) return 0.0; return this.fH[iDay] - this.fL[iDay]; } isWhiteCandle(iDay) { if (iDay >= this.fD.length || iDay < 0) return false; return this.fO[iDay] <= this.fC[iDay]; } isBlackCandle(iDay) { if (iDay >= this.fD.length || iDay < 0) return false; return this.fO[iDay] > this.fC[iDay]; } refresh() { this.fD = this.getDate(); this.fO = this.getOpen(); this.fH = this.getHigh(); this.fL = this.getLow(); this.fC = this.getClose(); // this.fV = this.getVolume(); } getValues(iDay) { return ("" + new Date(this.fD[iDay]).toISOString().slice(0, 19).replace('T', ' ') + "," + this.fO[iDay]) + "," + this.fH[iDay] + "," + this.fL[iDay] + "," + this.fC[iDay] + "," + this.fV[iDay]; } getDateToString(iDay) { return new Date(this.fD[iDay]).toISOString().slice(0, 19).replace('T', ' '); } isNonReversal(iDay) { // return this.getBody(iDay) > 2.0 * (this.getUpStick(iDay) + this.getDownStick(iDay)); return this.getBody(iDay) > (this.getUpStick(iDay) + this.getDownStick(iDay)); } isWhiteAndNonReversal(iDay) { return this.isWhiteCandle(iDay) && this.isNonReversal(iDay); } isBlackAndNonReversal(iDay) { return this.isBlackCandle(iDay) && this.isNonReversal(iDay); } toString() { return this.getSymbol() + "_" + IConstants_1.IConstants.sChartPeriods[this.getPeriod()]; } } exports.Technicals = Technicals;