|
@@ -0,0 +1,187 @@
|
|
|
|
|
+class MyKit {}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 豪秒级时间戳转换
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param timestamp
|
|
|
|
|
+ * @returns {*}
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit.getTimeByMillisecond = function (timestamp) {
|
|
|
|
|
+ // 组织日期格式并返回
|
|
|
|
|
+ return MyKit.dateFormat('YYYY-mm-dd HH:MM:SS', new Date(timestamp))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 秒级时间戳转换
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param timestamp
|
|
|
|
|
+ * @returns {*}
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit.getTimeBySecond = function (timestamp) {
|
|
|
|
|
+ // 组织日期格式并返回
|
|
|
|
|
+ return MyKit.dateFormat('YYYY-mm-dd HH:MM:SS', new Date(timestamp * 1000))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 格式化日期
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param fmt 日期格式
|
|
|
|
|
+ * @param date 日期对象
|
|
|
|
|
+ * @returns {*}
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit.dateFormat = function (fmt, date) {
|
|
|
|
|
+ let ret
|
|
|
|
|
+ const opt = {
|
|
|
|
|
+ "Y+": date.getFullYear().toString(), // 年
|
|
|
|
|
+ "m+": (date.getMonth() + 1).toString(), // 月
|
|
|
|
|
+ "d+": date.getDate().toString(), // 日
|
|
|
|
|
+ "H+": date.getHours().toString(), // 时
|
|
|
|
|
+ "M+": date.getMinutes().toString(), // 分
|
|
|
|
|
+ "S+": date.getSeconds().toString(), // 秒
|
|
|
|
|
+ "s+": date.getMilliseconds().toString() // 毫秒
|
|
|
|
|
+ // 有其他格式化字符需求可以继续添加,必须转化成字符串
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (let k in opt) {
|
|
|
|
|
+ ret = new RegExp("(" + k + ")").exec(fmt)
|
|
|
|
|
+ if (ret) {
|
|
|
|
|
+ fmt = fmt.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return fmt
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 截取小数位工具
|
|
|
|
|
+ * @param num 需要截取的小数
|
|
|
|
|
+ * @param n 截取位数
|
|
|
|
|
+ * @returns {number}
|
|
|
|
|
+ * @private
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit._N = function (num, n) {
|
|
|
|
|
+ if (!num) {
|
|
|
|
|
+ return 0
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let rst = num.toString()
|
|
|
|
|
+
|
|
|
|
|
+ if (rst.indexOf('.') !== -1) {
|
|
|
|
|
+ rst = rst.substring(0, rst.indexOf('.') + n + 1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return parseFloat(rst)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 转成非科学计数法
|
|
|
|
|
+ * @param num
|
|
|
|
|
+ * @returns {string}
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit.toNonExponential = function (num) {
|
|
|
|
|
+ const m = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/)
|
|
|
|
|
+ return num.toFixed(Math.max(0, (m[1] || '').length - m[2]))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 睡眠工具
|
|
|
|
|
+ * @param time 单位:毫秒
|
|
|
|
|
+ * @returns {Promise<unknown>}
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit.sleep = function (time) {
|
|
|
|
|
+ return new Promise(function (resolve) {
|
|
|
|
|
+ setTimeout(function () {
|
|
|
|
|
+ resolve(true)
|
|
|
|
|
+ }, time)
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * EMA计算器
|
|
|
|
|
+ * @param lastEma 上一个EMA
|
|
|
|
|
+ * @param closePrice 收盘价
|
|
|
|
|
+ * @param units 数据条数
|
|
|
|
|
+ * @returns {number}
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit.EMA = function (lastEma, closePrice, units) {
|
|
|
|
|
+ return (lastEma * (units - 1) + closePrice * 2) / (units + 1)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ *
|
|
|
|
|
+ * 计算移动平均线指标, ma的周期为days
|
|
|
|
|
+ *
|
|
|
|
|
+ * @method MA
|
|
|
|
|
+ * @param {Array} ticks 一维数组类型,每个元素为当前Tick的收盘价格
|
|
|
|
|
+ * @param {Integer} day
|
|
|
|
|
+ * @return {Array} mas
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit.MA = function (ticks, day) {
|
|
|
|
|
+ const mas = []
|
|
|
|
|
+ for (let i = 0; i < ticks.length; i++) {
|
|
|
|
|
+ if (i < day - 1) {
|
|
|
|
|
+ mas.push(ticks[i])
|
|
|
|
|
+ } else {
|
|
|
|
|
+ let valueSum = 0
|
|
|
|
|
+ for (let j = i; j > i - day; j--) {
|
|
|
|
|
+ valueSum += ticks[j]
|
|
|
|
|
+
|
|
|
|
|
+ if (i === ticks.length - 1) {
|
|
|
|
|
+ // console.log(day, ticks[j])
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (i === ticks.length - 1) {
|
|
|
|
|
+ // console.log(day, valueSum)
|
|
|
|
|
+ }
|
|
|
|
|
+ mas.push(valueSum / day)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return mas
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ *
|
|
|
|
|
+ * 计算macd指标,快速和慢速移动平均线的周期分别取12和26
|
|
|
|
|
+ *
|
|
|
|
|
+ * @method MACD
|
|
|
|
|
+ * @param {Array} ticks
|
|
|
|
|
+ * 一维数组类型,每个元素为tick的收盘价格
|
|
|
|
|
+ * @param {Integer} N1
|
|
|
|
|
+ * 整数类型,是为快线
|
|
|
|
|
+ * @param {Integer} N2
|
|
|
|
|
+ * 整数类型,是为慢线
|
|
|
|
|
+ * @param {Integer} N3
|
|
|
|
|
+ * 整数类型,是为信号长度
|
|
|
|
|
+ * @return {Object} 返回一个包含diffs deas bars属性的对象,每个属性对应的类型为{Array[Number]}
|
|
|
|
|
+ */
|
|
|
|
|
+MyKit.MACD = function (ticks, N1, N2, N3) {
|
|
|
|
|
+ const emaN1 = []
|
|
|
|
|
+ const emaN2 = []
|
|
|
|
|
+ const diffs = []
|
|
|
|
|
+ const deas = []
|
|
|
|
|
+ const bars = []
|
|
|
|
|
+
|
|
|
|
|
+ for (let i = 0; i < ticks.length; i++) {
|
|
|
|
|
+ const c = ticks[i]
|
|
|
|
|
+ if (i === 0) {
|
|
|
|
|
+ emaN1.push(c)
|
|
|
|
|
+ emaN2.push(c)
|
|
|
|
|
+ deas.push(0)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ emaN1.push(MyKit.EMA(emaN1[i - 1], c, N1))
|
|
|
|
|
+ emaN2.push(MyKit.EMA(emaN2[i - 1], c, N2))
|
|
|
|
|
+ }
|
|
|
|
|
+ // 计算离差值
|
|
|
|
|
+ diffs.push(emaN1[i] - emaN2[i])
|
|
|
|
|
+
|
|
|
|
|
+ if (i !== 0) {
|
|
|
|
|
+ deas.push(MyKit.EMA(deas[i - 1], diffs[i], N3))
|
|
|
|
|
+ }
|
|
|
|
|
+ // bars.push((diffs[i]-deas[i]) * 2);
|
|
|
|
|
+ bars.push(diffs[i] - deas[i])
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return { diffs: diffs, deas: deas, bars: bars }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export default MyKit
|