quan-k

描述:当前是关于Echarts图表中的 折线图 示例。
 
            // -10% ~ 10% 随机数
const rnd = () => 0.2 * Math.random() - 0.1;
// 随机漫步
const randomWalk = (count) => {
  const ps = [1];
  for (let i = 1; i < count; i++) {
    ps[i] = Number((ps[i - 1] * (1 + rnd())).toFixed(2));
  }
  return ps;
};

const prices = randomWalk(11);

// 交易次数不限制
const profit = (prices, kmax) => {
  console.log('start======================>');
  if (!prices || !prices.length) {
    return [0, 0];
  }
  const dp0 = [];
  const dp1 = [];
  for (let i = 0; i < prices.length; i++) {
    const p = prices[i];
    dp0[i] = [];
    dp1[i] = [];
    for (let k = kmax; k >= 1; k--) {
      if (i === 0) {
          dp0[i][k] = 0;
          dp1[i][k] = -p;
          continue;
      }
      if (dp1[i -1][k] + p > dp0[i-1][k]) {
          console.log('sell======>',i, k, p);
          dp0[i][k] = dp1[i -1][k] + p;
      } else {
          dp0[i][k] = dp0[i-1][k];
      }
      if (dp0[i-1][k-1] - p > dp1[i-1][k]) {
          console.log('buy======>', i, k, p);
          dp1[i][k] = dp0[i-1][k-1] - p;
      } else {
          dp1[i][k] = dp1[i-1][k];
      }
    }
  }
  
  console.log('vvv', dp0[prices.length - 1][kmax]);

  return [
   [],[]
  ];
};

const [bIdxs, sIdxs] = profit(prices, 2);

// 波峰波谷
const findValleyPeaks = (prices) => {
    if (!prices.length) {
        return [];
    }

    const tradeList = [];
    const buy = (index) => {
        tradeList.push({
            buyIndex: index,
            buyPrice: prices[index],
            sellIndex: -1,
            sellPrice: -Infinity,
        });
    };
    const sell = (index) => {
        const trade = tradeList[tradeList.length - 1];
        if (trade) {
            trade.sellIndex = index;
            trade.sellPrice = prices[index];
        }
    };

    let prev = prices[0];
    // 0-> 初始趋势不明   -1 -> 熊市   1 -> 牛市
    let trend = 0;
    for (let i = 0; i < prices.length; i++) {
        const p = prices[i];
        const delta = p - prev;
        if (trend <= 0 && delta > 0) {
            buy(i - 1);
            trend = 1;
        }
        if (trend >= 0 && delta < 0) {
            sell(i - 1);
            trend = -1;
        }
        prev = p;
    }
    // 最后一天卖出
    const lastTrade = tradeList[tradeList.length - 1];
    if (lastTrade.sellIndex === -1) {
        lastTrade.sellIndex === prices.length - 1;
        lastTrade.sellPrice === prices[prices.length - 1];
    }
    return tradeList;
};

const mergeTrade = (trade1, trade2) => {
    if (trade2.buyPrice > trade1.buyPrice && trade2.sellPrice > trade1.sellPrice) {
        return {
            buyIndex: trade1.buyIndex,
            buyPrice: trade1.buyPrice,
            sellIndex: trade2.sellIndex,
            sellPrice: trade2.sellPrice,
        };
    } else if ((trade1.sellPrice - trade1.buyPrice) > (trade2.sellPrice - trade2.buyPrice)) {
        return {
            buyIndex: trade1.buyIndex,
            buyPrice: trade1.buyPrice,
            sellIndex: trade1.sellIndex,
            sellPrice: trade1.sellPrice,
        };
    } else {
        return {
            buyIndex: trade2.buyIndex,
            buyPrice: trade2.buyPrice,
            sellIndex: trade2.sellIndex,
            sellPrice: trade2.sellPrice,
        };
    }
};

const profit2 = (prices, kmax) => {
    const tradeList = findValleyPeaks(prices);
    if (kmax >= tradeList.length) {
        return tradeList;
    }
    
};



const data = prices.map((v, index) => [index, v]);
const markPoints = [];

bIdxs.forEach(v => {
  markPoints.push({
    name : '买点',
    coord: [v, data[v][1]],
    symbolOffset: [0, 10],
    itemStyle: {
      color:'red',
    },
   });
});

sIdxs.forEach(v => {
  markPoints.push({
    name : '卖点',
    coord: [v, data[v][1]],
    symbolOffset: [0, -10],
    itemStyle: {
      color:'yellowgreen',
    },
   });
});

option = {
    backgroundColor: '#080b30',
    title: {
        text: 'quan-infinity',
        textStyle: {
          color: '#fff',  
        },
    },
    tooltip: {
        trigger: 'axis',
    },
    grid: {
        left: 64,
        right: 16,
        bottom: 80,
    },
    toolbox: {
        feature: {
            dataZoom: {
                yAxisIndex: 'none'
            },
            restore: {},
            saveAsImage: {}
        }
    },
    xAxis: {
        axisLine: {
            show: true,
            lineStyle: {
                color: 'rgba(255,255,255,0.3)'
            }
        },
        axisTick: {
            show: false,
        },
        splitLine: {
            show: false,
        },
    },
    yAxis: {
        axisLine: {
            show: false,
        },
        axisTick: {
            show: false,
        },
        axisLabel: {
            color: 'rgba(255,255,255,0.3)',
        },
        splitLine: {
            show: true,
            lineStyle: {
                color: 'rgba(255,255,255,0.3)'
            }
        },
    },
    dataZoom: [
        {
            type: 'inside',
            start: 0,
            end: 1000
        },
        {
            start: 0,
            end: 1000,
            handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
            handleSize: '80%',
            handleStyle: {
                color: '#fff',
                shadowBlur: 3,
                shadowColor: 'rgba(0, 0, 0, 0.6)',
                shadowOffsetX: 2,
                shadowOffsetY: 2
            }
        }
    ],
    series: [{
        type: 'line',
        lineStyle: {
            color: "#6c50f3",
        },
        markPoint : {
            symbol: 'circle',
            symbolSize: 10,
            data : markPoints,
        },
        data,
    }],
};