calcOrdersRatio.mjs

import map from 'lodash-es/map.js'
import isestr from 'wsemi/src/isestr.mjs'


/**
 * 計算各已平倉訂單之持倉天數與等效日盈虧比例
 *
 * dayHold以timeStart與timeEnd之日期差+1計算,rProfitOrLossDay為(1+rProfitOrLoss)^(1/dayHold)-1
 * modeResult非有效字串(未平倉)之訂單不計算
 *
 * Unit Test: {@link https://github.com/yuda-lyu/w-trade-backtest/blob/master/test/unit-WTradeBacktest.test.mjs Github}
 * @function
 * @param {Function} ott 輸入時區時間函數,傳入時間字串回傳dayjs時間物件(可用src/ott.mjs或自行以dayjs包裝)
 * @param {Array} orders 輸入已結算訂單陣列,各元素需含modeResult、timeStart、timeEnd、rProfitOrLoss欄位
 * @returns {Array} 回傳附加dayHold與rProfitOrLossDay之訂單陣列
 * @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
 * // }
 *
 */
let calcOrdersRatio = (ott, orders) => {

    //計算各單持倉天數, 盈虧比例, 等效日盈虧比例
    orders = map(orders, (o) => {

        //未平倉訂單不計算
        if (!isestr(o.modeResult)) {
            return o
        }

        //dayHold, 持倉天數
        let ts = ott(o.timeStart)
        let te = ott(o.timeEnd)
        let ds = ts.format('YYYY-MM-DD')
        let de = te.format('YYYY-MM-DD')
        let tcs = ott(ds, 'YYYY-MM-DD')
        let tce = ott(de, 'YYYY-MM-DD')
        let dayHold = tce.diff(tcs, 'day') + 1
        o.dayHold = dayHold
        // console.log('ds', ds, 'de', de, dayHold)

        //rProfitOrLossDay, 等效日盈虧比例(none)
        let rProfitOrLossDay = 0
        if ((1 + o.rProfitOrLoss) >= 0) {
            rProfitOrLossDay = Math.pow((1 + o.rProfitOrLoss), 1 / o.dayHold) - 1
        }
        // let rProfitOrLossDay = Math.pow((1 + o.rProfitOrLoss), 1 / o.dayHold) - 1

        o.rProfitOrLossDay = rProfitOrLossDay
        // console.log('rProfitOrLossDay', rProfitOrLossDay)

        return o
    })
    // console.log('orders', orders[size(orders) - 1], size(orders))

    return orders
}


export default calcOrdersRatio