কোড হল সেরা মন্তব্য, আমি বুঝতে পারছি না কিভাবে সূচক তৈরি করা হয়, কিভাবে আমি বলতে পারি যে আমি সূচক ব্যবহার করব। নিচের কোডটি আমি নিজের হাতে বানিয়েছিলাম যখন আমি একজন প্রোগ্রামার ছিলাম এবং তখন আমি ফিন্যান্সিয়াল ইন্ডাস্ট্রিতে ঢুকেছিলাম, কোন কপি পেস্ট নেই, আশা করি নতুনদের জন্য উপযোগী হবে।
var Std = {
_skip: function(arr, period) {
var j = 0;
for (var k = 0; j < arr.length; j++) {
if (!isNaN(arr[j]))
k++;
if (k == period)
break;
}
return j;
},
_sum: function(arr, num) {
var sum = 0.0;
for (var i = 0; i < num; i++) {
if (!isNaN(arr[i])) {
sum += arr[i];
}
}
return sum;
},
_avg: function(arr, num) {
var n = 0;
var sum = 0.0;
for (var i = 0; i < num; i++) {
if (!isNaN(arr[i])) {
sum += arr[i];
n++;
}
}
return sum / n;
},
_zeros: function(len) {
var n = [];
for (var i = 0; i < len; i++) {
n.push(0.0);
}
return n;
},
_set: function(arr, start, end, value) {
var e = Math.min(arr.length, end);
for (var i = start; i < e; i++) {
arr[i] = value;
}
},
_diff: function(a, b) {
var d = [];
for (var i = 0; i < b.length; i++) {
if (isNaN(a[i]) || isNaN(b[i])) {
d.push(NaN);
} else {
d.push(a[i] - b[i]);
}
}
return d;
},
_move_diff: function(a) {
var d = [];
for (var i = 1; i < a.length; i++) {
d.push(a[i] - a[i - 1]);
}
return d;
},
_sma: function(S, period) {
var R = Std._zeros(S.length);
var j = Std._skip(S, period);
Std._set(R, 0, j, NaN);
if (j < S.length) {
var sum = 0;
for (var i = j; i < S.length; i++) {
if (i == j) {
sum = Std._sum(S, i + 1);
} else {
sum += S[i] - S[i - period];
}
R[i] = sum / period;
}
}
return R;
},
_smma: function(S, period) {
var R = Std._zeros(S.length);
var j = Std._skip(S, period);
Std._set(R, 0, j, NaN);
if (j < S.length) {
R[j] = Std._avg(S, j + 1);
for (var i = j + 1; i < S.length; i++) {
R[i] = (R[i - 1] * (period - 1) + S[i]) / period;
}
}
return R;
},
_ema: function(S, period) {
var R = Std._zeros(S.length);
var multiplier = 2.0 / (period + 1);
var j = Std._skip(S, period);
Std._set(R, 0, j, NaN);
if (j < S.length) {
R[j] = Std._avg(S, j + 1);
for (var i = j + 1; i < S.length; i++) {
R[i] = ((S[i] - R[i - 1]) * multiplier) + R[i - 1];
}
}
return R;
},
_cmp: function(arr, start, end, cmpFunc) {
var v = arr[start];
for (var i = start; i < end; i++) {
v = cmpFunc(arr[i], v);
}
return v;
},
_filt: function(records, n, attr, iv, cmpFunc) {
if (records.length < 2) {
return NaN;
}
var v = iv;
var pos = n !== 0 ? records.length - Math.min(records.length - 1, n) - 1 : 0;
for (var i = records.length - 2; i >= pos; i--) {
if (typeof(attr) !== 'undefined') {
v = cmpFunc(v, records[i][attr]);
} else {
v = cmpFunc(v, records[i]);
}
}
return v;
},
_ticks: function(records) {
if (records.length === 0) {
return [];
}
var ticks = [];
if (typeof(records[0].Close) !== 'undefined') {
for (var i = 0; i < records.length; i++) {
ticks.push(records[i].Close);
}
} else {
ticks = records;
}
return ticks;
},
};
var TA = {
Highest: function(records, n, attr) {
return Std._filt(records, n, attr, Number.MIN_VALUE, Math.max);
},
Lowest: function(records, n, attr) {
return Std._filt(records, n, attr, Number.MAX_VALUE, Math.min);
},
MA: function(records, period) {
period = typeof(period) === 'undefined' ? 9 : period;
return Std._sma(Std._ticks(records), period);
},
SMA: function(records, period) {
period = typeof(period) === 'undefined' ? 9 : period;
return Std._sma(Std._ticks(records), period);
},
EMA: function(records, period) {
period = typeof(period) === 'undefined' ? 9 : period;
return Std._ema(Std._ticks(records), period);
},
MACD: function(records, fastEMA, slowEMA, signalEMA) {
fastEMA = typeof(fastEMA) === 'undefined' ? 12 : fastEMA;
slowEMA = typeof(slowEMA) === 'undefined' ? 26 : slowEMA;
signalEMA = typeof(signalEMA) === 'undefined' ? 9 : signalEMA;
var ticks = Std._ticks(records);
var slow = Std._ema(ticks, slowEMA);
var fast = Std._ema(ticks, fastEMA);
// DIF
var dif = Std._diff(fast, slow);
// DEA
var signal = Std._ema(dif, signalEMA);
var histogram = Std._diff(dif, signal);
return [dif, signal, histogram];
},
BOLL: function(records, period, multiplier) {
period = typeof(period) === 'undefined' ? 20 : period;
multiplier = typeof(multiplier) === 'undefined' ? 2 : multiplier;
var S = Std._ticks(records);
for (var j = period - 1; j < S.length && isNaN(S[j]); j++);
var UP = Std._zeros(S.length);
var MB = Std._zeros(S.length);
var DN = Std._zeros(S.length);
Std._set(UP, 0, j, NaN);
Std._set(MB, 0, j, NaN);
Std._set(DN, 0, j, NaN);
var sum = 0;
for (var i = j; i < S.length; i++) {
if (i == j) {
for (var k = 0; k < period; k++) {
sum += S[k];
}
} else {
sum = sum + S[i] - S[i - period];
}
var ma = sum / period;
var d = 0;
for (var k = i + 1 - period; k <= i; k++) {
d += (S[k] - ma) * (S[k] - ma);
}
var stdev = Math.sqrt(d / period);
var up = ma + (multiplier * stdev);
var dn = ma - (multiplier * stdev);
UP[i] = up;
MB[i] = ma;
DN[i] = dn;
}
// upper, middle, lower
return [UP, MB, DN];
},
KDJ: function(records, n, k, d) {
n = typeof(n) === 'undefined' ? 9 : n;
k = typeof(k) === 'undefined' ? 3 : k;
d = typeof(d) === 'undefined' ? 3 : d;
var RSV = Std._zeros(records.length);
Std._set(RSV, 0, n - 1, NaN);
var K = Std._zeros(records.length);
var D = Std._zeros(records.length);
var J = Std._zeros(records.length);
var hs = Std._zeros(records.length);
var ls = Std._zeros(records.length);
for (var i = 0; i < records.length; i++) {
hs[i] = records[i].High;
ls[i] = records[i].Low;
}
for (var i = 0; i < records.length; i++) {
if (i >= (n - 1)) {
var c = records[i].Close;
var h = Std._cmp(hs, i - (n - 1), i + 1, Math.max);
var l = Std._cmp(ls, i - (n - 1), i + 1, Math.min);
RSV[i] = 100 * ((c - l) / (h - l));
K[i] = (1 * RSV[i] + (k - 1) * K[i - 1]) / k;
D[i] = (1 * K[i] + (d - 1) * D[i - 1]) / d;
} else {
K[i] = D[i] = 50;
RSV[i] = 0;
}
J[i] = 3 * K[i] - 2 * D[i];
}
// remove prefix
for (var i = 0; i < n - 1; i++) {
K[i] = D[i] = J[i] = NaN;
}
return [K, D, J];
},
RSI: function(records, period) {
period = typeof(period) === 'undefined' ? 14 : period;
var i;
var n = period;
var rsi = Std._zeros(records.length);
Std._set(rsi, 0, rsi.length, NaN);
if (records.length < n) {
return rsi;
}
var ticks = Std._ticks(records);
var deltas = Std._move_diff(ticks);
var seed = deltas.slice(0, n);
var up = 0;
var down = 0;
for (i = 0; i < seed.length; i++) {
if (seed[i] >= 0) {
up += seed[i];
} else {
down += seed[i];
}
}
up /= n;
down = -(down /= n);
var rs = down != 0 ? up / down : 0;
rsi[n] = 100 - 100 / (1 + rs);
var delta = 0;
var upval = 0;
var downval = 0;
for (i = n + 1; i < ticks.length; i++) {
delta = deltas[i - 1];
if (delta > 0) {
upval = delta;
downval = 0;
} else {
upval = 0;
downval = -delta;
}
up = (up * (n - 1) + upval) / n;
down = (down * (n - 1) + downval) / n;
rs = up / down;
rsi[i] = 100 - 100 / (1 + rs);
}
return rsi;
},
OBV: function(records) {
if (records.length === 0) {
return [];
}
if (typeof(records[0].Close) === 'undefined') {
throw "argument must KLine";
}
var R = [];
for (var i = 0; i < records.length; i++) {
if (i === 0) {
R[i] = records[i].Volume;
} else if (records[i].Close >= records[i - 1].Close) {
R[i] = R[i - 1] + records[i].Volume;
} else {
R[i] = R[i - 1] - records[i].Volume;
}
}
return R;
},
ATR: function(records, period) {
if (records.length === 0) {
return [];
}
if (typeof(records[0].Close) === 'undefined') {
throw "argument must KLine";
}
period = typeof(period) === 'undefined' ? 14 : period;
var R = Std._zeros(records.length);
var sum = 0;
var n = 0;
for (var i = 0; i < records.length; i++) {
var TR = 0;
if (i == 0) {
TR = records[i].High - records[i].Low;
} else {
TR = Math.max(records[i].High - records[i].Low, Math.abs(records[i].High - records[i - 1].Close), Math.abs(records[i - 1].Close - records[i].Low));
}
sum += TR;
if (i < period) {
n = sum / (i + 1);
} else {
n = (((period - 1) * n) + TR) / period;
}
R[i] = n;
}
return R;
},
Alligator: function(records, jawLength, teethLength, lipsLength) {
jawLength = typeof(jawLength) === 'undefined' ? 13 : jawLength;
teethLength = typeof(teethLength) === 'undefined' ? 8 : teethLength;
lipsLength = typeof(lipsLength) === 'undefined' ? 5 : lipsLength;
var ticks = [];
for (var i = 0; i < records.length; i++) {
ticks.push((records[i].High + records[i].Low) / 2);
}
return [
[NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN].concat(Std._smma(ticks, jawLength)), // jaw (blue)
[NaN, NaN, NaN, NaN, NaN].concat(Std._smma(ticks, teethLength)), // teeth (red)
[NaN, NaN, NaN].concat(Std._smma(ticks, lipsLength)), // lips (green)
];
},
CMF: function(records, periods) {
periods = periods || 20;
var ret = [];
var sumD = 0;
var sumV = 0;
var arrD = [];
var arrV = [];
for (var i = 0; i < records.length; i++) {
var d = (records[i].High == records[i].Low) ? 0 : (2 * records[i].Close - records[i].Low - records[i].High) / (records[i].High - records[i].Low) * records[i].Volume;
arrD.push(d);
arrV.push(records[i].Volume);
sumD += d;
sumV += records[i].Volume;
if (i >= periods) {
sumD -= arrD.shift();
sumV -= arrV.shift();
}
ret.push(sumD / sumV);
}
return ret;
}
};
import math
class Std:
@staticmethod
def _skip(arr, period):
k = 0
for j in xrange(0, len(arr)):
if arr[j] is not None:
k+=1
if k == period:
break
return j
@staticmethod
def _sum(arr, num):
s = 0.0
for i in xrange(0, num):
if arr[i] is not None:
s += arr[i]
return s
@staticmethod
def _avg(arr, num):
if len(arr) == 0:
return 0
s = 0.0
n = 0
for i in xrange(0, min(len(arr), num)):
if arr[i] is not None:
s += arr[i]
n += 1
if n == 0:
return 0
return s / n
@staticmethod
def _zeros(n):
return [0.0] * n
@staticmethod
def _set(arr, start, end, value):
for i in xrange(start, min(len(arr), end)):
arr[i] = value
@staticmethod
def _diff(a, b):
d = [None] * len(b)
for i in xrange(0, len(b)):
if a[i] is not None and b[i] is not None:
d[i] = a[i] - b[i]
return d
@staticmethod
def _move_diff(a):
d = [None] * (len(a)-1)
for i in xrange(1, len(a)):
d[i-1] = a[i] - a[i-1]
return d
@staticmethod
def _cmp(arr, start, end, cmpFunc):
v = arr[start]
for i in xrange(start, end):
v = cmpFunc(arr[i], v)
return v
@staticmethod
def _filt(records, n, attr, iv, cmpFunc):
if len(records) < 2:
return None
v = iv
pos = 0
if n != 0:
pos = len(records) - min(len(records)-1, n) - 1
for i in xrange(len(records)-2, pos-1, -1):
if records[i] is not None:
if attr is not None:
v = cmpFunc(v, records[i][attr])
else:
v = cmpFunc(v, records[i])
return v
@staticmethod
def _ticks(records):
if len(records) == 0:
return []
if 'Close' not in records[0]:
return records
ticks = [None] * len(records)
for i in xrange(0, len(records)):
ticks[i] = records[i]['Close']
return ticks
@staticmethod
def _sma(S, period):
R = Std._zeros(len(S))
j = Std._skip(S, period)
Std._set(R, 0, j, None)
if j < len(S):
s = 0
for i in xrange(j, len(S)):
if i == j:
s = Std._sum(S, i+1)
else:
s += S[i] - S[i-period]
R[i] = s / period
return R
@staticmethod
def _smma(S, period):
R = Std._zeros(len(S))
j = Std._skip(S, period)
Std._set(R, 0, j, None)
if j < len(S):
R[j] = Std._avg(S, j+1)
for i in xrange(j+1, len(S)):
R[i] = (R[i-1] * (period-1) + S[i]) / period
return R
@staticmethod
def _ema(S, period):
R = Std._zeros(len(S))
multiplier = 2.0 / (period + 1)
j = Std._skip(S, period)
Std._set(R, 0, j, None)
if j < len(S):
R[j] = Std._avg(S, j+1)
for i in xrange(j+1, len(S)):
R[i] = ((S[i] - R[i-1] ) * multiplier) + R[i-1]
return R
class TA:
@staticmethod
def Highest(records, n, attr=None):
return Std._filt(records, n, attr, 5e-324, max)
@staticmethod
def Lowest(records, n, attr=None):
return Std._filt(records, n, attr, 1.7976931348623157e+308, min)
@staticmethod
def MA(records, period=9):
return Std._sma(Std._ticks(records), period)
@staticmethod
def SMA(records, period=9):
return Std._sma(Std._ticks(records), period)
@staticmethod
def EMA(records, period=9):
return Std._ema(Std._ticks(records), period)
@staticmethod
def MACD(records, fastEMA=12, slowEMA=26, signalEMA=9):
ticks = Std._ticks(records)
slow = Std._ema(ticks, slowEMA)
fast = Std._ema(ticks, fastEMA)
# DIF
dif = Std._diff(fast, slow)
# DEA
signal = Std._ema(dif, signalEMA)
histogram = Std._diff(dif, signal)
return [ dif, signal, histogram]
@staticmethod
def BOLL(records, period=20, multiplier=2):
S = Std._ticks(records)
j = period - 1
while j < len(S) and (S[j] is None):
j+=1
UP = Std._zeros(len(S))
MB = Std._zeros(len(S))
DN = Std._zeros(len(S))
Std._set(UP, 0, j, None)
Std._set(MB, 0, j, None)
Std._set(DN, 0, j, None)
n = 0.0
for i in xrange(j, len(S)):
if i == j:
for k in xrange(0, period):
n += S[k]
else:
n = n + S[i] - S[i - period]
ma = n / period
d = 0
for k in xrange(i+1-period, i+1):
d += (S[k] - ma) * (S[k] - ma)
stdev = math.sqrt(d / period)
up = ma + (multiplier * stdev)
dn = ma - (multiplier * stdev)
UP[i] = up
MB[i] = ma
DN[i] = dn
return [UP, MB, DN]
@staticmethod
def KDJ(records, n=9, k=3, d=3):
RSV = Std._zeros(len(records))
Std._set(RSV, 0, n - 1, None)
K = Std._zeros(len(records))
D = Std._zeros(len(records))
J = Std._zeros(len(records))
hs = Std._zeros(len(records))
ls = Std._zeros(len(records))
for i in xrange(0, len(records)):
hs[i] = records[i]['High']
ls[i] = records[i]['Low']
for i in xrange(0, len(records)):
if i >= (n - 1):
c = records[i]['Close']
h = Std._cmp(hs, i - (n - 1), i + 1, max)
l = Std._cmp(ls, i - (n - 1), i + 1, min)
RSV[i] = 100 * ((c - l) / (h - l))
K[i] = float(1 * RSV[i] + (k - 1) * K[i - 1]) / k
D[i] = float(1 * K[i] + (d - 1) * D[i - 1]) / d
else:
K[i] = D[i] = 50.0
RSV[i] = 0.0
J[i] = 3 * K[i] - 2 * D[i]
# remove prefix
for i in xrange(0, n-1):
K[i] = D[i] = J[i] = None
return [K, D, J]
@staticmethod
def RSI(records, period=14):
n = period
rsi = Std._zeros(len(records))
Std._set(rsi, 0, len(rsi), None)
if len(records) < n:
return rsi
ticks = Std._ticks(records)
deltas = Std._move_diff(ticks)
seed = deltas[:n]
up = 0.0
down = 0.0
for i in xrange(0, len(seed)):
if seed[i] >= 0:
up += seed[i]
else:
down += seed[i]
up /= n
down /= n
down = -down
if down != 0:
rs = up / down
else:
rs = 0
rsi[n] = 100 - 100 / (1 + rs)
delta = 0.0
upval = 0.0
downval = 0.0
for i in xrange(n+1, len(ticks)):
delta = deltas[i - 1]
if delta > 0:
upval = delta
downval = 0.0
else:
upval = 0.0
downval = -delta
up = (up * (n - 1) + upval) / n
down = (down * (n - 1) + downval) / n
rs = up / down
rsi[i] = 100 - 100 / (1 + rs)
return rsi
@staticmethod
def OBV(records):
if len(records) == 0:
return []
if 'Close' not in records[0]:
raise "TA.OBV argument must KLine"
R = Std._zeros(len(records))
for i in xrange(0, len(records)):
if i == 0:
R[i] = records[i]['Volume']
elif records[i]['Close'] >= records[i - 1]['Close']:
R[i] = R[i - 1] + records[i]['Volume']
else:
R[i] = R[i - 1] - records[i]['Volume']
return R
@staticmethod
def ATR(records, period=14):
if len(records) == 0:
return []
if 'Close' not in records[0]:
raise "TA.ATR argument must KLine"
R = Std._zeros(len(records))
m = 0.0
n = 0.0
for i in xrange(0, len(records)):
TR = 0
if i == 0:
TR = records[i]['High'] - records[i]['Low']
else:
TR = max(records[i]['High'] - records[i]['Low'], abs(records[i]['High'] - records[i - 1]['Close']), abs(records[i - 1]['Close'] - records[i]['Low']))
m += TR
if i < period:
n = m / (i + 1)
else:
n = (((period - 1) * n) + TR) / period
R[i] = n
return R
@staticmethod
def Alligator(records, jawLength=13, teethLength=8, lipsLength=5):
ticks = []
for i in xrange(0, len(records)):
ticks.append((records[i]['High'] + records[i]['Low']) / 2)
return [
[None]*8+Std._smma(ticks, jawLength), # // jaw (blue)
[None]*5+Std._smma(ticks, teethLength), # teeth (red)
[None]*3+Std._smma(ticks, lipsLength) # lips (green)
]
@staticmethod
def CMF(records, periods=20):
ret = []
sumD = 0.0
sumV = 0.0
arrD = []
arrV = []
for i in xrange(0, len(records)):
d = 0.0
if records[i]['High'] != records[i]['Low']:
d = (2 * records[i]['Close'] - records[i]['Low'] - records[i]['High']) / (records[i]['High'] - records[i]['Low']) * records[i]['Volume']
arrD.append(d)
arrV.append(records[i]['Volume'])
sumD += d
sumV += records[i]['Volume']
if i >= periods:
sumD -= arrD.pop(0)
sumV -= arrV.pop(0)
ret.append(sumD / sumV)
return ret
double _cmp_min(double a, double b) {
return a < b ? a : b;
}
double _cmp_max(double a, double b) {
return a > b ? a : b;
}
double _cmp_max(double a, double b, double c) {
double d = a > b ? a : b;
return d > c ? d : c;
}
class TAHelper {
public:
array<vector<double>, 3> MACD(Records &records, size_t fastEMA = 12, size_t slowEMA = 26, size_t signalEMA = 9) {
vector<double> ticks = records.Close();
vector<double> dif = _diff(_ema(ticks, fastEMA), _ema(ticks, slowEMA));
vector<double> signal = _ema(dif, signalEMA);
vector<double> histogram = _diff(dif, signal);
return {{ dif, signal, histogram }};
}
array<vector<double>, 3> KDJ(Records &records, size_t n = 9, size_t k = 3, size_t d = 3) {
size_t length = records.size();
vector<double> RSV(length, 0);
_set(RSV, 0, n - 1, NAN);
vector<double> K(length, 0);
vector<double> D(length, 0);
vector<double> J(length, 0);
vector<double> hs = records.High();
vector<double> ls = records.Low();
for (size_t i = 0; i < length; i++) {
if (i >= size_t(n - 1)) {
double c = records[i].Close;
double h = _cmp(hs, i - (n - 1), i + 1, _cmp_max);
double l = _cmp(ls, i - (n - 1), i + 1, _cmp_min);
RSV[i] = h != l ? (100 * ((c - l) / (h - l))) : 100;
K[i] = (1 * RSV[i] + (k - 1) * K[i - 1]) / k;
D[i] = (1 * K[i] + (d - 1) * D[i - 1]) / d;
} else {
K[i] = D[i] = 50;
RSV[i] = 0;
}
J[i] = 3 * K[i] - 2 * D[i];
}
for (size_t i = 0; i < n - 1; i++) {
K[i] = D[i] = J[i] = NAN;
}
return{{ K, D, J }};
}
vector<double> RSI(Records &records, size_t period = 14) {
size_t i = 0;
size_t n = period;
vector<double> rsi(records.size(), 0);
_set(rsi, 0, rsi.size(), NAN);
if (records.size() < n) {
return rsi;
}
vector<double> ticks = records.Close();
vector<double> deltas = _move_diff(ticks);
vector<double> seed(deltas.begin(), deltas.begin() + n);
double up = 0.0;
double down = 0.0;
for (i = 0; i < seed.size(); i++) {
if (seed[i] >= 0) {
up += seed[i];
} else {
down += seed[i];
}
}
up /= n;
down /= n;
down = -down;
double rs = down != 0 ? up / down : 0;
rsi[n] = 100 - 100 / (1 + rs);
double delta = 0.0;
double upval = 0.0;
double downval = 0.0;
for (i = n + 1; i < ticks.size(); i++) {
delta = deltas[i - 1];
if (delta > 0) {
upval = delta;
downval = 0;
} else {
upval = 0;
downval = -delta;
}
up = (up * (n - 1) + upval) / n;
down = (down * (n - 1) + downval) / n;
rs = up / down;
rsi[i] = 100 - 100 / (1 + rs);
}
return rsi;
}
vector<double> ATR(Records &records, size_t period = 14) {
vector<double> ret;
if (records.size() == 0) {
return ret;
}
vector<double> R(records.size(), 0);
double sum = 0.0;
double n = 0.0;
for (size_t i = 0; i < records.size(); i++) {
double TR = 0.0;
if (i == 0) {
TR = records[i].High - records[i].Low;
} else {
TR = _cmp_max(records[i].High - records[i].Low, abs(records[i].High - records[i - 1].Close), abs(records[i - 1].Close - records[i].Low));
}
sum += TR;
if (i < period) {
n = sum / (i + 1);
} else {
n = (((period - 1) * n) + TR) / period;
}
R[i] = n;
}
return R;
}
vector<double> OBV(Records &records) {
vector<double> R;
if (records.size() == 0) {
return R;
}
for (size_t i = 0; i < records.size(); i++) {
if (i == 0) {
R.push_back(records[i].Volume);
} else if (records[i].Close >= records[i - 1].Close) {
R.push_back(R[i - 1] + records[i].Volume);
} else {
R.push_back(R[i - 1] - records[i].Volume);
}
}
return R;
}
vector<double> MA(Records &records, size_t period = 9) {
return _sma(records.Close(), period);
}
vector<double> EMA(Records &records, size_t period = 9) {
return _ema(records.Close(), period);
}
array<vector<double>, 3> BOLL(Records &records, size_t period = 20, double multiplier = 2) {
vector<double> S = records.Close();
size_t j = 0;
for (j = period - 1; j < S.size() && isnan(S[j]); j++);
vector<double> UP(S.size(), 0);
vector<double> MB(S.size(), 0);
vector<double> DN(S.size(), 0);
_set(UP, 0, j, NAN);
_set(MB, 0, j, NAN);
_set(DN, 0, j, NAN);
double sum = 0;
for (size_t i = j; i < S.size(); i++) {
if (i == j) {
for (size_t k = 0; k < period; k++) {
sum += S[k];
}
} else {
sum = sum + S[i] - S[i - period];
}
double ma = sum / period;
double d = 0.0;
for (size_t k = i + 1 - period; k <= i; k++) {
d += (S[k] - ma) * (S[k] - ma);
}
double stdev = sqrt(d / period);
double up = ma + (multiplier * stdev);
double dn = ma - (multiplier * stdev);
UP[i] = up;
MB[i] = ma;
DN[i] = dn;
}
return {{ UP, MB, DN }};
}
array<vector<double>, 3> Alligator(Records &records, size_t jawLength = 13, size_t teethLength = 8, size_t lipsLength = 5) {
vector<double> ticks;
for (size_t i = 0; i < records.size(); i++) {
ticks.push_back((records[i].High + records[i].Low) / 2);
}
vector<double> jaw = _smma(ticks, jawLength);
jaw.insert(jaw.begin(), 8, NAN);
vector<double> teeth = _smma(ticks, teethLength);
teeth.insert(teeth.begin(), 5, NAN);
vector<double> lips = _smma(ticks, lipsLength);
lips.insert(lips.begin(), 3, NAN);
return{{ jaw, teeth, lips }};
}
vector<double> CMF(Records &records, size_t periods = 20) {
vector<double> ret;
double sumD = 0.0;
double sumV = 0.0;
vector<double> arrD;
vector<double> arrV;
for (size_t i = 0; i < records.size(); i++) {
double d = (records[i].High == records[i].Low) ? 0 : (2 * records[i].Close - records[i].Low - records[i].High) / (records[i].High - records[i].Low) * records[i].Volume;
arrD.push_back(d);
arrV.push_back(records[i].Volume);
sumD += d;
sumV += records[i].Volume;
if (i >= periods) {
sumD -= arrD.front();
arrD.erase(arrD.begin());
sumV -= arrV.front();
arrV.erase(arrV.begin());
}
ret.push_back(sumD / sumV);
}
return ret;
}
double Highest(vector<double> records, size_t n) {
return _filt(records, n, NAN, _cmp_max);
}
double Lowest(vector<double> records, size_t n) {
return _filt(records, n, NAN, _cmp_min);
}
double _filt(vector<double> records, double n, double iv, double(*pfun) (double a, double b)) {
if (records.size() < 2) {
return NAN;
}
double v = iv;
double pos = n != 0 ? records.size() - _cmp_min(records.size() - 1, n) - 1 : 0;
for (size_t i = records.size() - 2; i >= pos; i--) {
v = pfun(v, records[i]);
}
return v;
}
vector<double> _smma(vector<double> S, size_t period) {
size_t length = S.size();
vector<double> R(length, 0);
size_t j = _skip(S, period);
_set(R, 0, j, NAN);
if (j < length) {
R[j] = _avg(S, j + 1);
for (size_t i = j + 1; i < length; i++) {
R[i] = (R[i - 1] * (period - 1) + S[i]) / period;
}
}
return R;
}
vector<double> _move_diff(vector<double> a) {
vector<double> d;
for (size_t i = 1; i < a.size(); i++) {
d.push_back(a[i] - a[i - 1]);
}
return d;
}
vector<double> _ema(vector<double> S, size_t period) {
size_t length = S.size();
vector<double> R(length, 0);
double multiplier = 2.0 / (period + 1);
size_t j = _skip(S, period);
_set(R, 0, j, NAN);
if (j < length) {
R[j] = _avg(S, j + 1);
for (size_t i = j + 1; i < length; i++) {
R[i] = (S[i] - R[i - 1]) * multiplier + R[i - 1];
}
}
return R;
}
vector<double> _sma(vector<double> S, size_t period) {
vector<double> R(S.size(), 0);
size_t j = _skip(S, period);
_set(R, 0, j, NAN);
if (j < S.size()) {
double sum = 0;
for (size_t i = j; i < S.size(); i++) {
if (i == j) {
sum = _sum(S, i + 1);
} else {
if (i < period) {
R[i] = NAN;
continue;
}
sum += S[i] - S[i - period];
}
R[i] = sum / period;
}
}
return R;
}
double _sum(vector<double> arr, size_t num) {
double sum = 0.0;
for (size_t i = 0; i < num; i++) {
if (!isnan(arr[i])) {
sum += arr[i];
}
}
return sum;
}
vector<double> _diff(vector<double> a, vector<double> b) {
vector<double> d;
for (size_t i = 0; i < b.size(); i++) {
if (isnan(a[i]) || isnan(b[i])) {
d.push_back(NAN);
} else {
d.push_back(a[i] - b[i]);
}
}
return d;
}
double _avg(vector<double> arr, double num) {
size_t n = 0;
double sum = 0.0;
for (size_t i = 0; i < num; i++) {
if (!isnan(arr[i])) {
sum += arr[i];
n++;
}
}
return sum / n;
}
void _set(vector<double> &arr, size_t start, size_t end, double value) {
size_t e = _cmp_min(arr.size(), end);
for (size_t i = start; i < e; i++) {
arr[i] = value;
}
}
size_t _skip(vector<double> arr, size_t period) {
size_t j = 0;
for (size_t k = 0; j < arr.size(); j++) {
if (!isnan(arr[j])) {
k++;
}
if (k == period) {
break;
}
}
return j;
}
double _cmp(vector<double> arr, size_t start, size_t end, double(*pfun) (double a, double b)) {
double v = arr[start];
for (size_t i = start; i < end; i++) {
v = pfun(arr[i], v);
}
return v;
}
};
TAHelper TA;
স্কটলিআমি শিখেছি, অনেক সুবিধাজনক।
স্কটলিআমি শিখেছি, অনেক সুবিধাজনক।
পিক্সি ৩১৭৩ 666
চুনকোআমি ঠিক এটি ব্যবহার করতে চেয়েছিলাম। ধন্যবাদ।
মোমোক্সএটা কঠিন, কিন্তু আমি মনে করি পাই কোড জেএস এর চেয়েও বেশি, এটা বিজ্ঞানবিহীন।
এটা আমার মায়ের নাম।গভীরভাবে সহমত
শূন্যঅনেক পাইথন লেখকেরা খুব সহজেই বোঝা যায় না এমন কোডের একটি লাইন লিখতে পছন্দ করে, যা N লাইনকে প্রতিনিধিত্ব করে, আমি ব্যক্তিগতভাবে এটি করতে পছন্দ করি না, আমি কোডটি প্রথম দর্শনেই বুঝতে পারি এমন একটি স্টাইলে লিখি। ব্ল্যাক ম্যাজিক ব্যবহার না করে। যতটা সম্ভব কম ভাষা বৈশিষ্ট্য ব্যবহার করুন, কম তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করুন, এবং সর্বাধিক প্রচলিত লজিক্যাল সিলেবাস ব্যবহার করুন।