Search in sources :

Example 1 with HoldShares

use of com.mistra.plank.pojo.entity.HoldShares in project plank by MistraR.

the class Barbarossa method sellStock.

/**
 * 减仓或清仓股票
 *
 * @param date 日期
 */
private void sellStock(Date date) {
    List<HoldShares> holdShares = holdSharesMapper.selectList(new QueryWrapper<>());
    if (CollectionUtils.isNotEmpty(holdShares)) {
        for (HoldShares holdShare : holdShares) {
            if (!DateUtils.isSameDay(holdShare.getBuyTime(), date) && holdShare.getBuyTime().getTime() < date.getTime()) {
                Page<DailyRecord> selectPage = dailyRecordMapper.selectPage(new Page<>(1, 25), new QueryWrapper<DailyRecord>().eq("code", holdShare.getCode()).ge("date", DateUtils.addDays(date, -plankConfig.getDeficitMovingAverage() - 9)).le("date", date).orderByDesc("date"));
                // 今日数据明细
                DailyRecord todayRecord = selectPage.getRecords().get(0);
                List<DailyRecord> dailyRecords = selectPage.getRecords().size() >= plankConfig.getDeficitMovingAverage() ? selectPage.getRecords().subList(0, plankConfig.getDeficitMovingAverage() - 1) : selectPage.getRecords();
                // 止损均线价格
                OptionalDouble average = dailyRecords.stream().mapToDouble(dailyRecord -> dailyRecord.getClosePrice().doubleValue()).average();
                if (average.isPresent() && (todayRecord.getLowest().doubleValue() <= average.getAsDouble())) {
                    // 跌破均线,清仓
                    this.clearanceStock(holdShare, ClearanceReasonEnum.BREAK_POSITION, date, average.getAsDouble());
                    continue;
                }
                // 盘中最低收益率
                double profitLowRatio = todayRecord.getLowest().subtract(holdShare.getBuyPrice()).divide(holdShare.getBuyPrice(), 2, RoundingMode.HALF_UP).doubleValue();
                if (profitLowRatio < plankConfig.getDeficitRatio().doubleValue()) {
                    // 跌破止损线,清仓
                    this.clearanceStock(holdShare, ClearanceReasonEnum.BREAK_LOSS_LINE, date, holdShare.getBuyPrice().doubleValue() * (1 + plankConfig.getDeficitRatio().doubleValue()));
                    continue;
                }
                if (holdShare.getFifteenProfit() && profitLowRatio <= plankConfig.getProfitClearanceRatio().doubleValue()) {
                    // 收益回撤到10个点止盈清仓
                    this.clearanceStock(holdShare, ClearanceReasonEnum.TAKE_PROFIT, date, holdShare.getBuyPrice().doubleValue() * 1.1);
                    continue;
                }
                // 盘中最高收益率
                double profitHighRatio = todayRecord.getHighest().subtract(holdShare.getBuyPrice()).divide(holdShare.getBuyPrice(), 2, RoundingMode.HALF_UP).doubleValue();
                if (profitHighRatio >= plankConfig.getProfitUpperRatio().doubleValue()) {
                    // 收益25% 清仓
                    this.clearanceStock(holdShare, ClearanceReasonEnum.PROFIT_UPPER, date, holdShare.getBuyPrice().doubleValue() * (1 + plankConfig.getProfitUpperRatio().doubleValue()));
                } else if (profitHighRatio >= plankConfig.getProfitQuarterRatio().doubleValue()) {
                    // 收益20% 减至1/4仓
                    this.reduceStock(holdShare, ClearanceReasonEnum.POSITION_QUARTER, date, todayRecord, holdShare.getBuyPrice().doubleValue() * (1 + plankConfig.getProfitQuarterRatio().doubleValue()));
                } else if (profitHighRatio >= plankConfig.getProfitHalfRatio().doubleValue()) {
                    // 收益15% 减半仓
                    this.reduceStock(holdShare, ClearanceReasonEnum.POSITION_HALF, date, todayRecord, holdShare.getBuyPrice().doubleValue() * (1 + plankConfig.getProfitHalfRatio().doubleValue()));
                }
                // 持股超过x天 并且 收益不到20% 清仓
                if (Days.daysBetween(new LocalDate(holdShare.getBuyTime().getTime()), new LocalDate(date.getTime())).getDays() > plankConfig.getClearanceDay()) {
                    this.clearanceStock(holdShare, ClearanceReasonEnum.TEN_DAY, date, todayRecord.getOpenPrice().add(todayRecord.getClosePrice()).doubleValue() / 2);
                }
            }
        }
    }
}
Also used : DateUtil(cn.hutool.core.date.DateUtil) Date(java.util.Date) DailyRecord(com.mistra.plank.pojo.entity.DailyRecord) DragonList(com.mistra.plank.pojo.entity.DragonList) HoldShares(com.mistra.plank.pojo.entity.HoldShares) PlankConfig(com.mistra.plank.config.PlankConfig) Clearance(com.mistra.plank.pojo.entity.Clearance) BigDecimal(java.math.BigDecimal) Map(java.util.Map) TradeRecord(com.mistra.plank.pojo.entity.TradeRecord) Days(org.joda.time.Days) HoldSharesMapper(com.mistra.plank.mapper.HoldSharesMapper) HttpUtil(com.mistra.plank.util.HttpUtil) RoundingMode(java.math.RoundingMode) QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) FundHoldingsParam(com.mistra.plank.pojo.param.FundHoldingsParam) TradeRecordMapper(com.mistra.plank.mapper.TradeRecordMapper) FundHoldingsTrackingMapper(com.mistra.plank.mapper.FundHoldingsTrackingMapper) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) Collectors(java.util.stream.Collectors) Stock(com.mistra.plank.pojo.entity.Stock) UploadDataListener(com.mistra.plank.util.UploadDataListener) Objects(java.util.Objects) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) JSONObject(com.alibaba.fastjson.JSONObject) StockRealTimePrice(com.mistra.plank.pojo.dto.StockRealTimePrice) DragonListMapper(com.mistra.plank.mapper.DragonListMapper) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) OptionalDouble(java.util.OptionalDouble) SimpleDateFormat(java.text.SimpleDateFormat) HashMap(java.util.HashMap) EasyExcel(com.alibaba.excel.EasyExcel) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) JSONArray(com.alibaba.fastjson.JSONArray) CommandLineRunner(org.springframework.boot.CommandLineRunner) ExecutorService(java.util.concurrent.ExecutorService) DailyRecordMapper(com.mistra.plank.mapper.DailyRecordMapper) DateTime(org.joda.time.DateTime) IOException(java.io.IOException) DateUtils(org.apache.commons.lang3.time.DateUtils) TimeUnit(java.util.concurrent.TimeUnit) LocalDate(org.joda.time.LocalDate) Page(com.baomidou.mybatisplus.extension.plugins.pagination.Page) Component(org.springframework.stereotype.Component) ClearanceReasonEnum(com.mistra.plank.pojo.enums.ClearanceReasonEnum) JSON(com.alibaba.fastjson.JSON) NamedThreadFactory(cn.hutool.core.thread.NamedThreadFactory) ForeignFundHoldingsTracking(com.mistra.plank.pojo.entity.ForeignFundHoldingsTracking) StockMapper(com.mistra.plank.mapper.StockMapper) Collections(java.util.Collections) ClearanceMapper(com.mistra.plank.mapper.ClearanceMapper) HoldShares(com.mistra.plank.pojo.entity.HoldShares) DailyRecord(com.mistra.plank.pojo.entity.DailyRecord) LocalDate(org.joda.time.LocalDate) OptionalDouble(java.util.OptionalDouble)

Example 2 with HoldShares

use of com.mistra.plank.pojo.entity.HoldShares in project plank by MistraR.

the class Barbarossa method buyStock.

private void buyStock(List<Stock> stocks, Date date) {
    for (Stock stock : stocks) {
        List<HoldShares> holdShares = holdSharesMapper.selectList(new QueryWrapper<>());
        if (holdShares.size() >= plankConfig.getFundsPart()) {
            log.info("仓位已打满!无法开新仓!");
            return;
        }
        Page<DailyRecord> selectPage = dailyRecordMapper.selectPage(new Page<>(1, 5), new QueryWrapper<DailyRecord>().eq("code", stock.getCode()).ge("date", date).le("date", DateUtils.addDays(date, 12)).orderByAsc("date"));
        if (selectPage.getRecords().size() < 2) {
            continue;
        }
        DailyRecord dailyRecord = selectPage.getRecords().get(1);
        double openRatio = (selectPage.getRecords().get(1).getOpenPrice().subtract(selectPage.getRecords().get(0).getClosePrice())).divide(selectPage.getRecords().get(0).getClosePrice(), 2, RoundingMode.HALF_UP).doubleValue();
        if (openRatio > -0.03 && openRatio < plankConfig.getBuyPlankRatioLimit().doubleValue() && BALANCE_AVAILABLE.intValue() > 10000) {
            // 低开2个点以下不买
            HoldShares one = holdSharesMapper.selectOne(new QueryWrapper<HoldShares>().eq("code", stock.getCode()));
            if (Objects.isNull(one)) {
                int money = BALANCE.intValue() / plankConfig.getFundsPart();
                money = Math.min(money, BALANCE_AVAILABLE.intValue());
                int number = money / dailyRecord.getOpenPrice().multiply(new BigDecimal(100)).intValue();
                double cost = number * 100 * dailyRecord.getOpenPrice().doubleValue();
                BALANCE_AVAILABLE = BALANCE_AVAILABLE.subtract(new BigDecimal(cost));
                HoldShares holdShare = HoldShares.builder().buyTime(DateUtils.addHours(dailyRecord.getDate(), 9)).code(stock.getCode()).name(stock.getName()).cost(dailyRecord.getOpenPrice()).fifteenProfit(false).number(number * 100).profit(new BigDecimal(0)).currentPrice(dailyRecord.getOpenPrice()).rate(new BigDecimal(0)).buyPrice(dailyRecord.getOpenPrice()).buyNumber(number * 100).build();
                holdSharesMapper.insert(holdShare);
                TradeRecord tradeRecord = new TradeRecord();
                tradeRecord.setName(holdShare.getName());
                tradeRecord.setCode(holdShare.getCode());
                tradeRecord.setDate(DateUtils.addHours(dailyRecord.getDate(), 9));
                tradeRecord.setMoney((int) (number * 100 * dailyRecord.getOpenPrice().doubleValue()));
                tradeRecord.setReason("买入" + holdShare.getName() + number * 100 + "股,花费" + cost + "元,当前可用余额" + BALANCE_AVAILABLE.intValue());
                tradeRecord.setBalance(BALANCE.setScale(2, RoundingMode.HALF_UP));
                tradeRecord.setAvailableBalance(BALANCE_AVAILABLE.setScale(2, RoundingMode.HALF_UP));
                tradeRecord.setPrice(dailyRecord.getOpenPrice());
                tradeRecord.setNumber(number * 100);
                tradeRecord.setType(0);
                tradeRecordMapper.insert(tradeRecord);
            }
        }
    }
}
Also used : QueryWrapper(com.baomidou.mybatisplus.core.conditions.query.QueryWrapper) DailyRecord(com.mistra.plank.pojo.entity.DailyRecord) BigDecimal(java.math.BigDecimal) TradeRecord(com.mistra.plank.pojo.entity.TradeRecord) HoldShares(com.mistra.plank.pojo.entity.HoldShares) Stock(com.mistra.plank.pojo.entity.Stock)

Aggregations

QueryWrapper (com.baomidou.mybatisplus.core.conditions.query.QueryWrapper)2 DailyRecord (com.mistra.plank.pojo.entity.DailyRecord)2 HoldShares (com.mistra.plank.pojo.entity.HoldShares)2 Stock (com.mistra.plank.pojo.entity.Stock)2 TradeRecord (com.mistra.plank.pojo.entity.TradeRecord)2 BigDecimal (java.math.BigDecimal)2 DateUtil (cn.hutool.core.date.DateUtil)1 NamedThreadFactory (cn.hutool.core.thread.NamedThreadFactory)1 EasyExcel (com.alibaba.excel.EasyExcel)1 JSON (com.alibaba.fastjson.JSON)1 JSONArray (com.alibaba.fastjson.JSONArray)1 JSONObject (com.alibaba.fastjson.JSONObject)1 Page (com.baomidou.mybatisplus.extension.plugins.pagination.Page)1 PlankConfig (com.mistra.plank.config.PlankConfig)1 ClearanceMapper (com.mistra.plank.mapper.ClearanceMapper)1 DailyRecordMapper (com.mistra.plank.mapper.DailyRecordMapper)1 DragonListMapper (com.mistra.plank.mapper.DragonListMapper)1 FundHoldingsTrackingMapper (com.mistra.plank.mapper.FundHoldingsTrackingMapper)1 HoldSharesMapper (com.mistra.plank.mapper.HoldSharesMapper)1 StockMapper (com.mistra.plank.mapper.StockMapper)1