w-trade-backtest 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/w-trade-backtest.umd.js +2 -27
- package/dist/w-trade-backtest.umd.js.map +1 -1
- package/docs/buildKLinesTpSl.mjs.html +1 -1
- package/docs/calcOrders.mjs.html +1 -1
- package/docs/calcOrdersRatio.mjs.html +1 -1
- package/docs/calcOrdersSummary.mjs.html +1 -1
- package/docs/calcOrdersSummarySimple.mjs.html +1 -1
- package/docs/calcSummary.mjs.html +1 -1
- package/docs/closeAndSummaryOrders.mjs.html +6 -6
- package/docs/genKLinesTpSl.mjs.html +1 -1
- package/docs/genReport.mjs.html +33 -26
- package/docs/genReportCore.mjs.html +4 -4
- package/docs/global.html +2 -2
- package/docs/index.html +1 -1
- package/docs/loadKLinesTpSl.mjs.html +1 -1
- package/docs/runStrategies.mjs.html +1 -1
- package/docs/runStrategiesAndBacktest.mjs.html +6 -6
- package/docs/runStrategy.mjs.html +1 -1
- package/package.json +3 -5
- package/src/closeAndSummaryOrders.mjs +5 -5
- package/src/genReport.mjs +32 -25
- package/src/genReportCore.mjs +3 -3
- package/src/runStrategiesAndBacktest.mjs +5 -5
- package/test/unit-genReport.test.mjs +3 -3
- package/src/readJson.mjs +0 -26
- package/src/writeJson.mjs +0 -31
- package/src/writeTxt.mjs +0 -19
- package/test/unit-ott.test.mjs +0 -20
- package/test/unit-writeJson.test.mjs +0 -29
- package/test/unit-writeTxt.test.mjs +0 -27
|
@@ -205,7 +205,7 @@ export default buildKLinesTpSl
|
|
|
205
205
|
<br class="clear">
|
|
206
206
|
|
|
207
207
|
<footer>
|
|
208
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
208
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
209
209
|
</footer>
|
|
210
210
|
|
|
211
211
|
<script>prettyPrint();</script>
|
package/docs/calcOrders.mjs.html
CHANGED
|
@@ -265,7 +265,7 @@ export default calcOrders
|
|
|
265
265
|
<br class="clear">
|
|
266
266
|
|
|
267
267
|
<footer>
|
|
268
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
268
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
269
269
|
</footer>
|
|
270
270
|
|
|
271
271
|
<script>prettyPrint();</script>
|
|
@@ -133,7 +133,7 @@ export default calcOrdersRatio
|
|
|
133
133
|
<br class="clear">
|
|
134
134
|
|
|
135
135
|
<footer>
|
|
136
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
136
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
137
137
|
</footer>
|
|
138
138
|
|
|
139
139
|
<script>prettyPrint();</script>
|
|
@@ -493,7 +493,7 @@ export default calcOrdersSummary
|
|
|
493
493
|
<br class="clear">
|
|
494
494
|
|
|
495
495
|
<footer>
|
|
496
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
496
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
497
497
|
</footer>
|
|
498
498
|
|
|
499
499
|
<script>prettyPrint();</script>
|
|
@@ -194,7 +194,7 @@ export default calcOrdersSummarySimple
|
|
|
194
194
|
<br class="clear">
|
|
195
195
|
|
|
196
196
|
<footer>
|
|
197
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
197
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
198
198
|
</footer>
|
|
199
199
|
|
|
200
200
|
<script>prettyPrint();</script>
|
|
@@ -188,7 +188,7 @@ export default calcSummary
|
|
|
188
188
|
<br class="clear">
|
|
189
189
|
|
|
190
190
|
<footer>
|
|
191
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
191
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
192
192
|
</footer>
|
|
193
193
|
|
|
194
194
|
<script>prettyPrint();</script>
|
|
@@ -53,8 +53,8 @@ import isestr from 'wsemi/src/isestr.mjs'
|
|
|
53
53
|
import isarr from 'wsemi/src/isarr.mjs'
|
|
54
54
|
import cint from 'wsemi/src/cint.mjs'
|
|
55
55
|
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
56
|
+
import fsWriteJson from 'wsemi/src/fsWriteJson.mjs'
|
|
56
57
|
import WDataTdprovide from 'w-data-tdprovide/src/WDataTdprovide.mjs'
|
|
57
|
-
import writeJson from './writeJson.mjs'
|
|
58
58
|
import calcOrders from './calcOrders.mjs'
|
|
59
59
|
import calcSummary from './calcSummary.mjs'
|
|
60
60
|
import genReportCore from './genReportCore.mjs'
|
|
@@ -195,8 +195,8 @@ let closeAndSummaryOrders = async (ott, fdOhlc, fdParam, uIni, timeOhlcStart, ti
|
|
|
195
195
|
//fpOrders
|
|
196
196
|
let fpOrders = path.resolve(fdTest, fnOrders)
|
|
197
197
|
|
|
198
|
-
//
|
|
199
|
-
|
|
198
|
+
//fsWriteJson
|
|
199
|
+
fsWriteJson(fpOrders, r.orders, { useFormat: true })
|
|
200
200
|
|
|
201
201
|
}
|
|
202
202
|
|
|
@@ -215,8 +215,8 @@ let closeAndSummaryOrders = async (ott, fdOhlc, fdParam, uIni, timeOhlcStart, ti
|
|
|
215
215
|
}
|
|
216
216
|
// console.log('stsm', stsm)
|
|
217
217
|
|
|
218
|
-
//
|
|
219
|
-
|
|
218
|
+
//fsWriteJson
|
|
219
|
+
fsWriteJson(fpSummary, stsm, { useFormat: true })
|
|
220
220
|
|
|
221
221
|
console.log('summary', r.summary, size(r.orders))
|
|
222
222
|
}
|
|
@@ -252,7 +252,7 @@ export default closeAndSummaryOrders
|
|
|
252
252
|
<br class="clear">
|
|
253
253
|
|
|
254
254
|
<footer>
|
|
255
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
255
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
256
256
|
</footer>
|
|
257
257
|
|
|
258
258
|
<script>prettyPrint();</script>
|
|
@@ -141,7 +141,7 @@ export default genKLinesTpSl
|
|
|
141
141
|
<br class="clear">
|
|
142
142
|
|
|
143
143
|
<footer>
|
|
144
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
144
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
145
145
|
</footer>
|
|
146
146
|
|
|
147
147
|
<script>prettyPrint();</script>
|
package/docs/genReport.mjs.html
CHANGED
|
@@ -46,12 +46,19 @@
|
|
|
46
46
|
<section>
|
|
47
47
|
<article>
|
|
48
48
|
<pre class="prettyprint source linenums"><code>import path from 'path'
|
|
49
|
-
import
|
|
50
|
-
import
|
|
49
|
+
import find from 'lodash-es/find.js'
|
|
50
|
+
import get from 'lodash-es/get.js'
|
|
51
|
+
import map from 'lodash-es/map.js'
|
|
52
|
+
import max from 'lodash-es/max.js'
|
|
53
|
+
import min from 'lodash-es/min.js'
|
|
54
|
+
import isearr from 'wsemi/src/isearr.mjs'
|
|
55
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
56
|
+
import isnum from 'wsemi/src/isnum.mjs'
|
|
57
|
+
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
|
|
58
|
+
import fsReadJson from 'wsemi/src/fsReadJson.mjs'
|
|
59
|
+
import fsWriteJson from 'wsemi/src/fsWriteJson.mjs'
|
|
51
60
|
import calcSummary from './calcSummary.mjs'
|
|
52
61
|
import genReportCore from './genReportCore.mjs'
|
|
53
|
-
import readJson from './readJson.mjs'
|
|
54
|
-
import writeJson from './writeJson.mjs'
|
|
55
62
|
|
|
56
63
|
|
|
57
64
|
/**
|
|
@@ -108,57 +115,57 @@ import writeJson from './writeJson.mjs'
|
|
|
108
115
|
let genReport = async (ott, fpOrders, opt = {}) => {
|
|
109
116
|
|
|
110
117
|
//check
|
|
111
|
-
if (!
|
|
118
|
+
if (!isestr(fpOrders)) {
|
|
112
119
|
throw new Error(`invalid fpOrders`)
|
|
113
120
|
}
|
|
114
|
-
if (!
|
|
121
|
+
if (!fsIsFile(fpOrders)) {
|
|
115
122
|
throw new Error(`fpOrders[${fpOrders}] is not a file`)
|
|
116
123
|
}
|
|
117
124
|
|
|
118
|
-
//orders
|
|
119
|
-
let orders =
|
|
120
|
-
if (!
|
|
125
|
+
//orders, fsReadJson回傳{success}或{error}, 讀取或解析失敗時取不到success
|
|
126
|
+
let orders = get(fsReadJson(fpOrders), 'success', null)
|
|
127
|
+
if (!isearr(orders)) {
|
|
121
128
|
throw new Error(`orders in fpOrders[${fpOrders}] is not an effective array`)
|
|
122
129
|
}
|
|
123
130
|
|
|
124
131
|
//fpOut
|
|
125
|
-
let fpOut =
|
|
126
|
-
if (!
|
|
132
|
+
let fpOut = get(opt, 'fpOut', '')
|
|
133
|
+
if (!isestr(fpOut)) {
|
|
127
134
|
fpOut = path.resolve(path.dirname(fpOrders), 'report.html')
|
|
128
135
|
}
|
|
129
136
|
|
|
130
137
|
//name
|
|
131
|
-
let name =
|
|
132
|
-
if (!
|
|
138
|
+
let name = get(opt, 'name', '')
|
|
139
|
+
if (!isestr(name)) {
|
|
133
140
|
name = path.basename(path.dirname(path.resolve(fpOrders)))
|
|
134
141
|
}
|
|
135
142
|
|
|
136
143
|
//uIni, 未給則由首筆已結算單推回(calcOrders 定義 uEquity = uIni + uCumuProfitOrLoss)
|
|
137
|
-
let uIni =
|
|
138
|
-
if (!
|
|
139
|
-
let o =
|
|
144
|
+
let uIni = get(opt, 'uIni', null)
|
|
145
|
+
if (!isnum(uIni)) {
|
|
146
|
+
let o = find(orders, (o) => isnum(o.uEquity) && isnum(o.uCumuProfitOrLoss))
|
|
140
147
|
uIni = o ? o.uEquity - o.uCumuProfitOrLoss : 1000
|
|
141
148
|
}
|
|
142
149
|
|
|
143
150
|
//timeOhlcStart, timeOhlcEnd, 未給則由訂單起訖推得
|
|
144
|
-
let timeOhlcStart =
|
|
145
|
-
if (!
|
|
146
|
-
timeOhlcStart =
|
|
151
|
+
let timeOhlcStart = get(opt, 'timeOhlcStart', '')
|
|
152
|
+
if (!isestr(timeOhlcStart)) {
|
|
153
|
+
timeOhlcStart = min(map(orders, 'timeStart'))
|
|
147
154
|
}
|
|
148
|
-
let timeOhlcEnd =
|
|
149
|
-
if (!
|
|
150
|
-
timeOhlcEnd =
|
|
155
|
+
let timeOhlcEnd = get(opt, 'timeOhlcEnd', '')
|
|
156
|
+
if (!isestr(timeOhlcEnd)) {
|
|
157
|
+
timeOhlcEnd = max(map(orders, (o) => isestr(o.timeEnd) ? o.timeEnd : o.timeStart))
|
|
151
158
|
}
|
|
152
159
|
|
|
153
160
|
//withWriteSummary
|
|
154
|
-
let withWriteSummary =
|
|
161
|
+
let withWriteSummary = get(opt, 'withWriteSummary', false)
|
|
155
162
|
|
|
156
163
|
//calcSummary
|
|
157
164
|
let summary = await calcSummary(ott, uIni, orders, timeOhlcStart, timeOhlcEnd)
|
|
158
165
|
|
|
159
|
-
//
|
|
166
|
+
//fsWriteJson
|
|
160
167
|
if (withWriteSummary) {
|
|
161
|
-
|
|
168
|
+
fsWriteJson(path.resolve(path.dirname(fpOut), 'summary.json'), { name, summary }, { useFormat: true })
|
|
162
169
|
}
|
|
163
170
|
|
|
164
171
|
//genReportCore
|
|
@@ -183,7 +190,7 @@ export default genReport
|
|
|
183
190
|
<br class="clear">
|
|
184
191
|
|
|
185
192
|
<footer>
|
|
186
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
193
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
187
194
|
</footer>
|
|
188
195
|
|
|
189
196
|
<script>prettyPrint();</script>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
<pre class="prettyprint source linenums"><code>import path from 'path'
|
|
49
49
|
import fs from 'fs'
|
|
50
50
|
import { fileURLToPath } from 'url'
|
|
51
|
-
import
|
|
51
|
+
import fsWriteText from 'wsemi/src/fsWriteText.mjs'
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
//模板資產(tmp.html, render*.js)與本模組同資料夾, 以模組位置解析, 不依賴 cwd
|
|
@@ -94,8 +94,8 @@ let genReportCore = (r, fpOut) => {
|
|
|
94
94
|
h = h.replace(`{orders}`, JSON.stringify(r.orders))
|
|
95
95
|
h = h.replace(`{summary}`, JSON.stringify(r.summary))
|
|
96
96
|
|
|
97
|
-
//
|
|
98
|
-
|
|
97
|
+
//fsWriteText
|
|
98
|
+
fsWriteText(fpOut, h)
|
|
99
99
|
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -115,7 +115,7 @@ export default genReportCore
|
|
|
115
115
|
<br class="clear">
|
|
116
116
|
|
|
117
117
|
<footer>
|
|
118
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
118
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
119
119
|
</footer>
|
|
120
120
|
|
|
121
121
|
<script>prettyPrint();</script>
|
package/docs/global.html
CHANGED
|
@@ -3534,7 +3534,7 @@ fpOrders非有效字串或非檔案、內容非有效陣列時throw</p>
|
|
|
3534
3534
|
|
|
3535
3535
|
<dt class="tag-source">Source:</dt>
|
|
3536
3536
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
3537
|
-
<a href="genReport.mjs.html">genReport.mjs</a>, <a href="genReport.mjs.html#
|
|
3537
|
+
<a href="genReport.mjs.html">genReport.mjs</a>, <a href="genReport.mjs.html#line68">line 68</a>
|
|
3538
3538
|
</li></ul></dd>
|
|
3539
3539
|
|
|
3540
3540
|
|
|
@@ -5916,7 +5916,7 @@ console.log(r.summary.numTrade, r.summary.rWin, r.summary.uEquityFinal)
|
|
|
5916
5916
|
<br class="clear">
|
|
5917
5917
|
|
|
5918
5918
|
<footer>
|
|
5919
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
5919
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
5920
5920
|
</footer>
|
|
5921
5921
|
|
|
5922
5922
|
<script>prettyPrint();</script>
|
package/docs/index.html
CHANGED
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
<br class="clear">
|
|
72
72
|
|
|
73
73
|
<footer>
|
|
74
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
74
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
75
75
|
</footer>
|
|
76
76
|
|
|
77
77
|
<script>prettyPrint();</script>
|
|
@@ -176,7 +176,7 @@ export default loadKLinesTpSl
|
|
|
176
176
|
<br class="clear">
|
|
177
177
|
|
|
178
178
|
<footer>
|
|
179
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
179
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
180
180
|
</footer>
|
|
181
181
|
|
|
182
182
|
<script>prettyPrint();</script>
|
|
@@ -231,7 +231,7 @@ export default runStrategies
|
|
|
231
231
|
<br class="clear">
|
|
232
232
|
|
|
233
233
|
<footer>
|
|
234
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
234
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
235
235
|
</footer>
|
|
236
236
|
|
|
237
237
|
<script>prettyPrint();</script>
|
|
@@ -50,10 +50,10 @@ import get from 'lodash-es/get.js'
|
|
|
50
50
|
import size from 'lodash-es/size.js'
|
|
51
51
|
import isearr from 'wsemi/src/isearr.mjs'
|
|
52
52
|
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
53
|
+
import fsWriteJson from 'wsemi/src/fsWriteJson.mjs'
|
|
53
54
|
import WDataTdprovide from 'w-data-tdprovide/src/WDataTdprovide.mjs'
|
|
54
55
|
import runStrategies from './runStrategies.mjs'
|
|
55
56
|
import genReportCore from './genReportCore.mjs'
|
|
56
|
-
import writeJson from './writeJson.mjs'
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
/**
|
|
@@ -153,8 +153,8 @@ let runStrategiesAndBacktest = async (ott, fdOhlc, fdParam, strategies, timeStar
|
|
|
153
153
|
//fpOrders
|
|
154
154
|
let fpOrders = path.resolve(fdTest, fnOrders)
|
|
155
155
|
|
|
156
|
-
//
|
|
157
|
-
|
|
156
|
+
//fsWriteJson
|
|
157
|
+
fsWriteJson(fpOrders, r.orders, { useFormat: true })
|
|
158
158
|
|
|
159
159
|
}
|
|
160
160
|
|
|
@@ -173,8 +173,8 @@ let runStrategiesAndBacktest = async (ott, fdOhlc, fdParam, strategies, timeStar
|
|
|
173
173
|
}
|
|
174
174
|
// console.log('stsm', stsm)
|
|
175
175
|
|
|
176
|
-
//
|
|
177
|
-
|
|
176
|
+
//fsWriteJson
|
|
177
|
+
fsWriteJson(fpSummary, stsm, { useFormat: true })
|
|
178
178
|
|
|
179
179
|
console.log('summary', r.summary, size(r.orders))
|
|
180
180
|
}
|
|
@@ -211,7 +211,7 @@ export default runStrategiesAndBacktest
|
|
|
211
211
|
<br class="clear">
|
|
212
212
|
|
|
213
213
|
<footer>
|
|
214
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
214
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
215
215
|
</footer>
|
|
216
216
|
|
|
217
217
|
<script>prettyPrint();</script>
|
|
@@ -442,7 +442,7 @@ export default runStrategy
|
|
|
442
442
|
<br class="clear">
|
|
443
443
|
|
|
444
444
|
<footer>
|
|
445
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
445
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 08 2026 00:22:43 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
446
446
|
</footer>
|
|
447
447
|
|
|
448
448
|
<script>prettyPrint();</script>
|
package/package.json
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w-trade-backtest",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"main": "dist/w-trade-backtest.umd.js",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"w-data-tdprovide": "^1.0.3",
|
|
9
|
-
"wsemi": "^1.8.67"
|
|
6
|
+
"w-data-tdprovide": "^1.0.5",
|
|
7
|
+
"wsemi": "^1.8.68"
|
|
10
8
|
},
|
|
11
9
|
"devDependencies": {
|
|
12
10
|
"w-package-tools": "^1.1.12"
|
|
@@ -6,8 +6,8 @@ import isestr from 'wsemi/src/isestr.mjs'
|
|
|
6
6
|
import isarr from 'wsemi/src/isarr.mjs'
|
|
7
7
|
import cint from 'wsemi/src/cint.mjs'
|
|
8
8
|
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
9
|
+
import fsWriteJson from 'wsemi/src/fsWriteJson.mjs'
|
|
9
10
|
import WDataTdprovide from 'w-data-tdprovide/src/WDataTdprovide.mjs'
|
|
10
|
-
import writeJson from './writeJson.mjs'
|
|
11
11
|
import calcOrders from './calcOrders.mjs'
|
|
12
12
|
import calcSummary from './calcSummary.mjs'
|
|
13
13
|
import genReportCore from './genReportCore.mjs'
|
|
@@ -148,8 +148,8 @@ let closeAndSummaryOrders = async (ott, fdOhlc, fdParam, uIni, timeOhlcStart, ti
|
|
|
148
148
|
//fpOrders
|
|
149
149
|
let fpOrders = path.resolve(fdTest, fnOrders)
|
|
150
150
|
|
|
151
|
-
//
|
|
152
|
-
|
|
151
|
+
//fsWriteJson
|
|
152
|
+
fsWriteJson(fpOrders, r.orders, { useFormat: true })
|
|
153
153
|
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -168,8 +168,8 @@ let closeAndSummaryOrders = async (ott, fdOhlc, fdParam, uIni, timeOhlcStart, ti
|
|
|
168
168
|
}
|
|
169
169
|
// console.log('stsm', stsm)
|
|
170
170
|
|
|
171
|
-
//
|
|
172
|
-
|
|
171
|
+
//fsWriteJson
|
|
172
|
+
fsWriteJson(fpSummary, stsm, { useFormat: true })
|
|
173
173
|
|
|
174
174
|
console.log('summary', r.summary, size(r.orders))
|
|
175
175
|
}
|
package/src/genReport.mjs
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import find from 'lodash-es/find.js'
|
|
3
|
+
import get from 'lodash-es/get.js'
|
|
4
|
+
import map from 'lodash-es/map.js'
|
|
5
|
+
import max from 'lodash-es/max.js'
|
|
6
|
+
import min from 'lodash-es/min.js'
|
|
7
|
+
import isearr from 'wsemi/src/isearr.mjs'
|
|
8
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
9
|
+
import isnum from 'wsemi/src/isnum.mjs'
|
|
10
|
+
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
|
|
11
|
+
import fsReadJson from 'wsemi/src/fsReadJson.mjs'
|
|
12
|
+
import fsWriteJson from 'wsemi/src/fsWriteJson.mjs'
|
|
4
13
|
import calcSummary from './calcSummary.mjs'
|
|
5
14
|
import genReportCore from './genReportCore.mjs'
|
|
6
|
-
import readJson from './readJson.mjs'
|
|
7
|
-
import writeJson from './writeJson.mjs'
|
|
8
15
|
|
|
9
16
|
|
|
10
17
|
/**
|
|
@@ -61,57 +68,57 @@ import writeJson from './writeJson.mjs'
|
|
|
61
68
|
let genReport = async (ott, fpOrders, opt = {}) => {
|
|
62
69
|
|
|
63
70
|
//check
|
|
64
|
-
if (!
|
|
71
|
+
if (!isestr(fpOrders)) {
|
|
65
72
|
throw new Error(`invalid fpOrders`)
|
|
66
73
|
}
|
|
67
|
-
if (!
|
|
74
|
+
if (!fsIsFile(fpOrders)) {
|
|
68
75
|
throw new Error(`fpOrders[${fpOrders}] is not a file`)
|
|
69
76
|
}
|
|
70
77
|
|
|
71
|
-
//orders
|
|
72
|
-
let orders =
|
|
73
|
-
if (!
|
|
78
|
+
//orders, fsReadJson回傳{success}或{error}, 讀取或解析失敗時取不到success
|
|
79
|
+
let orders = get(fsReadJson(fpOrders), 'success', null)
|
|
80
|
+
if (!isearr(orders)) {
|
|
74
81
|
throw new Error(`orders in fpOrders[${fpOrders}] is not an effective array`)
|
|
75
82
|
}
|
|
76
83
|
|
|
77
84
|
//fpOut
|
|
78
|
-
let fpOut =
|
|
79
|
-
if (!
|
|
85
|
+
let fpOut = get(opt, 'fpOut', '')
|
|
86
|
+
if (!isestr(fpOut)) {
|
|
80
87
|
fpOut = path.resolve(path.dirname(fpOrders), 'report.html')
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
//name
|
|
84
|
-
let name =
|
|
85
|
-
if (!
|
|
91
|
+
let name = get(opt, 'name', '')
|
|
92
|
+
if (!isestr(name)) {
|
|
86
93
|
name = path.basename(path.dirname(path.resolve(fpOrders)))
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
//uIni, 未給則由首筆已結算單推回(calcOrders 定義 uEquity = uIni + uCumuProfitOrLoss)
|
|
90
|
-
let uIni =
|
|
91
|
-
if (!
|
|
92
|
-
let o =
|
|
97
|
+
let uIni = get(opt, 'uIni', null)
|
|
98
|
+
if (!isnum(uIni)) {
|
|
99
|
+
let o = find(orders, (o) => isnum(o.uEquity) && isnum(o.uCumuProfitOrLoss))
|
|
93
100
|
uIni = o ? o.uEquity - o.uCumuProfitOrLoss : 1000
|
|
94
101
|
}
|
|
95
102
|
|
|
96
103
|
//timeOhlcStart, timeOhlcEnd, 未給則由訂單起訖推得
|
|
97
|
-
let timeOhlcStart =
|
|
98
|
-
if (!
|
|
99
|
-
timeOhlcStart =
|
|
104
|
+
let timeOhlcStart = get(opt, 'timeOhlcStart', '')
|
|
105
|
+
if (!isestr(timeOhlcStart)) {
|
|
106
|
+
timeOhlcStart = min(map(orders, 'timeStart'))
|
|
100
107
|
}
|
|
101
|
-
let timeOhlcEnd =
|
|
102
|
-
if (!
|
|
103
|
-
timeOhlcEnd =
|
|
108
|
+
let timeOhlcEnd = get(opt, 'timeOhlcEnd', '')
|
|
109
|
+
if (!isestr(timeOhlcEnd)) {
|
|
110
|
+
timeOhlcEnd = max(map(orders, (o) => isestr(o.timeEnd) ? o.timeEnd : o.timeStart))
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
//withWriteSummary
|
|
107
|
-
let withWriteSummary =
|
|
114
|
+
let withWriteSummary = get(opt, 'withWriteSummary', false)
|
|
108
115
|
|
|
109
116
|
//calcSummary
|
|
110
117
|
let summary = await calcSummary(ott, uIni, orders, timeOhlcStart, timeOhlcEnd)
|
|
111
118
|
|
|
112
|
-
//
|
|
119
|
+
//fsWriteJson
|
|
113
120
|
if (withWriteSummary) {
|
|
114
|
-
|
|
121
|
+
fsWriteJson(path.resolve(path.dirname(fpOut), 'summary.json'), { name, summary }, { useFormat: true })
|
|
115
122
|
}
|
|
116
123
|
|
|
117
124
|
//genReportCore
|
package/src/genReportCore.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'path'
|
|
2
2
|
import fs from 'fs'
|
|
3
3
|
import { fileURLToPath } from 'url'
|
|
4
|
-
import
|
|
4
|
+
import fsWriteText from 'wsemi/src/fsWriteText.mjs'
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
//模板資產(tmp.html, render*.js)與本模組同資料夾, 以模組位置解析, 不依賴 cwd
|
|
@@ -47,8 +47,8 @@ let genReportCore = (r, fpOut) => {
|
|
|
47
47
|
h = h.replace(`{orders}`, JSON.stringify(r.orders))
|
|
48
48
|
h = h.replace(`{summary}`, JSON.stringify(r.summary))
|
|
49
49
|
|
|
50
|
-
//
|
|
51
|
-
|
|
50
|
+
//fsWriteText
|
|
51
|
+
fsWriteText(fpOut, h)
|
|
52
52
|
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -3,10 +3,10 @@ import get from 'lodash-es/get.js'
|
|
|
3
3
|
import size from 'lodash-es/size.js'
|
|
4
4
|
import isearr from 'wsemi/src/isearr.mjs'
|
|
5
5
|
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
6
|
+
import fsWriteJson from 'wsemi/src/fsWriteJson.mjs'
|
|
6
7
|
import WDataTdprovide from 'w-data-tdprovide/src/WDataTdprovide.mjs'
|
|
7
8
|
import runStrategies from './runStrategies.mjs'
|
|
8
9
|
import genReportCore from './genReportCore.mjs'
|
|
9
|
-
import writeJson from './writeJson.mjs'
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -106,8 +106,8 @@ let runStrategiesAndBacktest = async (ott, fdOhlc, fdParam, strategies, timeStar
|
|
|
106
106
|
//fpOrders
|
|
107
107
|
let fpOrders = path.resolve(fdTest, fnOrders)
|
|
108
108
|
|
|
109
|
-
//
|
|
110
|
-
|
|
109
|
+
//fsWriteJson
|
|
110
|
+
fsWriteJson(fpOrders, r.orders, { useFormat: true })
|
|
111
111
|
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -126,8 +126,8 @@ let runStrategiesAndBacktest = async (ott, fdOhlc, fdParam, strategies, timeStar
|
|
|
126
126
|
}
|
|
127
127
|
// console.log('stsm', stsm)
|
|
128
128
|
|
|
129
|
-
//
|
|
130
|
-
|
|
129
|
+
//fsWriteJson
|
|
130
|
+
fsWriteJson(fpSummary, stsm, { useFormat: true })
|
|
131
131
|
|
|
132
132
|
console.log('summary', r.summary, size(r.orders))
|
|
133
133
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import assert from 'assert'
|
|
2
2
|
import fs from 'fs'
|
|
3
3
|
import path from 'path'
|
|
4
|
+
import fsWriteJson from 'wsemi/src/fsWriteJson.mjs'
|
|
4
5
|
import calcOrders from '../src/calcOrders.mjs'
|
|
5
6
|
import genReport from '../src/genReport.mjs'
|
|
6
7
|
import ott from '../src/ott.mjs'
|
|
7
|
-
import writeJson from '../src/writeJson.mjs'
|
|
8
8
|
import { approx, t00, t16, t20, buildArrOhlc, buildOrders, buildFdTmp } from './unit-setup.mjs'
|
|
9
9
|
|
|
10
10
|
|
|
@@ -27,7 +27,7 @@ describe('genReport', function() {
|
|
|
27
27
|
let writeSettledOrders = async (fd) => {
|
|
28
28
|
let orders = await calcOrders(buildArrOhlc(), buildOrders(), { uIni: 1000 })
|
|
29
29
|
let fpOrders = path.resolve(fdTmp, fd, 'orders.json')
|
|
30
|
-
|
|
30
|
+
fsWriteJson(fpOrders, orders)
|
|
31
31
|
return fpOrders
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -106,7 +106,7 @@ describe('genReport', function() {
|
|
|
106
106
|
|
|
107
107
|
it('orders.json內容非有效陣列時reject', async function() {
|
|
108
108
|
let fp = path.resolve(fdTmp, 'gr-invalid', 'orders.json')
|
|
109
|
-
|
|
109
|
+
fsWriteJson(fp, [])
|
|
110
110
|
await assert.rejects(genReport(ott, fp), { message: `orders in fpOrders[${fp}] is not an effective array` })
|
|
111
111
|
})
|
|
112
112
|
|
package/src/readJson.mjs
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import w from 'wsemi'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
let readJson = (fp) => {
|
|
6
|
-
|
|
7
|
-
//check
|
|
8
|
-
if (!w.fsIsFile(fp)) {
|
|
9
|
-
throw new Error(`fp[${fp}] does not exist`)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
//obj
|
|
13
|
-
let obj = null
|
|
14
|
-
try {
|
|
15
|
-
let j = fs.readFileSync(fp, 'utf8')
|
|
16
|
-
obj = JSON.parse(j)
|
|
17
|
-
}
|
|
18
|
-
catch (err) {
|
|
19
|
-
console.log(err)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return obj
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export default readJson
|