def apy(self, _: ApySamples) -> Apy: data = requests.get( "https://api.pickle.finance/prod/protocol/pools").json() yvboost_eth_pool = [ pool for pool in data if pool["identifier"] == "yvboost-eth" ][0] apy = yvboost_eth_pool["apy"] / 100. points = ApyPoints(apy, apy, apy) return Apy("yvecrv-jar", apy, apy, ApyFees(), points=points)
def simple(vault: VaultV1, samples: ApySamples) -> Apy: inception_block = contract_creation_block(vault.vault.address) if not inception_block: raise ApyError("v1:blocks", "inception_block not found") contract = vault.vault price_per_share = contract.getPricePerFullShare inception_price = 1e18 try: now_price = price_per_share(block_identifier=samples.now) except ValueError: now_price = inception_price if samples.week_ago > inception_block: try: week_ago_price = price_per_share(block_identifier=samples.week_ago) except ValueError: week_ago_price = now_price else: week_ago_price = now_price if samples.month_ago > inception_block: try: month_ago_price = price_per_share(block_identifier=samples.month_ago) except ValueError: month_ago_price = week_ago_price else: month_ago_price = week_ago_price now_point = SharePricePoint(samples.now, now_price) week_ago_point = SharePricePoint(samples.week_ago, week_ago_price) month_ago_point = SharePricePoint(samples.month_ago, month_ago_price) inception_point = SharePricePoint(inception_block, inception_price) week_ago_apy = calculate_roi(now_point, week_ago_point) month_ago_apy = calculate_roi(now_point, month_ago_point) inception_apy = calculate_roi(now_point, inception_point) net_apy = month_ago_apy strategy = vault.strategy withdrawal = strategy.withdrawalFee() if hasattr(strategy, "withdrawalFee") else 0 strategist_performance = strategy.performanceFee() if hasattr(strategy, "performanceFee") else 0 strategist_reward = strategy.strategistReward() if hasattr(strategy, "strategistReward") else 0 treasury = strategy.treasuryFee() if hasattr(strategy, "treasuryFee") else 0 performance = strategist_reward + strategist_performance + treasury apy = net_apy / (1 - performance / 1e4) points = ApyPoints(week_ago_apy, month_ago_apy, inception_apy) fees = ApyFees(performance=performance, withdrawal=withdrawal) return Apy("v1:simple", apy, net_apy, fees, points=points)
def simple(vault: Vault, samples: ApySamples) -> Apy: harvests = sorted([ harvest for strategy in vault.strategies for harvest in strategy.harvests ]) if len(harvests) < 10: raise ApyError("v2:harvests", "harvests are < 10") now = harvests[-1] week_ago = closest(harvests, samples.week_ago) month_ago = closest(harvests, samples.month_ago) inception_block = harvests[2] contract = vault.vault price_per_share = contract.pricePerShare now_price = price_per_share(block_identifier=now) inception_price = 10**contract.decimals() if samples.week_ago > inception_block: week_ago_price = price_per_share(block_identifier=week_ago) else: week_ago_price = now_price if samples.month_ago > inception_block: month_ago_price = price_per_share(block_identifier=month_ago) else: month_ago_price = week_ago_price now_point = SharePricePoint(samples.now, now_price) week_ago_point = SharePricePoint(samples.week_ago, week_ago_price) month_ago_point = SharePricePoint(samples.month_ago, month_ago_price) inception_point = SharePricePoint(inception_block, inception_price) week_ago_apy = calculate_roi(now_point, week_ago_point) month_ago_apy = calculate_roi(now_point, month_ago_point) inception_apy = calculate_roi(now_point, inception_point) net_apy = month_ago_apy # performance fee is doubled since 1x strategists + 1x treasury performance = (contract.performanceFee() * 2) if hasattr(contract, "performanceFee") else 0 management = contract.managementFee() if hasattr(contract, "managementFee") else 0 apy = net_apy / (1 - performance / 1e4) + (management / 1e4) points = ApyPoints(week_ago_apy, month_ago_apy, inception_apy) fees = ApyFees(performance=performance, management=management) return Apy("v2:simple", apy, net_apy, fees, points=points)
def simple(vault, samples: ApySamples) -> Apy: harvests = sorted([harvest for strategy in vault.strategies for harvest in strategy.harvests]) # we don't want to display APYs when vaults are ramping up if len(harvests) < 2: raise ApyError("v2:harvests", "harvests are < 2") # set our time values for simple calcs, closest to a harvest around that time period now = closest(harvests, samples.now) week_ago = closest(harvests, samples.week_ago) month_ago = closest(harvests, samples.month_ago) # set our parameters contract = vault.vault price_per_share = contract.pricePerShare # calculate our current price now_price = price_per_share(block_identifier=now) # get our inception data inception_price = 10 ** contract.decimals() inception_block = harvests[:2][-1] if now_price == inception_price: raise ApyError("v2:inception", "no change from inception price") # check our historical data if samples.week_ago > inception_block: week_ago_price = price_per_share(block_identifier=week_ago) else: week_ago_price = inception_price if samples.month_ago > inception_block: month_ago_price = price_per_share(block_identifier=month_ago) else: month_ago_price = inception_price now_point = SharePricePoint(samples.now, now_price) week_ago_point = SharePricePoint(samples.week_ago, week_ago_price) month_ago_point = SharePricePoint(samples.month_ago, month_ago_price) inception_point = SharePricePoint(inception_block, inception_price) week_ago_apy = calculate_roi(now_point, week_ago_point) month_ago_apy = calculate_roi(now_point, month_ago_point) inception_apy = calculate_roi(now_point, inception_point) # use the first non-zero apy, ordered by precedence apys = [month_ago_apy, week_ago_apy, inception_apy] net_apy = next((value for value in apys if value != 0), 0) # for performance fee, half comes from strategy (strategist share) and half from the vault (treasury share) strategy_fees = [] for strategy in vault.strategies: # look at all of our strategies debt_ratio = contract.strategies(strategy.strategy)['debtRatio'] / 10000 performance_fee = contract.strategies(strategy.strategy)['performanceFee'] proportional_fee = debt_ratio * performance_fee strategy_fees.append(proportional_fee) strategy_performance = sum(strategy_fees) vault_performance = contract.performanceFee() if hasattr(contract, "performanceFee") else 0 management = contract.managementFee() if hasattr(contract, "managementFee") else 0 performance = vault_performance + strategy_performance performance /= 1e4 management /= 1e4 # assume we are compounding every week compounding = 52 # calculate our APR after fees apr_after_fees = compounding * ((net_apy + 1) ** (1 / compounding)) - compounding # calculate our pre-fee APR gross_apr = apr_after_fees / (1 - performance) + management # 0.3.5+ should never be < 0% because of management if net_apy < 0 and Version(vault.api_version) >= Version("0.3.5"): net_apy = 0 points = ApyPoints(week_ago_apy, month_ago_apy, inception_apy) fees = ApyFees(performance=performance, management=management) return Apy("v2:simple", gross_apr, net_apy, fees, points=points)
def average(vault, samples: ApySamples) -> Apy: harvests = sorted([harvest for strategy in vault.strategies for harvest in strategy.harvests]) # we don't want to display APYs when vaults are ramping up if len(harvests) < 2: raise ApyError("v2:harvests", "harvests are < 2") # set our parameters contract = vault.vault price_per_share = contract.pricePerShare # calculate our current price now_price = price_per_share(block_identifier=samples.now) # get our inception data inception_price = 10 ** contract.decimals() inception_block = harvests[:2][-1] if now_price == inception_price: raise ApyError("v2:inception", "no change from inception price") # check our historical data if samples.week_ago > inception_block: week_ago_price = price_per_share(block_identifier=samples.week_ago) else: week_ago_price = inception_price if samples.month_ago > inception_block: month_ago_price = price_per_share(block_identifier=samples.month_ago) else: month_ago_price = inception_price now_point = SharePricePoint(samples.now, now_price) week_ago_point = SharePricePoint(samples.week_ago, week_ago_price) month_ago_point = SharePricePoint(samples.month_ago, month_ago_price) inception_point = SharePricePoint(inception_block, inception_price) week_ago_apy = calculate_roi(now_point, week_ago_point) month_ago_apy = calculate_roi(now_point, month_ago_point) inception_apy = calculate_roi(now_point, inception_point) # we should look at a vault's harvests, age, etc to determine whether to show new APY or not # use the first non-zero apy, ordered by precedence apys = [month_ago_apy, week_ago_apy] two_months_ago = datetime.now() - timedelta(days=60) if contract.activation() > two_months_ago.timestamp(): # if the vault was activated less than two months ago then it's ok to use # the inception apy, otherwise using it isn't representative of the current apy apys.append(inception_apy) net_apy = next((value for value in apys if value != 0), 0) # for performance fee, half comes from strategy (strategist share) and half from the vault (treasury share) strategy_fees = [] for strategy in vault.strategies: # look at all of our strategies debt_ratio = contract.strategies(strategy.strategy)['debtRatio'] / 10000 performance_fee = contract.strategies(strategy.strategy)['performanceFee'] proportional_fee = debt_ratio * performance_fee strategy_fees.append(proportional_fee) strategy_performance = sum(strategy_fees) vault_performance = contract.performanceFee() if hasattr(contract, "performanceFee") else 0 management = contract.managementFee() if hasattr(contract, "managementFee") else 0 performance = vault_performance + strategy_performance performance /= 1e4 management /= 1e4 # assume we are compounding every week compounding = 52 # calculate our APR after fees # if net_apy is negative no fees are charged apr_after_fees = compounding * ((net_apy + 1) ** (1 / compounding)) - compounding if net_apy > 0 else net_apy # calculate our pre-fee APR gross_apr = apr_after_fees / (1 - performance) + management # 0.3.5+ should never be < 0% because of management if net_apy < 0 and Version(vault.api_version) >= Version("0.3.5"): net_apy = 0 points = ApyPoints(week_ago_apy, month_ago_apy, inception_apy) fees = ApyFees(performance=performance, management=management) return Apy("v2:averaged", gross_apr, net_apy, fees, points=points)
def simple(vault, samples: ApySamples) -> Apy: inception_block = contract_creation_block(vault.vault.address) if not inception_block: raise ApyError("v1:blocks", "inception_block not found") contract = vault.vault price_per_share = contract.getPricePerFullShare inception_price = 1e18 try: now_price = price_per_share(block_identifier=samples.now) except ValueError: now_price = inception_price if samples.week_ago > inception_block: try: week_ago_price = price_per_share(block_identifier=samples.week_ago) except ValueError: week_ago_price = now_price else: week_ago_price = now_price if samples.month_ago > inception_block: try: month_ago_price = price_per_share( block_identifier=samples.month_ago) except ValueError: month_ago_price = week_ago_price else: month_ago_price = week_ago_price now_point = SharePricePoint(samples.now, now_price) week_ago_point = SharePricePoint(samples.week_ago, week_ago_price) month_ago_point = SharePricePoint(samples.month_ago, month_ago_price) inception_point = SharePricePoint(inception_block, inception_price) week_ago_apy = calculate_roi(now_point, week_ago_point) month_ago_apy = calculate_roi(now_point, month_ago_point) inception_apy = calculate_roi(now_point, inception_point) # use the first non-zero apy, ordered by precedence apys = [week_ago_apy, month_ago_apy, inception_apy] net_apy = next((value for value in apys if value != 0), 0) strategy = vault.strategy withdrawal = strategy.withdrawalFee() if hasattr(strategy, "withdrawalFee") else 0 strategist_performance = strategy.performanceFee() if hasattr( strategy, "performanceFee") else 0 strategist_reward = strategy.strategistReward() if hasattr( strategy, "strategistReward") else 0 treasury = strategy.treasuryFee() if hasattr(strategy, "treasuryFee") else 0 performance = (strategist_reward + strategist_performance + treasury) / 1e4 # assume we are compounding every week compounding = 52 # calculate our APR after fees # if net_apy is negative no fees are charged apr_after_fees = compounding * ( (net_apy + 1)** (1 / compounding)) - compounding if net_apy > 0 else net_apy # calculate our pre-fee APR gross_apr = apr_after_fees / (1 - performance) points = ApyPoints(week_ago_apy, month_ago_apy, inception_apy) fees = ApyFees(performance=performance, withdrawal=withdrawal) return Apy("v1:simple", gross_apr, net_apy, fees, points=points)