w-trade-backtest 1.0.4 → 1.0.6

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.
Files changed (47) hide show
  1. package/dist/w-trade-backtest.umd.js +2 -27
  2. package/dist/w-trade-backtest.umd.js.map +1 -1
  3. package/docs/buildKLinesTpSl.mjs.html +218 -0
  4. package/docs/calcOrders.mjs.html +2 -2
  5. package/docs/calcOrdersRatio.mjs.html +2 -2
  6. package/docs/calcOrdersSummary.mjs.html +2 -2
  7. package/docs/calcOrdersSummarySimple.mjs.html +2 -2
  8. package/docs/calcSummary.mjs.html +2 -2
  9. package/docs/closeAndSummaryOrders.mjs.html +7 -7
  10. package/docs/genKLinesTpSl.mjs.html +154 -0
  11. package/docs/genReport.mjs.html +34 -27
  12. package/docs/genReportCore.mjs.html +5 -5
  13. package/docs/global.html +1274 -165
  14. package/docs/index.html +2 -2
  15. package/docs/loadKLinesTpSl.mjs.html +189 -0
  16. package/docs/runStrategies.mjs.html +2 -2
  17. package/docs/runStrategiesAndBacktest.mjs.html +7 -7
  18. package/docs/runStrategy.mjs.html +2 -2
  19. package/package.json +2 -3
  20. package/src/WTradeBacktest.mjs +6 -0
  21. package/src/buildKLinesTpSl.mjs +146 -0
  22. package/src/closeAndSummaryOrders.mjs +5 -5
  23. package/src/genKLinesTpSl.mjs +82 -0
  24. package/src/genReport.mjs +32 -25
  25. package/src/genReportCore.mjs +3 -3
  26. package/src/loadKLinesTpSl.mjs +117 -0
  27. package/src/runStrategiesAndBacktest.mjs +5 -5
  28. package/test/unit-WTradeBacktest.test.mjs +23 -643
  29. package/test/unit-buildKLinesTpSl.test.mjs +98 -0
  30. package/test/unit-calcOrders.test.mjs +60 -0
  31. package/test/unit-calcOrdersRatio.test.mjs +39 -0
  32. package/test/unit-calcOrdersSummary.test.mjs +71 -0
  33. package/test/unit-calcOrdersSummarySimple.test.mjs +30 -0
  34. package/test/unit-calcSummary.test.mjs +30 -0
  35. package/test/unit-closeAndSummaryOrders.test.mjs +53 -0
  36. package/test/unit-genKLinesTpSl.test.mjs +46 -0
  37. package/test/unit-genReport.test.mjs +113 -0
  38. package/test/unit-genReportCore.test.mjs +39 -0
  39. package/test/unit-loadKLinesTpSl.test.mjs +158 -0
  40. package/test/unit-ott.test.mjs +20 -0
  41. package/test/unit-runStrategies.test.mjs +30 -0
  42. package/test/unit-runStrategiesAndBacktest.test.mjs +114 -0
  43. package/test/unit-runStrategy.test.mjs +53 -0
  44. package/test/unit-setup.mjs +120 -0
  45. package/src/readJson.mjs +0 -26
  46. package/src/writeJson.mjs +0 -31
  47. package/src/writeTxt.mjs +0 -19
package/docs/global.html CHANGED
@@ -29,7 +29,7 @@
29
29
  <nav >
30
30
 
31
31
 
32
- <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#calcOrders">calcOrders</a></li><li><a href="global.html#calcOrdersRatio">calcOrdersRatio</a></li><li><a href="global.html#calcOrdersSummary">calcOrdersSummary</a></li><li><a href="global.html#calcOrdersSummarySimple">calcOrdersSummarySimple</a></li><li><a href="global.html#calcSummary">calcSummary</a></li><li><a href="global.html#closeAndSummaryOrders">closeAndSummaryOrders</a></li><li><a href="global.html#genReport">genReport</a></li><li><a href="global.html#genReportCore">genReportCore</a></li><li><a href="global.html#runStrategies">runStrategies</a></li><li><a href="global.html#runStrategiesAndBacktest">runStrategiesAndBacktest</a></li><li><a href="global.html#runStrategy">runStrategy</a></li></ul>
32
+ <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#buildKLinesTpSl">buildKLinesTpSl</a></li><li><a href="global.html#calcOrders">calcOrders</a></li><li><a href="global.html#calcOrdersRatio">calcOrdersRatio</a></li><li><a href="global.html#calcOrdersSummary">calcOrdersSummary</a></li><li><a href="global.html#calcOrdersSummarySimple">calcOrdersSummarySimple</a></li><li><a href="global.html#calcSummary">calcSummary</a></li><li><a href="global.html#closeAndSummaryOrders">closeAndSummaryOrders</a></li><li><a href="global.html#genKLinesTpSl">genKLinesTpSl</a></li><li><a href="global.html#genReport">genReport</a></li><li><a href="global.html#genReportCore">genReportCore</a></li><li><a href="global.html#loadKLinesTpSl">loadKLinesTpSl</a></li><li><a href="global.html#runStrategies">runStrategies</a></li><li><a href="global.html#runStrategiesAndBacktest">runStrategiesAndBacktest</a></li><li><a href="global.html#runStrategy">runStrategy</a></li></ul>
33
33
 
34
34
  </nav>
35
35
 
@@ -130,7 +130,7 @@
130
130
 
131
131
 
132
132
 
133
- <h4 class="name" id="calcOrders"><span class="type-signature type-signature-async">(async) </span>calcOrders<span class="signature">(arrOhlc, orders, opt<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Promise}</span></h4>
133
+ <h4 class="name" id="buildKLinesTpSl"><span class="type-signature type-signature-async">(async) </span>buildKLinesTpSl<span class="signature">(fdOhlc, fdParam, fpJson, opt<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Promise}</span></h4>
134
134
 
135
135
 
136
136
 
@@ -140,17 +140,19 @@
140
140
  <dl class="details">
141
141
 
142
142
  <dt class="tag-description">Description:</dt>
143
- <dd class="tag-description"><ul class="dummy"><li><p>結算訂單,依K線序列判斷各下單之止盈止損觸發並計算盈虧</p>
144
- <p>各單僅檢查time大於timeStart之K棒,long以Low&lt;=priceStopLoss先判止損、High&gt;=priceTakeProfit判止盈,short以High&gt;=priceStopLoss先判止損、Low&lt;=priceTakeProfit判止盈
145
- long盈虧為uTrade*(priceEnd/priceStart)-uTrade-2<em>uFee,short盈虧為(priceStart-priceEnd)</em>(uTrade/priceStart)-2*uFee
146
- 依timeStart排序逐單累計uCumuProfitOrLoss與uEquity(自uIni起算),modeResult為盈虧&lt;0時'loss'否則'profit',未觸發止盈止損者維持原單(未平倉)</p>
143
+ <dd class="tag-description"><ul class="dummy"><li><p>建置各K線與各止盈止損組合之先觸結果快取檔</p>
144
+ <p>以w-data-tdprovide讀取fdOhlc與fdParam資料夾內keyOhlc序列,取ts至te範圍K線後,逐一組合modes與tps呼叫genKLinesTpSl
145
+ 各組合以<code>${mode}_${tpsl}</code>為key存入各根K線,win為1(止盈先觸)、0(止損先觸)或-1(至區間末仍未結)
146
+ timeEnd於建置時由hold位移換算為絕對時間,故下游查表即得而不需位置索引,未結者為null
147
+ 僅存win、timeEnd與各根close,盈虧由下游loadKLinesTpSl之ordersFromBars以close與手續費重算
148
+ fdOhlc或fdParam非資料夾、fpJson或opt.keyOhlc非有效字串、opt.ts或opt.te非時間字串時throw</p>
147
149
  <p>Unit Test: <a href="https://github.com/yuda-lyu/w-trade-backtest/blob/master/test/unit-WTradeBacktest.test.mjs">Github</a></p></li></ul></dd>
148
150
 
149
151
 
150
152
 
151
153
  <dt class="tag-source">Source:</dt>
152
154
  <dd class="tag-source"><ul class="dummy"><li>
153
- <a href="calcOrders.mjs.html">calcOrders.mjs</a>, <a href="calcOrders.mjs.html#line69">line 69</a>
155
+ <a href="buildKLinesTpSl.mjs.html">buildKLinesTpSl.mjs</a>, <a href="buildKLinesTpSl.mjs.html#line72">line 72</a>
154
156
  </li></ul></dd>
155
157
 
156
158
 
@@ -197,7 +199,9 @@ long盈虧為uTrade*(priceEnd/priceStart)-uTrade-2<em>uFee,short盈虧為(pric
197
199
 
198
200
  <h5 class="h5-examples">Example</h5>
199
201
 
200
- <pre class="prettyprint"><code>let arrOhlc = [
202
+ <pre class="prettyprint"><code>import fs from 'fs'
203
+
204
+ let arrOhlc = [
201
205
  { time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
202
206
  { time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
203
207
  { time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
@@ -206,40 +210,31 @@ long盈虧為uTrade*(priceEnd/priceStart)-uTrade-2<em>uFee,short盈虧為(pric
206
210
  { time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
207
211
  ]
208
212
 
209
- let orders = [{
210
- mode: 'long',
211
- timeStart: '2020-01-01T00:00:00',
212
- priceStart: 100,
213
- uTrade: 100,
214
- priceTakeProfit: 105,
215
- priceStopLoss: 97,
216
- timeEnd: '',
217
- priceEnd: '',
218
- modeResult: '',
219
- uFee: 0.05,
220
- }]
213
+ //建立數據資料夾, fdOhlc放K線序列, fdParam放指標參數序列
214
+ fs.mkdirSync('./data-ohlc', { recursive: true })
215
+ fs.mkdirSync('./data-param', { recursive: true })
216
+ fs.writeFileSync('./data-ohlc/btc.json', JSON.stringify(arrOhlc), 'utf8')
221
217
 
222
- calcOrders(arrOhlc, orders, { uIni: 1000 })
223
- .then((rs) => {
224
- console.log(rs[0])
225
- // => {
226
- // mode: 'long',
227
- // timeStart: '2020-01-01T00:00:00',
228
- // priceStart: 100,
229
- // uTrade: 100,
230
- // priceTakeProfit: 105,
231
- // priceStopLoss: 97,
232
- // timeEnd: '2020-01-01T04:00:00',
233
- // priceEnd: 105,
234
- // modeResult: 'profit',
235
- // uFee: 0.05,
236
- // uProfitOrLoss: 4.9,
237
- // rProfitOrLoss: 0.049,
238
- // uCumuProfitOrLoss: 4.9,
239
- // rCumuProfitOrLoss: '0.49%',
240
- // uEquity: 1004.9
241
- // }
242
- })</code></pre>
218
+ let r = await buildKLinesTpSl('./data-ohlc', './data-param', './cache/kltpsl.json', {
219
+ keyOhlc: 'btc',
220
+ ts: '2020-01-01T00:00:00',
221
+ te: '2020-01-01T20:00:00',
222
+ tps: [5],
223
+ modes: ['long'],
224
+ })
225
+ console.log(r.meta)
226
+ // => {
227
+ // keyOhlc: 'btc',
228
+ // ts: '2020-01-01T00:00:00',
229
+ // te: '2020-01-01T20:00:00',
230
+ // tps: [ 5 ],
231
+ // modes: [ 'long' ],
232
+ // nBars: 6
233
+ // }
234
+ console.log(r.bars['2020-01-01T00:00:00'])
235
+ // => { close: 100, long_5: { win: 1, timeEnd: '2020-01-01T04:00:00' } }
236
+ console.log(r.bars['2020-01-01T12:00:00'])
237
+ // => { close: 95, long_5: { win: -1, timeEnd: null } }</code></pre>
243
238
 
244
239
 
245
240
 
@@ -273,13 +268,13 @@ calcOrders(arrOhlc, orders, { uIni: 1000 })
273
268
 
274
269
  <tr>
275
270
 
276
- <td class="name"><code>arrOhlc</code></td>
271
+ <td class="name"><code>fdOhlc</code></td>
277
272
 
278
273
 
279
274
  <td class="type">
280
275
 
281
276
 
282
- <span class="param-type">Array</span>
277
+ <span class="param-type">String</span>
283
278
 
284
279
 
285
280
 
@@ -302,20 +297,20 @@ calcOrders(arrOhlc, orders, { uIni: 1000 })
302
297
  </td>
303
298
 
304
299
 
305
- <td class="description last"><p>輸入K線陣列,各元素需含time、High、Low欄位</p></td>
300
+ <td class="description last"><p>輸入儲存K線(ohlc)序列資料夾字串,各序列以<code>${key}.json</code>儲存</p></td>
306
301
  </tr>
307
302
 
308
303
 
309
304
 
310
305
  <tr>
311
306
 
312
- <td class="name"><code>orders</code></td>
307
+ <td class="name"><code>fdParam</code></td>
313
308
 
314
309
 
315
310
  <td class="type">
316
311
 
317
312
 
318
- <span class="param-type">Array</span>
313
+ <span class="param-type">String</span>
319
314
 
320
315
 
321
316
 
@@ -338,7 +333,43 @@ calcOrders(arrOhlc, orders, { uIni: 1000 })
338
333
  </td>
339
334
 
340
335
 
341
- <td class="description last"><p>輸入下單陣列,各元素需含mode('long'或'short')、timeStart、priceStart、uTrade、priceTakeProfit、priceStopLoss、uFee欄位</p></td>
336
+ <td class="description last"><p>輸入儲存指標參數序列資料夾字串</p></td>
337
+ </tr>
338
+
339
+
340
+
341
+ <tr>
342
+
343
+ <td class="name"><code>fpJson</code></td>
344
+
345
+
346
+ <td class="type">
347
+
348
+
349
+ <span class="param-type">String</span>
350
+
351
+
352
+
353
+
354
+ </td>
355
+
356
+
357
+ <td class="attributes">
358
+
359
+
360
+
361
+
362
+
363
+ </td>
364
+
365
+
366
+
367
+ <td class="default">
368
+
369
+ </td>
370
+
371
+
372
+ <td class="description last"><p>輸入輸出快取json檔案路徑字串,資料夾不存在時自動建立</p></td>
342
373
  </tr>
343
374
 
344
375
 
@@ -408,13 +439,121 @@ calcOrders(arrOhlc, orders, { uIni: 1000 })
408
439
 
409
440
  <tr>
410
441
 
411
- <td class="name"><code>uIni</code></td>
442
+ <td class="name"><code>keyOhlc</code></td>
412
443
 
413
444
 
414
445
  <td class="type">
415
446
 
416
447
 
417
- <span class="param-type">Number</span>
448
+ <span class="param-type">String</span>
449
+
450
+
451
+
452
+
453
+ </td>
454
+
455
+
456
+ <td class="attributes">
457
+
458
+
459
+
460
+
461
+
462
+ </td>
463
+
464
+
465
+
466
+ <td class="default">
467
+
468
+ </td>
469
+
470
+
471
+ <td class="description last"><p>輸入K線序列key字串</p></td>
472
+ </tr>
473
+
474
+
475
+
476
+ <tr>
477
+
478
+ <td class="name"><code>ts</code></td>
479
+
480
+
481
+ <td class="type">
482
+
483
+
484
+ <span class="param-type">String</span>
485
+
486
+
487
+
488
+
489
+ </td>
490
+
491
+
492
+ <td class="attributes">
493
+
494
+
495
+
496
+
497
+
498
+ </td>
499
+
500
+
501
+
502
+ <td class="default">
503
+
504
+ </td>
505
+
506
+
507
+ <td class="description last"><p>輸入起始秒時間字串</p></td>
508
+ </tr>
509
+
510
+
511
+
512
+ <tr>
513
+
514
+ <td class="name"><code>te</code></td>
515
+
516
+
517
+ <td class="type">
518
+
519
+
520
+ <span class="param-type">String</span>
521
+
522
+
523
+
524
+
525
+ </td>
526
+
527
+
528
+ <td class="attributes">
529
+
530
+
531
+
532
+
533
+
534
+ </td>
535
+
536
+
537
+
538
+ <td class="default">
539
+
540
+ </td>
541
+
542
+
543
+ <td class="description last"><p>輸入結束秒時間字串</p></td>
544
+ </tr>
545
+
546
+
547
+
548
+ <tr>
549
+
550
+ <td class="name"><code>tps</code></td>
551
+
552
+
553
+ <td class="type">
554
+
555
+
556
+ <span class="param-type">Array</span>
418
557
 
419
558
 
420
559
 
@@ -436,12 +575,52 @@ calcOrders(arrOhlc, orders, { uIni: 1000 })
436
575
 
437
576
  <td class="default">
438
577
 
439
- <code>1000</code>
578
+ <code>[4,5,6,7,8,9,10]</code>
440
579
 
441
580
  </td>
442
581
 
443
582
 
444
- <td class="description last"><p>輸入初始資金數字,預設1000</p></td>
583
+ <td class="description last"><p>輸入止盈止損百分比數值陣列,如5代表止盈與止損皆5%,預設[4,5,6,7,8,9,10]</p></td>
584
+ </tr>
585
+
586
+
587
+
588
+ <tr>
589
+
590
+ <td class="name"><code>modes</code></td>
591
+
592
+
593
+ <td class="type">
594
+
595
+
596
+ <span class="param-type">Array</span>
597
+
598
+
599
+
600
+
601
+ </td>
602
+
603
+
604
+ <td class="attributes">
605
+
606
+ &lt;optional><br>
607
+
608
+
609
+
610
+
611
+
612
+ </td>
613
+
614
+
615
+
616
+ <td class="default">
617
+
618
+ <code>['long','short']</code>
619
+
620
+ </td>
621
+
622
+
623
+ <td class="description last"><p>輸入交易方向字串陣列,預設['long','short']</p></td>
445
624
  </tr>
446
625
 
447
626
 
@@ -474,7 +653,7 @@ calcOrders(arrOhlc, orders, { uIni: 1000 })
474
653
 
475
654
 
476
655
  <div class="param-desc">
477
- <p>回傳Promise,resolve為結算後訂單陣列</p>
656
+ <p>回傳Promise,resolve為{meta,bars}物件,meta內含keyOhlc、ts、te、tps、modes與nBars(K線根數),bars以進場時間為key,各值內含close與各<code>${mode}_${tpsl}</code>之{win,timeEnd},並同步寫出至fpJson</p>
478
657
  </div>
479
658
 
480
659
 
@@ -501,7 +680,7 @@ calcOrders(arrOhlc, orders, { uIni: 1000 })
501
680
 
502
681
 
503
682
 
504
- <h4 class="name" id="calcOrdersRatio"><span class="type-signature"></span>calcOrdersRatio<span class="signature">(ott, orders)</span><span class="type-signature"> &rarr; {Array}</span></h4>
683
+ <h4 class="name" id="calcOrders"><span class="type-signature type-signature-async">(async) </span>calcOrders<span class="signature">(arrOhlc, orders, opt<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Promise}</span></h4>
505
684
 
506
685
 
507
686
 
@@ -511,16 +690,17 @@ calcOrders(arrOhlc, orders, { uIni: 1000 })
511
690
  <dl class="details">
512
691
 
513
692
  <dt class="tag-description">Description:</dt>
514
- <dd class="tag-description"><ul class="dummy"><li><p>計算各已平倉訂單之持倉天數與等效日盈虧比例</p>
515
- <p>dayHold以timeStart與timeEnd之日期差+1計算,rProfitOrLossDay為(1+rProfitOrLoss)^(1/dayHold)-1
516
- modeResult非有效字串(未平倉)之訂單不計算</p>
693
+ <dd class="tag-description"><ul class="dummy"><li><p>結算訂單,依K線序列判斷各下單之止盈止損觸發並計算盈虧</p>
694
+ <p>各單僅檢查time大於timeStart之K棒,long以Low&lt;=priceStopLoss先判止損、High&gt;=priceTakeProfit判止盈,short以High&gt;=priceStopLoss先判止損、Low&lt;=priceTakeProfit判止盈
695
+ long盈虧為uTrade*(priceEnd/priceStart)-uTrade-2<em>uFee,short盈虧為(priceStart-priceEnd)</em>(uTrade/priceStart)-2*uFee
696
+ 依timeStart排序逐單累計uCumuProfitOrLoss與uEquity(自uIni起算),modeResult為盈虧&lt;0時'loss'否則'profit',未觸發止盈止損者維持原單(未平倉)</p>
517
697
  <p>Unit Test: <a href="https://github.com/yuda-lyu/w-trade-backtest/blob/master/test/unit-WTradeBacktest.test.mjs">Github</a></p></li></ul></dd>
518
698
 
519
699
 
520
700
 
521
701
  <dt class="tag-source">Source:</dt>
522
702
  <dd class="tag-source"><ul class="dummy"><li>
523
- <a href="calcOrdersRatio.mjs.html">calcOrdersRatio.mjs</a>, <a href="calcOrdersRatio.mjs.html#line35">line 35</a>
703
+ <a href="calcOrders.mjs.html">calcOrders.mjs</a>, <a href="calcOrders.mjs.html#line69">line 69</a>
524
704
  </li></ul></dd>
525
705
 
526
706
 
@@ -567,9 +747,379 @@ modeResult非有效字串(未平倉)之訂單不計算</p>
567
747
 
568
748
  <h5 class="h5-examples">Example</h5>
569
749
 
570
- <pre class="prettyprint"><code>let orders = calcOrdersRatio(ott, [{
571
- modeResult: 'profit',
572
- timeStart: '2020-01-01T20:00:00',
750
+ <pre class="prettyprint"><code>let arrOhlc = [
751
+ { time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
752
+ { time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
753
+ { time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
754
+ { time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
755
+ { time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
756
+ { time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
757
+ ]
758
+
759
+ let orders = [{
760
+ mode: 'long',
761
+ timeStart: '2020-01-01T00:00:00',
762
+ priceStart: 100,
763
+ uTrade: 100,
764
+ priceTakeProfit: 105,
765
+ priceStopLoss: 97,
766
+ timeEnd: '',
767
+ priceEnd: '',
768
+ modeResult: '',
769
+ uFee: 0.05,
770
+ }]
771
+
772
+ calcOrders(arrOhlc, orders, { uIni: 1000 })
773
+ .then((rs) => {
774
+ console.log(rs[0])
775
+ // => {
776
+ // mode: 'long',
777
+ // timeStart: '2020-01-01T00:00:00',
778
+ // priceStart: 100,
779
+ // uTrade: 100,
780
+ // priceTakeProfit: 105,
781
+ // priceStopLoss: 97,
782
+ // timeEnd: '2020-01-01T04:00:00',
783
+ // priceEnd: 105,
784
+ // modeResult: 'profit',
785
+ // uFee: 0.05,
786
+ // uProfitOrLoss: 4.9,
787
+ // rProfitOrLoss: 0.049,
788
+ // uCumuProfitOrLoss: 4.9,
789
+ // rCumuProfitOrLoss: '0.49%',
790
+ // uEquity: 1004.9
791
+ // }
792
+ })</code></pre>
793
+
794
+
795
+
796
+
797
+ <h5 class="h5-parameters">Parameters:</h5>
798
+
799
+
800
+ <table class="params">
801
+ <thead>
802
+ <tr>
803
+
804
+ <th>Name</th>
805
+
806
+
807
+ <th>Type</th>
808
+
809
+
810
+ <th>Attributes</th>
811
+
812
+
813
+
814
+ <th>Default</th>
815
+
816
+
817
+ <th class="last">Description</th>
818
+ </tr>
819
+ </thead>
820
+
821
+ <tbody>
822
+
823
+
824
+ <tr>
825
+
826
+ <td class="name"><code>arrOhlc</code></td>
827
+
828
+
829
+ <td class="type">
830
+
831
+
832
+ <span class="param-type">Array</span>
833
+
834
+
835
+
836
+
837
+ </td>
838
+
839
+
840
+ <td class="attributes">
841
+
842
+
843
+
844
+
845
+
846
+ </td>
847
+
848
+
849
+
850
+ <td class="default">
851
+
852
+ </td>
853
+
854
+
855
+ <td class="description last"><p>輸入K線陣列,各元素需含time、High、Low欄位</p></td>
856
+ </tr>
857
+
858
+
859
+
860
+ <tr>
861
+
862
+ <td class="name"><code>orders</code></td>
863
+
864
+
865
+ <td class="type">
866
+
867
+
868
+ <span class="param-type">Array</span>
869
+
870
+
871
+
872
+
873
+ </td>
874
+
875
+
876
+ <td class="attributes">
877
+
878
+
879
+
880
+
881
+
882
+ </td>
883
+
884
+
885
+
886
+ <td class="default">
887
+
888
+ </td>
889
+
890
+
891
+ <td class="description last"><p>輸入下單陣列,各元素需含mode('long'或'short')、timeStart、priceStart、uTrade、priceTakeProfit、priceStopLoss、uFee欄位</p></td>
892
+ </tr>
893
+
894
+
895
+
896
+ <tr>
897
+
898
+ <td class="name"><code>opt</code></td>
899
+
900
+
901
+ <td class="type">
902
+
903
+
904
+ <span class="param-type">Object</span>
905
+
906
+
907
+
908
+
909
+ </td>
910
+
911
+
912
+ <td class="attributes">
913
+
914
+ &lt;optional><br>
915
+
916
+
917
+
918
+
919
+
920
+ </td>
921
+
922
+
923
+
924
+ <td class="default">
925
+
926
+ <code>{}</code>
927
+
928
+ </td>
929
+
930
+
931
+ <td class="description last"><p>輸入設定物件,預設{}</p>
932
+ <h6>Properties</h6>
933
+
934
+
935
+ <table class="params">
936
+ <thead>
937
+ <tr>
938
+
939
+ <th>Name</th>
940
+
941
+
942
+ <th>Type</th>
943
+
944
+
945
+ <th>Attributes</th>
946
+
947
+
948
+
949
+ <th>Default</th>
950
+
951
+
952
+ <th class="last">Description</th>
953
+ </tr>
954
+ </thead>
955
+
956
+ <tbody>
957
+
958
+
959
+ <tr>
960
+
961
+ <td class="name"><code>uIni</code></td>
962
+
963
+
964
+ <td class="type">
965
+
966
+
967
+ <span class="param-type">Number</span>
968
+
969
+
970
+
971
+
972
+ </td>
973
+
974
+
975
+ <td class="attributes">
976
+
977
+ &lt;optional><br>
978
+
979
+
980
+
981
+
982
+
983
+ </td>
984
+
985
+
986
+
987
+ <td class="default">
988
+
989
+ <code>1000</code>
990
+
991
+ </td>
992
+
993
+
994
+ <td class="description last"><p>輸入初始資金數字,預設1000</p></td>
995
+ </tr>
996
+
997
+
998
+ </tbody>
999
+ </table>
1000
+
1001
+ </td>
1002
+ </tr>
1003
+
1004
+
1005
+ </tbody>
1006
+ </table>
1007
+
1008
+
1009
+
1010
+
1011
+
1012
+
1013
+
1014
+
1015
+
1016
+
1017
+
1018
+
1019
+
1020
+
1021
+
1022
+
1023
+ <h5 class="h5-returns">Returns:</h5>
1024
+
1025
+
1026
+ <div class="param-desc">
1027
+ <p>回傳Promise,resolve為結算後訂單陣列</p>
1028
+ </div>
1029
+
1030
+
1031
+
1032
+ <dl class="param-type">
1033
+ <dt>
1034
+ Type
1035
+ </dt>
1036
+ <dd>
1037
+
1038
+ <span class="param-type">Promise</span>
1039
+
1040
+
1041
+
1042
+ </dd>
1043
+ </dl>
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+
1053
+
1054
+ <h4 class="name" id="calcOrdersRatio"><span class="type-signature"></span>calcOrdersRatio<span class="signature">(ott, orders)</span><span class="type-signature"> &rarr; {Array}</span></h4>
1055
+
1056
+
1057
+
1058
+
1059
+
1060
+
1061
+ <dl class="details">
1062
+
1063
+ <dt class="tag-description">Description:</dt>
1064
+ <dd class="tag-description"><ul class="dummy"><li><p>計算各已平倉訂單之持倉天數與等效日盈虧比例</p>
1065
+ <p>dayHold以timeStart與timeEnd之日期差+1計算,rProfitOrLossDay為(1+rProfitOrLoss)^(1/dayHold)-1
1066
+ modeResult非有效字串(未平倉)之訂單不計算</p>
1067
+ <p>Unit Test: <a href="https://github.com/yuda-lyu/w-trade-backtest/blob/master/test/unit-WTradeBacktest.test.mjs">Github</a></p></li></ul></dd>
1068
+
1069
+
1070
+
1071
+ <dt class="tag-source">Source:</dt>
1072
+ <dd class="tag-source"><ul class="dummy"><li>
1073
+ <a href="calcOrdersRatio.mjs.html">calcOrdersRatio.mjs</a>, <a href="calcOrdersRatio.mjs.html#line35">line 35</a>
1074
+ </li></ul></dd>
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+
1083
+
1084
+
1085
+
1086
+
1087
+
1088
+
1089
+
1090
+
1091
+
1092
+
1093
+
1094
+
1095
+
1096
+
1097
+
1098
+
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+
1106
+ </dl>
1107
+
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+
1114
+
1115
+
1116
+
1117
+
1118
+ <h5 class="h5-examples">Example</h5>
1119
+
1120
+ <pre class="prettyprint"><code>let orders = calcOrdersRatio(ott, [{
1121
+ modeResult: 'profit',
1122
+ timeStart: '2020-01-01T20:00:00',
573
1123
  timeEnd: '2020-01-03T04:00:00',
574
1124
  rProfitOrLoss: 0.331,
575
1125
  }])
@@ -1988,49 +2538,265 @@ let ordersSubmit = [{
1988
2538
  uFee: 0.05,
1989
2539
  }]
1990
2540
 
1991
- await closeAndSummaryOrders(ott, './data-ohlc', './data-param', 1000, '2020-01-01T00:00:00', '2020-01-01T20:00:00', 'btc', ordersSubmit, './result')
1992
- console.log(fs.readdirSync('./result'))
1993
- // => [ 'orders.json', 'report.html', 'summary.json' ]</code></pre>
2541
+ await closeAndSummaryOrders(ott, './data-ohlc', './data-param', 1000, '2020-01-01T00:00:00', '2020-01-01T20:00:00', 'btc', ordersSubmit, './result')
2542
+ console.log(fs.readdirSync('./result'))
2543
+ // => [ 'orders.json', 'report.html', 'summary.json' ]</code></pre>
2544
+
2545
+
2546
+
2547
+
2548
+ <h5 class="h5-parameters">Parameters:</h5>
2549
+
2550
+
2551
+ <table class="params">
2552
+ <thead>
2553
+ <tr>
2554
+
2555
+ <th>Name</th>
2556
+
2557
+
2558
+ <th>Type</th>
2559
+
2560
+
2561
+ <th>Attributes</th>
2562
+
2563
+
2564
+
2565
+ <th>Default</th>
2566
+
2567
+
2568
+ <th class="last">Description</th>
2569
+ </tr>
2570
+ </thead>
2571
+
2572
+ <tbody>
2573
+
2574
+
2575
+ <tr>
2576
+
2577
+ <td class="name"><code>ott</code></td>
2578
+
2579
+
2580
+ <td class="type">
2581
+
2582
+
2583
+ <span class="param-type">function</span>
2584
+
2585
+
2586
+
2587
+
2588
+ </td>
2589
+
2590
+
2591
+ <td class="attributes">
2592
+
2593
+
2594
+
2595
+
2596
+
2597
+ </td>
2598
+
2599
+
2600
+
2601
+ <td class="default">
2602
+
2603
+ </td>
2604
+
2605
+
2606
+ <td class="description last"><p>輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝)</p></td>
2607
+ </tr>
2608
+
2609
+
2610
+
2611
+ <tr>
2612
+
2613
+ <td class="name"><code>fdOhlc</code></td>
2614
+
2615
+
2616
+ <td class="type">
2617
+
2618
+
2619
+ <span class="param-type">String</span>
2620
+
2621
+
2622
+
2623
+
2624
+ </td>
2625
+
2626
+
2627
+ <td class="attributes">
2628
+
2629
+
2630
+
2631
+
2632
+
2633
+ </td>
2634
+
2635
+
2636
+
2637
+ <td class="default">
2638
+
2639
+ </td>
2640
+
2641
+
2642
+ <td class="description last"><p>輸入儲存K線(ohlc)序列資料夾字串,各序列以<code>${key}.json</code>儲存</p></td>
2643
+ </tr>
2644
+
2645
+
2646
+
2647
+ <tr>
2648
+
2649
+ <td class="name"><code>fdParam</code></td>
2650
+
2651
+
2652
+ <td class="type">
2653
+
2654
+
2655
+ <span class="param-type">String</span>
2656
+
2657
+
2658
+
2659
+
2660
+ </td>
2661
+
2662
+
2663
+ <td class="attributes">
2664
+
2665
+
2666
+
2667
+
2668
+
2669
+ </td>
2670
+
2671
+
2672
+
2673
+ <td class="default">
2674
+
2675
+ </td>
2676
+
2677
+
2678
+ <td class="description last"><p>輸入儲存指標參數序列資料夾字串</p></td>
2679
+ </tr>
2680
+
2681
+
2682
+
2683
+ <tr>
2684
+
2685
+ <td class="name"><code>uIni</code></td>
2686
+
2687
+
2688
+ <td class="type">
2689
+
2690
+
2691
+ <span class="param-type">Number</span>
2692
+
2693
+
2694
+
2695
+
2696
+ </td>
2697
+
2698
+
2699
+ <td class="attributes">
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+ </td>
2706
+
2707
+
2708
+
2709
+ <td class="default">
2710
+
2711
+ </td>
2712
+
2713
+
2714
+ <td class="description last"><p>輸入初始資金正數</p></td>
2715
+ </tr>
2716
+
2717
+
2718
+
2719
+ <tr>
2720
+
2721
+ <td class="name"><code>timeOhlcStart</code></td>
2722
+
2723
+
2724
+ <td class="type">
2725
+
2726
+
2727
+ <span class="param-type">String</span>
2728
+
2729
+
2730
+
2731
+
2732
+ </td>
2733
+
2734
+
2735
+ <td class="attributes">
2736
+
2737
+
2738
+
2739
+
2740
+
2741
+ </td>
2742
+
2743
+
2744
+
2745
+ <td class="default">
2746
+
2747
+ </td>
2748
+
2749
+
2750
+ <td class="description last"><p>輸入回測起始秒時間字串</p></td>
2751
+ </tr>
2752
+
2753
+
1994
2754
 
2755
+ <tr>
2756
+
2757
+ <td class="name"><code>timeOhlcEnd</code></td>
2758
+
1995
2759
 
2760
+ <td class="type">
2761
+
2762
+
2763
+ <span class="param-type">String</span>
1996
2764
 
1997
2765
 
1998
- <h5 class="h5-parameters">Parameters:</h5>
1999
-
2000
2766
 
2001
- <table class="params">
2002
- <thead>
2003
- <tr>
2004
-
2005
- <th>Name</th>
2006
-
2767
+
2768
+ </td>
2007
2769
 
2008
- <th>Type</th>
2770
+
2771
+ <td class="attributes">
2772
+
2009
2773
 
2010
-
2011
- <th>Attributes</th>
2012
-
2774
+
2013
2775
 
2014
-
2015
- <th>Default</th>
2016
-
2776
+
2777
+ </td>
2778
+
2017
2779
 
2018
- <th class="last">Description</th>
2019
- </tr>
2020
- </thead>
2780
+
2781
+ <td class="default">
2782
+
2783
+ </td>
2784
+
2785
+
2786
+ <td class="description last"><p>輸入回測結束秒時間字串</p></td>
2787
+ </tr>
2021
2788
 
2022
- <tbody>
2023
2789
 
2024
2790
 
2025
2791
  <tr>
2026
2792
 
2027
- <td class="name"><code>ott</code></td>
2793
+ <td class="name"><code>keyOhlc</code></td>
2028
2794
 
2029
2795
 
2030
2796
  <td class="type">
2031
2797
 
2032
2798
 
2033
- <span class="param-type">function</span>
2799
+ <span class="param-type">String</span>
2034
2800
 
2035
2801
 
2036
2802
 
@@ -2053,20 +2819,20 @@ console.log(fs.readdirSync('./result'))
2053
2819
  </td>
2054
2820
 
2055
2821
 
2056
- <td class="description last"><p>輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝)</p></td>
2822
+ <td class="description last"><p>輸入K線序列key字串</p></td>
2057
2823
  </tr>
2058
2824
 
2059
2825
 
2060
2826
 
2061
2827
  <tr>
2062
2828
 
2063
- <td class="name"><code>fdOhlc</code></td>
2829
+ <td class="name"><code>ordersSubmit</code></td>
2064
2830
 
2065
2831
 
2066
2832
  <td class="type">
2067
2833
 
2068
2834
 
2069
- <span class="param-type">String</span>
2835
+ <span class="param-type">Array</span>
2070
2836
 
2071
2837
 
2072
2838
 
@@ -2089,14 +2855,14 @@ console.log(fs.readdirSync('./result'))
2089
2855
  </td>
2090
2856
 
2091
2857
 
2092
- <td class="description last"><p>輸入儲存K線(ohlc)序列資料夾字串,各序列以<code>${key}.json</code>儲存</p></td>
2858
+ <td class="description last"><p>輸入下單陣列(格式同calcOrders之orders)</p></td>
2093
2859
  </tr>
2094
2860
 
2095
2861
 
2096
2862
 
2097
2863
  <tr>
2098
2864
 
2099
- <td class="name"><code>fdParam</code></td>
2865
+ <td class="name"><code>fdTest</code></td>
2100
2866
 
2101
2867
 
2102
2868
  <td class="type">
@@ -2125,20 +2891,20 @@ console.log(fs.readdirSync('./result'))
2125
2891
  </td>
2126
2892
 
2127
2893
 
2128
- <td class="description last"><p>輸入儲存指標參數序列資料夾字串</p></td>
2894
+ <td class="description last"><p>輸入輸出結果資料夾字串</p></td>
2129
2895
  </tr>
2130
2896
 
2131
2897
 
2132
2898
 
2133
2899
  <tr>
2134
2900
 
2135
- <td class="name"><code>uIni</code></td>
2901
+ <td class="name"><code>opt</code></td>
2136
2902
 
2137
2903
 
2138
2904
  <td class="type">
2139
2905
 
2140
2906
 
2141
- <span class="param-type">Number</span>
2907
+ <span class="param-type">Object</span>
2142
2908
 
2143
2909
 
2144
2910
 
@@ -2148,6 +2914,8 @@ console.log(fs.readdirSync('./result'))
2148
2914
 
2149
2915
  <td class="attributes">
2150
2916
 
2917
+ &lt;optional><br>
2918
+
2151
2919
 
2152
2920
 
2153
2921
 
@@ -2158,23 +2926,48 @@ console.log(fs.readdirSync('./result'))
2158
2926
 
2159
2927
  <td class="default">
2160
2928
 
2929
+ <code>{}</code>
2930
+
2161
2931
  </td>
2162
2932
 
2163
2933
 
2164
- <td class="description last"><p>輸入初始資金正數</p></td>
2165
- </tr>
2934
+ <td class="description last"><p>輸入設定物件,預設{}</p>
2935
+ <h6>Properties</h6>
2936
+
2937
+
2938
+ <table class="params">
2939
+ <thead>
2940
+ <tr>
2941
+
2942
+ <th>Name</th>
2943
+
2944
+
2945
+ <th>Type</th>
2946
+
2947
+
2948
+ <th>Attributes</th>
2949
+
2950
+
2951
+
2952
+ <th>Default</th>
2953
+
2954
+
2955
+ <th class="last">Description</th>
2956
+ </tr>
2957
+ </thead>
2166
2958
 
2959
+ <tbody>
2167
2960
 
2168
2961
 
2169
2962
  <tr>
2170
2963
 
2171
- <td class="name"><code>timeOhlcStart</code></td>
2964
+ <td class="name"><code>writeOrders</code></td>
2172
2965
 
2173
2966
 
2174
2967
  <td class="type">
2175
2968
 
2176
2969
 
2177
- <span class="param-type">String</span>
2970
+ <span class="param-type">Boolean</span>
2178
2971
 
2179
2972
 
2180
2973
 
@@ -2184,6 +2977,8 @@ console.log(fs.readdirSync('./result'))
2184
2977
 
2185
2978
  <td class="attributes">
2186
2979
 
2980
+ &lt;optional><br>
2981
+
2187
2982
 
2188
2983
 
2189
2984
 
@@ -2194,23 +2989,25 @@ console.log(fs.readdirSync('./result'))
2194
2989
 
2195
2990
  <td class="default">
2196
2991
 
2992
+ <code>true</code>
2993
+
2197
2994
  </td>
2198
2995
 
2199
2996
 
2200
- <td class="description last"><p>輸入回測起始秒時間字串</p></td>
2997
+ <td class="description last"><p>輸入是否輸出orders.json布林值,預設true</p></td>
2201
2998
  </tr>
2202
2999
 
2203
3000
 
2204
3001
 
2205
3002
  <tr>
2206
3003
 
2207
- <td class="name"><code>timeOhlcEnd</code></td>
3004
+ <td class="name"><code>writeSummary</code></td>
2208
3005
 
2209
3006
 
2210
3007
  <td class="type">
2211
3008
 
2212
3009
 
2213
- <span class="param-type">String</span>
3010
+ <span class="param-type">Boolean</span>
2214
3011
 
2215
3012
 
2216
3013
 
@@ -2220,6 +3017,8 @@ console.log(fs.readdirSync('./result'))
2220
3017
 
2221
3018
  <td class="attributes">
2222
3019
 
3020
+ &lt;optional><br>
3021
+
2223
3022
 
2224
3023
 
2225
3024
 
@@ -2230,95 +3029,234 @@ console.log(fs.readdirSync('./result'))
2230
3029
 
2231
3030
  <td class="default">
2232
3031
 
3032
+ <code>true</code>
3033
+
2233
3034
  </td>
2234
3035
 
2235
3036
 
2236
- <td class="description last"><p>輸入回測結束秒時間字串</p></td>
3037
+ <td class="description last"><p>輸入是否輸出summary.json布林值,預設true</p></td>
2237
3038
  </tr>
2238
3039
 
2239
3040
 
2240
3041
 
2241
3042
  <tr>
2242
3043
 
2243
- <td class="name"><code>keyOhlc</code></td>
3044
+ <td class="name"><code>writeReport</code></td>
2244
3045
 
2245
3046
 
2246
3047
  <td class="type">
2247
3048
 
2248
3049
 
2249
- <span class="param-type">String</span>
3050
+ <span class="param-type">Boolean</span>
3051
+
3052
+
3053
+
3054
+
3055
+ </td>
2250
3056
 
3057
+
3058
+ <td class="attributes">
3059
+
3060
+ &lt;optional><br>
3061
+
3062
+
3063
+
2251
3064
 
3065
+
3066
+ </td>
3067
+
2252
3068
 
2253
3069
 
3070
+ <td class="default">
3071
+
3072
+ <code>true</code>
3073
+
3074
+ </td>
3075
+
3076
+
3077
+ <td class="description last"><p>輸入是否輸出report.html布林值,預設true</p></td>
3078
+ </tr>
3079
+
3080
+
3081
+ </tbody>
3082
+ </table>
3083
+
2254
3084
  </td>
3085
+ </tr>
3086
+
3087
+
3088
+ </tbody>
3089
+ </table>
3090
+
3091
+
3092
+
3093
+
3094
+
3095
+
3096
+
3097
+
3098
+
3099
+
3100
+
3101
+
3102
+
3103
+
3104
+
3105
+
3106
+ <h5 class="h5-returns">Returns:</h5>
3107
+
3108
+
3109
+ <div class="param-desc">
3110
+ <p>回傳Promise,無resolve值,於fdTest輸出結果檔案</p>
3111
+ </div>
3112
+
3113
+
3114
+
3115
+ <dl class="param-type">
3116
+ <dt>
3117
+ Type
3118
+ </dt>
3119
+ <dd>
3120
+
3121
+ <span class="param-type">Promise</span>
3122
+
3123
+
3124
+
3125
+ </dd>
3126
+ </dl>
3127
+
3128
+
3129
+
3130
+
3131
+
3132
+
3133
+
3134
+
3135
+
3136
+
3137
+ <h4 class="name" id="genKLinesTpSl"><span class="type-signature"></span>genKLinesTpSl<span class="signature">(arrOhlc, opt<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Object}</span></h4>
3138
+
3139
+
3140
+
3141
+
3142
+
3143
+
3144
+ <dl class="details">
3145
+
3146
+ <dt class="tag-description">Description:</dt>
3147
+ <dd class="tag-description"><ul class="dummy"><li><p>計算各K線進場後之止盈止損先觸結果</p>
3148
+ <p>以各根K線收盤價為進場價,往後逐根K線掃描first-touch,long以Low&lt;=進場價*(1-sl)判止損、High&gt;=進場價*(1+tp)判止盈
3149
+ short以High&gt;=進場價*(1+sl)判止損、Low&lt;=進場價*(1-tp)判止盈,同根同時觸發時皆先判止損
3150
+ 末根K線與掃描至序列末仍未觸發者視為未結,win為-1且pnl與hold為NaN</p>
3151
+ <p>Unit Test: <a href="https://github.com/yuda-lyu/w-trade-backtest/blob/master/test/unit-WTradeBacktest.test.mjs">Github</a></p></li></ul></dd>
3152
+
3153
+
3154
+
3155
+ <dt class="tag-source">Source:</dt>
3156
+ <dd class="tag-source"><ul class="dummy"><li>
3157
+ <a href="genKLinesTpSl.mjs.html">genKLinesTpSl.mjs</a>, <a href="genKLinesTpSl.mjs.html#line36">line 36</a>
3158
+ </li></ul></dd>
3159
+
3160
+
3161
+
3162
+
3163
+
3164
+
3165
+
3166
+
3167
+
3168
+
3169
+
3170
+
3171
+
3172
+
3173
+
3174
+
3175
+
3176
+
3177
+
3178
+
3179
+
3180
+
3181
+
3182
+
3183
+
3184
+
3185
+
3186
+
3187
+
3188
+
3189
+
3190
+ </dl>
3191
+
3192
+
3193
+
3194
+
2255
3195
 
2256
-
2257
- <td class="attributes">
2258
-
2259
3196
 
2260
-
2261
3197
 
2262
-
2263
- </td>
2264
-
2265
3198
 
2266
-
2267
- <td class="default">
2268
-
2269
- </td>
2270
-
2271
3199
 
2272
- <td class="description last"><p>輸入K線序列key字串</p></td>
2273
- </tr>
2274
3200
 
3201
+
3202
+ <h5 class="h5-examples">Example</h5>
2275
3203
 
3204
+ <pre class="prettyprint"><code>let arrOhlc = [
3205
+ { time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
3206
+ { time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
3207
+ { time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
3208
+ { time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
3209
+ { time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
3210
+ { time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
3211
+ ]
2276
3212
 
2277
- <tr>
2278
-
2279
- <td class="name"><code>ordersSubmit</code></td>
2280
-
3213
+ let r = genKLinesTpSl(arrOhlc, { tp: 0.05, sl: 0.05, mode: 'long' })
3214
+ console.log(Array.from(r.win))
3215
+ // => [ 1, 0, 0, -1, 1, -1 ]
3216
+ console.log(Array.from(r.hold))
3217
+ // => [ 1, 2, 1, NaN, 1, NaN ]
3218
+ console.log(Array.from(r.pnl))
3219
+ // => [ 0.05, -0.05, -0.05, NaN, 0.05, NaN ]</code></pre>
2281
3220
 
2282
- <td class="type">
2283
-
2284
-
2285
- <span class="param-type">Array</span>
2286
3221
 
2287
3222
 
2288
3223
 
2289
-
2290
- </td>
3224
+ <h5 class="h5-parameters">Parameters:</h5>
3225
+
2291
3226
 
2292
-
2293
- <td class="attributes">
2294
-
3227
+ <table class="params">
3228
+ <thead>
3229
+ <tr>
3230
+
3231
+ <th>Name</th>
3232
+
2295
3233
 
2296
-
3234
+ <th>Type</th>
2297
3235
 
2298
-
2299
- </td>
2300
-
3236
+
3237
+ <th>Attributes</th>
3238
+
2301
3239
 
2302
-
2303
- <td class="default">
2304
-
2305
- </td>
2306
-
3240
+
3241
+ <th>Default</th>
3242
+
2307
3243
 
2308
- <td class="description last"><p>輸入下單陣列(格式同calcOrders之orders)</p></td>
2309
- </tr>
3244
+ <th class="last">Description</th>
3245
+ </tr>
3246
+ </thead>
2310
3247
 
3248
+ <tbody>
2311
3249
 
2312
3250
 
2313
3251
  <tr>
2314
3252
 
2315
- <td class="name"><code>fdTest</code></td>
3253
+ <td class="name"><code>arrOhlc</code></td>
2316
3254
 
2317
3255
 
2318
3256
  <td class="type">
2319
3257
 
2320
3258
 
2321
- <span class="param-type">String</span>
3259
+ <span class="param-type">Array</span>
2322
3260
 
2323
3261
 
2324
3262
 
@@ -2341,7 +3279,7 @@ console.log(fs.readdirSync('./result'))
2341
3279
  </td>
2342
3280
 
2343
3281
 
2344
- <td class="description last"><p>輸入輸出結果資料夾字串</p></td>
3282
+ <td class="description last"><p>輸入K線陣列,各元素需含time(秒時間字串)、Close、High、Low欄位,且依時間由小至大排序</p></td>
2345
3283
  </tr>
2346
3284
 
2347
3285
 
@@ -2411,13 +3349,13 @@ console.log(fs.readdirSync('./result'))
2411
3349
 
2412
3350
  <tr>
2413
3351
 
2414
- <td class="name"><code>writeOrders</code></td>
3352
+ <td class="name"><code>tp</code></td>
2415
3353
 
2416
3354
 
2417
3355
  <td class="type">
2418
3356
 
2419
3357
 
2420
- <span class="param-type">Boolean</span>
3358
+ <span class="param-type">Number</span>
2421
3359
 
2422
3360
 
2423
3361
 
@@ -2427,8 +3365,6 @@ console.log(fs.readdirSync('./result'))
2427
3365
 
2428
3366
  <td class="attributes">
2429
3367
 
2430
- &lt;optional><br>
2431
-
2432
3368
 
2433
3369
 
2434
3370
 
@@ -2439,25 +3375,23 @@ console.log(fs.readdirSync('./result'))
2439
3375
 
2440
3376
  <td class="default">
2441
3377
 
2442
- <code>true</code>
2443
-
2444
3378
  </td>
2445
3379
 
2446
3380
 
2447
- <td class="description last"><p>輸入是否輸出orders.json布林值,預設true</p></td>
3381
+ <td class="description last"><p>輸入止盈比例正數,如0.05代表5%</p></td>
2448
3382
  </tr>
2449
3383
 
2450
3384
 
2451
3385
 
2452
3386
  <tr>
2453
3387
 
2454
- <td class="name"><code>writeSummary</code></td>
3388
+ <td class="name"><code>sl</code></td>
2455
3389
 
2456
3390
 
2457
3391
  <td class="type">
2458
3392
 
2459
3393
 
2460
- <span class="param-type">Boolean</span>
3394
+ <span class="param-type">Number</span>
2461
3395
 
2462
3396
 
2463
3397
 
@@ -2467,8 +3401,6 @@ console.log(fs.readdirSync('./result'))
2467
3401
 
2468
3402
  <td class="attributes">
2469
3403
 
2470
- &lt;optional><br>
2471
-
2472
3404
 
2473
3405
 
2474
3406
 
@@ -2479,25 +3411,23 @@ console.log(fs.readdirSync('./result'))
2479
3411
 
2480
3412
  <td class="default">
2481
3413
 
2482
- <code>true</code>
2483
-
2484
3414
  </td>
2485
3415
 
2486
3416
 
2487
- <td class="description last"><p>輸入是否輸出summary.json布林值,預設true</p></td>
3417
+ <td class="description last"><p>輸入止損比例正數,如0.05代表5%</p></td>
2488
3418
  </tr>
2489
3419
 
2490
3420
 
2491
3421
 
2492
3422
  <tr>
2493
3423
 
2494
- <td class="name"><code>writeReport</code></td>
3424
+ <td class="name"><code>mode</code></td>
2495
3425
 
2496
3426
 
2497
3427
  <td class="type">
2498
3428
 
2499
3429
 
2500
- <span class="param-type">Boolean</span>
3430
+ <span class="param-type">String</span>
2501
3431
 
2502
3432
 
2503
3433
 
@@ -2519,12 +3449,12 @@ console.log(fs.readdirSync('./result'))
2519
3449
 
2520
3450
  <td class="default">
2521
3451
 
2522
- <code>true</code>
3452
+ <code>'long'</code>
2523
3453
 
2524
3454
  </td>
2525
3455
 
2526
3456
 
2527
- <td class="description last"><p>輸入是否輸出report.html布林值,預設true</p></td>
3457
+ <td class="description last"><p>輸入交易方向字串,可為'long'或'short',預設'long'</p></td>
2528
3458
  </tr>
2529
3459
 
2530
3460
 
@@ -2557,7 +3487,7 @@ console.log(fs.readdirSync('./result'))
2557
3487
 
2558
3488
 
2559
3489
  <div class="param-desc">
2560
- <p>回傳Promise,無resolve值,於fdTest輸出結果檔案</p>
3490
+ <p>回傳物件,內含time(時間字串陣列)、pnl(Float64Array,止盈為tp、止損為-sl、未結為NaN)、win(Int8Array,1為止盈先觸、0為止損先觸、-1為未結)、hold(Float64Array,出場K線與進場K線之位移根數,未結為NaN)欄位,各陣列長度同arrOhlc且index對應</p>
2561
3491
  </div>
2562
3492
 
2563
3493
 
@@ -2568,7 +3498,7 @@ console.log(fs.readdirSync('./result'))
2568
3498
  </dt>
2569
3499
  <dd>
2570
3500
 
2571
- <span class="param-type">Promise</span>
3501
+ <span class="param-type">Object</span>
2572
3502
 
2573
3503
 
2574
3504
 
@@ -2604,7 +3534,7 @@ fpOrders非有效字串或非檔案、內容非有效陣列時throw</p>
2604
3534
 
2605
3535
  <dt class="tag-source">Source:</dt>
2606
3536
  <dd class="tag-source"><ul class="dummy"><li>
2607
- <a href="genReport.mjs.html">genReport.mjs</a>, <a href="genReport.mjs.html#line61">line 61</a>
3537
+ <a href="genReport.mjs.html">genReport.mjs</a>, <a href="genReport.mjs.html#line68">line 68</a>
2608
3538
  </li></ul></dd>
2609
3539
 
2610
3540
 
@@ -3305,6 +4235,185 @@ genReportCore({ name: '示範策略', orders: rr.orders, summary: rr.summary },
3305
4235
 
3306
4236
 
3307
4237
 
4238
+ <h4 class="name" id="loadKLinesTpSl"><span class="type-signature"></span>loadKLinesTpSl<span class="signature">(fpJson)</span><span class="type-signature"> &rarr; {Object}</span></h4>
4239
+
4240
+
4241
+
4242
+
4243
+
4244
+
4245
+ <dl class="details">
4246
+
4247
+ <dt class="tag-description">Description:</dt>
4248
+ <dd class="tag-description"><ul class="dummy"><li><p>載入止盈止損先觸結果快取檔並提供訂單重建</p>
4249
+ <p>讀取buildKLinesTpSl產出之快取json,提供ordersFromBars依指定mode與tpsl組合與進場時間陣列重建訂單陣列
4250
+ 重建訂單之盈虧與累計欄位公式逐欄對齊calcOrders,可直接餵入calcOrdersSummary或calcOrdersSummarySimple
4251
+ fpJson非有效字串或非檔案時throw</p>
4252
+ <p>Unit Test: <a href="https://github.com/yuda-lyu/w-trade-backtest/blob/master/test/unit-WTradeBacktest.test.mjs">Github</a></p></li></ul></dd>
4253
+
4254
+
4255
+
4256
+ <dt class="tag-source">Source:</dt>
4257
+ <dd class="tag-source"><ul class="dummy"><li>
4258
+ <a href="loadKLinesTpSl.mjs.html">loadKLinesTpSl.mjs</a>, <a href="loadKLinesTpSl.mjs.html#line36">line 36</a>
4259
+ </li></ul></dd>
4260
+
4261
+
4262
+
4263
+
4264
+
4265
+
4266
+
4267
+
4268
+
4269
+
4270
+
4271
+
4272
+
4273
+
4274
+
4275
+
4276
+
4277
+
4278
+
4279
+
4280
+
4281
+
4282
+
4283
+
4284
+
4285
+
4286
+
4287
+
4288
+
4289
+
4290
+
4291
+ </dl>
4292
+
4293
+
4294
+
4295
+
4296
+
4297
+
4298
+
4299
+
4300
+
4301
+
4302
+
4303
+ <h5 class="h5-examples">Example</h5>
4304
+
4305
+ <pre class="prettyprint"><code>//fpJson為buildKLinesTpSl產出之快取檔
4306
+ let r = loadKLinesTpSl('./cache/kltpsl.json')
4307
+ console.log(r.meta.nBars)
4308
+ // => 6
4309
+
4310
+ let orders = r.ordersFromBars('long', 5, ['2020-01-01T00:00:00', '2020-01-01T12:00:00'], { uTrade: 100, uIni: 1000 })
4311
+ console.log(orders.map((o) => `${o.timeStart} ${o.timeEnd || 'unsettled'} ${o.modeResult || '-'}`))
4312
+ // => [
4313
+ // '2020-01-01T00:00:00 2020-01-01T04:00:00 profit',
4314
+ // '2020-01-01T12:00:00 unsettled -'
4315
+ // ]
4316
+ console.log(orders[0].priceStart, orders[0].priceEnd, orders[0].uProfitOrLoss, orders[0].uEquity)
4317
+ // => 100 105 4.9 1004.9</code></pre>
4318
+
4319
+
4320
+
4321
+
4322
+ <h5 class="h5-parameters">Parameters:</h5>
4323
+
4324
+
4325
+ <table class="params">
4326
+ <thead>
4327
+ <tr>
4328
+
4329
+ <th>Name</th>
4330
+
4331
+
4332
+ <th>Type</th>
4333
+
4334
+
4335
+
4336
+
4337
+
4338
+ <th class="last">Description</th>
4339
+ </tr>
4340
+ </thead>
4341
+
4342
+ <tbody>
4343
+
4344
+
4345
+ <tr>
4346
+
4347
+ <td class="name"><code>fpJson</code></td>
4348
+
4349
+
4350
+ <td class="type">
4351
+
4352
+
4353
+ <span class="param-type">String</span>
4354
+
4355
+
4356
+
4357
+
4358
+ </td>
4359
+
4360
+
4361
+
4362
+
4363
+
4364
+ <td class="description last"><p>輸入buildKLinesTpSl產出之快取json檔案路徑字串</p></td>
4365
+ </tr>
4366
+
4367
+
4368
+ </tbody>
4369
+ </table>
4370
+
4371
+
4372
+
4373
+
4374
+
4375
+
4376
+
4377
+
4378
+
4379
+
4380
+
4381
+
4382
+
4383
+
4384
+
4385
+
4386
+ <h5 class="h5-returns">Returns:</h5>
4387
+
4388
+
4389
+ <div class="param-desc">
4390
+ <p>回傳物件,內含meta(快取設定物件)、bars(以進場時間為key之結果物件)與ordersFromBars(mode, tpsl, entryTimes, opt)訂單重建函數,函數之opt可給uTrade(每單金額,預設1)、uIni(初始資金,預設1000)、rFee(手續費率,預設0.0005)、maxExitTime(出場時間大於等於此值之單視為未平倉,預設null)與skipSort(呼叫端保證entryTimes已升序時可省排序,預設false),回傳訂單陣列,快取內查無之進場時間會被濾除,未結單各盈虧欄位留空</p>
4391
+ </div>
4392
+
4393
+
4394
+
4395
+ <dl class="param-type">
4396
+ <dt>
4397
+ Type
4398
+ </dt>
4399
+ <dd>
4400
+
4401
+ <span class="param-type">Object</span>
4402
+
4403
+
4404
+
4405
+ </dd>
4406
+ </dl>
4407
+
4408
+
4409
+
4410
+
4411
+
4412
+
4413
+
4414
+
4415
+
4416
+
3308
4417
  <h4 class="name" id="runStrategies"><span class="type-signature type-signature-async">(async) </span>runStrategies<span class="signature">(ott, strategies, funGetSeries, opt<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Promise}</span></h4>
3309
4418
 
3310
4419
 
@@ -4807,7 +5916,7 @@ console.log(r.summary.numTrade, r.summary.rWin, r.summary.uEquityFinal)
4807
5916
  <br class="clear">
4808
5917
 
4809
5918
  <footer>
4810
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Aug 03 2026 10:26:54 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
5919
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Tue Aug 04 2026 23:16:05 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
4811
5920
  </footer>
4812
5921
 
4813
5922
  <script>prettyPrint();</script>