-
-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathichimokuCloud.ts
165 lines (151 loc) · 4.57 KB
/
ichimokuCloud.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright (c) 2022 Onur Cinar. All Rights Reserved.
// https://github.com/cinar/indicatorts
import {checkSameLength, shiftLeftBy,} from '../../helper/numArray';
/**
* Ichimoku cloud result object.
*/
export interface IchimokuCloudResult {
tenkan: number[];
kijun: number[];
ssa: number[];
ssb: number[];
laggingSpan: number[];
}
/**
* Optional configuration of Ichimoku cloud parameters.
*/
export interface IchimokuCloudConfig {
short?: number;
medium?: number;
long?: number;
close?: number;
}
/**
* The default configuration of Ichimoku cloud.
*/
export const IchimokuCloudDefaultConfig: Required<IchimokuCloudConfig> = {
short: 9,
medium: 26,
long: 52,
close: 26,
};
/**
* Returns a function calculating average price (max - min) / 2 based on period and projection
*
* @param period
* @param highs
* @param lows
* @param projection
*/
const averagePriceReducer = ({period, highs, lows, projection = 0}: {
period: number,
highs: number[],
lows: number[],
projection?: number
}) => (acc: number[], _: number, i: number) => {
if (i < period - 1) return [...acc, 0]
const from = i + 1 - period
const to = i - projection + 1
const max = Math.max(...highs.slice(from, to))
const min = Math.min(...lows.slice(from, to))
return [...acc, (max + min) / 2]
}
/**
* Tenkan-sen (Conversion Line) = (9-Period High + 9-Period Low) / 2
*
* @param highs high values.
* @param lows low values.
* @param short short period.
*/
const calculateTenkanSen = ({highs, lows, short}: {
highs: number[],
lows: number[],
short: number
}) => highs.reduce(averagePriceReducer({period: short, highs, lows}), [] as Array<number>)
/**
* Kijun-sen (Conversion Line) = (26-Period High + 26-Period Low) / 2
*
* @param highs high values.
* @param lows low values.
* @param medium mediym period.
*/
const calculateKijunSen = ({highs, lows, medium}: {
highs: number[],
lows: number[],
medium: number
}) => highs.reduce(averagePriceReducer({period: medium, highs, lows}), [] as Array<number>)
/**
* Senkou Span A (Leading Span A) = (Tenkan-sen Line + Kijun-sen) / 2 projected 26 periods in the future
*
* @param tenkanSen Tenkan-sen values.
* @param kijunSen Kijun-sen values.
* @param medium medium period.
*/
const calculateSenkouSpanA = ({tenkanSen, kijunSen, medium}: {
tenkanSen: number[],
kijunSen: number[],
medium: number
}) => {
const ssa = new Array<number>(kijunSen.length + medium).fill(0)
kijunSen.forEach((k, i) => {
if (k) ssa[i + medium] = (k + tenkanSen[i]) / 2
})
return ssa
}
/**
* Senkou Span B (Leading Span B) = (52-Period High + 52-Period Low) / 2 projected 26 periods in the future
*
* @param highs high values.
* @param lows low values.
* @param long long period.
* @param medium mediym period.
*/
const calculateSenkouSpanB = ({highs, lows, long, medium}: {
highs: number[],
lows: number[],
long: number,
medium: number
}) => new Array<number>(highs.length + medium).fill(0).reduce(averagePriceReducer({
period: long + medium,
highs,
lows,
projection: medium
}), [] as Array<number>)
/**
* Ichimoku Cloud. Also known as Ichimoku Kinko Hyo, is a versatile indicator
* that defines support and resistence, identifies trend direction, gauges
* momentum, and provides trading signals.
*
* Tenkan-sen (Conversion Line) = (9-Period High + 9-Period Low) / 2
* Kijun-sen (Base Line) = (26-Period High + 26-Period Low) / 2
* Senkou Span A (Leading Span A) = (Conversion Line + Base Line) / 2 projected 26 periods in the future
* Senkou Span B (Leading Span B) = (52-Period High + 52-Period Low) / 2 projected 26 periods in the future
* Chikou Span (Lagging Span) = Closing plotted 26 periods in the past.
*
* @param highs high values.
* @param lows low values.
* @param closings closing values.
* @param config configuration.
* @return ichimoku cloud result object.
*/
export function ichimokuCloud(
highs: number[],
lows: number[],
closings: number[],
config: IchimokuCloudConfig = {}
): IchimokuCloudResult {
checkSameLength(highs, lows, closings);
const {short, medium, long, close} = {
...IchimokuCloudDefaultConfig,
...config,
};
const tenkan = calculateTenkanSen({highs, lows, short})
const kijun = calculateKijunSen({highs, lows, medium})
return {
tenkan,
kijun,
ssa: calculateSenkouSpanA({tenkanSen: tenkan, kijunSen: kijun, medium}),
ssb: calculateSenkouSpanB({highs, lows, medium, long}),
laggingSpan: shiftLeftBy(close, closings),
};
}