2
0
Преглед на файлове

✨ feat(stock-chart): 更新收益计算方式为答题卡模式

- 修改累计收益为累计收益率,显示格式改为百分比形式
- 调整收益计算逻辑为单日涨幅简单相加的方式
- 更新注释说明计算方式变更
- 优化交易数据处理流程,按日期分组交易记录
- 添加持股状态判断,仅在持股期间计算价格变化收益
yourname преди 6 месеца
родител
ревизия
f89b6c2992

+ 3 - 3
src/client/mobile/components/stock/components/stock-chart/src/components/ProfitDisplay.tsx

@@ -12,11 +12,11 @@ export const ProfitDisplay: React.FC<ProfitDisplayProps> = ({
   
   return (
     <div className="flex justify-between items-center p-4 bg-gray-800 text-white shadow-lg">
-      {/* 累计收益 */}
+      {/* 累计收益率(采用答题卡的计算方式) */}
       <div className="flex items-center space-x-2">
-        <span className="text-gray-400">累计收益</span>
+        <span className="text-gray-400">累计收益</span>
         <span className={`text-xl font-bold ${totalProfit >= 0 ? 'text-red-500' : 'text-green-500'}`}>
-          {totalProfit >= 0 ? '+' : ''}{totalProfit.toFixed(2)}
+          {totalProfit >= 0 ? '+' : ''}{(totalProfit * 100).toFixed(2)}%
         </span>
       </div>
 

+ 46 - 17
src/client/mobile/components/stock/components/stock-chart/src/hooks/useProfitCalculator.ts

@@ -4,11 +4,12 @@ import type { TradeRecord, DailyProfit, ProfitSummary, StockData } from '../type
 export function useProfitCalculator(stockData: StockData[], trades: TradeRecord[]) {
   const [currentDate, setCurrentDate] = useState<string>('');
 
-  // 计算每日收益
+  // 计算每日收益(采用答题卡的计算方式:单日涨幅简单相加)
   const dailyProfits = useMemo(() => {
     const profitMap = new Map<string, DailyProfit>();
     let accumulatedProfit = 0;  // 累计收益
     
+    // 按日期分组交易
     trades.forEach(trade => {
       const date = trade.date;
       if (!profitMap.has(date)) {
@@ -21,29 +22,57 @@ export function useProfitCalculator(stockData: StockData[], trades: TradeRecord[
       
       const dailyProfit = profitMap.get(date)!;
       dailyProfit.trades.push(trade);
-      
-      if (trade.type === 'SELL' && trade.buyPrice !== undefined) {
-        // 本次收益 = (当天收盘价 - 买入收盘价) / 买入收盘价
-        const currentProfit = (trade.price - trade.buyPrice) / trade.buyPrice;
-        // 累计收益 = 之前的累计收益 + 本次收益
-        accumulatedProfit += currentProfit;
-        // 记录当日收益为累计收益
-        dailyProfit.profit = accumulatedProfit;
-      }
     });
     
     return Array.from(profitMap.values());
   }, [trades]);
 
-  // 计算当日行情
+  // 计算当日行情(采用答题卡的计算方式:基于价格变化百分比)
   const profitSummary = useMemo(() => {
-    // 获取累计收益
-    const totalProfit = trades.reduce((sum, trade) => {
-      if (trade.type === 'SELL' && trade.buyPrice !== undefined) {
-        return sum + (trade.price - trade.buyPrice) / trade.buyPrice;
+    // 获取累计收益(单日涨幅简单相加)
+    let totalProfit = 0;
+    
+    // 如果有交易记录,计算基于价格变化的收益
+    if (stockData.length > 1 && trades.length > 0) {
+      // 按日期排序股票数据
+      const sortedStockData = [...stockData].sort((a, b) =>
+        new Date(a.d).getTime() - new Date(b.d).getTime()
+      );
+      
+      // 按日期排序交易记录
+      const sortedTrades = [...trades].sort((a, b) =>
+        new Date(a.date).getTime() - new Date(b.date).getTime()
+      );
+      
+      // 计算每日收益(答题卡方式:基于价格变化百分比)
+      // 这里需要根据用户的买卖决策来计算
+      let isHolding = false; // 是否持股
+      
+      for (let i = 1; i < sortedStockData.length; i++) {
+        const prevDate = sortedStockData[i - 1].d;
+        const currentDate = sortedStockData[i].d;
+        const prevPrice = parseFloat(sortedStockData[i - 1].c);
+        const currentPrice = parseFloat(sortedStockData[i].c);
+        
+        // 检查该日期是否有交易
+        const dateTrades = sortedTrades.filter(trade => trade.date === prevDate);
+        
+        // 处理该日期的交易
+        dateTrades.forEach(trade => {
+          if (trade.type === 'BUY') {
+            isHolding = true;
+          } else if (trade.type === 'SELL') {
+            isHolding = false;
+          }
+        });
+        
+        // 如果持股,计算当日收益(答题卡方式:基于连续两天的价格变化)
+        if (isHolding) {
+          const dailyChange = ((currentPrice - prevPrice) / prevPrice);
+          totalProfit += dailyChange;
+        }
       }
-      return sum;
-    }, 0);
+    }
     
     // 获取当日行情数据
     // 如果没有指定currentDate,则使用最新一天的数据