@bancor/carbon-sdk
Advanced tools
Comparing version 0.0.91-DEV to 0.0.92-DEV
@@ -24,3 +24,31 @@ import { D as DecToBn, O as ONE, c as BnToDec, B as BigNumber, d as Decimal } from './numerics.js'; | ||
}; | ||
const encodeOrder = (order) => { | ||
const encodeOrders = ([order0, order1]) => { | ||
const liquidity0 = new Decimal(order0.liquidity); | ||
const lowestRate0 = new Decimal(order0.lowestRate); | ||
const highestRate0 = new Decimal(order0.highestRate); | ||
const liquidity1 = new Decimal(order1.liquidity); | ||
const lowestRate1 = new Decimal(order1.lowestRate); | ||
const highestRate1 = new Decimal(order1.highestRate); | ||
// if one order has 0 liquidity and the other has > 0 liquidity - use it to calculate z. | ||
if (liquidity0.eq(0) && | ||
liquidity1.gt(0) && | ||
lowestRate1.gt(0) && | ||
highestRate1.gt(0)) { | ||
return [ | ||
encodeOrder(order0, calculateCorrelatedZ(order1)), | ||
encodeOrder(order1), | ||
]; | ||
} | ||
if (liquidity1.eq(0) && | ||
liquidity0.gt(0) && | ||
lowestRate0.gt(0) && | ||
highestRate0.gt(0)) { | ||
return [ | ||
encodeOrder(order0), | ||
encodeOrder(order1, calculateCorrelatedZ(order0)), | ||
]; | ||
} | ||
return [encodeOrder(order0), encodeOrder(order1)]; | ||
}; | ||
const encodeOrder = (order, z) => { | ||
const liquidity = new Decimal(order.liquidity); | ||
@@ -31,8 +59,11 @@ const lowestRate = new Decimal(order.lowestRate); | ||
if (!((highestRate.gte(marginalRate) && marginalRate.gt(lowestRate)) || | ||
(highestRate.eq(marginalRate) && marginalRate.eq(lowestRate)))) { | ||
(highestRate.eq(marginalRate) && marginalRate.eq(lowestRate)) || | ||
(highestRate.gt(marginalRate) && | ||
marginalRate.eq(lowestRate) && | ||
liquidity.isZero()))) | ||
throw new Error('Either one of the following must hold:\n' + | ||
'- highestRate >= marginalRate > lowestRate\n' + | ||
'- highestRate == marginalRate == lowestRate\n' + | ||
'- (highestRate > marginalRate == lowestRate) AND liquidity == 0\n' + | ||
`(highestRate = ${highestRate}, marginalRate = ${marginalRate}, lowestRate = ${lowestRate})`); | ||
} | ||
const y = DecToBn(liquidity); | ||
@@ -43,4 +74,8 @@ const L = DecToBn(encodeRate(lowestRate)); | ||
return { | ||
y: y, | ||
z: H.eq(M) ? y : y.mul(H.sub(L)).div(M.sub(L)), | ||
y, | ||
z: z !== undefined | ||
? z | ||
: H.eq(M) || y.isZero() | ||
? y | ||
: y.mul(H.sub(L)).div(M.sub(L)), | ||
A: encodeFloat(H.sub(L)), | ||
@@ -62,14 +97,28 @@ B: encodeFloat(L), | ||
}; | ||
/** | ||
* Use the ratio between the z and the price geometric average to calculate what z | ||
* value should be used for the other order in order to preserve correlation between | ||
* the two orders - and provide the liquidity that should be used to achieve that. | ||
*/ | ||
const calculateRequiredLiquidity = (knownOrder, vagueOrder) => { | ||
const capacity = BnToDec(encodeOrder(knownOrder).z); | ||
const lowestRate = new Decimal(knownOrder.lowestRate); | ||
const highestRate = new Decimal(knownOrder.highestRate); | ||
const geoAverageRate = lowestRate.mul(highestRate).sqrt(); | ||
const z = DecToBn(capacity.div(geoAverageRate).floor()); | ||
const z = calculateCorrelatedZ(knownOrder); | ||
const L = DecToBn(encodeRate(new Decimal(vagueOrder.lowestRate))); | ||
const H = DecToBn(encodeRate(new Decimal(vagueOrder.highestRate))); | ||
const M = DecToBn(encodeRate(new Decimal(vagueOrder.marginalRate))); | ||
return z.mul(M.sub(L)).div(H.sub(L)); | ||
return z.mul(M.sub(L)).div(H.sub(L)).toString(); | ||
}; | ||
/** | ||
* Use the ratio between the z and the price geometric average to calculate what z | ||
* value should be used for the other order in order to preserve correlation between | ||
* the two orders. This should be used when the other order has 0 liquidity - as z can't | ||
* be determined otherwise. | ||
*/ | ||
const calculateCorrelatedZ = (order) => { | ||
const capacity = BnToDec(encodeOrder(order).z); | ||
const lowestRate = new Decimal(order.lowestRate); | ||
const highestRate = new Decimal(order.highestRate); | ||
const geoAverageRate = lowestRate.mul(highestRate).sqrt(); | ||
return DecToBn(capacity.div(geoAverageRate).floor()); | ||
}; | ||
export { decodeOrder as a, decodeRate as b, calculateRequiredLiquidity as c, decodeFloat as d, encodeFloat as e, encodeOrder as f, encodeRate as g }; | ||
export { calculateRequiredLiquidity as a, decodeOrder as b, calculateCorrelatedZ as c, decodeFloat as d, decodeRate as e, encodeFloat as f, encodeOrder as g, encodeOrders as h, encodeRate as i }; |
import { D as Decimals } from './decimals.js'; | ||
import { c as calculateRequiredLiquidity, d as decodeFloat, a as decodeOrder, b as decodeRate, e as encodeFloat, f as encodeOrder, g as encodeRate } from './encoders.js'; | ||
import { c as calculateCorrelatedZ, a as calculateRequiredLiquidity, d as decodeFloat, b as decodeOrder, e as decodeRate, f as encodeFloat, g as encodeOrder, h as encodeOrders, i as encodeRate } from './encoders.js'; | ||
import { e as encodedOrderBNToStr, a as encodedOrderStrToBN, b as encodedStrategyBNToStr, c as encodedStrategyStrToBN, m as matchActionBNToStr, o as ordersMapBNToStr, d as ordersMapStrToBN, r as replaceBigNumbersWithStrings, t as tradeActionStrToBN } from './serializers.js'; | ||
@@ -17,2 +17,3 @@ import { B as BigNumber, a as BigNumberMax, b as BigNumberMin, c as BnToDec, D as DecToBn, d as Decimal, O as ONE, T as TEN, f as formatUnits, m as mulDiv, p as parseUnits, t as tenPow, e as trimDecimal } from './numerics.js'; | ||
TEN: TEN, | ||
calculateCorrelatedZ: calculateCorrelatedZ, | ||
calculateRequiredLiquidity: calculateRequiredLiquidity, | ||
@@ -24,2 +25,3 @@ decodeFloat: decodeFloat, | ||
encodeOrder: encodeOrder, | ||
encodeOrders: encodeOrders, | ||
encodeRate: encodeRate, | ||
@@ -26,0 +28,0 @@ encodedOrderBNToStr: encodedOrderBNToStr, |
@@ -5,3 +5,3 @@ 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'; | ||
import { L as Logger } from './logger.js'; | ||
import { f as encodeOrder, a as decodeOrder, c as calculateRequiredLiquidity } from './encoders.js'; | ||
import { h as encodeOrders, b as decodeOrder, a as calculateRequiredLiquidity } from './encoders.js'; | ||
import { b as encodedStrategyBNToStr, d as ordersMapStrToBN, m as matchActionBNToStr, o as ordersMapBNToStr, t as tradeActionStrToBN, c as encodedStrategyStrToBN } from './serializers.js'; | ||
@@ -72,7 +72,8 @@ | ||
const encodeStrategy = (strategy) => { | ||
const [order0, order1] = encodeOrders([strategy.order0, strategy.order1]); | ||
return { | ||
token0: strategy.token0, | ||
token1: strategy.token1, | ||
order0: encodeOrder(strategy.order0), | ||
order1: encodeOrder(strategy.order1), | ||
order0, | ||
order1, | ||
}; | ||
@@ -191,33 +192,44 @@ }; | ||
} | ||
function createOrders(baseTokenDecimals, quoteTokenDecimals, buyPriceLow, buyPriceMarginal, buyPriceHigh, buyBudget, sellPriceLow, sellPriceMarginal, sellPriceHigh, sellBudget) { | ||
logger$1.debug('createOrders called', arguments); | ||
function createFromBuyOrder(baseTokenDecimals, quoteTokenDecimals, buyPriceLow, buyPriceMarginal, buyPriceHigh, buyBudget) { | ||
logger$1.debug('createFromBuyOrder called', arguments); | ||
// convert quote token liquidity (budget) to wei | ||
const liquidity = parseUnits(buyBudget, quoteTokenDecimals); | ||
/* this order sells quote token so the rates are quote token per 1 base token. | ||
Converting to wei in order to factor out different decimals */ | ||
const lowestRate = normalizeRate(buyPriceLow, quoteTokenDecimals, baseTokenDecimals); | ||
const marginalRate = normalizeRate(buyPriceMarginal, quoteTokenDecimals, baseTokenDecimals); | ||
const highestRate = normalizeRate(buyPriceHigh, quoteTokenDecimals, baseTokenDecimals); | ||
const order = { | ||
liquidity: liquidity.toString(), | ||
lowestRate: lowestRate, | ||
highestRate: highestRate, | ||
marginalRate: marginalRate, | ||
}; | ||
logger$1.debug('createFromBuyOrder info:', { order }); | ||
return order; | ||
} | ||
function createFromSellOrder(baseTokenDecimals, quoteTokenDecimals, sellPriceLow, sellPriceMarginal, sellPriceHigh, sellBudget) { | ||
logger$1.debug('createFromSellOrder called', arguments); | ||
// order 0 is selling the base token | ||
// convert base token liquidity (budget) to wei | ||
const liquidity0 = parseUnits(sellBudget, baseTokenDecimals); | ||
const liquidity = parseUnits(sellBudget, baseTokenDecimals); | ||
/* this order sells base token so the rates are base token per 1 quote token, | ||
meaning we need to do 1 over - and then low rate is 1/high price. | ||
Converting to wei in order to factor out different decimals */ | ||
const lowestRate0 = normalizeInvertedRate(sellPriceHigh, quoteTokenDecimals, baseTokenDecimals); | ||
const marginalRate0 = normalizeInvertedRate(sellPriceMarginal, quoteTokenDecimals, baseTokenDecimals); | ||
const highestRate0 = normalizeInvertedRate(sellPriceLow, quoteTokenDecimals, baseTokenDecimals); | ||
// order 1 is selling the quote token | ||
// convert quote token liquidity (budget) to wei | ||
const liquidity1 = parseUnits(buyBudget, quoteTokenDecimals); | ||
/* this order sells quote token so the rates are quote token per 1 base token. | ||
Converting to wei in order to factor out different decimals */ | ||
const lowestRate1 = normalizeRate(buyPriceLow, quoteTokenDecimals, baseTokenDecimals); | ||
const marginalRate1 = normalizeRate(buyPriceMarginal, quoteTokenDecimals, baseTokenDecimals); | ||
const highestRate1 = normalizeRate(buyPriceHigh, quoteTokenDecimals, baseTokenDecimals); | ||
const order0 = { | ||
liquidity: liquidity0.toString(), | ||
lowestRate: lowestRate0, | ||
highestRate: highestRate0, | ||
marginalRate: marginalRate0, | ||
const lowestRate = normalizeInvertedRate(sellPriceHigh, quoteTokenDecimals, baseTokenDecimals); | ||
const marginalRate = normalizeInvertedRate(sellPriceMarginal, quoteTokenDecimals, baseTokenDecimals); | ||
const highestRate = normalizeInvertedRate(sellPriceLow, quoteTokenDecimals, baseTokenDecimals); | ||
const order = { | ||
liquidity: liquidity.toString(), | ||
lowestRate: lowestRate, | ||
highestRate: highestRate, | ||
marginalRate: marginalRate, | ||
}; | ||
const order1 = { | ||
liquidity: liquidity1.toString(), | ||
lowestRate: lowestRate1, | ||
highestRate: highestRate1, | ||
marginalRate: marginalRate1, | ||
}; | ||
logger$1.debug('createFromSellOrder info:', { order }); | ||
return order; | ||
} | ||
function createOrders(baseTokenDecimals, quoteTokenDecimals, buyPriceLow, buyPriceMarginal, buyPriceHigh, buyBudget, sellPriceLow, sellPriceMarginal, sellPriceHigh, sellBudget) { | ||
logger$1.debug('createOrders called', arguments); | ||
const order0 = createFromSellOrder(baseTokenDecimals, quoteTokenDecimals, sellPriceLow, sellPriceMarginal, sellPriceHigh, sellBudget); | ||
const order1 = createFromBuyOrder(baseTokenDecimals, quoteTokenDecimals, buyPriceLow, buyPriceMarginal, buyPriceHigh, buyBudget); | ||
logger$1.debug('createOrders info:', { order0, order1 }); | ||
@@ -239,8 +251,7 @@ return { order0, order1 }; | ||
} | ||
function enforcePriceRange(minPrice, maxPrice, marginalPrice, tokenDecimals, canEqualMin, canEqualMax) { | ||
const oneWei = new Decimal(1).div(new Decimal(10).pow(tokenDecimals)); | ||
function enforcePriceRange(minPrice, maxPrice, marginalPrice) { | ||
if (marginalPrice.lte(minPrice)) | ||
return canEqualMin ? minPrice : minPrice.plus(oneWei); | ||
return minPrice; | ||
if (marginalPrice.gte(maxPrice)) | ||
return canEqualMax ? maxPrice : maxPrice.minus(oneWei); | ||
return maxPrice; | ||
return marginalPrice; | ||
@@ -251,70 +262,62 @@ } | ||
marketPrice, // in quote tkn per 1 base tkn | ||
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 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); | ||
spreadPercentage // e.g. for 0.1% pass '0.1' | ||
) { | ||
const spreadFactor = new Decimal(spreadPercentage).div(100).plus(1); | ||
const buyPriceHigh = new Decimal(sellPriceHigh).div(spreadFactor); | ||
const sellPriceLow = new Decimal(buyPriceLow).mul(spreadFactor); | ||
// buy marginal price is derived from the market price. But must be LTE buyPriceHigh and GTE buyPriceLow | ||
const buyPriceMarginal = enforcePriceRange(new Decimal(buyPriceLow), buyPriceHigh, new Decimal(marketPrice).div(spreadFactor.sqrt())); | ||
// sell marginal price is derived from the market price. But must be GTE sellPriceLow and LTE sellPriceHigh | ||
const sellPriceMarginal = enforcePriceRange(sellPriceLow, new Decimal(sellPriceHigh), new Decimal(marketPrice).mul(spreadFactor.sqrt())); | ||
return { | ||
buyPriceHigh, | ||
buyPriceMarginal, | ||
sellPriceLow, | ||
sellPriceMarginal, | ||
buyPriceHigh: buyPriceHigh.toString(), | ||
buyPriceMarginal: buyPriceMarginal.toString(), | ||
sellPriceLow: sellPriceLow.toString(), | ||
sellPriceMarginal: sellPriceMarginal.toString(), | ||
}; | ||
} | ||
function calculateOverlappingSellBudget(buyPriceLow, // in quote tkn per 1 base tkn | ||
function calculateOverlappingSellBudget(baseTokenDecimals, quoteTokenDecimals, 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' | ||
buyBudget, // in quote tkn | ||
quoteTokenDecimals) { | ||
buyBudget // in quote tkn | ||
) { | ||
// zero buy budget means zero sell budget | ||
if (buyBudget.isZero()) | ||
return new Decimal(0); | ||
const { buyPriceHigh, sellPriceMarginal, buyPriceMarginal } = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, quoteTokenDecimals); | ||
if (buyBudget === '0') | ||
return '0'; | ||
const { buyPriceHigh, sellPriceLow, sellPriceMarginal, buyPriceMarginal } = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage); | ||
// if buy range takes the entire range then there's zero sell budget | ||
if (sellPriceMarginal.gte(sellPriceHigh)) | ||
return new Decimal(0); | ||
if (new Decimal(sellPriceMarginal).gte(sellPriceHigh)) | ||
return '0'; | ||
// if buy range is zero there's no point to this call | ||
if (buyPriceMarginal.lte(buyPriceLow)) { | ||
if (new Decimal(buyPriceMarginal).lte(buyPriceLow)) { | ||
throw new Error('calculateOverlappingSellBudget called with zero buy range and non zero buy budget'); | ||
} | ||
const buyPriceRange = buyPriceHigh.minus(buyPriceLow); | ||
const buyLowRange = buyPriceMarginal.minus(buyPriceLow); | ||
const buyLowBudgetRatio = buyLowRange.div(buyPriceRange); | ||
const buyOrderYint = new Decimal(buyBudget).div(buyLowBudgetRatio); | ||
const geoMeanOfBuyRange = buyPriceLow.mul(buyPriceHigh).sqrt(); | ||
const sellOrderYint = buyOrderYint.div(geoMeanOfBuyRange); | ||
const sellHighBudgetRatio = new Decimal(1).minus(buyLowBudgetRatio); | ||
const sellBudget = sellOrderYint.mul(sellHighBudgetRatio); | ||
const decodedBuyOrder = createFromBuyOrder(baseTokenDecimals, quoteTokenDecimals, buyPriceLow, buyPriceMarginal, buyPriceHigh, buyBudget); | ||
const decodedSellOrder = createFromSellOrder(baseTokenDecimals, quoteTokenDecimals, sellPriceLow, sellPriceMarginal, sellPriceHigh, '0'); | ||
const sellLiquidity = calculateRequiredLiquidity(decodedBuyOrder, decodedSellOrder); | ||
const sellBudget = formatUnits(sellLiquidity, baseTokenDecimals); | ||
return sellBudget; | ||
} | ||
function calculateOverlappingBuyBudget(buyPriceLow, // in quote tkn per 1 base tkn | ||
function calculateOverlappingBuyBudget(baseTokenDecimals, quoteTokenDecimals, 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' | ||
sellBudget, // in quote tkn | ||
quoteTokenDecimals) { | ||
sellBudget // in base tkn | ||
) { | ||
// zero sell budget means zero buy budget | ||
if (sellBudget.isZero()) | ||
return new Decimal(0); | ||
const { sellPriceLow, sellPriceMarginal, buyPriceMarginal } = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, quoteTokenDecimals); | ||
if (sellBudget === '0') | ||
return '0'; | ||
const { sellPriceLow, buyPriceHigh, sellPriceMarginal, buyPriceMarginal } = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage); | ||
// if sell range takes the entire range then there's zero buy budget | ||
if (buyPriceMarginal.lte(buyPriceLow)) | ||
return new Decimal(0); | ||
if (new Decimal(buyPriceMarginal).lte(buyPriceLow)) | ||
return '0'; | ||
// if sell range is zero there's no point to this call | ||
if (sellPriceMarginal.gte(sellPriceHigh)) { | ||
if (new Decimal(sellPriceMarginal).gte(sellPriceHigh)) { | ||
throw new Error('calculateOverlappingBuyBudget called with zero sell range and non zero sell budget'); | ||
} | ||
const sellPriceRange = sellPriceHigh.minus(sellPriceLow); | ||
const sellHighRange = sellPriceHigh.minus(sellPriceMarginal); | ||
const sellHighBudgetRatio = sellHighRange.div(sellPriceRange); | ||
const sellOrderYint = new Decimal(sellBudget).div(sellHighBudgetRatio); | ||
const geoMeanOfSellRange = sellPriceHigh.mul(sellPriceLow).sqrt(); | ||
const buyOrderYint = sellOrderYint.mul(geoMeanOfSellRange); | ||
const buyLowBudgetRatio = new Decimal(1).minus(sellHighBudgetRatio); | ||
const buyBudget = buyOrderYint.mul(buyLowBudgetRatio); | ||
const decodedBuyOrder = createFromBuyOrder(baseTokenDecimals, quoteTokenDecimals, buyPriceLow, buyPriceMarginal, buyPriceHigh, '0'); | ||
const decodedSellOrder = createFromSellOrder(baseTokenDecimals, quoteTokenDecimals, sellPriceLow, sellPriceMarginal, sellPriceHigh, sellBudget); | ||
const buyLiquidity = calculateRequiredLiquidity(decodedSellOrder, decodedBuyOrder); | ||
const buyBudget = formatUnits(buyLiquidity, quoteTokenDecimals); | ||
return buyBudget; | ||
@@ -334,2 +337,8 @@ } | ||
})(MarginalPriceOptions || (MarginalPriceOptions = {})); | ||
// Helper function to check whether an actual number was passed and not undefined or the reset/maintain options | ||
function isMarginalPriceValue(marginalPrice) { | ||
return (marginalPrice !== undefined && | ||
marginalPrice !== MarginalPriceOptions.reset && | ||
marginalPrice !== MarginalPriceOptions.maintain); | ||
} | ||
class Toolkit { | ||
@@ -790,10 +799,10 @@ _api; | ||
const quoteDecimals = await decimals.fetchDecimals(quoteToken); | ||
const prices = calculateOverlappingPriceRanges(new Decimal(buyPriceLow), new Decimal(sellPriceHigh), new Decimal(marketPrice), new Decimal(spreadPercentage), quoteDecimals); | ||
const prices = calculateOverlappingPriceRanges(buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage); | ||
const result = { | ||
buyPriceLow: trimDecimal(buyPriceLow, quoteDecimals), | ||
buyPriceHigh: trimDecimal(prices.buyPriceHigh.toString(), quoteDecimals), | ||
buyPriceMarginal: trimDecimal(prices.buyPriceMarginal.toString(), quoteDecimals), | ||
sellPriceLow: trimDecimal(prices.sellPriceLow.toString(), quoteDecimals), | ||
buyPriceHigh: trimDecimal(prices.buyPriceHigh, quoteDecimals), | ||
buyPriceMarginal: trimDecimal(prices.buyPriceMarginal, quoteDecimals), | ||
sellPriceLow: trimDecimal(prices.sellPriceLow, quoteDecimals), | ||
sellPriceHigh: trimDecimal(sellPriceHigh, quoteDecimals), | ||
sellPriceMarginal: trimDecimal(prices.sellPriceMarginal.toString(), quoteDecimals), | ||
sellPriceMarginal: trimDecimal(prices.sellPriceMarginal, quoteDecimals), | ||
marketPrice: trimDecimal(marketPrice, quoteDecimals), | ||
@@ -823,9 +832,8 @@ }; | ||
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); | ||
const budget = calculateOverlappingSellBudget(baseDecimals, quoteDecimals, buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, buyBudget); | ||
logger.debug('calculateOverlappingStrategySellBudget info:', { | ||
baseDecimals, | ||
result, | ||
budget, | ||
}); | ||
return result; | ||
return budget; | ||
} | ||
@@ -843,13 +851,13 @@ /** | ||
*/ | ||
async calculateOverlappingStrategyBuyBudget(quoteToken, buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, sellBudget) { | ||
async calculateOverlappingStrategyBuyBudget(baseToken, quoteToken, buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, sellBudget) { | ||
logger.debug('calculateOverlappingStrategyBuyBudget called', arguments); | ||
const decimals = this._decimals; | ||
const baseDecimals = await decimals.fetchDecimals(baseToken); | ||
const quoteDecimals = await decimals.fetchDecimals(quoteToken); | ||
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); | ||
const budget = calculateOverlappingBuyBudget(baseDecimals, quoteDecimals, buyPriceLow, sellPriceHigh, marketPrice, spreadPercentage, sellBudget); | ||
logger.debug('calculateOverlappingStrategyBuyBudget info:', { | ||
quoteDecimals, | ||
result, | ||
budget, | ||
}); | ||
return result; | ||
return budget; | ||
} | ||
@@ -912,10 +920,2 @@ /** | ||
const encStrategy = encodeStrategy(strategy); | ||
// if exactly one of the encStrategy orders has y value 0 we will set its z value using calculateRequiredLiquidity | ||
if (encStrategy.order0.y.isZero() && !encStrategy.order1.y.isZero()) { | ||
encStrategy.order0.z = calculateRequiredLiquidity(strategy.order1, strategy.order0); | ||
} | ||
else if (!encStrategy.order0.y.isZero() && | ||
encStrategy.order1.y.isZero()) { | ||
encStrategy.order1.z = calculateRequiredLiquidity(strategy.order0, strategy.order1); | ||
} | ||
logger.debug('createBuySellStrategy info:', { strategy, encStrategy }); | ||
@@ -947,9 +947,5 @@ return this._api.composer.createStrategy(encStrategy.token0, encStrategy.token1, encStrategy.order0, encStrategy.order1, overrides); | ||
// 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 !== undefined && // if we got marginal price use it - otherwise act as reset and use buy high | ||
buyPriceMarginal !== MarginalPriceOptions.reset && | ||
buyPriceMarginal !== MarginalPriceOptions.maintain | ||
const newStrategy = buildStrategyObject(originalStrategy.baseToken, originalStrategy.quoteToken, baseDecimals, quoteDecimals, buyPriceLow ?? originalStrategy.buyPriceLow, isMarginalPriceValue(buyPriceMarginal) // if we got marginal price use it - otherwise act as reset and use buy high | ||
? buyPriceMarginal | ||
: 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 | ||
: buyPriceHigh ?? originalStrategy.buyPriceHigh, buyPriceHigh ?? originalStrategy.buyPriceHigh, buyBudget ?? originalStrategy.buyBudget, sellPriceLow ?? originalStrategy.sellPriceLow, isMarginalPriceValue(sellPriceMarginal) // if we got marginal price use it - otherwise act as reset and use sell low | ||
? sellPriceMarginal | ||
@@ -980,3 +976,4 @@ : sellPriceLow ?? originalStrategy.sellPriceLow, sellPriceHigh ?? originalStrategy.sellPriceHigh, sellBudget ?? originalStrategy.sellBudget); | ||
if (buyBudget !== undefined) { | ||
if (buyPriceMarginal === undefined || | ||
if (isMarginalPriceValue(buyPriceMarginal)) ; | ||
else if (buyPriceMarginal === undefined || | ||
buyPriceMarginal === MarginalPriceOptions.reset || | ||
@@ -993,3 +990,4 @@ encodedBN.order1.y.isZero()) { | ||
if (sellBudget !== undefined) { | ||
if (sellPriceMarginal === undefined || | ||
if (isMarginalPriceValue(sellPriceMarginal)) ; | ||
else if (sellPriceMarginal === undefined || | ||
sellPriceMarginal === MarginalPriceOptions.reset || | ||
@@ -1105,2 +1103,4 @@ encodedBN.order0.y.isZero()) { | ||
calculateOverlappingSellBudget: calculateOverlappingSellBudget, | ||
createFromBuyOrder: createFromBuyOrder, | ||
createFromSellOrder: createFromSellOrder, | ||
createOrders: createOrders, | ||
@@ -1110,2 +1110,3 @@ decodeStrategy: decodeStrategy, | ||
enforcePriceRange: enforcePriceRange, | ||
isMarginalPriceValue: isMarginalPriceValue, | ||
normalizeInvertedRate: normalizeInvertedRate, | ||
@@ -1117,2 +1118,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, enforcePriceRange as g, calculateOverlappingPriceRanges as h, index as i, calculateOverlappingSellBudget as j, calculateOverlappingBuyBudget as k, normalizeRate as n, parseStrategy as p, subtractFee as s }; | ||
export { MarginalPriceOptions as M, PPM_RESOLUTION as P, Toolkit as T, isMarginalPriceValue as a, normalizeInvertedRate as b, buildStrategyObject as c, decodeStrategy as d, encodeStrategy as e, createFromBuyOrder as f, createFromSellOrder as g, createOrders as h, index as i, addFee as j, enforcePriceRange as k, calculateOverlappingPriceRanges as l, calculateOverlappingSellBudget as m, normalizeRate as n, calculateOverlappingBuyBudget as o, 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, 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'; | ||
export { M as MarginalPriceOptions, P as PPM_RESOLUTION, T as Toolkit, j as addFee, c as buildStrategyObject, o as calculateOverlappingBuyBudget, l as calculateOverlappingPriceRanges, m as calculateOverlappingSellBudget, f as createFromBuyOrder, g as createFromSellOrder, h as createOrders, d as decodeStrategy, e as encodeStrategy, k as enforcePriceRange, a as isMarginalPriceValue, b 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'; |
@@ -16,2 +16,3 @@ import { PopulatedTransaction } from '@ethersproject/contracts'; | ||
} | ||
export declare function isMarginalPriceValue(marginalPrice?: MarginalPriceOptions | string): boolean; | ||
export declare class Toolkit { | ||
@@ -292,3 +293,3 @@ private _api; | ||
*/ | ||
calculateOverlappingStrategyBuyBudget(quoteToken: string, buyPriceLow: string, sellPriceHigh: string, marketPrice: string, spreadPercentage: string, sellBudget: string): Promise<string>; | ||
calculateOverlappingStrategyBuyBudget(baseToken: string, quoteToken: string, buyPriceLow: string, sellPriceHigh: string, marketPrice: string, spreadPercentage: string, sellBudget: string): Promise<string>; | ||
/** | ||
@@ -295,0 +296,0 @@ * Creates an unsigned transaction to create a strategy for buying and selling tokens of `baseToken` for price in `quoteToken` per 1 `baseToken`. |
@@ -30,2 +30,4 @@ import { BigNumber, BigNumberish, Decimal } from '../utils/numerics'; | ||
sellBudget: string): DecodedStrategy; | ||
export declare function createFromBuyOrder(baseTokenDecimals: number, quoteTokenDecimals: number, buyPriceLow: string, buyPriceMarginal: string, buyPriceHigh: string, buyBudget: string): DecodedOrder; | ||
export declare function createFromSellOrder(baseTokenDecimals: number, quoteTokenDecimals: number, sellPriceLow: string, sellPriceMarginal: string, sellPriceHigh: string, sellBudget: string): DecodedOrder; | ||
export declare function createOrders(baseTokenDecimals: number, quoteTokenDecimals: number, buyPriceLow: string, buyPriceMarginal: string, buyPriceHigh: string, buyBudget: string, sellPriceLow: string, sellPriceMarginal: string, sellPriceHigh: string, sellBudget: string): { | ||
@@ -38,25 +40,22 @@ order0: DecodedOrder; | ||
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, // e.g. for 0.1% pass '0.1' | ||
tokenDecimals: number): { | ||
buyPriceHigh: Decimal; | ||
buyPriceMarginal: Decimal; | ||
sellPriceLow: Decimal; | ||
sellPriceMarginal: Decimal; | ||
export declare function enforcePriceRange(minPrice: Decimal, maxPrice: Decimal, marginalPrice: Decimal): Decimal; | ||
export declare function calculateOverlappingPriceRanges(buyPriceLow: string, // in quote tkn per 1 base tkn | ||
sellPriceHigh: string, // in quote tkn per 1 base tkn | ||
marketPrice: string, // in quote tkn per 1 base tkn | ||
spreadPercentage: string): { | ||
buyPriceHigh: string; | ||
buyPriceMarginal: string; | ||
sellPriceLow: string; | ||
sellPriceMarginal: string; | ||
}; | ||
export declare function calculateOverlappingSellBudget(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, // e.g. for 0.1% pass '0.1' | ||
buyBudget: Decimal, // in quote tkn | ||
quoteTokenDecimals: number): Decimal; | ||
export declare function calculateOverlappingBuyBudget(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, // e.g. for 0.1% pass '0.1' | ||
sellBudget: Decimal, // in quote tkn | ||
quoteTokenDecimals: number): Decimal; | ||
export declare function calculateOverlappingSellBudget(baseTokenDecimals: number, quoteTokenDecimals: number, buyPriceLow: string, // in quote tkn per 1 base tkn | ||
sellPriceHigh: string, // in quote tkn per 1 base tkn | ||
marketPrice: string, // in quote tkn per 1 base tkn | ||
spreadPercentage: string, // e.g. for 0.1% pass '0.1' | ||
buyBudget: string): string; | ||
export declare function calculateOverlappingBuyBudget(baseTokenDecimals: number, quoteTokenDecimals: number, buyPriceLow: string, // in quote tkn per 1 base tkn | ||
sellPriceHigh: string, // in quote tkn per 1 base tkn | ||
marketPrice: string, // in quote tkn per 1 base tkn | ||
spreadPercentage: string, // e.g. for 0.1% pass '0.1' | ||
sellBudget: string): string; | ||
//# sourceMappingURL=utils.d.ts.map |
@@ -7,5 +7,21 @@ import { BigNumber, Decimal } from './numerics'; | ||
export declare const decodeFloat: (value: BigNumber) => BigNumber; | ||
export declare const encodeOrder: (order: DecodedOrder) => EncodedOrder; | ||
export declare const encodeOrders: ([order0, order1]: [DecodedOrder, DecodedOrder]) => [ | ||
EncodedOrder, | ||
EncodedOrder | ||
]; | ||
export declare const encodeOrder: (order: DecodedOrder, z?: BigNumber) => EncodedOrder; | ||
export declare const decodeOrder: (order: EncodedOrder) => DecodedOrder; | ||
export declare const calculateRequiredLiquidity: (knownOrder: DecodedOrder, vagueOrder: DecodedOrder) => BigNumber; | ||
/** | ||
* Use the ratio between the z and the price geometric average to calculate what z | ||
* value should be used for the other order in order to preserve correlation between | ||
* the two orders - and provide the liquidity that should be used to achieve that. | ||
*/ | ||
export declare const calculateRequiredLiquidity: (knownOrder: DecodedOrder, vagueOrder: DecodedOrder) => string; | ||
/** | ||
* Use the ratio between the z and the price geometric average to calculate what z | ||
* value should be used for the other order in order to preserve correlation between | ||
* the two orders. This should be used when the other order has 0 liquidity - as z can't | ||
* be determined otherwise. | ||
*/ | ||
export declare const calculateCorrelatedZ: (order: DecodedOrder) => BigNumber; | ||
//# sourceMappingURL=encoders.d.ts.map |
export { D as Decimals } from '../shared/decimals.js'; | ||
export { c as calculateRequiredLiquidity, d as decodeFloat, a as decodeOrder, b as decodeRate, e as encodeFloat, f as encodeOrder, g as encodeRate } from '../shared/encoders.js'; | ||
export { c as calculateCorrelatedZ, a as calculateRequiredLiquidity, d as decodeFloat, b as decodeOrder, e as decodeRate, f as encodeFloat, g as encodeOrder, h as encodeOrders, i as encodeRate } from '../shared/encoders.js'; | ||
export { e as encodedOrderBNToStr, a as encodedOrderStrToBN, b as encodedStrategyBNToStr, c as encodedStrategyStrToBN, m as matchActionBNToStr, o as ordersMapBNToStr, d as ordersMapStrToBN, r as replaceBigNumbersWithStrings, t as tradeActionStrToBN } from '../shared/serializers.js'; | ||
export { B as BigNumber, a as BigNumberMax, b as BigNumberMin, c as BnToDec, D as DecToBn, d as Decimal, O as ONE, T as TEN, f as formatUnits, m as mulDiv, p as parseUnits, t as tenPow, e as trimDecimal } from '../shared/numerics.js'; |
@@ -5,3 +5,3 @@ { | ||
"source": "src/index.ts", | ||
"version": "0.0.91-DEV", | ||
"version": "0.0.92-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
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
1067002
24642