Good video. @Adaizen, can you provide the sources for the calculator? Or the exact formulas you have used to set it up? (And I don’t mean jscalc itself)
Did you fully used the same math as in https://github.com/cffls/cardano-stake-pool-desirability?
Or are there changes we should know about?
No.
Backstory,
My original thought was to use R and not display any values to drive home the point that changes to one can have an impact on desirability.
It was a disaster. I was never going to have the time to finish it on lunch hours.
Then I decided to go the universal Javascript route while reusing what I had done before, a hack job.
I have never worked with Javascript, as is evident if one views the code. The calculator was made on jscalc.io so that anyone with a browser could use it and make it their own. Note, the Javascript behind the calculator is not best practices, do not learn Javascript from it.
I could not have knocked this out as fast as I did, in Javascript, if it wasn’t for Cliffs desirability calculator.
My calculator was not meant to be accurate, it was designed to get to a level of understanding which is why for example it does not fuse rewards.
Hopefully, a 100% accurate calculator is forthcoming provided by IOHK, Foundation or Emurgo so pool operators can chart out there future.
Cheers
This appears at the head of the blog post:
First, the reason this calculator exists is to enable Cardano stake pool operators and or owners to think and see long term, non-myopic. It was never intended to be 100% accurate, it is correct to a degree, but that degree of correctness is not material here, it’s not the reason this slide calculator exists .
DO NOT USE IT AS INVESTMENT ADVICE.
This appears on the lefthand side of the calculator:
A Cardano stake pool desirability, estimation (not accurate, which is not the intent) slide calculator to get operators & owners thinking about what it will take to get a viable stake pool operating for the non-myopic time ahead of Cardano’s ecosystem.
Through emails I have received some great suggestions like clearly marking inputs. Which I did as Market Driven, Protocol Set, Operator Estimate & Operator Control, 1 - 3.
Thanks for the suggestions.
Go Shelley.
Does it use all the same formulas, or some calculations are changed?
Ok, I found it finally. Actual sources for this tool:
'use strict';
var iohkEmurgoFoundation = 5185414108;
var poolWeight = (1 / inputs.k);
var epoch = (1 / 73);
var saturation = (inputs.totalSupplyAda / inputs.k);
var totalPledgedAndDelegated = (inputs.pledgedToPoolPercent) + (inputs.delegatedToPoolPercent);
var pledgedToPoolPercent = ((inputs.pledgedToPoolPercent / 100) * saturation);
var delegatedToPoolPercent = ((inputs.delegatedToPoolPercent / 100) * saturation);
var poolCapacityRemaining = ((saturation) - (pledgedToPoolPercent + delegatedToPoolPercent));
var poolCapacityRemainingPercent = poolCapacityRemaining / saturation;
var adaWeight = (saturation / inputs.totalSupplyAda);
var poolRank = math.abs((inputs.k * (inputs.poolRank/100)) -1);
var dAda = ((inputs.delegableAda / 100) * inputs.totalSupplyAda);
var incentiveInflationYearly = (inputs.incentivePercentYear / 100);
var probSat = math.max((dAda -(saturation * poolRank)), 0);
var pR = (pledgedToPoolPercent / inputs.totalSupplyAda);
var incent = (inputs.totalSupplyAda * math.pow(1 + incentiveInflationYearly, epoch) - inputs.totalSupplyAda);
var pRpWmin = (math.min(pR, poolWeight));
var sPmax = (math.min((saturation / inputs.totalSupplyAda), poolWeight));
var aWpWmin = (math.min(adaWeight, poolWeight));
var totalPoolReward = ((incent / (1 + inputs.a0)) * (aWpWmin + (pRpWmin * inputs.a0 * (aWpWmin - (pRpWmin * (poolWeight - aWpWmin)) / poolWeight)) / poolWeight));
var totalPoolRewardPledge0 = ((incent / (1 + inputs.a0)) * (aWpWmin + (0 * inputs.a0 * (aWpWmin - (0 * (poolWeight - aWpWmin)) / poolWeight)) / poolWeight));
var nonmyopicPoolReward = (totalPoolReward * (1 - (poolCapacityRemaining / saturation)));
var costPerEpochInAda = (inputs.costPerEpoch / inputs.usdToAdaExchangeRate);
var delegateAdaLevel = ((inputs.delegatedToPoolPercent / 100));
if ((pledgedToPoolPercent + delegatedToPoolPercent) > saturation) {
delegateAdaLevel = (1 - (inputs.pledgedToPoolPercent / 100));
}
if (nonmyopicPoolReward > totalPoolReward) {
nonmyopicPoolReward = totalPoolReward;
}
var poolFeeReward = (nonmyopicPoolReward * delegateAdaLevel) * (inputs.feePool / 100);
if (totalPledgedAndDelegated > 100) {
totalPledgedAndDelegated = 100;
}
var probPool = (((saturation * totalPledgedAndDelegated)/ 100) / dAda);
if (poolCapacityRemainingPercent < 0) {
poolCapacityRemainingPercent = 0;
}
var desirability = (totalPoolReward - costPerEpochInAda) * (1 - (inputs.feePool / 100));
var maxPoolReward =((incent / (1 + inputs.a0)) * (aWpWmin + (sPmax * inputs.a0 * (aWpWmin - (sPmax * (poolWeight - aWpWmin)) / poolWeight)) / poolWeight));
var des = (desirability / maxPoolReward);
var totalPoolRewardNoa0 = ((incent / (1 + 0)) * (aWpWmin + (pRpWmin * 0 * (aWpWmin - (pRpWmin * (poolWeight - aWpWmin)) / poolWeight)) / poolWeight));
var desirabilityNoa0 = (totalPoolRewardNoa0 - costPerEpochInAda) * (1 - (inputs.feePool / 100));
var maxPoolRewardNoa0 =((incent / (1 + 0)) * (aWpWmin + (sPmax * 0 * (aWpWmin - (sPmax * (poolWeight - aWpWmin)) / poolWeight)) / poolWeight));
var desNoa0 = (desirability - totalPoolReward);
var profitMargin = ((totalPoolReward - desirability) / totalPoolReward);
var poolEdge = (desirability - totalPoolRewardPledge0);
return {
a: [{
'Pool Saturation ADA': saturation,
'Pool Capacity Remaining ADA': poolCapacityRemaining,
'Pool Capacity Remaining %': poolCapacityRemainingPercent
}],
delegation: [{
'dAda': dAda,
'probSat': probSat,
'dAdaS': math.ceil((dAda / saturation))
}],
poolSpec: [{
'pledgedToPoolPercent': pledgedToPoolPercent,
'delegatedToPoolPercent': delegatedToPoolPercent,
'poolRank': poolRank
}],
nonmyopic: [{
'nonmyopicPoolReward': nonmyopicPoolReward,
'costPerEpochInAda': costPerEpochInAda,
'poolFee': poolFeeReward,
}],
nonmyopiclevel: [{
'totalPoolReward': desirability,
'desirability': poolEdge,
}]
};