Methods
(async) calcOrders(arrOhlc, orders, optopt) → {Promise}
- Description:
結算訂單,依K線序列判斷各下單之止盈止損觸發並計算盈虧
各單僅檢查time大於timeStart之K棒,long以Low<=priceStopLoss先判止損、High>=priceTakeProfit判止盈,short以High>=priceStopLoss先判止損、Low<=priceTakeProfit判止盈 long盈虧為uTrade*(priceEnd/priceStart)-uTrade-2uFee,short盈虧為(priceStart-priceEnd)(uTrade/priceStart)-2*uFee 依timeStart排序逐單累計uCumuProfitOrLoss與uEquity(自uIni起算),modeResult為盈虧<0時'loss'否則'profit',未觸發止盈止損者維持原單(未平倉)
Unit Test: Github
- Source:
Example
let arrOhlc = [
{ time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
{ time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
{ time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
{ time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
{ time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
{ time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
]
let orders = [{
mode: 'long',
timeStart: '2020-01-01T00:00:00',
priceStart: 100,
uTrade: 100,
priceTakeProfit: 105,
priceStopLoss: 97,
timeEnd: '',
priceEnd: '',
modeResult: '',
uFee: 0.05,
}]
calcOrders(arrOhlc, orders, { uIni: 1000 })
.then((rs) => {
console.log(rs[0])
// => {
// mode: 'long',
// timeStart: '2020-01-01T00:00:00',
// priceStart: 100,
// uTrade: 100,
// priceTakeProfit: 105,
// priceStopLoss: 97,
// timeEnd: '2020-01-01T04:00:00',
// priceEnd: 105,
// modeResult: 'profit',
// uFee: 0.05,
// uProfitOrLoss: 4.9,
// rProfitOrLoss: 0.049,
// uCumuProfitOrLoss: 4.9,
// rCumuProfitOrLoss: '0.49%',
// uEquity: 1004.9
// }
})
Parameters:
| Name | Type | Attributes | Default | Description | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
arrOhlc |
Array | 輸入K線陣列,各元素需含time、High、Low欄位 |
||||||||||||
orders |
Array | 輸入下單陣列,各元素需含mode('long'或'short')、timeStart、priceStart、uTrade、priceTakeProfit、priceStopLoss、uFee欄位 |
||||||||||||
opt |
Object |
<optional> |
{}
|
輸入設定物件,預設{} Properties
|
Returns:
回傳Promise,resolve為結算後訂單陣列
- Type
- Promise
calcOrdersRatio(ott, orders) → {Array}
- Description:
計算各已平倉訂單之持倉天數與等效日盈虧比例
dayHold以timeStart與timeEnd之日期差+1計算,rProfitOrLossDay為(1+rProfitOrLoss)^(1/dayHold)-1 modeResult非有效字串(未平倉)之訂單不計算
Unit Test: Github
- Source:
Example
let orders = calcOrdersRatio(ott, [{
modeResult: 'profit',
timeStart: '2020-01-01T20:00:00',
timeEnd: '2020-01-03T04:00:00',
rProfitOrLoss: 0.331,
}])
console.log(orders[0])
// => {
// modeResult: 'profit',
// timeStart: '2020-01-01T20:00:00',
// timeEnd: '2020-01-03T04:00:00',
// rProfitOrLoss: 0.331,
// dayHold: 3,
// rProfitOrLossDay: 0.10000000000000009
// }
Parameters:
| Name | Type | Description |
|---|---|---|
ott |
function | 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝) |
orders |
Array | 輸入已結算訂單陣列,各元素需含modeResult、timeStart、timeEnd、rProfitOrLoss欄位 |
Returns:
回傳附加dayHold與rProfitOrLossDay之訂單陣列
- Type
- Array
calcOrdersSummary(ott, uIni, ordersAll, timeOhlcStart, timeOhlcEnd) → {Object}
- Description:
統計全部訂單之回測摘要
統計交易次數、勝率、最大回撤、最大持倉、夏普值、最終權益與各盈虧比例等欄位 訂單需先經calcOrders結算(含uEquity)與calcOrdersRatio計算(含dayHold與rProfitOrLossDay,夏普值計算所需) uIni非正數或timeOhlcStart、timeOhlcEnd非有效字串時throw
Unit Test: Github
- Source:
Example
let arrOhlc = [
{ time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
{ time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
{ time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
{ time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
{ time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
{ time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
]
//ordersSubmit, 4張下單: 前3張分別於後續K棒觸發止盈或止損, 第4張未觸發(未平倉)
let kpDef = { uTrade: 100, timeEnd: '', priceEnd: '', modeResult: '', uFee: 0.05 }
let ordersSubmit = [
{ mode: 'long', timeStart: '2020-01-01T00:00:00', priceStart: 100, priceTakeProfit: 105, priceStopLoss: 97, ...kpDef },
{ mode: 'long', timeStart: '2020-01-01T04:00:00', priceStart: 105, priceTakeProfit: 110.25, priceStopLoss: 101.85, ...kpDef },
{ mode: 'short', timeStart: '2020-01-01T08:00:00', priceStart: 103, priceTakeProfit: 97.85, priceStopLoss: 106.09, ...kpDef },
{ mode: 'long', timeStart: '2020-01-01T16:00:00', priceStart: 93, priceTakeProfit: 105, priceStopLoss: 85, ...kpDef },
]
let orders = await calcOrders(arrOhlc, ordersSubmit, { uIni: 1000 })
orders = calcOrdersRatio(ott, orders)
let summary = calcOrdersSummary(ott, 1000, orders, '2020-01-01T00:00:00', '2020-01-01T20:00:00')
console.log(summary)
// => {
// btDays: 0,
// btYears: '0.0',
// numTrade: 4,
// numTradeFin: 3,
// numTradeUnsettled: 1,
// uTradeAllMax: 200,
// rTradeAllMax: '20.00%',
// numTradeAllMax: 2,
// uDrawdownMax: 3.1000000000000227,
// rDrawdownMax: '0.31%',
// rEquivalentDrawdownMax: '1.51%',
// rSharpe: 7.675814289051032,
// rWin: '66.67%',
// uEquityFinal: 1006.6999999999999,
// uCumuProfitOrLossFinal: 6.700000000000006,
// rCumuProfitOrLossFinal: '0.67%',
// rCumuProfitOrLossFinalNormYear: '0.00%',
// rEquivalentCumuProfitOrLossFinal: '3.35%',
// rEquivalentCumuProfitOrLossFinalNormYear: '0.00%'
// }
Parameters:
| Name | Type | Description |
|---|---|---|
ott |
function | 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝) |
uIni |
Number | 輸入初始資金正數 |
ordersAll |
Array | 輸入已結算訂單陣列 |
timeOhlcStart |
String | 輸入回測起始秒時間字串 |
timeOhlcEnd |
String | 輸入回測結束秒時間字串 |
Returns:
回傳回測摘要物件
- Type
- Object
calcOrdersSummarySimple(ott, uIni, ordersAll, timeOhlcStart, timeOhlcEnd, optopt) → {Object}
- Description:
統計全部訂單之精簡版回測摘要
為calcOrdersSummary之精簡版,只算選股熱路徑所需欄位,純迴圈實作且不需先跑calcOrdersRatio 對應欄位與完整版bit-exact: numTrade、numTradeFin、rWin、uTradeAllMax、rTradeAllMax、uEquityFinal、btDays、btYears、rEquivalentCumuProfitOrLossFinalNormYear 不算drawdown、夏普值與累計曲線
Unit Test: Github
- Source:
Example
let arrOhlc = [
{ time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
{ time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
{ time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
{ time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
{ time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
{ time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
]
//ordersSubmit, 4張下單: 前3張分別於後續K棒觸發止盈或止損, 第4張未觸發(未平倉)
let kpDef = { uTrade: 100, timeEnd: '', priceEnd: '', modeResult: '', uFee: 0.05 }
let ordersSubmit = [
{ mode: 'long', timeStart: '2020-01-01T00:00:00', priceStart: 100, priceTakeProfit: 105, priceStopLoss: 97, ...kpDef },
{ mode: 'long', timeStart: '2020-01-01T04:00:00', priceStart: 105, priceTakeProfit: 110.25, priceStopLoss: 101.85, ...kpDef },
{ mode: 'short', timeStart: '2020-01-01T08:00:00', priceStart: 103, priceTakeProfit: 97.85, priceStopLoss: 106.09, ...kpDef },
{ mode: 'long', timeStart: '2020-01-01T16:00:00', priceStart: 93, priceTakeProfit: 105, priceStopLoss: 85, ...kpDef },
]
let orders = await calcOrders(arrOhlc, ordersSubmit, { uIni: 1000 })
let summary = calcOrdersSummarySimple(ott, 1000, orders, '2020-01-01T00:00:00', '2020-01-01T20:00:00')
console.log(summary)
// => {
// numTrade: 4,
// numTradeFin: 3,
// rWin: '66.67%',
// uTradeAllMax: 200,
// rTradeAllMax: '20.00%',
// uEquityFinal: 1006.6999999999999,
// btDays: 0,
// btYears: '0.0',
// rEquivalentCumuProfitOrLossFinalNormYear: '0.00%',
// timeOhlcStart: '2020-01-01T00:00:00',
// timeOhlcEnd: '2020-01-01T20:00:00'
// }
Parameters:
| Name | Type | Attributes | Default | Description | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ott |
function | 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝) |
||||||||||||
uIni |
Number | 輸入初始資金正數 |
||||||||||||
ordersAll |
Array | 輸入已結算訂單陣列(經calcOrders設定timeStart、timeEnd、uTrade、uEquity、modeResult) |
||||||||||||
timeOhlcStart |
String | 輸入回測起始秒時間字串 |
||||||||||||
timeOhlcEnd |
String | 輸入回測結束秒時間字串 |
||||||||||||
opt |
Object |
<optional> |
{}
|
輸入設定物件,預設{} Properties
|
Returns:
回傳精簡版回測摘要物件
- Type
- Object
(async) calcSummary(ott, uIni, orders, timeOhlcStart, timeOhlcEnd, optopt) → {Promise}
- Description:
基於全部交易單重算累積收益並統計回測摘要
依timeStart排序後重算各已平倉單之uEquity、uCumuProfitOrLoss與rCumuProfitOrLoss(多策略各自結算後合併重算用) 再執行calcOrdersRatio與calcOrdersSummary,並附加timeTest、timeOhlcStart、timeOhlcEnd、uIni欄位 uIni非正數或timeOhlcStart、timeOhlcEnd非有效字串時reject
Unit Test: Github
- Source:
Example
let arrOhlc = [
{ time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
{ time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
{ time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
{ time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
{ time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
{ time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
]
//ordersSubmit, 4張下單: 前3張分別於後續K棒觸發止盈或止損, 第4張未觸發(未平倉)
let kpDef = { uTrade: 100, timeEnd: '', priceEnd: '', modeResult: '', uFee: 0.05 }
let ordersSubmit = [
{ mode: 'long', timeStart: '2020-01-01T00:00:00', priceStart: 100, priceTakeProfit: 105, priceStopLoss: 97, ...kpDef },
{ mode: 'long', timeStart: '2020-01-01T04:00:00', priceStart: 105, priceTakeProfit: 110.25, priceStopLoss: 101.85, ...kpDef },
{ mode: 'short', timeStart: '2020-01-01T08:00:00', priceStart: 103, priceTakeProfit: 97.85, priceStopLoss: 106.09, ...kpDef },
{ mode: 'long', timeStart: '2020-01-01T16:00:00', priceStart: 93, priceTakeProfit: 105, priceStopLoss: 85, ...kpDef },
]
let orders = await calcOrders(arrOhlc, ordersSubmit, { uIni: 1000 })
let summary = await calcSummary(ott, 1000, orders, '2020-01-01T00:00:00', '2020-01-01T20:00:00')
console.log(summary)
// => {
// timeTest: '2026-08-01T22:27:10+08:00', //執行當下時間
// timeOhlcStart: '2020-01-01T00:00:00',
// timeOhlcEnd: '2020-01-01T20:00:00',
// uIni: 1000,
// btDays: 0,
// btYears: '0.0',
// numTrade: 4,
// numTradeFin: 3,
// numTradeUnsettled: 1,
// uTradeAllMax: 200,
// rTradeAllMax: '20.00%',
// numTradeAllMax: 2,
// uDrawdownMax: 3.1000000000000227,
// rDrawdownMax: '0.31%',
// rEquivalentDrawdownMax: '1.51%',
// rSharpe: 7.675814289051032,
// rWin: '66.67%',
// uEquityFinal: 1006.6999999999999,
// uCumuProfitOrLossFinal: 6.700000000000006,
// rCumuProfitOrLossFinal: '0.67%',
// rCumuProfitOrLossFinalNormYear: '0.00%',
// rEquivalentCumuProfitOrLossFinal: '3.35%',
// rEquivalentCumuProfitOrLossFinalNormYear: '0.00%'
// }
Parameters:
| Name | Type | Attributes | Default | Description |
|---|---|---|---|---|
ott |
function | 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝) |
||
uIni |
Number | 輸入初始資金正數 |
||
orders |
Array | 輸入已結算訂單陣列(經calcOrders) |
||
timeOhlcStart |
String | 輸入回測起始秒時間字串 |
||
timeOhlcEnd |
String | 輸入回測結束秒時間字串 |
||
opt |
Object |
<optional> |
{}
|
輸入設定物件,預設{} |
Returns:
回傳Promise,resolve為回測摘要物件
- Type
- Promise
(async) closeAndSummaryOrders(ott, fdOhlc, fdParam, uIni, timeOhlcStart, timeOhlcEnd, keyOhlc, ordersSubmit, fdTest, optopt) → {Promise}
- Description:
結算下單清單並輸出訂單、摘要與報告檔案
以w-data-tdprovide讀取fdOhlc與fdParam資料夾數據,依timeOhlcStart至timeOhlcEnd範圍取keyOhlc之K線序列 經calcOrders結算ordersSubmit與calcSummary統計後,輸出orders.json、summary.json、report.html至fdTest資料夾 fdOhlc或fdParam非資料夾、uIni非正數、timeOhlcStart或timeOhlcEnd非有效字串或非4小時整數倍區間時reject
Unit Test: Github
- Source:
Example
import fs from 'fs'
let arrOhlc = [
{ time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
{ time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
{ time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
{ time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
{ time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
{ time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
]
//建立數據資料夾, fdOhlc放K線序列, fdParam放指標參數序列
fs.mkdirSync('./data-ohlc', { recursive: true })
fs.mkdirSync('./data-param', { recursive: true })
fs.writeFileSync('./data-ohlc/btc.json', JSON.stringify(arrOhlc), 'utf8')
let ordersSubmit = [{
mode: 'long',
timeStart: '2020-01-01T00:00:00',
priceStart: 100,
uTrade: 100,
priceTakeProfit: 105,
priceStopLoss: 97,
timeEnd: '',
priceEnd: '',
modeResult: '',
uFee: 0.05,
}]
await closeAndSummaryOrders(ott, './data-ohlc', './data-param', 1000, '2020-01-01T00:00:00', '2020-01-01T20:00:00', 'btc', ordersSubmit, './result')
console.log(fs.readdirSync('./result'))
// => [ 'orders.json', 'report.html', 'summary.json' ]
Parameters:
| Name | Type | Attributes | Default | Description | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ott |
function | 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝) |
||||||||||||||||||||||
fdOhlc |
String | 輸入儲存K線(ohlc)序列資料夾字串,各序列以 |
||||||||||||||||||||||
fdParam |
String | 輸入儲存指標參數序列資料夾字串 |
||||||||||||||||||||||
uIni |
Number | 輸入初始資金正數 |
||||||||||||||||||||||
timeOhlcStart |
String | 輸入回測起始秒時間字串 |
||||||||||||||||||||||
timeOhlcEnd |
String | 輸入回測結束秒時間字串 |
||||||||||||||||||||||
keyOhlc |
String | 輸入K線序列key字串 |
||||||||||||||||||||||
ordersSubmit |
Array | 輸入下單陣列(格式同calcOrders之orders) |
||||||||||||||||||||||
fdTest |
String | 輸入輸出結果資料夾字串 |
||||||||||||||||||||||
opt |
Object |
<optional> |
{}
|
輸入設定物件,預設{} Properties
|
Returns:
回傳Promise,無resolve值,於fdTest輸出結果檔案
- Type
- Promise
genReport(r, fpOut) → {undefined}
- Description:
產出html回測報告
讀取與本模組同資料夾之模板資產(tmp.html與render*.js),置換{name}、{orders}、{summary}後寫出html 報告內含權益曲線、訂單表格、時間軸與摘要
Unit Test: Github
- Source:
Example
//rr為runStrategies範例之回傳{orders,summary}
genReport({ name: '示範策略', orders: rr.orders, summary: rr.summary }, './report.html')
// => 於'./report.html'寫出html報告
Parameters:
| Name | Type | Description |
|---|---|---|
r |
Object | 輸入報告物件,需含name(報告名稱字串)、orders(訂單陣列)、summary(摘要物件)欄位 |
fpOut |
String | 輸入輸出html檔案路徑字串 |
Returns:
無回傳,於fpOut寫出html報告
- Type
- undefined
(async) runStrategies(ott, strategies, funGetSeries, optopt) → {Promise}
- Description:
執行多策略回測
逐策略呼叫runStrategy(withSummary:false),各單附加策略sid後合併並依timeStart排序 以各策略settings.uIni總和為初始資金呼叫calcSummary統計合併摘要 個別策略執行失敗(如時間點無參數無法下單)時強制略過
Unit Test: Github
- Source:
Example
let arrOhlc = [
{ time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
{ time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
{ time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
{ time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
{ time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
{ time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
]
let arrSig = [
{ time: '2020-01-01T00:00:00', param: 1 },
{ time: '2020-01-01T04:00:00', param: 0 },
{ time: '2020-01-01T08:00:00', param: 1 },
{ time: '2020-01-01T12:00:00', param: 0 },
{ time: '2020-01-01T16:00:00', param: 0 },
{ time: '2020-01-01T20:00:00', param: 0 },
]
let funGetSeries = async (key) => {
if (key === 'btc') {
return arrOhlc
}
if (key === 'sig') {
return arrSig
}
throw new Error(`invalid key[${key}]`)
}
let settings = { uIni: 1000, uTrade: 100, rTakeProfit: 0.05, rStopLoss: 0.03, rFee: 0.0005 }
let strategies = [
{ sid: 's1', mode: 'long', keyOhlc: 'btc', conds: [{ key: 'sig', sym: '>', th: 0.5, opr: 'and' }], settings },
{ sid: 's2', mode: 'short', keyOhlc: 'btc', conds: [{ key: 'sig', sym: '<', th: 0.5, opr: 'and' }], settings },
]
let rr = await runStrategies(ott, strategies, funGetSeries)
console.log(rr.orders.map((o) => `${o.sid} ${o.timeStart} ${o.mode} ${o.modeResult || 'unsettled'}`))
// => [
// 's1 2020-01-01T00:00:00 long profit',
// 's2 2020-01-01T04:00:00 short profit',
// 's1 2020-01-01T08:00:00 long loss',
// 's2 2020-01-01T12:00:00 short loss',
// 's2 2020-01-01T16:00:00 short loss',
// 's2 2020-01-01T20:00:00 short unsettled'
// ]
console.log(rr.summary.uIni, rr.summary.numTrade, rr.summary.rWin)
// => 2000 6 40.00%
Parameters:
| Name | Type | Attributes | Default | Description | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ott |
function | 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝) |
|||||||||||||||||
strategies |
Array | 輸入策略陣列,各元素需含sid與runStrategy之strategy欄位 |
|||||||||||||||||
funGetSeries |
function | 輸入序列查詢async函數,依key回傳時間序列陣列 |
|||||||||||||||||
opt |
Object |
<optional> |
{}
|
輸入設定物件,預設{} Properties
|
Returns:
回傳Promise,resolve為{orders,summary}物件
- Type
- Promise
(async) runStrategy(ott, strategy, funGetSeries, optopt) → {Promise}
- Description:
執行單一策略回測
於各時間點以conds判斷觸發下單(各條件以sym與th比較該key序列之param值,opr為'and'須全真、'or'至少一真) 觸發時以該K棒Close下單,並依settings計算止盈止損價格,再經calcOrders結算與calcOrdersRatio、calcOrdersSummary統計 僅於全部conds序列皆有值之共同時間點判斷觸發 strategy.mode非'long'或'short'、keyOhlc或conds無效、funGetSeries非函數時reject
Unit Test: Github
- Source:
Example
let arrOhlc = [
{ time: '2020-01-01T00:00:00', Open: 100, High: 101, Low: 99, Close: 100 },
{ time: '2020-01-01T04:00:00', Open: 100, High: 106, Low: 100, Close: 105 },
{ time: '2020-01-01T08:00:00', Open: 105, High: 107, Low: 102, Close: 103 },
{ time: '2020-01-01T12:00:00', Open: 103, High: 104, Low: 94, Close: 95 },
{ time: '2020-01-01T16:00:00', Open: 95, High: 98, Low: 92, Close: 93 },
{ time: '2020-01-01T20:00:00', Open: 93, High: 99, Low: 95, Close: 97 },
]
let arrSig = [
{ time: '2020-01-01T00:00:00', param: 1 },
{ time: '2020-01-01T04:00:00', param: 0 },
{ time: '2020-01-01T08:00:00', param: 1 },
{ time: '2020-01-01T12:00:00', param: 0 },
{ time: '2020-01-01T16:00:00', param: 0 },
{ time: '2020-01-01T20:00:00', param: 0 },
]
let funGetSeries = async (key) => {
if (key === 'btc') {
return arrOhlc
}
if (key === 'sig') {
return arrSig
}
throw new Error(`invalid key[${key}]`)
}
let strategy = {
mode: 'long',
keyOhlc: 'btc',
conds: [{ key: 'sig', sym: '>', th: 0.5, opr: 'and' }],
settings: { uIni: 1000, uTrade: 100, rTakeProfit: 0.05, rStopLoss: 0.03, rFee: 0.0005 },
}
let r = await runStrategy(ott, strategy, funGetSeries)
console.log(r.orders.map((o) => `${o.timeStart} ${o.mode} ${o.priceStart}->${o.priceEnd} ${o.modeResult}`))
// => [
// '2020-01-01T00:00:00 long 100->105 profit',
// '2020-01-01T08:00:00 long 103->99.91 loss'
// ]
console.log(r.summary.numTrade, r.summary.rWin, r.summary.uEquityFinal)
// => 2 50.00% 1001.8
Parameters:
| Name | Type | Attributes | Default | Description | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ott |
function | 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝) |
|||||||||||||||||
strategy |
Object | 輸入策略物件,需含mode('long'或'short')、keyOhlc(K線序列key字串)、conds(條件陣列,各元素為{key,sym,th,opr})、settings({uIni,uTrade,rTakeProfit,rStopLoss,rFee})欄位 |
|||||||||||||||||
funGetSeries |
function | 輸入序列查詢async函數,依key回傳時間序列陣列 |
|||||||||||||||||
opt |
Object |
<optional> |
{}
|
輸入設定物件,預設{} Properties
|
Returns:
回傳Promise,resolve為{orders,summary}物件
- Type
- Promise