|
|
@@ -31,12 +31,17 @@ class MexDailyPriceTrendLogic
|
|
|
->get();
|
|
|
|
|
|
if ($transactions->isEmpty()) {
|
|
|
- return null;
|
|
|
+ // 没有成交记录时,使用前一日数据或价格配置数据生成趋势记录
|
|
|
+ return $this->generateTrendFromPreviousOrConfig($date, $itemId, $currencyType);
|
|
|
}
|
|
|
|
|
|
// 计算价格统计
|
|
|
$priceStats = $this->calculatePriceStatistics($transactions);
|
|
|
-
|
|
|
+
|
|
|
+ // 计算买入卖出价格统计
|
|
|
+ $buyPriceStats = $this->calculateBuyPriceStatistics($transactions);
|
|
|
+ $sellPriceStats = $this->calculateSellPriceStatistics($transactions);
|
|
|
+
|
|
|
// 计算交易统计
|
|
|
$tradeStats = $this->calculateTradeStatistics($transactions);
|
|
|
|
|
|
@@ -53,7 +58,7 @@ class MexDailyPriceTrendLogic
|
|
|
'currency_type' => $currencyType,
|
|
|
'trade_date' => $date,
|
|
|
],
|
|
|
- array_merge($priceStats, $tradeStats, $priceChange)
|
|
|
+ array_merge($priceStats, $buyPriceStats, $sellPriceStats, $tradeStats, $priceChange)
|
|
|
);
|
|
|
|
|
|
return MexDailyPriceTrendDto::fromModel($trend);
|
|
|
@@ -261,4 +266,160 @@ class MexDailyPriceTrendLogic
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从前一日数据或价格配置生成趋势记录
|
|
|
+ */
|
|
|
+ private function generateTrendFromPreviousOrConfig(string $date, int $itemId, FUND_CURRENCY_TYPE $currencyType): ?MexDailyPriceTrendDto
|
|
|
+ {
|
|
|
+ // 获取前一日收盘价
|
|
|
+ $previousClosePrice = $this->getPreviousClosePrice($date, $itemId, $currencyType);
|
|
|
+
|
|
|
+ if ($previousClosePrice !== null) {
|
|
|
+ // 使用前一日收盘价作为当日所有价格
|
|
|
+ $priceData = [
|
|
|
+ 'open_price' => $previousClosePrice,
|
|
|
+ 'close_price' => $previousClosePrice,
|
|
|
+ 'high_price' => $previousClosePrice,
|
|
|
+ 'low_price' => $previousClosePrice,
|
|
|
+ 'avg_price' => $previousClosePrice,
|
|
|
+ 'buy_open_price' => $previousClosePrice,
|
|
|
+ 'buy_close_price' => $previousClosePrice,
|
|
|
+ 'buy_high_price' => $previousClosePrice,
|
|
|
+ 'buy_low_price' => $previousClosePrice,
|
|
|
+ 'buy_avg_price' => $previousClosePrice,
|
|
|
+ 'sell_open_price' => $previousClosePrice,
|
|
|
+ 'sell_close_price' => $previousClosePrice,
|
|
|
+ 'sell_high_price' => $previousClosePrice,
|
|
|
+ 'sell_low_price' => $previousClosePrice,
|
|
|
+ 'sell_avg_price' => $previousClosePrice,
|
|
|
+ ];
|
|
|
+ } else {
|
|
|
+ // 使用价格配置数据
|
|
|
+ $priceConfig = \App\Module\Mex\Logic\MexPriceConfigLogic::getItemPriceConfig($itemId);
|
|
|
+ if (!$priceConfig) {
|
|
|
+ return null; // 没有价格配置,无法生成趋势
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用价格配置的中间价作为参考价格
|
|
|
+ $referencePrice = ($priceConfig['min_price'] + $priceConfig['max_price']) / 2;
|
|
|
+
|
|
|
+ $priceData = [
|
|
|
+ 'open_price' => $referencePrice,
|
|
|
+ 'close_price' => $referencePrice,
|
|
|
+ 'high_price' => $referencePrice,
|
|
|
+ 'low_price' => $referencePrice,
|
|
|
+ 'avg_price' => $referencePrice,
|
|
|
+ 'buy_open_price' => $referencePrice,
|
|
|
+ 'buy_close_price' => $referencePrice,
|
|
|
+ 'buy_high_price' => $referencePrice,
|
|
|
+ 'buy_low_price' => $referencePrice,
|
|
|
+ 'buy_avg_price' => $referencePrice,
|
|
|
+ 'sell_open_price' => $referencePrice,
|
|
|
+ 'sell_close_price' => $referencePrice,
|
|
|
+ 'sell_high_price' => $referencePrice,
|
|
|
+ 'sell_low_price' => $referencePrice,
|
|
|
+ 'sell_avg_price' => $referencePrice,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 无成交时的统计数据
|
|
|
+ $statsData = [
|
|
|
+ 'total_volume' => 0,
|
|
|
+ 'total_amount' => 0,
|
|
|
+ 'transaction_count' => 0,
|
|
|
+ 'buy_volume' => 0,
|
|
|
+ 'sell_volume' => 0,
|
|
|
+ 'buy_amount' => 0,
|
|
|
+ 'sell_amount' => 0,
|
|
|
+ 'admin_inject_volume' => 0,
|
|
|
+ 'admin_recycle_volume' => 0,
|
|
|
+ 'admin_inject_amount' => 0,
|
|
|
+ 'admin_recycle_amount' => 0,
|
|
|
+ 'volatility' => 0,
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 计算价格变化
|
|
|
+ $priceChange = $this->calculatePriceChange($priceData['close_price'], $previousClosePrice);
|
|
|
+
|
|
|
+ // 创建或更新趋势记录
|
|
|
+ $trend = MexDailyPriceTrend::updateOrCreate(
|
|
|
+ [
|
|
|
+ 'item_id' => $itemId,
|
|
|
+ 'currency_type' => $currencyType,
|
|
|
+ 'trade_date' => $date,
|
|
|
+ ],
|
|
|
+ array_merge($priceData, $statsData, $priceChange)
|
|
|
+ );
|
|
|
+
|
|
|
+ return MexDailyPriceTrendDto::fromModel($trend);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算买入价格统计
|
|
|
+ */
|
|
|
+ private function calculateBuyPriceStatistics(Collection $transactions): array
|
|
|
+ {
|
|
|
+ // 筛选买入交易
|
|
|
+ $buyTransactions = $transactions->where('transaction_type', 'USER_BUY');
|
|
|
+
|
|
|
+ if ($buyTransactions->isEmpty()) {
|
|
|
+ return [
|
|
|
+ 'buy_open_price' => null,
|
|
|
+ 'buy_close_price' => null,
|
|
|
+ 'buy_high_price' => null,
|
|
|
+ 'buy_low_price' => null,
|
|
|
+ 'buy_avg_price' => null,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $buyPrices = $buyTransactions->pluck('price');
|
|
|
+
|
|
|
+ // 计算买入加权平均价格
|
|
|
+ $buyTotalAmount = $buyTransactions->sum('total_amount');
|
|
|
+ $buyTotalQuantity = $buyTransactions->sum('quantity');
|
|
|
+ $buyAvgPrice = $buyTotalQuantity > 0 ? $buyTotalAmount / $buyTotalQuantity : 0;
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'buy_open_price' => $buyTransactions->first()->price,
|
|
|
+ 'buy_close_price' => $buyTransactions->last()->price,
|
|
|
+ 'buy_high_price' => $buyPrices->max(),
|
|
|
+ 'buy_low_price' => $buyPrices->min(),
|
|
|
+ 'buy_avg_price' => $buyAvgPrice,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算卖出价格统计
|
|
|
+ */
|
|
|
+ private function calculateSellPriceStatistics(Collection $transactions): array
|
|
|
+ {
|
|
|
+ // 筛选卖出交易
|
|
|
+ $sellTransactions = $transactions->where('transaction_type', 'USER_SELL');
|
|
|
+
|
|
|
+ if ($sellTransactions->isEmpty()) {
|
|
|
+ return [
|
|
|
+ 'sell_open_price' => null,
|
|
|
+ 'sell_close_price' => null,
|
|
|
+ 'sell_high_price' => null,
|
|
|
+ 'sell_low_price' => null,
|
|
|
+ 'sell_avg_price' => null,
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $sellPrices = $sellTransactions->pluck('price');
|
|
|
+
|
|
|
+ // 计算卖出加权平均价格
|
|
|
+ $sellTotalAmount = $sellTransactions->sum('total_amount');
|
|
|
+ $sellTotalQuantity = $sellTransactions->sum('quantity');
|
|
|
+ $sellAvgPrice = $sellTotalQuantity > 0 ? $sellTotalAmount / $sellTotalQuantity : 0;
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'sell_open_price' => $sellTransactions->first()->price,
|
|
|
+ 'sell_close_price' => $sellTransactions->last()->price,
|
|
|
+ 'sell_high_price' => $sellPrices->max(),
|
|
|
+ 'sell_low_price' => $sellPrices->min(),
|
|
|
+ 'sell_avg_price' => $sellAvgPrice,
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|