Commit b6e994fc authored by “dujiuxin”'s avatar “dujiuxin”

添加项目调研相关业务

parent ae3b32a5
...@@ -96,4 +96,7 @@ public class CommonConfig { ...@@ -96,4 +96,7 @@ public class CommonConfig {
//资管股票统计开关 //资管股票统计开关
@Value("${nacos.config.smartStockPriceTask}") @Value("${nacos.config.smartStockPriceTask}")
private String smartStockPriceTask; private String smartStockPriceTask;
//资管股票统计开关
@Value("${nacos.config.surveyStockPriceTask}")
private String surveyStockPriceTask;
} }
package com.zfxftech.telmarket.common.pojo.dao.survey;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* @Description TODO
* @Author Dell
* @Date 2021/10/26 14:25
*账户和产品关系表
* 示范盘数据
*/
@Data
@TableName(value = "survey_account_product_relation")
public class SurveyAccountProductRelation {
/**
* 唯一标记
*/
@TableId(type = IdType.INPUT)
private Long id;
/**
* 客户id
*/
private Long customerId;
/**
* 产品id
*/
private Long productId;
/**
* 产品名称
*/
private String productName;
/**
* 产品类型
*/
private String productType;
/**
* 删除标记
*/
@TableLogic
@TableField(value = "is_deleted")
private Boolean isDeleted;
/**
* 初始资金
*/
private BigDecimal initialFunding;
/**
* 示范盘资金
*/
private BigDecimal simulatedFunding;
/**
* 实盘资金
*/
private BigDecimal realFunding;
/**
* 虚拟盘id
*/
private Long simulatedMarketId;
/**
* 实盘id
*/
private Long realMarketId;
/**
* 产品生效时间
*/
private Date createdAt;
/**
* 产品到期时间
*/
private Date expiredAt;
/**
* 状态 true 正常 false 到期
*/
private Integer status;
/**
* 是否问题
*/
private Boolean isProblem;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String modifyBy;
/**
* 更新时间
*/
private Date modifyTime;
/**
* 粉丝ID
*/
private Long tpFansId;
/**
* 公众号id
*/
private Integer wid;
/**
* 产品经理
*/
private Long pmUserId;
/**
* 销售Id
*/
private Long salesId;
/**
* 备注
*/
private String remark;
/**
* 示范总资产
*/
private BigDecimal simulatedTotalPrice;
/**
* 示范盈亏比例
*/
private BigDecimal simulatedTotalProfit;
/**
* 示范持仓比
*/
private BigDecimal simulatedProportion;
//跟投联动专用传参字段
@TableField(exist = false)
private String followAccountName;
/**
* 连续止损数
*/
private Integer continuityStopLoss;
private Integer weekBuyNum;
private Integer maxBuyNum;
private Integer stockBuyNum;
/**
* 连续5天周交易次数
* */
private Integer ticketWeekBuyNum;
/**
* 盈利数
* */
private Integer profitNum;
/**
* 委托项目数
* */
private Integer orderTicketNum;
/**
* 示范持仓比
*/
private BigDecimal profitAmount;
/**
* 示范持仓数量
*/
private Integer positionCount;
}
\ No newline at end of file
package com.zfxftech.telmarket.common.pojo.dao.survey;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.Date;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/3 9:29
*/
@Data
@TableName(value = "survey_stock_position")
@NoArgsConstructor
public class SurveyStockPosition {
/**
* 唯一标记
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 客户id
*/
@TableField(value = "customer_id")
private Long customerId;
/**
* 产品id
*/
private Long productId;
/**
* 股票盘id
*/
private Long marketId;
/**
* 股票代码
*/
private String code;
/**
* 股票名称
*/
private String name;
/**
* 成交价格
*/
private BigDecimal cost;
@TableField(value = "rise_down_range")
private BigDecimal riseDownRange;
@TableField(value = "profit_loss_ratio")
private BigDecimal profitLossRatio;
@TableField(value = "stock_position")
private BigDecimal stockPosition;
/**
* 股票数量
*/
private Long count;
/**
* 删除标记
*/
@TableLogic
@TableField(value = "is_deleted")
private boolean isDeleted;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String modifyBy;
/**
* 更新时间
*/
private Date modifyTime;
@TableField(value = "custom_industry")
private String customIndustry;
/**
* 止盈位
*/
@TableField(value = "stop_profit")
private String stopProfit;
@TableField(value = "is_stop_profit")
private String isStopProfit;
/**
* 止损位
*/
@TableField(value = "stop_loss")
private String stopLoss;
@TableField(value = "is_stop_loss")
private String isStopLoss;
@TableField(value = "yday_rise_down_range")
private BigDecimal ydayRiseDownRange;
@TableField(value = "position_day")
private Integer positionDay;
@TableField(value = "stop_loss_price")
private BigDecimal stopLossPrice;
@TableField(value = "sell_price1")
private BigDecimal sellPrice1;
@TableField(value = "sell_price2")
private BigDecimal sellPrice2;
}
\ No newline at end of file
package com.zfxftech.telmarket.common.pojo.vo.survey;
import com.zfxftech.telmarket.common.pojo.vo.smart.SmartStockVO;
import lombok.Data;
import org.apache.commons.lang3.tuple.Pair;
import java.util.List;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/17 15:10
*/
@Data
public class SurveyMarketDetailsVO {
/**
* 姓名
*/
private String name;
/**
* 昵称
*/
private String nickName;
/**
* 投资风格
*/
private String investmentStyle;
/**
* 公司
*/
private String company;
/**
* 账户限制
*/
private String accountLimit;
/**
* 产品名称
*/
private String productName;
/**
* 产品类型
*/
private String productType;
/**
* 产品开始时间
*/
private Long productStartTime;
/**
* 产品结束时间
*/
private Long productEndTime;
/**
* 总价格
*/
private String totalPrice;
/**
* 总股票价值
*/
private String totalStocksPrice;
/**
* 可用资金
*/
private String availableFunding;
/**
* 当前仓位
*/
private String position;
/**
* 交易股票数
*/
private Integer stockCount;
/**
* 盈利股票数
*/
private Integer profitStockCount;
/**
* 持仓信息
*/
List<SmartStockVO> stocksInfo;
/**
* 行业占比
*/
List<Pair<String, String>> industryProportion;
/**
* 产品类型(中文)
*/
private String productTypeDesc;
/**
* 总盈亏比例
*/
private String totalProfitRate;
/**
* 总盈亏
*/
private String totalProfit;
/**
* 产品经理
*/
private String pmUserName;
/**
* 销售关系名称
*/
private String teamRelationNames;
/**
* 是否问题客户 1=问题客户
*/
private String isProblem;
}
package com.zfxftech.telmarket.mapper.business.survey;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyAccountProductRelation;
import org.springframework.stereotype.Repository;
/**
* 账户和产品关联信息表
*
* @author jianghua
* @version 1.0
* @date 2021-08-24 15:55
*/
@Repository
public interface SurveyAccountProductRelationMapper extends BaseMapper<SurveyAccountProductRelation> {
}
\ No newline at end of file
package com.zfxftech.telmarket.mapper.business.survey;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyStockPosition;
import org.springframework.stereotype.Repository;
/**
* 用户股票持仓
*
* @author jianghua
* @version 1.0
* @date 2021-08-24 15:55
*/
@Repository
public interface SurveyStockPositionMapper extends BaseMapper<SurveyStockPosition> {
}
\ No newline at end of file
package com.zfxftech.telmarket.service.business.survey;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyAccountProductRelation;
public interface SurveyAccountProductRelationService extends IService<SurveyAccountProductRelation> {
}
package com.zfxftech.telmarket.service.business.survey;
import com.zfxftech.telmarket.common.pojo.dao.Quote;
import com.zfxftech.telmarket.common.pojo.dao.StocksCode;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyStockPosition;
import org.apache.commons.lang3.tuple.Pair;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
public interface SurveyFinanceCalculateService {
/**
* 计算股价均值
*
* @param totalPrice
* @param count
* @return
*/
BigDecimal calculateAverageStockPrice(BigDecimal totalPrice, Long count);
/**
* 计算股价均值
*
* @param count1 新买入股数
* @param price1 新买入股票成交价
* @param count2 原先总股数
* @param price2 原先股票平均成交价
* @return
*/
BigDecimal calculateAverageStockPrice(Long count1, BigDecimal price1, Long count2, BigDecimal price2);
/**
* 计算总资产(股票+可用资金)
*
* @param availableFund 可用资金
* @param stockPositions 股票持仓
* @param stockCodeAndPriceMapping 股票代码-股票映射关系
* @return
*/
BigDecimal calculateTotalAssets(BigDecimal availableFund, List<SurveyStockPosition> stockPositions, Map<String, Quote> stockCodeAndPriceMapping);
/**
* 计算股票总市值(当前价格)
*
* @param stockPositions
* @param stockCodeAndPriceMapping
* @return
*/
BigDecimal calculateTotalAssets(List<SurveyStockPosition> stockPositions, Map<String, Quote> stockCodeAndPriceMapping);
/**
* 计算股票总市值(成本价格)
*
* @param stockPositions
* @return
*/
BigDecimal calculateTotalAssets(List<SurveyStockPosition> stockPositions);
/**
* 计算可买入股票价格
*
* @param totalFund 资金
* @param price 价格
* @return
*/
Long calculateBuyStockCount(BigDecimal totalFund, BigDecimal price);
/**
* 计算总价
*
* @param count 股数
* @param price 股票价格
* @return
*/
BigDecimal calculateTotalPrice(Long count, BigDecimal price);
/**
* 计算股票站总股票市值的占比
*
* @param totalValue 股票总值
* @param count 股数
* @param price 价格
* @return
*/
BigDecimal calculateIndustryShare(BigDecimal totalValue, Long count, BigDecimal price);
/**
* 计算收益率(盈亏比例)
*
* @param value1 减数
* @param value2 被减数
* @return
*/
BigDecimal calculateProfitRate(BigDecimal value1, BigDecimal value2);
/**
* 计算收益率(盈亏比例)
*
* @param value1 减数
* @param value2 被减数
* @return
*/
BigDecimal calculateProfitRate2(BigDecimal value1, BigDecimal value2);
/**
* 计算单个股票的涨跌幅
* 最新价格
* 收盘价格
* 涨跌幅=(现价-上一个交易日收盘价)/上一个交易日收盘价*100%
* @return
*/
BigDecimal riseDownRange(BigDecimal now, BigDecimal close);
/**
* 计算单个股票的盈亏比例
* 最新价格
* 成本价格
* 盈亏比例=(现价-成本价)/成本价×100%
* @return
*/
BigDecimal profitLossRatio(BigDecimal now, BigDecimal cost);
/**
* 计算收益
*
* @param value1 分子
* @param value2 分母
* @return
*/
BigDecimal calculateProfit(BigDecimal value1, BigDecimal value2);
/**
* @param price 价格
* @param range 范围
* @return
*/
Pair<String, String> calculatePriceRange(String price, String range);
/**
* @param stocksCode 根据股票计算涨跌幅
* @return
*/
Pair<BigDecimal, BigDecimal> calculatePriceLimit(StocksCode stocksCode);
}
package com.zfxftech.telmarket.service.business.survey;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyAccountProductRelation;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyStockPosition;
import com.zfxftech.telmarket.common.pojo.vo.survey.SurveyMarketDetailsVO;
import java.math.BigDecimal;
import java.util.List;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/3 9:34
*/
public interface SurveyStockPositionService extends IService<SurveyStockPosition> {
List<SurveyStockPosition> queryStockPositions(Long marketId);
SurveyMarketDetailsVO createMarketDetailsVOTask(List<SurveyStockPosition> stockPositions, BigDecimal funding, SurveyAccountProductRelation accountProductRelation);
}
package com.zfxftech.telmarket.service.impl.business.survey;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyAccountProductRelation;
import com.zfxftech.telmarket.mapper.business.survey.SurveyAccountProductRelationMapper;
import com.zfxftech.telmarket.service.business.survey.SurveyAccountProductRelationService;
import org.springframework.stereotype.Service;
@Service
public class SurveyAccountProductRelationServiceImpl extends ServiceImpl<SurveyAccountProductRelationMapper, SurveyAccountProductRelation> implements SurveyAccountProductRelationService {
}
package com.zfxftech.telmarket.service.impl.business.survey;
import com.zfxf.tools.utils.AssertUtil;
import com.zfxftech.telmarket.common.pojo.dao.Quote;
import com.zfxftech.telmarket.common.pojo.dao.StocksCode;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyStockPosition;
import com.zfxftech.telmarket.common.util.BigDecimalUtil;
import com.zfxftech.telmarket.service.business.survey.SurveyFinanceCalculateService;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.zfxftech.telmarket.common.constant.AdminConstant.CompareTypeEnum.LESS;
import static com.zfxftech.telmarket.common.constant.AdminConstant.NumberEnum.*;
/**
* @Description TODO
* @Author Dell
* @Date 2021/11/10 17:02
* 金融计算类
*/
@Service
public class SurveyFinanceCalculateServiceImpl implements SurveyFinanceCalculateService {
@Override
public BigDecimal calculateAverageStockPrice(BigDecimal totalPrice, Long count) {
return BigDecimalUtil.div(totalPrice, new BigDecimal(count), 4);
}
@Override
public BigDecimal calculateAverageStockPrice(Long count1, BigDecimal price1, Long count2, BigDecimal price2) {
BigDecimal mul1 = BigDecimalUtil.mul(new BigDecimal(count1), price1);
BigDecimal mul2 = BigDecimalUtil.mul(new BigDecimal(count2), price2);
BigDecimal totalCost = BigDecimalUtil.add(mul1, mul2);
BigDecimal totalCount = BigDecimalUtil.add(new BigDecimal(count1), new BigDecimal(count2));
if (BigDecimalUtil.compare(totalCount,new BigDecimal("0"),0)){
return price1;
}
return BigDecimalUtil.div(totalCost, totalCount, 4);
}
@Override
public BigDecimal calculateTotalAssets(BigDecimal availableFund, List<SurveyStockPosition> stockPositions, Map<String, Quote> stockCodeAndQuoteMapping) {
if (CollectionUtils.isEmpty(stockPositions)) {
return availableFund;
}
BigDecimal totalStock = calculateTotalAssets(stockPositions, stockCodeAndQuoteMapping);
BigDecimal totalAssets = BigDecimalUtil.add(availableFund, totalStock);
return totalAssets;
}
@Override
public BigDecimal calculateTotalAssets(List<SurveyStockPosition> stockPositions, Map<String, Quote> stockCodeAndPriceMapping) {
BigDecimal totalAssets = new BigDecimal(ZERO.getCode());
for (SurveyStockPosition temStockPosition : stockPositions) {
Long count = temStockPosition.getCount();
String code = temStockPosition.getCode();
Quote quote = stockCodeAndPriceMapping.get(code);
totalAssets = BigDecimalUtil.add(BigDecimalUtil.mul(String.valueOf(count), quote.getNow().toString()), totalAssets);
}
return totalAssets;
}
@Override
public BigDecimal calculateTotalAssets(List<SurveyStockPosition> stockPositions) {
BigDecimal totalAssets = new BigDecimal(ZERO.getCode());
for (SurveyStockPosition stockPosition : stockPositions) {
Long count = stockPosition.getCount();
BigDecimal cost = stockPosition.getCost();
totalAssets = BigDecimalUtil.add(BigDecimalUtil.mul(new BigDecimal(count), cost), totalAssets);
}
return totalAssets;
}
@Override
public Long calculateBuyStockCount(BigDecimal totalFund, BigDecimal price) {
BigDecimal total = BigDecimalUtil.div(totalFund, price, ZERO.getCode());
if (BigDecimalUtil.compare(total, new BigDecimal(HUNDRED.getCode().toString()), LESS.getCode())) {
return 0L;
}
total = BigDecimalUtil.roundToHundreds(total);
//除以100
return total.longValue();
}
@Override
public BigDecimal calculateTotalPrice(Long count, BigDecimal price) {
return BigDecimalUtil.mul(new BigDecimal(count), price);
}
@Override
public BigDecimal calculateIndustryShare(BigDecimal totalValue, Long count, BigDecimal price) {
//计算股票市值
BigDecimal value = BigDecimalUtil.mul(new BigDecimal(count), price);
return BigDecimalUtil.div(value, totalValue);
}
@Override
public BigDecimal calculateProfitRate(BigDecimal value1, BigDecimal value2) {
if (Objects.equals(value1, value2)) {
return new BigDecimal(ZERO.getCode());
}
BigDecimal value = BigDecimalUtil.div(value1, value2);
return BigDecimalUtil.sub(value.toString(), ONE.getCode().toString());
}
@Override
public BigDecimal calculateProfitRate2(BigDecimal value1, BigDecimal value2) {
if (Objects.equals(value1, value2)) {
return new BigDecimal(ZERO.getCode());
}
BigDecimal profitRate = BigDecimalUtil.div(
BigDecimalUtil.sub(
value1,
value2
),
value2);
return profitRate;
}
@Override
public BigDecimal riseDownRange(BigDecimal now, BigDecimal close) {
return BigDecimalUtil.div(BigDecimalUtil.sub(now, close),close);
}
@Override
public BigDecimal profitLossRatio(BigDecimal now, BigDecimal cost) {
return BigDecimalUtil.div(BigDecimalUtil.sub(now, cost),cost);
}
@Override
public BigDecimal calculateProfit(BigDecimal value1, BigDecimal value2) {
return BigDecimalUtil.sub(value1, value2);
}
@Override
public Pair<String, String> calculatePriceRange(String price, String range) {
BigDecimal upperLimit = BigDecimalUtil.mul(price, BigDecimalUtil.add("1", range).toString());
BigDecimal lowerLimit = BigDecimalUtil.mul(price, BigDecimalUtil.sub("1", range).toString());
ImmutablePair<String, String> rangePair = new ImmutablePair(BigDecimalUtil.keepDecimal(lowerLimit).toPlainString(), BigDecimalUtil.keepDecimal(upperLimit).toPlainString());
return rangePair;
}
@Override
public Pair<BigDecimal, BigDecimal> calculatePriceLimit(StocksCode stocksCode) {
//300 688 浮动20%
String code = stocksCode.getSymbol();
BigDecimal up;
BigDecimal low;
if (stocksCode.getName().contains("ST") || stocksCode.getName().contains("st")) {
low = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("0.95"));
up = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("1.05"));
} else if (code.startsWith("3") || code.startsWith("68")) {
low = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("0.8"));
up = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("1.2"));
} else {
//其他 浮动10%
low = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("0.9"));
up = BigDecimalUtil.mul(stocksCode.getRecentClosingPrice(), new BigDecimal("1.1"));
}
Pair<BigDecimal, BigDecimal> pair = new ImmutablePair(BigDecimalUtil.keepDecimal(low), BigDecimalUtil.keepDecimal(up));
return pair;
}
}
package com.zfxftech.telmarket.service.impl.business.survey;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zfxftech.telmarket.common.pojo.dao.Quote;
import com.zfxftech.telmarket.common.pojo.dao.smart.SmartStockPosition;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyAccountProductRelation;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyStockPosition;
import com.zfxftech.telmarket.common.pojo.vo.smart.SmartMarketDetailsVO;
import com.zfxftech.telmarket.common.pojo.vo.survey.SurveyMarketDetailsVO;
import com.zfxftech.telmarket.common.util.BigDecimalUtil;
import com.zfxftech.telmarket.mapper.business.survey.SurveyStockPositionMapper;
import com.zfxftech.telmarket.service.business.StockCodeService;
import com.zfxftech.telmarket.service.business.survey.SurveyFinanceCalculateService;
import com.zfxftech.telmarket.service.business.survey.SurveyStockPositionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @version 1.0
* @Author: hxq
* @Date: 2021/9/16 13:49
*/
@Service
@Slf4j
public class SurveyStockPositionServiceImpl extends ServiceImpl<SurveyStockPositionMapper, SurveyStockPosition> implements SurveyStockPositionService {
@Autowired
private StockCodeService stockCodeService;
@Autowired
private SurveyFinanceCalculateService surveyFinanceCalculateService;
@Override
public List<SurveyStockPosition> queryStockPositions(Long marketId) {
QueryWrapper<SurveyStockPosition> queryWrapper = new QueryWrapper();
queryWrapper.eq("market_id", marketId);
List<SurveyStockPosition> stockPositions = list(queryWrapper);
return stockPositions;
}
@Override
public SurveyMarketDetailsVO createMarketDetailsVOTask(List<SurveyStockPosition> stockPositions, BigDecimal funding, SurveyAccountProductRelation accountProductRelation) {
SurveyMarketDetailsVO marketDetailsVO = new SurveyMarketDetailsVO();
List<String> codes = stockPositions.stream().map(SurveyStockPosition::getCode).collect(Collectors.toList());
//批量获取股票当前价格
Map<String, Quote> codeAndPriceMapping = stockCodeService.batchQueryStockPrice(codes);
//计算股票总市值(当前)
BigDecimal stocksTotalPrice = surveyFinanceCalculateService.calculateTotalAssets(stockPositions, codeAndPriceMapping);
//计算总值
BigDecimal totalPrice = BigDecimalUtil.add(funding, stocksTotalPrice);
//计算仓位
BigDecimal position = BigDecimalUtil.div(stocksTotalPrice, totalPrice);
//盈亏比例
BigDecimal totalProfitRate = surveyFinanceCalculateService.calculateProfitRate(totalPrice, accountProductRelation.getInitialFunding());
//总盈亏(股票当前市值和成本总值的差值)
BigDecimal totalProfit = surveyFinanceCalculateService.calculateProfit(totalPrice, accountProductRelation.getInitialFunding());
marketDetailsVO.setPosition(position.toPlainString());
marketDetailsVO.setAvailableFunding(funding.toPlainString());
marketDetailsVO.setTotalPrice(totalPrice.toPlainString());
marketDetailsVO.setTotalProfit(totalProfit.toPlainString());
marketDetailsVO.setTotalProfitRate(totalProfitRate.toPlainString());
return marketDetailsVO;
}
}
package com.zfxftech.telmarket.task.followAccount;
import com.zfxftech.telmarket.common.config.CommonConfig;
import com.zfxftech.telmarket.common.pojo.dao.MemberBase;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyAccountProductRelation;
import com.zfxftech.telmarket.common.pojo.dao.survey.SurveyStockPosition;
import com.zfxftech.telmarket.common.pojo.vo.survey.SurveyMarketDetailsVO;
import com.zfxftech.telmarket.common.util.DateUtil;
import com.zfxftech.telmarket.common.util.OptionalUtil;
import com.zfxftech.telmarket.service.business.UsMemberBaseService;
import com.zfxftech.telmarket.service.business.survey.SurveyAccountProductRelationService;
import com.zfxftech.telmarket.service.business.survey.SurveyStockPositionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;
import static com.zfxftech.telmarket.common.constant.AdminConstant.MarketTypeEnum.REAL;
import static com.zfxftech.telmarket.common.constant.AdminConstant.MarketTypeEnum.SIMULATED;
/**
* Create time: 2022/1/26
*/
@Slf4j
@Component
@Order(value = 1)
/**
* 项目调研计算总市值、股票市值、持仓数量
*/
public class SurveyStockPriceTask implements ApplicationRunner {
@Autowired
private SurveyAccountProductRelationService surveyAccountProductRelationService;
@Autowired
private SurveyStockPositionService surveyStockPositionService;
@Autowired
private CommonConfig commonConfig;
@Autowired
private UsMemberBaseService memberBaseService;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info("项目调研计算股票统计日志开始", commonConfig.getSurveyStockPriceTask());
//log.info("项目调研计算股票统计日志开始配置更新开关状态:" + commonConfig.getStockPriceTask());
if (commonConfig.getSurveyStockPriceTask() != null && commonConfig.getSurveyStockPriceTask().equals("run")) {
// if (true) {
//分页查询异动配置列表
ExecutorService surveyExecutorService = Executors.newSingleThreadExecutor();
ExecutorService executorServiceSurvey = Executors.newFixedThreadPool(100);
CompletableFuture.runAsync(() -> {
while (true) {
if (DateUtil.isTradeDayForChangeRemind()&& commonConfig.getStockPriceTask().equals("run")) {
// if (true) {
AtomicReference<Integer> pageNo = new AtomicReference<>(1);
Integer pageSize = 50;
Date startTime = new Date();
List<CompletableFuture<String>> futureList = new ArrayList<>();
List<SurveyAccountProductRelation> accountProductRelations = surveyAccountProductRelationService.list();
if (!ObjectUtils.isEmpty(accountProductRelations) && accountProductRelations.size() > 0) {
log.info("项目调研计算股票统计数据大小:{}", accountProductRelations.size());
Integer pageTOtl = accountProductRelations.size() % pageSize == 0 ? accountProductRelations.size() / pageSize : accountProductRelations.size() / pageSize + 1;
for (Integer i = 0; i < pageTOtl; i++) {
List<SurveyAccountProductRelation> accountProductRelationList = this.page(accountProductRelations, pageNo.get(), pageSize);
CompletableFuture cf = CompletableFuture.supplyAsync(() -> {
List<SurveyAccountProductRelation> productRelations = new ArrayList<>();
for (SurveyAccountProductRelation accountProductRelation : accountProductRelationList) {
SurveyAccountProductRelation surveyAccountProductRelation = this.AccountProductRelationTask(accountProductRelation);
if (!ObjectUtils.isEmpty(surveyAccountProductRelation) && !ObjectUtils.isEmpty(surveyAccountProductRelation.getId())) {
productRelations.add(surveyAccountProductRelation);
}
}
surveyAccountProductRelationService.updateBatchById(productRelations);
return " ";
}, executorServiceSurvey).handle((result, ex) -> {
if (null != ex) {
log.error("项目调研错误消息:{}", ex);
return 0;
} else {
return result;
}
});
futureList.add(cf);
pageNo.set(pageNo.get() + 1);
}
}
try {
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0]));
combinedFuture.get();
log.info("持仓统计--------主线程开始阻塞,消息发送完成--------");
log.info("项目调研持仓统计,本次共计算" + (ObjectUtils.isEmpty(accountProductRelations) == true ? 0 : accountProductRelations.size()) + "持仓统计。耗时" + DateUtil.calculateTimeGapSecond(startTime, new Date()) + "秒");
} catch (Exception e) {
log.error("持仓统计错误信息:{}", e);
e.printStackTrace();
}
try {
Thread.sleep(600000);
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
Thread.sleep(1200000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, surveyExecutorService);
}
}
public List<SurveyAccountProductRelation> page(List<SurveyAccountProductRelation> list, Integer pageNo, Integer pageSize) {
if (CollectionUtils.isEmpty(list)) {
return list;
}
List<SurveyAccountProductRelation> resultList = new ArrayList();
// 所有dataList数据中的第几条
int currIdx = pageNo > 1 ? (pageNo - 1) * pageSize : 0;
for (int i = 0; i < pageSize && i < list.size() - currIdx; i++) {
resultList.add(list.get(currIdx + i));
}
return resultList;
}
//项目调研
public SurveyAccountProductRelation AccountProductRelationTask(SurveyAccountProductRelation accountProductRelation) {
SurveyAccountProductRelation surveyAccountProductRelation = new SurveyAccountProductRelation();
try {
String type = SIMULATED.getCode();
OptionalUtil.checkNull(accountProductRelation, "当前用户产品关系不存在");
//查询客户信息
Long customerId = accountProductRelation.getCustomerId();
MemberBase memberBase = memberBaseService.queryUsMemberBaseById(customerId);
Long marketId = accountProductRelation.getSimulatedMarketId();
OptionalUtil.checkNull(memberBase, "查询用户数据不存在");
//查询持仓信息
BigDecimal funding = null;
//获取可用资金
if (REAL.getCode().equals(type)) {
funding = accountProductRelation.getRealFunding();
}
if (SIMULATED.getCode().equals(type)) {
funding = accountProductRelation.getSimulatedFunding();
}
//获取所有买入过的股票
List<SurveyStockPosition> stockPositions = surveyStockPositionService.queryStockPositions(marketId);
//汇总数据
SurveyMarketDetailsVO marketDetailsVO = surveyStockPositionService.createMarketDetailsVOTask(stockPositions, funding, accountProductRelation);
//示范盈亏比例
surveyAccountProductRelation.setId(accountProductRelation.getId());
if (!ObjectUtils.isEmpty(marketDetailsVO.getTotalProfitRate())) {
surveyAccountProductRelation.setSimulatedTotalProfit(new BigDecimal(marketDetailsVO.getTotalProfitRate()));
}
if (!ObjectUtils.isEmpty(marketDetailsVO.getTotalPrice())) {
//示范盘总资产
surveyAccountProductRelation.setSimulatedTotalPrice(new BigDecimal(marketDetailsVO.getTotalPrice()));
}
if (!ObjectUtils.isEmpty(marketDetailsVO.getPosition())) {
//示范持仓比
surveyAccountProductRelation.setSimulatedProportion(new BigDecimal(marketDetailsVO.getPosition()));
}
//示范盘持仓数量
surveyAccountProductRelation.setPositionCount(ObjectUtils.isEmpty(stockPositions.size()) ? 0 : stockPositions.size());
if (!ObjectUtils.isEmpty(marketDetailsVO.getTotalProfit())) {
//示范盘盈亏金额
surveyAccountProductRelation.setProfitAmount(new BigDecimal(marketDetailsVO.getTotalProfit()));
}
} catch (Exception e) {
log.error("更新数据错误:{}", e);
}
return surveyAccountProductRelation;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment