private void increaseBid(double cpcBidChange, AdGroupPerformance base, AdGroupPerformance r) {
   DsaMetrics metrics = (DsaMetrics) r.adGroup.getMetrics();
   double INCREASE_FACTOR = 1 + cpcBidChange;
   double value = metrics.getMaxBid() * INCREASE_FACTOR;
   if (value > base.minBaseCpc) metrics.setMaxBid(base.maxBaseCpc);
   else metrics.setMaxBid(value);
 }
  private void modifyBids(
      IDsaTrackerUserConfiguration userConfig,
      NewTargetValues values,
      AdGroupPerformance base,
      AdGroupPerformance r) {
    // We can modify bids with averagePosition > 0
    if (r.averagePosition == 0) {
      return;
    }

    DsaMetrics metrics = (DsaMetrics) r.adGroup.getMetrics();
    r.previousCpc = metrics.getMaxBid();

    // compareByThreshold AvgPositions.
    // Bid modifications are allowed in case when AvgPosition delta <
    // configuration.tracker.maxAvgPositionChange
    double avgPositionDelta = abs(base.averagePosition - r.averagePosition);

    if (avgPositionDelta < userConfig.getDsaTracker().maxAvgPositionChange) {
      if (r.hasConversions) {
        if (avgPositionDelta < 0.1) {
          decreaseBid(userConfig.getDsaTracker().cpcBidChange, base, r);
        } else {
          if (values.currentValueOfMetric > values.newTarget) {
            decreaseBid(userConfig.getDsaTracker().cpcBidChange, base, r);
          } else {
            increaseBid(userConfig.getDsaTracker().cpcBidChange, base, r);
          }
        }
      } else {
        if (avgPositionDelta < 0.1) {
          decreaseBid(userConfig.getDsaTracker().cpcBidChange, base, r);
        } else {
          if (values.currentValueOfMetric > values.newTarget) {
            decreaseBid(userConfig.getDsaTracker().cpcBidChange, base, r);
          } else {
            increaseBid(userConfig.getDsaTracker().cpcBidChange, base, r);
          }
        }
      }
    }
  }
  private Map<Long, AdGroupPerformance> initializeBaseReport(
      IDsaTrackerUserConfiguration userConfig, final Map<String, Account> accounts)
      throws Exception {
    if (userConfig.getDsaTracker().reinitializeBaseReport) {
      File baseReportFile = fsUtils.getResultFile(userConfig, "DsaBaseReport");
      LOGGER.info("Reinitialize base report");

      // update adGroups bids
      if (!userConfig.getIdleMode()) {
        adGroupBidUploaderService.uploadBids(
            userConfig,
            accounts
                .values()
                .stream()
                .flatMap(accountData -> accountData.getCampaigns().values().stream())
                .flatMap(campaignData -> campaignData.getAdGroups().values().stream()));
      }

      if (!configuration.dsaTracker.singleRunMod) {
        LOGGER.info(
            "Wait for data to accumulate (waitTime = "
                + userConfig.getDsaTracker().waitTime
                + " sec)...");
        Thread.sleep(userConfig.getDsaTracker().waitTime * 1000);
      }

      LocalDateTime dateOne = now();
      LocalDateTime dateTwo = dateOne.minusDays(REPORT_DAYS);
      Map<Long, AdGroupPerformance> baseReport =
          performanceDataLoader.downloadPerformanceData(
              accounts, dateTwo.toLocalDate(), dateOne.toLocalDate());

      for (Long key : baseReport.keySet()) {
        if (baseReport.get(key).adGroup == null) baseReport.remove(key);
      }

      for (Account account : accounts.values()) {
        for (Campaign campaign : account.getCampaigns().values()) {
          for (AdGroup adGroup : campaign.getAdGroups().values()) {
            if (baseReport.get(adGroup.getAdGroupId()) != null) continue;
            AdGroupPerformance adGroupPerformance = new AdGroupPerformance();
            Long campaignId = campaign.getCampaignId();
            Long adGroupId = adGroup.getAdGroupId();
            adGroupPerformance.adGroup =
                new AdGroupImpl(
                    new CampaignImpl(new AccountImpl(account.getAccountId()), campaignId),
                    adGroupId);
            adGroupPerformance.adGroup.setMetrics(
                new DsaMetrics() {
                  {
                    setMaxBid(0.0);
                  }
                });
            adGroupPerformance.hasConversions = false;
            adGroupPerformance.averageCpc = 0;
            adGroupPerformance.averagePosition = 0;
            adGroupPerformance.clicks = 0;
            adGroupPerformance.cost = 0;
            adGroupPerformance.impressions = 0;

            baseReport.put(adGroupId, adGroupPerformance);
          }
        }
      }

      baseReport
          .values()
          .forEach(
              r -> {
                DsaMetrics metrics = (DsaMetrics) r.adGroup.getMetrics();
                r.maxBaseCpc =
                    metrics.getMaxBid() * (1 + userConfig.getDsaTracker().maxCpcBidChange);
                r.minBaseCpc =
                    metrics.getMaxBid() * (1 - userConfig.getDsaTracker().maxCpcBidChange);
              });

      dsaTrackerUtils.saveBaseReport(baseReportFile, baseReport);
      ((DsaTrackerUserConfiguration) userConfig).baseReportFilePath =
          baseReportFile.getAbsolutePath();

      return baseReport;
    } else {
      LOGGER.info("Load base report from previous launch");
      File baseReportFile = new File(((DsaTrackerUserConfiguration) userConfig).baseReportFilePath);
      if (!baseReportFile.exists()) {
        throw new FileNotFoundException("Basic landscape report file does not exist");
      }

      return dsaTrackerUtils.loadBaseReport(baseReportFile, accounts);
    }
  }