diff --git a/R/InsuranceParameters.R b/R/InsuranceParameters.R
index 9caff53ad100a15c1e195efca9ecd95f7f74eb56..1696f23e03083a0cc8675337a1ae493a9e5041b3 100644
--- a/R/InsuranceParameters.R
+++ b/R/InsuranceParameters.R
@@ -513,6 +513,8 @@ InsuranceContract.Values = list(
 #'     \item{\code{$adjustCosts}}{Function with signature \code{function(costs, params, values, ...)} to adjust the tariff costs after their setup (e.g. contract-specific conditions/waivers, etc.).}
 #'     \item{\code{$adjustMinCosts}}{Function with signature \code{function(minCosts, costs, params, values, ...)} to adjust the tariff minimum (unwaivable) costs after their setup (e.g. contract-specific conditions/waivers, etc.).}
 #'     \item{\code{$adjustPremiumCoefficients}}{Function with signature \code{function(coeff, type, premiums, params, values, premiumCalculationTime)} to adjust the coefficients for premium calculation after their default setup. Use cases are e.g. term-fix tariffs where the Zillmer premium term contains the administration cost over the whole contract, but not other gamma- or beta-costs.}
+#'     \item{\code{$adjustPVForReserves}}{Adjust the absolute present value vectors used to derive reserves (e.g. when a sum rebate is subtracted from the gamma-cost reserves without influencing the premium calculation). \code{function(absPV, params, values)}}
+#'     \item{\code{$premiumRebateCalculation}}{Calculate the actual premium rebate from the rebate rate (e.g. when the premium rate is given as a yearly cost reduction applied to a single-premium contract). \code{function(premiumRebateRate, params = params, values = values)}}
 #' }
 #'
 #'
@@ -626,7 +628,9 @@ InsuranceContract.ParameterDefaults = list(
       adjustCashFlowsCosts = NULL,
       adjustCosts = NULL,
       adjustMinCosts = NULL,
-      adjustPremiumCoefficients = NULL # function(coeff, type = type, premiums = premiums, params = params, values = values, premiumCalculationTime = premiumCalculationTime)
+      adjustPremiumCoefficients = NULL,  # function(coeff, type = type, premiums = premiums, params = params, values = values, premiumCalculationTime = premiumCalculationTime)
+      adjustPVForReserves = NULL,        # function(absPresentValues, params, values)
+      premiumRebateCalculation = NULL   # function(premiumRebateRate, params = params, values = values)
     )
 );
 
diff --git a/R/InsuranceTarif.R b/R/InsuranceTarif.R
index 52734ebbdf0c4441e8dc7579d86f07bcaf6957d7..a5d791e393ae51feb05d39ed5d5be4c72780b996 100644
--- a/R/InsuranceTarif.R
+++ b/R/InsuranceTarif.R
@@ -991,7 +991,9 @@ InsuranceTarif = R6Class(
       noMedicalExam.relative = valueOrFunction(loadings$noMedicalExamRelative,params = params, values = values);
       extraRebate   = valueOrFunction(loadings$extraRebate,  params = params, values = values);
       sumRebate     = valueOrFunction(loadings$sumRebate,    params = params, values = values);
-      premiumRebate = valueOrFunction(loadings$premiumRebate,params = params, values = values);
+      premiumRebateRate = valueOrFunction(loadings$premiumRebate,params = params, values = values);
+      premiumRebate = applyHook(params$Hooks$premiumRebateCalculation, premiumRebateRate, params = params, values = values);
+
       extraChargeGrossPremium = valueOrFunction(loadings$extraChargeGrossPremium, params = params, values = values);
       advanceProfitParticipation = 0;
       advanceProfitParticipationUnitCosts = 0;
@@ -1016,7 +1018,7 @@ InsuranceTarif = R6Class(
       values$premiums[["unitcost"]] = premium.unitcosts;
 
 
-            frequencyLoading = self$evaluateFrequencyLoading(loadings$premiumFrequencyLoading, params$ContractData$premiumFrequency, params = params, values = values)
+      frequencyLoading = self$evaluateFrequencyLoading(loadings$premiumFrequencyLoading, params$ContractData$premiumFrequency, params = params, values = values)
       premiumBeforeTax = (values$premiums[["unit.gross"]]*(1 + noMedicalExam.relative + extraChargeGrossPremium) + noMedicalExam - sumRebate - extraRebate) * sumInsured * (1 - advanceProfitParticipation);
       if (!params$Features$unitcostsInGross) {
         premiumBeforeTax = premiumBeforeTax + premium.unitcosts;
@@ -1045,20 +1047,22 @@ InsuranceTarif = R6Class(
       securityFactor = (1 + valueOrFunction(params$Loadings$security, params = params, values = values));
       ppScheme      = params$ProfitParticipation$profitParticipationScheme;
 
+      absPV = applyHook(params$Hooks$adjustPVForReserves, values$absPresentValues, params = params, values = values);
+
       # Net, Zillmer and Gross reserves
-      resNet = values$absPresentValues[,"benefitsAndRefund"] * securityFactor - values$premiums[["net"]] * values$absPresentValues[,"premiums.unit"];
-      BWZcorr = ifelse(values$absPresentValues[t, "premiums"] == 0, 0,
-                       values$absPresentValues[t, "Zillmer"] / values$absPresentValues[t, "premiums"]) * values$absPresentValues[,"premiums"];
+      resNet = absPV[,"benefitsAndRefund"] * securityFactor - values$premiums[["net"]] * absPV[,"premiums.unit"];
+      BWZcorr = ifelse(absPV[t, "premiums"] == 0, 0,
+                       absPV[t, "Zillmer"] / absPV[t, "premiums"]) * absPV[,"premiums"];
       resZ = resNet - BWZcorr;
 
-      resAdeq = values$absPresentValues[,"benefitsAndRefund"] * securityFactor +
-        values$absPresentValues[,"alpha"] + values$absPresentValues[,"beta"] + values$absPresentValues[,"gamma"] -
-        values$premiums[["gross"]] * values$absPresentValues[,"premiums.unit"];
+      resAdeq = absPV[,"benefitsAndRefund"] * securityFactor +
+          absPV[,"alpha"] + absPV[,"beta"] + absPV[,"gamma"] -
+        values$premiums[["gross"]] * absPV[,"premiums.unit"];
 
-      #values$premiums[["Zillmer"]] * values$absPresentValues[,"premiums"];
-      resGamma = values$absPresentValues[,"gamma"] -
-        ifelse(values$absPresentValues[t, "premiums"] == 0, 0,
-               values$absPresentValues[t, "gamma"] / values$absPresentValues[t, "premiums"]) * values$absPresentValues[,"premiums"]
+      #values$premiums[["Zillmer"]] * absPV[,"premiums"];
+      resGamma = absPV[,"gamma"] -
+        ifelse(absPV[t, "premiums"] == 0, 0,
+               absPV[t, "gamma"] / absPV[t, "premiums"]) * absPV[,"premiums"]
 
       advanceProfitParticipation = 0;
       if (!is.null(ppScheme)) {
@@ -1106,7 +1110,7 @@ InsuranceTarif = R6Class(
             "reduction"   = resReduction
             #, "Reserve.premiumfree"=res.premiumfree, "Reserve.gamma.premiumfree"=res.gamma.premiumfree);
       );
-      rownames(res) <- rownames(values$absPresentValues);
+      rownames(res) <- rownames(absPV);
       values$reserves = res;
 
       # The surrender value functions can have arbitrary form, so we store a function
@@ -1136,9 +1140,9 @@ InsuranceTarif = R6Class(
         premiumfreeValue = surrenderValue
       }
       Storno = 0; # TODO: Implement storno costs
-      premiumfreePV = (values$absPresentValues[, "benefits"] * securityFactor + values$absPresentValues[, "gamma_nopremiums"]); # PV of future premium free claims + costs
+      premiumfreePV = (absPV[, "benefits"] * securityFactor + absPV[, "gamma_nopremiums"]); # PV of future premium free claims + costs
       newSI = ifelse(premiumfreePV == 0, 0,
-        (premiumfreeValue - values$absPresentValues[,"death_Refund_past"] * securityFactor - c(Storno)) /
+        (premiumfreeValue - absPV[,"death_Refund_past"] * securityFactor - c(Storno)) /
         premiumfreePV * params$ContractData$sumInsured);
 
       cbind(res,
@@ -1348,7 +1352,9 @@ InsuranceTarif = R6Class(
       profits.advance  = profits.advance + afterProfit - afterUnitCosts;
 
       # premium rebate
-      premiumRebate    = valueOrFunction(loadings$premiumRebate,params = params, values = values);
+      premiumRebateRate = valueOrFunction(loadings$premiumRebate,params = params, values = values);
+      premiumRebate = applyHook(params$Hooks$premiumRebateCalculation, premiumRebateRate, params = params, values = values);
+
       afterPremiumRebate = afterUnitCosts * (1 - premiumRebate);
       rebate.premium   = afterPremiumRebate - afterUnitCosts;
 
diff --git a/man/InsuranceContract.ParameterDefaults.Rd b/man/InsuranceContract.ParameterDefaults.Rd
index 3026da892a3daf36f48e3adc3de060306ec39f16..6060c66bb1d9baf7b7a4f1aab74f1c306cc55e89 100644
--- a/man/InsuranceContract.ParameterDefaults.Rd
+++ b/man/InsuranceContract.ParameterDefaults.Rd
@@ -110,6 +110,9 @@ those cost components that are defined to be waivable, i.e. by
 defining a corresponding \code{$minCosts}). Linearly interpolates
 between \code{$Costs} and \code{$minCosts}, if the latter is set.
 Otherwise is has no effect.}
+\item{\code{$attributes}}{Additional custom attributes (as a named list),
+which can be used for particular behaviour of different contracts
+or contract slices.}
 }
 }
 
@@ -291,6 +294,8 @@ participation rates are defined at the level of profit classes.}
 \item{\code{$adjustCosts}}{Function with signature \code{function(costs, params, values, ...)} to adjust the tariff costs after their setup (e.g. contract-specific conditions/waivers, etc.).}
 \item{\code{$adjustMinCosts}}{Function with signature \code{function(minCosts, costs, params, values, ...)} to adjust the tariff minimum (unwaivable) costs after their setup (e.g. contract-specific conditions/waivers, etc.).}
 \item{\code{$adjustPremiumCoefficients}}{Function with signature \code{function(coeff, type, premiums, params, values, premiumCalculationTime)} to adjust the coefficients for premium calculation after their default setup. Use cases are e.g. term-fix tariffs where the Zillmer premium term contains the administration cost over the whole contract, but not other gamma- or beta-costs.}
+\item{\code{$adjustPVForReserves}}{Adjust the absolute present value vectors used to derive reserves (e.g. when a sum rebate is subtracted from the gamma-cost reserves without influencing the premium calculation). \code{function(absPV, params, values)}}
+\item{\code{$premiumRebateCalculation}}{Calculate the actual premium rebate from the rebate rate (e.g. when the premium rate is given as a yearly cost reduction applied to a single-premium contract). \code{function(premiumRebateRate, params = params, values = values)}}
 }
 }
 }