public FinalRating calculateRating(TuningResDTO tuningRes) { int nbSuccess = 0; int nbFailure = 0; for (PeriodRatingDTO periodRatingDTO : tuningRes.getPeriods()) { Validity periodValidity = smoothedPeriodValidity(periodRatingDTO, tuningRes.getStockPriceChange()); // nbSuccess = nbSuccess + ((periodValidity.equals(Validity.SUCCESS))?1:0); if (periodRatingDTO .getTrend() .equals(EventType.BULLISH.toString())) { // we tally only the bullish failures and success nbSuccess = nbSuccess + ((periodValidity.equals(Validity.SUCCESS)) ? 1 : 0); nbFailure = nbFailure + ((periodValidity.equals(Validity.FAILURE)) ? 1 : 0); } } FinalRating finalRating = tuningFinalizationRating( tuningRes.getFollowProfit(), tuningRes.getStockPriceChange(), nbSuccess, nbFailure); // Test // finalRating.validity = Validity.SUCCESS; return finalRating; }
private Validity smoothedPeriodValidity( PeriodRatingDTO periodRatingDTO, Double totalPriceChange) { Validity periodValidity = Validity.NORATING; double errorDelta = 0.0; double ratioToTotPriceChange = 0.10; boolean isBullAndNeg = periodRatingDTO.getTrend().equals(EventType.BULLISH.name()) && periodRatingDTO.getPriceRateOfChange() < -errorDelta; boolean isBearAndPos = periodRatingDTO.getTrend().equals(EventType.BEARISH.name()) && periodRatingDTO.getPriceRateOfChange() > errorDelta; boolean isPeriodSignificant = Math.abs(periodRatingDTO.getPriceRateOfChange()) > Math.abs(totalPriceChange * ratioToTotPriceChange); if (isBullAndNeg || isBearAndPos) { if (isPeriodSignificant) { periodValidity = Validity.FAILURE; } else { periodValidity = Validity.NORATING; } } else { periodValidity = Validity.SUCCESS; } return periodValidity; }
private void addFilteredPeriod( List<PeriodRatingDTO> periods, PeriodRatingDTO period, int sizeConstraint) { if ((periods.size() == 0) && EventType.valueOf(period.getTrend()).equals(EventType.BULLISH)) { LOGGER.info("First bullish period discarded : " + period); return; } if (sizeConstraint != -1 && period.getPeriodLenght() < sizeConstraint) { String invFlasePositiveTrend = (EventType.valueOf(period.getTrend()).equals(EventType.BULLISH)) ? EventType.NONE.toString() : EventType.BULLISH.toString(); LOGGER.info( "Period is too short (false positive) : " + period + ". Trend will be set as " + invFlasePositiveTrend); period.setTrend(invFlasePositiveTrend); if ((periods.size() == 0) && EventType.valueOf(period.getTrend()).equals(EventType.BULLISH)) { LOGGER.info("First bullish period discarded : " + period); return; } } PeriodRatingDTO previousPeriod; if (periods.size() > 0 && (previousPeriod = periods.get(periods.size() - 1)) .getTrend() .equals(period.getTrend())) { previousPeriod.setTo(period.getTo()); previousPeriod.setPriceAtTo(period.getPriceAtTo()); previousPeriod.setRealised(period.isRealised()); } else { periods.add(period); } }
/** * Builds a *_ConfigRating.csv file for the stock containing the trend periods results of the * stock tuning. The from and to dates are the date for the start of a trend (BULLISH/BEARISH) and * the end of the trend. The file contains one line per config elected over the tuning. For each * config its trend period of occurrence and the trend values during this period. Hence you can * have several lines with different configs over the same trend period where they were * consecutively elected with the same trend results. As in fact the config elected will change at * the pace of the tuning periods which are different from the trend periods. On the other hand, * when trend changes, also does the trend period dates. In the same way the same config can be * elected over several consecutive trend period changes. */ public void exportConfigRating( String analysisName, TuningResDTO tuningRes, Date startDate, Date endDate, FinalRating calculatedRating) throws IOException { String fileName = "tmp" + File.separator + analysisName + "_ConfigRating.csv"; File configRatings = new File(System.getProperty("installdir") + File.separator + fileName); FileWriter fileWriter = new FileWriter(configRatings); fileWriter.write( "config, cfg start, cfg end, trend start, trend end, length, price change, trend, success/failure, compound profit \n"); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy MM dd"); Double compoundProfit = 1d; for (PeriodRatingDTO periodRatingDTO : tuningRes.getPeriods()) { String successOrFailure = ((periodRatingDTO.getTrend().equals(EventType.BULLISH.name()) && periodRatingDTO.getPriceRateOfChange() <= 0) || (periodRatingDTO.getTrend().equals(EventType.BEARISH.name()) && periodRatingDTO.getPriceRateOfChange() > 0)) ? "FAILURE" : "SUCCESS"; if (periodRatingDTO.getTrend().equals(EventType.BULLISH.name())) compoundProfit = compoundProfit * (periodRatingDTO.getPriceRateOfChange() + 1); String cfgStr = dateFormat.format(periodRatingDTO.getFrom()) + " , " + dateFormat.format(periodRatingDTO.getTo()) + " , " + periodRatingDTO.getPeriodLenght() + " , " + periodRatingDTO.getPriceRateOfChange() + " , " + periodRatingDTO.getTrend() + " , " + successOrFailure + " , " + compoundProfit; if (periodRatingDTO.getConfigs().size() > 0) { for (String pConfig : periodRatingDTO.getConfigs()) { String cfgStart = dateFormat.format(startDate); String cfgEnd = dateFormat.format(endDate); fileWriter.write(pConfig + " , " + cfgStart + " , " + cfgEnd + " , " + cfgStr + "\n"); } } else { // No config fileWriter.write("No config? " + " , , , " + cfgStr + "\n"); } } fileWriter.write( "total , percent gain : " + tuningRes.getFollowProfit() + ", price change : " + tuningRes.getStockPriceChange() + "\n"); tuningRes.setConfigRatingFile(fileName); fileWriter.write("rating , " + calculatedRating); fileWriter.close(); }