-
Notifications
You must be signed in to change notification settings - Fork 429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Limit Orders #3347
feat: Limit Orders #3347
Changes from 219 commits
bb69828
54dfc5f
979cdc3
8246e8e
3883bd5
307ca2c
6352059
2862289
7d32901
9da40bc
74784ff
262f22b
2a357e6
70d7f0a
075fa96
427a4ed
eb6db5f
034ece2
cfb264c
7e8d0bd
ffa37d2
20c75d0
97dcf0e
4c0bfd2
1ec29fa
8c6460c
d5b4d1f
fc56f6b
8355353
67bbc62
6b66869
63fe05f
27ab841
43d4cbe
90cb83f
2fabf3b
09482b5
d04a655
dad8df5
086d35b
f6b977b
294e763
4a96ea1
c082fae
1617658
effb213
1d3ede7
a3f4c6b
98cd94f
446116d
921f944
72d2fd6
d39c718
46b75c8
c17284b
4d6011f
ee2f644
7b85b07
9617a83
5ac9f98
67100bf
40c5b0b
52da424
72cf757
784c059
5717447
60fc2af
06fc4b9
5e9d988
5183f93
06ab7a8
0e5de26
f5f160c
a3c12fa
ad8e9fa
f27ee96
fc3f688
bdad3f0
ea8e400
14bb1c8
409b13a
31128bc
6fd53c7
684ae0e
ef33052
4670be1
2c6d3de
bdd7521
deb660b
438020b
49150b8
f1f71ea
17c16ac
5d27e3e
9461630
a7e8b1f
c412f04
0467185
e283f4b
7dec55d
e7d36c7
b8843c4
11309f5
74dd987
1562414
90a8ebf
40cc6b5
dc6000a
0f4c64d
707891d
257ea3b
f5e740c
20289d0
ad12f9d
4495569
3c8e2ac
82413ab
02dc2bc
a22eb70
0a345ea
780be4b
8cd430f
eba4a19
389b3ce
c8ae72d
f9b043d
167273f
b646aeb
6e0c425
1f5f54a
ad7e453
07145e3
185e96a
f12a07e
09a0ef9
fd9ed43
9dc0ba3
f9eba89
4b05410
5ca5441
ed2a5e0
311da45
d75ad86
b63f395
fe52f29
3546c8c
d8e55d7
087ff3f
e36a1f7
494685a
4dffe1e
bce6afe
35b8fce
3f0bf9e
22b76e0
b879790
b2cd80f
759ee2c
8f5d6a5
fc2c766
7cda9fe
fc4fa94
234747a
57bb5fe
8324fa3
33f3e13
8658986
3849bf9
fc5fef1
7d847ff
6d39361
942122a
47299fd
6a64941
12e278f
ebafac3
d781312
af50e3f
c33df32
36ee65a
353cc0a
f242a65
d6c30da
e19e6a8
3b6c3c8
a483834
276eb54
9e14d30
4c18118
ef571b3
949e0f8
7eaa406
9879bed
567fe35
22f3792
e3d40f4
aac1f50
adbc9b8
5a05846
263abdc
2252e21
d7abb8e
97ec861
2645c84
6723212
0c313fa
8c494a9
813384a
cfefbc8
ba7e396
d13cdff
a9f0dfc
59d656a
c9905d8
453dc97
b285353
3ab1a47
20bced0
a2762af
968c822
5d51491
125f8c5
9d69d0e
a3715fa
7b0e795
497f330
72c2853
ec28773
659570e
567cb3d
a1962c6
951ab61
670f993
7452f33
6f09a42
5bdff10
1a9fd45
c020cd6
ab95012
5b5a7a1
42e5cca
61d9056
0e95d9c
0b97b5a
1e1828e
8598adb
20ce7ad
97c9b88
99b0ce9
538e49c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,53 @@ export function tickToSqrtPrice(tickIndex: Int): Dec { | |
return approxSqrt(price); | ||
} | ||
|
||
export function tickToPrice(tickIndex: Int): Dec { | ||
if (tickIndex.isZero()) { | ||
return new Dec(1); | ||
} | ||
|
||
const geometricExponentIncrementDistanceInTicks = nine.mul( | ||
powTenBigDec(new Int(exponentAtPriceOne).neg()).toDec() | ||
); | ||
|
||
if (tickIndex.lt(minTick) || tickIndex.gt(maxTick)) { | ||
throw new Error( | ||
`tickIndex is out of range: ${tickIndex.toString()}, min: ${minTick.toString()}, max: ${maxTick.toString()}` | ||
); | ||
} | ||
|
||
const geometricExponentDelta = new Dec(tickIndex) | ||
.quoTruncate(new Dec(geometricExponentIncrementDistanceInTicks.truncate())) | ||
.truncate(); | ||
|
||
let exponentAtCurTick = new Int(exponentAtPriceOne).add( | ||
geometricExponentDelta | ||
); | ||
if (tickIndex.lt(new Int(0))) { | ||
exponentAtCurTick = exponentAtCurTick.sub(new Int(1)); | ||
} | ||
|
||
const currentAdditiveIncrementInTicks = powTenBigDec(exponentAtCurTick); | ||
|
||
const numAdditiveTicks = tickIndex.sub( | ||
geometricExponentDelta.mul( | ||
geometricExponentIncrementDistanceInTicks.truncate() | ||
) | ||
); | ||
|
||
const price = powTenBigDec(geometricExponentDelta) | ||
.add(new BigDec(numAdditiveTicks).mul(currentAdditiveIncrementInTicks)) | ||
.toDec(); | ||
|
||
if (price.gt(maxSpotPrice) || price.lt(minSpotPrice)) { | ||
throw new Error( | ||
`price is out of range: ${price.toString()}, min: ${minSpotPrice.toString()}, max: ${maxSpotPrice.toString()}` | ||
); | ||
} | ||
|
||
return price; | ||
} | ||
Comment on lines
+69
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactor suggestion: Consider modularizing repetitive code blocks in The + function calculateGeometricExponentDelta(tickIndex, geometricExponentIncrementDistanceInTicks) {
+ return new Dec(tickIndex)
+ .quoTruncate(new Dec(geometricExponentIncrementDistanceInTicks.truncate()))
+ .truncate();
+ }
+
+ function checkTickIndexBounds(tickIndex) {
+ if (tickIndex.lt(minTick) || tickIndex.gt(maxTick)) {
+ throw new Error(
+ `tickIndex is out of range: ${tickIndex.toString()}, min: ${minTick.toString()}, max: ${maxTick.toString()}`
+ );
+ }
+ }
+
+ function checkPriceBounds(price) {
+ if (price.gt(maxSpotPrice) || price.lt(minSpotPrice)) {
+ throw new Error(
+ `price is out of range: ${price.toString()}, min: ${minSpotPrice.toString()}, max: ${maxSpotPrice.toString()}`
+ );
+ }
+ }
- if (tickIndex.lt(minTick) || tickIndex.gt(maxTick)) {
- throw new Error(
- `tickIndex is out of range: ${tickIndex.toString()}, min: ${minTick.toString()}, max: ${maxTick.toString()}`
- );
- }
- if (price.gt(maxSpotPrice) || price.lt(minSpotPrice)) {
- throw new Error(
- `price is out of range: ${price.toString()}, min: ${minSpotPrice.toString()}, max: ${maxSpot
|
||
|
||
/** PriceToTick takes a price and returns the corresponding tick index | ||
* This function does not take into consideration tick spacing. | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Chain } from "@osmosis-labs/types"; | ||
import cachified, { CacheEntry } from "cachified"; | ||
import { LRUCache } from "lru-cache"; | ||
|
||
import { DEFAULT_LRU_OPTIONS } from "../../../utils/cache"; | ||
import { LimitOrder, queryOrderbookActiveOrders } from "../../osmosis"; | ||
|
||
const activeOrdersCache = new LRUCache<string, CacheEntry>(DEFAULT_LRU_OPTIONS); | ||
|
||
export function getOrderbookActiveOrders({ | ||
orderbookAddress, | ||
userOsmoAddress, | ||
chainList, | ||
}: { | ||
orderbookAddress: string; | ||
userOsmoAddress: string; | ||
chainList: Chain[]; | ||
}) { | ||
return cachified({ | ||
cache: activeOrdersCache, | ||
key: `orderbookActiveOrders-${orderbookAddress}-${userOsmoAddress}`, | ||
ttl: 1000 * 60 * 2, // 2 minutes | ||
getFreshValue: () => | ||
queryOrderbookActiveOrders({ | ||
orderbookAddress, | ||
userAddress: userOsmoAddress, | ||
chainList, | ||
}).then( | ||
({ data }: { data: { count: number; orders: LimitOrder[] } }) => data | ||
), | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from "./active-orders"; | ||
export * from "./maker-fee"; | ||
export * from "./spot-price"; | ||
export * from "./tick-state"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Dec } from "@keplr-wallet/unit"; | ||
import { Chain } from "@osmosis-labs/types"; | ||
import cachified, { CacheEntry } from "cachified"; | ||
import { LRUCache } from "lru-cache"; | ||
|
||
import { DEFAULT_LRU_OPTIONS } from "../../../utils/cache"; | ||
import { queryOrderbookMakerFee } from "../../osmosis"; | ||
|
||
const makerFeeCache = new LRUCache<string, CacheEntry>(DEFAULT_LRU_OPTIONS); | ||
|
||
export function getOrderbookMakerFee({ | ||
orderbookAddress, | ||
chainList, | ||
}: { | ||
orderbookAddress: string; | ||
chainList: Chain[]; | ||
}) { | ||
return cachified({ | ||
cache: makerFeeCache, | ||
key: `orderbookMakerFee-${orderbookAddress}`, | ||
ttl: 1000 * 60 * 60 * 4, // 4 hours | ||
getFreshValue: () => | ||
queryOrderbookMakerFee({ orderbookAddress, chainList }).then( | ||
({ data }: { data: string }) => new Dec(data) | ||
), | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,36 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Dec } from "@keplr-wallet/unit"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { Chain } from "@osmosis-labs/types"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import cachified, { CacheEntry } from "cachified"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { LRUCache } from "lru-cache"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { DEFAULT_LRU_OPTIONS } from "../../../utils/cache"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { queryOrderbookSpotPrice } from "../../osmosis"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const orderbookSpotPriceCache = new LRUCache<string, CacheEntry>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DEFAULT_LRU_OPTIONS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export function getOrderbookSpotPrice({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
orderbookAddress, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
chainList, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
quoteAssetDenom, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
baseAssetDenom, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
orderbookAddress: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
quoteAssetDenom: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
baseAssetDenom: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
chainList: Chain[]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return cachified({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cache: orderbookSpotPriceCache, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
key: `orderbookSpotPrice-${orderbookAddress}-${quoteAssetDenom}-${baseAssetDenom}`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ttl: 1000 * 60 * 2, // 2 minutes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
getFreshValue: () => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
queryOrderbookSpotPrice({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
orderbookAddress, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
chainList, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
quoteAssetDenom, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
baseAssetDenom, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}).then(({ data }) => new Dec(data.spot_price)), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure proper error handling in The function + }).catch(error => {
+ console.error('Failed to fetch spot price:', error);
+ throw error; // Rethrow or handle as needed
+ }) Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { Chain } from "@osmosis-labs/types"; | ||
import cachified, { CacheEntry } from "cachified"; | ||
import { LRUCache } from "lru-cache"; | ||
|
||
import { DEFAULT_LRU_OPTIONS } from "../../../utils/cache"; | ||
import { | ||
queryOrderbookTicks, | ||
queryOrderbookTickUnrealizedCancelsById, | ||
} from "../../osmosis"; | ||
|
||
const tickInfoCache = new LRUCache<string, CacheEntry>(DEFAULT_LRU_OPTIONS); | ||
|
||
export function getOrderbookTickState({ | ||
orderbookAddress, | ||
chainList, | ||
tickIds, | ||
}: { | ||
orderbookAddress: string; | ||
chainList: Chain[]; | ||
tickIds: number[]; | ||
}) { | ||
return cachified({ | ||
cache: tickInfoCache, | ||
key: `orderbookTickInfo-${orderbookAddress}-${tickIds | ||
.sort((a, b) => a - b) | ||
.join(",")}`, | ||
ttl: 1000 * 60 * 2, // 2 minutes | ||
getFreshValue: () => | ||
queryOrderbookTicks({ orderbookAddress, chainList, tickIds }).then( | ||
({ data }) => data.ticks | ||
), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure consistent caching and error handling in tick state retrieval functions. Both + }).catch(error => {
+ console.error('Failed to fetch tick information:', error);
+ throw error; // Rethrow or handle as needed
+ }) Also applies to: 35-55 |
||
}); | ||
} | ||
|
||
export function getOrderbookTickUnrealizedCancels({ | ||
orderbookAddress, | ||
chainList, | ||
tickIds, | ||
}: { | ||
orderbookAddress: string; | ||
chainList: Chain[]; | ||
tickIds: number[]; | ||
}) { | ||
return cachified({ | ||
cache: tickInfoCache, | ||
key: `orderbookTickUnrealizedCancels-${orderbookAddress}-${tickIds | ||
.sort((a, b) => a - b) | ||
.join(",")}`, | ||
ttl: 1000 * 60 * 2, // 2 minutes | ||
getFreshValue: () => | ||
queryOrderbookTickUnrealizedCancelsById({ | ||
orderbookAddress, | ||
chainList, | ||
tickIds, | ||
}).then(({ data }) => data.ticks), | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimize imports in test file.
The import
tickToSqrtPrice
is not used in the provided test cases. Consider removing it to keep the code clean and efficient.Committable suggestion