Global

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
Name Type Attributes Default Description
uIni Number <optional>
1000

輸入初始資金數字,預設1000

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
Name Type Attributes Default Description
skipSort Boolean <optional>
false

輸入呼叫端保證ordersAll已依timeStart升序時可跳過排序布林值,預設false

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)序列資料夾字串,各序列以${key}.json儲存

fdParam String

輸入儲存指標參數序列資料夾字串

uIni Number

輸入初始資金正數

timeOhlcStart String

輸入回測起始秒時間字串

timeOhlcEnd String

輸入回測結束秒時間字串

keyOhlc String

輸入K線序列key字串

ordersSubmit Array

輸入下單陣列(格式同calcOrders之orders)

fdTest String

輸入輸出結果資料夾字串

opt Object <optional>
{}

輸入設定物件,預設{}

Properties
Name Type Attributes Default Description
writeOrders Boolean <optional>
true

輸入是否輸出orders.json布林值,預設true

writeSummary Boolean <optional>
true

輸入是否輸出summary.json布林值,預設true

writeReport Boolean <optional>
true

輸入是否輸出report.html布林值,預設true

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
Name Type Attributes Default Description
withCalcOrderProfitOrLoss Boolean <optional>
true

輸入是否經calcOrders結算訂單布林值,預設true

withSummary Boolean <optional>
true

輸入是否計算統計摘要布林值,預設true

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
Name Type Attributes Default Description
withCalcOrderProfitOrLoss Boolean <optional>
true

輸入是否經calcOrders結算訂單布林值,預設true

withSummary Boolean <optional>
true

輸入是否計算統計摘要布林值,預設true

Returns:

回傳Promise,resolve為{orders,summary}物件

Type
Promise