@bancor/carbon-sdk
Advanced tools
Comparing version 0.0.88-DEV to 0.0.89-DEV
@@ -236,14 +236,22 @@ import { d as Decimal, t as tenPow, f as formatUnits, p as parseUnits, B as BigNumber, e as trimDecimal, m as mulDiv } from './numerics.js'; | ||
} | ||
function enforcePriceRange(minPrice, maxPrice, marginalPrice, tokenDecimals, canEqualMin, canEqualMax) { | ||
const oneWei = new Decimal(1).div(new Decimal(10).pow(tokenDecimals)); | ||
if (marginalPrice.lte(minPrice)) | ||
return canEqualMin ? minPrice : minPrice.plus(oneWei); | ||
if (marginalPrice.gte(maxPrice)) | ||
return canEqualMax ? maxPrice : maxPrice.minus(oneWei); | ||
return marginalPrice; | ||
} | ||
function calculateOverlappingPriceRanges(buyPriceLow, // in quote tkn per 1 base tkn | ||
sellPriceHigh, // in quote tkn per 1 base tkn | ||
marketPrice, // in quote tkn per 1 base tkn | ||
spreadPercentage // e.g. for 0.1% pass '0.1' | ||
) { | ||
spreadPercentage, // e.g. for 0.1% pass '0.1' | ||
tokenDecimals) { | ||
const spreadFactor = spreadPercentage.div(100).plus(1); | ||
const buyPriceHigh = sellPriceHigh.div(spreadFactor); | ||
const sellPriceLow = buyPriceLow.mul(spreadFactor); | ||
// buy marginal price is the market price minus 0.5 spread. But it can never be lower than buyPriceLow | ||
const buyPriceMarginal = Decimal.max(buyPriceLow, marketPrice.div(spreadFactor.sqrt())); | ||
// sell marginal price is the market price plus 0.5 spread. But ir can never be higher than sellPriceHigh | ||
const sellPriceMarginal = Decimal.min(sellPriceHigh, marketPrice.mul(spreadFactor.sqrt())); | ||
// buy marginal price is derived from the market price. But must be LTE buyPriceHigh and GT buyPriceLow | ||
const buyPriceMarginal = enforcePriceRange(buyPriceLow, buyPriceHigh, marketPrice.div(spreadFactor.sqrt()), tokenDecimals, false, true); | ||
// sell marginal price is derived from the market price. But must be GTE sellPriceLow and LT sellPriceHigh | ||
const sellPriceMarginal = enforcePriceRange(sellPriceLow, sellPriceHigh, marketPrice.mul(spreadFactor.sqrt()), tokenDecimals, true, false); | ||
return { | ||
@@ -260,8 +268,8 @@ buyPriceHigh, | ||
spreadPercentage, // e.g. for 0.1% pass '0.1' | ||
buyBudget // in quote tkn | ||
) { | ||
buyBudget, // in quote tkn | ||
quoteTokenDecimals) { | ||
// zero buy budget means zero sell budget | ||
if (buyBudget.isZero()) | ||
return new Decimal(0); | ||
const { buyPriceHigh, sellPriceMarginal, buyPriceMarginal } = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage); | ||
const { buyPriceHigh, sellPriceMarginal, buyPriceMarginal } = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, quoteTokenDecimals); | ||
// if buy range takes the entire range then there's zero sell budget | ||
@@ -288,8 +296,8 @@ if (sellPriceMarginal.gte(sellPriceHigh)) | ||
spreadPercentage, // e.g. for 0.1% pass '0.1' | ||
sellBudget // in quote tkn | ||
) { | ||
sellBudget, // in quote tkn | ||
quoteTokenDecimals) { | ||
// zero sell budget means zero buy budget | ||
if (sellBudget.isZero()) | ||
return new Decimal(0); | ||
const { sellPriceLow, sellPriceMarginal, buyPriceMarginal } = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage); | ||
const { sellPriceLow, sellPriceMarginal, buyPriceMarginal } = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, quoteTokenDecimals); | ||
// if sell range takes the entire range then there's zero buy budget | ||
@@ -761,3 +769,3 @@ if (buyPriceMarginal.lte(buyPriceLow)) | ||
const quoteDecimals = await decimals.fetchDecimals(quoteToken); | ||
const prices = calculateOverlappingPriceRanges(new Decimal(buyPriceLow), new Decimal(sellPriceHigh), new Decimal(marketPrice), new Decimal(spreadPercentage)); | ||
const prices = calculateOverlappingPriceRanges(new Decimal(buyPriceLow), new Decimal(sellPriceHigh), new Decimal(marketPrice), new Decimal(spreadPercentage), quoteDecimals); | ||
const result = { | ||
@@ -786,7 +794,8 @@ buyPriceHigh: trimDecimal(prices.buyPriceHigh.toString(), quoteDecimals), | ||
*/ | ||
async calculateOverlappingStrategySellBudget(baseToken, buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, buyBudget) { | ||
async calculateOverlappingStrategySellBudget(baseToken, quoteToken, buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, buyBudget) { | ||
logger.debug('calculateOverlappingStrategySellBudget called', arguments); | ||
const decimals = this._decimals; | ||
const baseDecimals = await decimals.fetchDecimals(baseToken); | ||
const budget = calculateOverlappingSellBudget(new Decimal(buyPriceLow), new Decimal(sellPriceHigh), new Decimal(marketPrice), new Decimal(spreadPercentage), new Decimal(buyBudget)); | ||
const quoteDecimals = await decimals.fetchDecimals(quoteToken); | ||
const budget = calculateOverlappingSellBudget(new Decimal(buyPriceLow), new Decimal(sellPriceHigh), new Decimal(marketPrice), new Decimal(spreadPercentage), new Decimal(buyBudget), quoteDecimals); | ||
const result = trimDecimal(budget.toString(), baseDecimals); | ||
@@ -814,3 +823,3 @@ logger.debug('calculateOverlappingStrategySellBudget info:', { | ||
const quoteDecimals = await decimals.fetchDecimals(quoteToken); | ||
const budget = calculateOverlappingBuyBudget(new Decimal(buyPriceLow), new Decimal(sellPriceHigh), new Decimal(marketPrice), new Decimal(spreadPercentage), new Decimal(sellBudget)); | ||
const budget = calculateOverlappingBuyBudget(new Decimal(buyPriceLow), new Decimal(sellPriceHigh), new Decimal(marketPrice), new Decimal(spreadPercentage), new Decimal(sellBudget), quoteDecimals); | ||
const result = trimDecimal(budget.toString(), quoteDecimals); | ||
@@ -898,11 +907,11 @@ logger.debug('calculateOverlappingStrategyBuyBudget info:', { | ||
// step 2: create an encoded strategy object using the method params and the values from the encoded strategy | ||
const newStrategy = buildStrategyObject(originalStrategy.baseToken, originalStrategy.quoteToken, baseDecimals, quoteDecimals, buyPriceLow ?? originalStrategy.buyPriceLow, buyPriceMarginal && | ||
const newStrategy = buildStrategyObject(originalStrategy.baseToken, originalStrategy.quoteToken, baseDecimals, quoteDecimals, buyPriceLow ?? originalStrategy.buyPriceLow, buyPriceMarginal !== undefined && // if we got marginal price use it - otherwise act as reset and use buy high | ||
buyPriceMarginal !== MarginalPriceOptions.reset && | ||
buyPriceMarginal !== MarginalPriceOptions.maintain | ||
? buyPriceMarginal | ||
: originalStrategy.buyPriceMarginal, buyPriceHigh ?? originalStrategy.buyPriceHigh, buyBudget ?? originalStrategy.buyBudget, sellPriceLow ?? originalStrategy.sellPriceLow, sellPriceMarginal && | ||
: buyPriceHigh ?? originalStrategy.buyPriceHigh, buyPriceHigh ?? originalStrategy.buyPriceHigh, buyBudget ?? originalStrategy.buyBudget, sellPriceLow ?? originalStrategy.sellPriceLow, sellPriceMarginal !== undefined && // if we got marginal price use it - otherwise act as reset and use sell low | ||
sellPriceMarginal !== MarginalPriceOptions.reset && | ||
sellPriceMarginal !== MarginalPriceOptions.maintain | ||
? sellPriceMarginal | ||
: originalStrategy.sellPriceMarginal, sellPriceHigh ?? originalStrategy.sellPriceHigh, sellBudget ?? originalStrategy.sellBudget); | ||
: sellPriceLow ?? originalStrategy.sellPriceLow, sellPriceHigh ?? originalStrategy.sellPriceHigh, sellBudget ?? originalStrategy.sellBudget); | ||
const newEncodedStrategy = encodeStrategy(newStrategy); | ||
@@ -912,4 +921,4 @@ // step 3: to avoid changes due to rounding errors, we will override the new encoded strategy with selected values from the old encoded strategy: | ||
// - if no price was defined - we will use the old A and B | ||
// - if any budget was defined - will set z according to MarginalPriceOptions | ||
// - if any price was defined - we will reset z to y | ||
// - if any budget was defined - will set z according to MarginalPriceOptions | ||
// - if marginalPrice is a number - we will use it to calculate z | ||
@@ -942,2 +951,3 @@ const encodedBN = encodedStrategyStrToBN(encoded); | ||
} | ||
// if we have budget to set we handle reset (z <- y) and maintain (maintain y:z ratio). We don't handle marginal price value because it's expressed in z | ||
if (sellBudget !== undefined) { | ||
@@ -954,6 +964,10 @@ if (sellPriceMarginal === undefined || | ||
} | ||
if (buyPriceLow !== undefined || buyPriceHigh !== undefined) { | ||
if ((buyPriceLow !== undefined || buyPriceHigh !== undefined) && | ||
(buyPriceMarginal === MarginalPriceOptions.reset || | ||
buyPriceMarginal === undefined)) { | ||
newEncodedStrategy.order1.z = newEncodedStrategy.order1.y; | ||
} | ||
if (sellPriceLow !== undefined || sellPriceHigh !== undefined) { | ||
if ((sellPriceLow !== undefined || sellPriceHigh !== undefined) && | ||
(sellPriceMarginal === MarginalPriceOptions.reset || | ||
sellPriceMarginal === undefined)) { | ||
newEncodedStrategy.order0.z = newEncodedStrategy.order0.y; | ||
@@ -1055,2 +1069,3 @@ } | ||
encodeStrategy: encodeStrategy, | ||
enforcePriceRange: enforcePriceRange, | ||
normalizeInvertedRate: normalizeInvertedRate, | ||
@@ -1062,2 +1077,2 @@ normalizeRate: normalizeRate, | ||
export { MarginalPriceOptions as M, PPM_RESOLUTION as P, Toolkit as T, normalizeInvertedRate as a, buildStrategyObject as b, createOrders as c, decodeStrategy as d, encodeStrategy as e, addFee as f, calculateOverlappingPriceRanges as g, calculateOverlappingSellBudget as h, index as i, calculateOverlappingBuyBudget as j, normalizeRate as n, parseStrategy as p, subtractFee as s }; | ||
export { MarginalPriceOptions as M, PPM_RESOLUTION as P, Toolkit as T, normalizeInvertedRate as a, buildStrategyObject as b, createOrders as c, decodeStrategy as d, encodeStrategy as e, addFee as f, enforcePriceRange as g, calculateOverlappingPriceRanges as h, index as i, calculateOverlappingSellBudget as j, calculateOverlappingBuyBudget as k, normalizeRate as n, parseStrategy as p, subtractFee as s }; |
@@ -1,2 +0,2 @@ | ||
export { M as MarginalPriceOptions, P as PPM_RESOLUTION, T as Toolkit, f as addFee, b as buildStrategyObject, j as calculateOverlappingBuyBudget, g as calculateOverlappingPriceRanges, h as calculateOverlappingSellBudget, c as createOrders, d as decodeStrategy, e as encodeStrategy, a as normalizeInvertedRate, n as normalizeRate, p as parseStrategy, s as subtractFee } from '../shared/index5.js'; | ||
export { M as MarginalPriceOptions, P as PPM_RESOLUTION, T as Toolkit, f as addFee, b as buildStrategyObject, k as calculateOverlappingBuyBudget, h as calculateOverlappingPriceRanges, j as calculateOverlappingSellBudget, c as createOrders, d as decodeStrategy, e as encodeStrategy, g as enforcePriceRange, a as normalizeInvertedRate, n as normalizeRate, p as parseStrategy, s as subtractFee } from '../shared/index5.js'; | ||
import '../shared/numerics.js'; | ||
@@ -3,0 +3,0 @@ import '../shared/match.js'; |
@@ -258,3 +258,3 @@ import { PopulatedTransaction } from '@ethersproject/contracts'; | ||
*/ | ||
calculateOverlappingStrategySellBudget(baseToken: string, buyPriceLow: string, sellPriceHigh: string, marketPrice: string, spreadPercentage: string, buyBudget: string): Promise<string>; | ||
calculateOverlappingStrategySellBudget(baseToken: string, quoteToken: string, buyPriceLow: string, sellPriceHigh: string, marketPrice: string, spreadPercentage: string, buyBudget: string): Promise<string>; | ||
/** | ||
@@ -261,0 +261,0 @@ * Calculates the buy budget given a sell budget of an overlapping strategy. |
@@ -37,6 +37,8 @@ import { BigNumber, BigNumberish, Decimal } from '../utils/numerics'; | ||
export declare function subtractFee(amount: BigNumberish, tradingFeePPM: number): Decimal; | ||
export declare function enforcePriceRange(minPrice: Decimal, maxPrice: Decimal, marginalPrice: Decimal, tokenDecimals: number, canEqualMin: boolean, canEqualMax: boolean): Decimal; | ||
export declare function calculateOverlappingPriceRanges(buyPriceLow: Decimal, // in quote tkn per 1 base tkn | ||
sellPriceHigh: Decimal, // in quote tkn per 1 base tkn | ||
marketPrice: Decimal, // in quote tkn per 1 base tkn | ||
spreadPercentage: Decimal): { | ||
spreadPercentage: Decimal, // e.g. for 0.1% pass '0.1' | ||
tokenDecimals: number): { | ||
buyPriceHigh: Decimal; | ||
@@ -51,3 +53,4 @@ buyPriceMarginal: Decimal; | ||
spreadPercentage: Decimal, // e.g. for 0.1% pass '0.1' | ||
buyBudget: Decimal): Decimal; | ||
buyBudget: Decimal, // in quote tkn | ||
quoteTokenDecimals: number): Decimal; | ||
export declare function calculateOverlappingBuyBudget(buyPriceLow: Decimal, // in quote tkn per 1 base tkn | ||
@@ -57,3 +60,4 @@ sellPriceHigh: Decimal, // in quote tkn per 1 base tkn | ||
spreadPercentage: Decimal, // e.g. for 0.1% pass '0.1' | ||
sellBudget: Decimal): Decimal; | ||
sellBudget: Decimal, // in quote tkn | ||
quoteTokenDecimals: number): Decimal; | ||
//# sourceMappingURL=utils.d.ts.map |
@@ -5,3 +5,3 @@ { | ||
"source": "src/index.ts", | ||
"version": "0.0.88-DEV", | ||
"version": "0.0.89-DEV", | ||
"description": "The SDK is a READ-ONLY tool, intended to facilitate working with Carbon contracts. It's a convenient wrapper around our matching algorithm, allowing programs and users get a ready to use transaction data that will allow them to manage strategies and fulfill trades", | ||
@@ -8,0 +8,0 @@ "main": "dist/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1056575
24497