sql-synergy
Version:
Synergy Wave TA
401 lines (400 loc) • 12.5 kB
JavaScript
"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;