Browse Source

1.1.4:

成交量球改用视阈内(合并后的规则也一样)的交易量的中位数
skyffire 1 year ago
parent
commit
485474ff91
3 changed files with 39 additions and 6 deletions
  1. 1 1
      example/package.json
  2. 7 4
      src/index.js
  3. 31 1
      src/utils.js

+ 1 - 1
example/package.json

@@ -1,7 +1,7 @@
 {
   "name": "heatmap",
   "homepage": ".",
-  "version": "1.1.3",
+  "version": "1.1.4",
   "private": true,
   "main": "main.js",
   "scripts": {

+ 7 - 4
src/index.js

@@ -12,6 +12,7 @@ import {
   extractBidVolumes,
   extractMaxTradedVolume,
   extractAvgTradedVolume,
+  extractMedianTradedVolume,
   extractMaxVolume,
   zoomTimeFormat,
   extractMaxAskBidVolume
@@ -312,7 +313,8 @@ export default class StockHeatmap extends React.Component {
     this.updateHeatmapDimensions();
 
     // 2. Draw the bid ask spread heatmap
-    this.clearCanvas(0, 0, this.defaults.hmWidth(), this.defaults.hmHeight(), '#ffffff');
+    this.clearCanvas(this.defaults.borderPadding[3], this.defaults.borderPadding[0],
+      this.defaults.hmWidth(), this.defaults.hmHeight(), this.defaults.clearColor);
     this.drawMainGraph();
 
     // 3. Draw xy Axis
@@ -629,7 +631,8 @@ export default class StockHeatmap extends React.Component {
   drawMainGraph = () => {
     this.drawingContext.save();
     if (this.xScale && this.yScale && this.bidAskScale && this.drawingContext !== null) {
-      const avgTradedVolume = extractAvgTradedVolume(this.data);
+      // const avgTradedVolume = extractAvgTradedVolume(this.data);
+      const medianTradedVolume = extractMedianTradedVolume(this.windowedData);
       const maxBidAskVolume = extractMaxAskBidVolume(this.windowedData);
       const xh2 = this.xScale.bandwidth() * 0.5;
       const yh2 = this.yScale.bandwidth() * 0.5;
@@ -693,7 +696,7 @@ export default class StockHeatmap extends React.Component {
           let trade_color = d3.color("#44c98b").rgb();
           trade_color.opacity = 0.7;
           this.drawingContext.fillStyle = trade_color.toString();
-          const r = 50 - 45 * (2.71 ** (-0.01 * (+marketDepth.lastBuyQty / avgTradedVolume)));
+          const r = 50 - 45 * (2.71 ** (-0.01 * (+marketDepth.lastBuyQty / medianTradedVolume)));
           this.drawingContext.beginPath();
           this.drawingContext.arc(
             this.xScale(ts) + xh2,
@@ -728,7 +731,7 @@ export default class StockHeatmap extends React.Component {
           let trade_color = d3.color("#cc5040").rgb();
           trade_color.opacity = 0.7;
           this.drawingContext.fillStyle = trade_color.toString();
-          const r = 50 - 45 * (2.71 ** (-0.01 * (+marketDepth.lastSellQty / avgTradedVolume)));
+          const r = 50 - 45 * (2.71 ** (-0.01 * (+marketDepth.lastSellQty / medianTradedVolume)));
           this.drawingContext.beginPath();
           this.drawingContext.arc(
             this.xScale(ts) + xh2,

+ 31 - 1
src/utils.js

@@ -85,7 +85,6 @@ export const extractMaxAskBidVolume = (data) => {
   else return 1;
 }
 
-
 export const extractAvgTradedVolume = (data) => {
   let vols = data.map(d => {
     if (d.marketDepth) return (+d.marketDepth.lastSellQty + +d.marketDepth.lastBuyQty) / 2;
@@ -95,6 +94,37 @@ export const extractAvgTradedVolume = (data) => {
   else return 1;
 }
 
+export const extractMedianTradedVolume = (data) => {
+  let vols = data.map(d => {
+    if (d.marketDepth) {
+      return (+d.marketDepth.lastSellQty + +d.marketDepth.lastBuyQty) / 2;
+    } else {
+      return 0;
+    }
+  });
+
+  // 过滤掉为0的值,确保中位数计算不受无效数据影响
+  vols = vols.filter(vol => vol !== 0);
+
+  if (vols.length === 0) {
+    return 0; // 如果没有有效的交易量数据,返回0
+  }
+
+  // 对交易量进行排序
+  vols.sort((a, b) => a - b);
+
+  // 计算中位数
+  const middle = Math.floor(vols.length / 2);
+
+  if (vols.length % 2 === 0) {
+    // 如果是偶数长度,取中间两个数的平均值
+    return (vols[middle - 1] + vols[middle]) / 2;
+  } else {
+    // 如果是奇数长度,取中间的数
+    return vols[middle];
+  }
+};
+
 /**
  * Format zoom scale time
  * @param {number} seconds