| 146 | * @param {import('./session').ChartSessionBridge} chartSession |
| 147 | */ |
| 148 | module.exports = (chartSession) => class ChartStudy { |
| 149 | #studID = genSessionID('st'); |
| 150 | |
| 151 | #studyListeners = chartSession.studyListeners; |
| 152 | |
| 153 | /** |
| 154 | * Table of periods values indexed by timestamp |
| 155 | * @type {Object<number, {}[]>} |
| 156 | */ |
| 157 | #periods = {}; |
| 158 | |
| 159 | /** @return {{}[]} List of periods values */ |
| 160 | get periods() { |
| 161 | return Object.values(this.#periods).sort((a, b) => b.$time - a.$time); |
| 162 | } |
| 163 | |
| 164 | /** |
| 165 | * List of graphic xPos indexes |
| 166 | * @type {number[]} |
| 167 | */ |
| 168 | #indexes = []; |
| 169 | |
| 170 | /** |
| 171 | * Table of graphic drawings indexed by type and ID |
| 172 | * @type {Object<string, Object<number, {}>>} |
| 173 | */ |
| 174 | #graphic = {}; |
| 175 | |
| 176 | /** |
| 177 | * Table of graphic drawings indexed by type |
| 178 | * @return {import('./graphicParser').GraphicData} |
| 179 | */ |
| 180 | get graphic() { |
| 181 | const translator = {}; |
| 182 | |
| 183 | Object.keys(chartSession.indexes) |
| 184 | .sort((a, b) => chartSession.indexes[b] - chartSession.indexes[a]) |
| 185 | .forEach((r, n) => { translator[r] = n; }); |
| 186 | |
| 187 | const indexes = this.#indexes.map((i) => translator[i]); |
| 188 | return graphicParser(this.#graphic, indexes); |
| 189 | } |
| 190 | |
| 191 | /** @type {StrategyReport} */ |
| 192 | #strategyReport = { |
| 193 | trades: [], |
| 194 | history: {}, |
| 195 | performance: {}, |
| 196 | }; |
| 197 | |
| 198 | /** @return {StrategyReport} Get the strategy report if available */ |
| 199 | get strategyReport() { |
| 200 | return this.#strategyReport; |
| 201 | } |
| 202 | |
| 203 | #callbacks = { |
| 204 | studyCompleted: [], |
| 205 | update: [], |
nothing calls this directly
no test coverage detected