167 lines
4.0 KiB
Java
167 lines
4.0 KiB
Java
package com.afe.dc.tranlog.service;
|
|||
|
|
|
||
|
|
import com.afe.dc.tranlog.domain.dto.BuySellStrength;
|
||
|
|
import com.afe.dc.tranlog.domain.model.entity.TranRecord;
|
||
|
|
import lombok.extern.slf4j.Slf4j;
|
||
|
|
import org.springframework.stereotype.Service;
|
||
|
|
|
||
|
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 买卖强度逻辑服务
|
||
|
|
* 对应C++的CBuySellStrengthLogic类
|
||
|
|
* 负责计算买卖强度(高/中/低)
|
||
|
|
*/
|
||
|
|
@Slf4j
|
||
|
|
@Service
|
||
|
|
public class BuySellStrengthService {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 是否已更新
|
||
|
|
*/
|
||
|
|
private Boolean updated = false;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 买入成交量
|
||
|
|
*/
|
||
|
|
private Double buyVolume = 0.0;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 卖出成交量
|
||
|
|
*/
|
||
|
|
private Double sellVolume = 0.0;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 中性成交量
|
||
|
|
*/
|
||
|
|
private Double neutralVolume = 0.0;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 读写锁
|
||
|
|
*/
|
||
|
|
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 是否启用
|
||
|
|
*/
|
||
|
|
public static boolean enabled = true;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 更新买卖强度数据
|
||
|
|
* 对应C++的internalUpdate方法
|
||
|
|
*/
|
||
|
|
public void update(TranRecord record) {
|
||
|
|
if (!enabled) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
lock.writeLock().lock();
|
||
|
|
try {
|
||
|
|
if (!isInterestedFlag(record)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Double volume = record.getVolume() != null ? record.getVolume() : 0.0;
|
||
|
|
Byte flag = record.getFlag();
|
||
|
|
|
||
|
|
// 根据flag判断买卖方向
|
||
|
|
if (record.isAsk()) {
|
||
|
|
// 卖盘
|
||
|
|
sellVolume += volume;
|
||
|
|
} else if (record.isBid()) {
|
||
|
|
// 买盘
|
||
|
|
buyVolume += volume;
|
||
|
|
} else {
|
||
|
|
// 中性
|
||
|
|
neutralVolume += volume;
|
||
|
|
}
|
||
|
|
|
||
|
|
updated = true;
|
||
|
|
|
||
|
|
} finally {
|
||
|
|
lock.writeLock().unlock();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 获取买卖强度数据
|
||
|
|
*/
|
||
|
|
public BuySellStrength getData() {
|
||
|
|
lock.readLock().lock();
|
||
|
|
try {
|
||
|
|
// 计算买卖强度
|
||
|
|
// 这里简化处理,实际应该根据价格-成交量分布来计算
|
||
|
|
Float high = calculateHigh();
|
||
|
|
Float mid = calculateMid();
|
||
|
|
Float low = calculateLow();
|
||
|
|
|
||
|
|
return BuySellStrength.builder()
|
||
|
|
.high(high)
|
||
|
|
.mid(mid)
|
||
|
|
.low(low)
|
||
|
|
.build();
|
||
|
|
} finally {
|
||
|
|
lock.readLock().unlock();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 清空数据
|
||
|
|
*/
|
||
|
|
public void drop() {
|
||
|
|
lock.writeLock().lock();
|
||
|
|
try {
|
||
|
|
buyVolume = 0.0;
|
||
|
|
sellVolume = 0.0;
|
||
|
|
neutralVolume = 0.0;
|
||
|
|
updated = false;
|
||
|
|
} finally {
|
||
|
|
lock.writeLock().unlock();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 判断是否为感兴趣的标志
|
||
|
|
*/
|
||
|
|
private boolean isInterestedFlag(TranRecord record) {
|
||
|
|
Byte flag = record.getFlag();
|
||
|
|
return flag != null && (flag == ' ' || flag == 'A' || flag == 'B' || flag == 'Y' || flag == 'U');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 计算高强度
|
||
|
|
*/
|
||
|
|
private Float calculateHigh() {
|
||
|
|
// 简化计算,实际应该根据业务逻辑
|
||
|
|
double total = buyVolume + sellVolume + neutralVolume;
|
||
|
|
if (total == 0) {
|
||
|
|
return 0.0f;
|
||
|
|
}
|
||
|
|
return (float) (buyVolume / total * 100);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 计算中强度
|
||
|
|
*/
|
||
|
|
private Float calculateMid() {
|
||
|
|
// 简化计算
|
||
|
|
double total = buyVolume + sellVolume + neutralVolume;
|
||
|
|
if (total == 0) {
|
||
|
|
return 0.0f;
|
||
|
|
}
|
||
|
|
return (float) (neutralVolume / total * 100);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 计算低强度
|
||
|
|
*/
|
||
|
|
private Float calculateLow() {
|
||
|
|
// 简化计算
|
||
|
|
double total = buyVolume + sellVolume + neutralVolume;
|
||
|
|
if (total == 0) {
|
||
|
|
return 0.0f;
|
||
|
|
}
|
||
|
|
return (float) (sellVolume / total * 100);
|
||
|
|
}
|
||
|
|
}
|