Uniswap Liquidity Calculation issue on Arbitrum Chain - uniswap

According to the "Liqudity Math in uniswap v3", the liqudity of a position should be:
L = amt0 * (sqrt(upper) * sqrt(cprice)) / (sqrt(upper) - sqrt(cprice))
or
L = amt1 / (sqrt(cprice) - sqrt(lower))
I tried to calculate the liquidity of the below position on Arbitrum:
The nft token ID of the position is 69171, so I can get the liqudity by calling the contract(0xC36442b4a4522E871399CD717aBDD847Ab11FE88) on https://arbiscan.io
You can see it shows the liqudity is 50242219347523, and we can do more unit convertion:
Now I try to calcuate this number with the uniswap V3 math:
This is the output:
As we can see, the code output is very similar to the contract output, but if we look carefully, we will find the unit seems to be different. I know the unit of the contract ouput should be 'wei', but I don't know what the unit of the code results is. Can anybody help? Thanks.

I checked that position and pool. Best to query the current price from the pool's contract, for quick look the UI can be found at https://info.uniswap.org/#/arbitrum/pools/0x2f5e87c9312fa29aed5c179e456625d79015299c
The current price is shown as 11.9011 ETH per BTC, and there are 0.3122 BTC and 1.466 ETH in the pool. This gives:
price = 11.9011 * (1e18 / 1e8)
x = 0.3122 * 1e8
y = 1.466 * 1e18
The tick range of the position No. 69171 is 253300 to 259900. Use these values to calculate sp = sqrt(price) and the square roots of the price range boundaries, and from them, the liquidity:
sp = price ** 0.5
sa = 1.0001 ** (253300 // 2)
sb = 1.0001 ** (259900 // 2)
Lx = x * sp * sb / (sb - sp)
Ly = y / (sp - sa)
L = min(Lx, Ly)
The result Lx is 49905251975363.266 and Ly is 51071435112054.96. The Etherscan info shows liquidity L=50242219347523, in between these two values, which have a few % difference. A few % is an acceptable error given the imprecise input values used in this calculation; the UI shows the price and amount values in a rounded format.

Related

Octave script falling into error when processing data with sampling frequency above 50kS/s

I'm working with an Octave script to process data files with high sample rates (up to 200kS/s collected over 3 minutes). The code runs into issues when processing any files with a sample rate above 50kS/s, regardless of size or number of samples but functions correctly otherwise.
The error I receive when attempting to run the code with files above 50kS/s is called from the hist function:
error: x(0): subscripts must be either integers 1 to (2^63)-1 or logicals
error:
I have narrowed the cause to the following section of code (note that FS is the detected sampling frequency):
FILTER_ORDER = 1;
FILTER_CUTOFF = 1 / (2 * pi * 300e-3);
[b_lp, a_lp] = butter(FILTER_ORDER, FILTER_CUTOFF / (FS / 2), 'low');
%
s = SCALING_FACTOR * filter(b_lp, a_lp, u_q) ;
P = s ;
%
tau = 20;
transient = tau * FS; % index after the transient
Pmax = max(P(transient:end));
%
s = s(transient:end);
%
NUMOF_CLASSES = 10000; % number of bins used for the histogram
[bin_cnt, cpf.magnitude] = hist(s, NUMOF_CLASSES); % sorts data into the number of bins specified
I can try to provide more information if required, I'm not very familiar with Octave.

How can I obtain this specific series data to calculate time-to-funding-weighted average of premium index?

I'm looking to calculate and plot the funding rate of Binance BTCUSDT Perpetual and have come across the following documentation page: https://www.binance.com/en/support/faq/360033525031
It states:
The Funding Rate formula:
"Funding Rate (F) = Average Premium Index (P) + clamp (interest rate - Premium Index (P), 0.05%, -0.05%)"
I'm obtaining the "Premium Index" just fine, just with "p = request.security("BINANCE:BTCUSDT_PREMIUM", "", close)*100"
However I'm currently struggling with how to obtain the:
"Time-to-funding weighted Average of Premium Index " which apparently is calculated with
"Average Premium Index (P) = (1 * Premium_Index_1 + 2 * Premium_Index_2 + 3 * Premium_Index_3 +···+·480 * Premium_index_480)/(1+2+3+···+480)"
(the funding period for Binance is 8 hours hence the average over 480 minutes)
My exact question is, how do I backtrack to the last funding timestamp of 00:00 / 08:00 / 16:00, then obtain an array / series data of the premium index at each of the last 480 minutes, so that I can then iterate over it to use the above formula for the time weighted average?
Thank you very much for any advice in advance. My apologies if the answer is obvious I'm very new to Pine Script.
I believe you can obtain the time weighted average premium like so:
premium = request.security("BINANCE:BTCUSDT_PREMIUM", "1", close)
new_funding_period = ta.change(time("480")) != 0
var int n = na
var float premium_sum = na
var int n_sum = na
if new_funding_period
n := 1
premium_sum := premium
n_sum := 1
else
n += 1
premium_sum += premium * n
n_sum += n
predicted_TWAP = premium_sum / n_sum
current_TWAP = ta.valuewhen(new_funding_period, predicted_TWAP[1], 0)
However, you are limited to performing the calculation on a 1 minute chart to obtain accurate results due to being unable to reliably retrieve the values from a security call from a lower timeframe when the chart is set to a higher timeframe than 1 minute.

Time series simulation (Monte Carlo) code

I'm trying to make a Monte Carlo Simulation with time series and I can't get what I'm doing wrong due to my little knowledge in Stata.
With my ARMA model I'm able to create a time series with 300 observations.
My idea is to do this process 1000 times and in every process I want to save the mean and variance of the 300 observations in a matrix.
This is my ARMA model:
This is my code:
clear all
set more off
set matsize 1000
matrix simulaciones =J(1000,2,0) *To save every simulation of every time series generated
matrix serie = J(300,3,0) *To save each time series
set obs 300 *For the 300 observations in every time series
gen t = _n
tsset t
g y1=0
forvalue j = 1(1)1000{
* Creating a time series
forvalues i = 1(1)300 {
gen e = rnormal(0,1)
replace y1=0 if t==1
replace y1 = 0.7*L1.y1 + e - 0.6*L1.e if t == 2
replace y1 = 0.7*L1.y1 - 0.1*L2.y1 + e - 0.6*L1.e + 0.08*L2.e if t > 2
matrix serie[`i',3] = y1
drop e y1
}
svmat serie
matrix simulaciones[`j',1] = mean(y1)
matrix simulaciones[`j',2] = var(y1)
}
I have no idea how to follow and any idea or recommendation is more than welcomed.
Thanks a lot for your help and time.

shape of input to calculate information gain

I want to calculate the information gain on 20_newsgroup data set.
I am using the code here(also I put a copy of the code down of the question).
As you see the input to the algorithm is X,y
My confusion is that, X is going to be a matrix with documents in rows and features as column. (according to 20_newsgroup it is 11314,1000
in case i only considered 1000 features).
but according to the concept of information gain, it should calculate information gain for each feature.
(So I was expecting to see the code in a way loop through each feature, so the input to the function be a matrix where rows are features and columns are class)
But X is not feature here but X stands for documents, and I can not see the part in the code that take care of this part! ( I mean considering each document, and then going through each feature of that document; like looping through rows but at the same time looping through columns as the features are stored in columns).
I have read this and this and many similar questions but they are not clear in terms of input matrix shape.
this is the code for reading 20_newsgroup:
newsgroup_train = fetch_20newsgroups(subset='train')
X,y = newsgroup_train.data,newsgroup_train.target
cv = CountVectorizer(max_df=0.99,min_df=0.001, max_features=1000,stop_words='english',lowercase=True,analyzer='word')
X_vec = cv.fit_transform(X)
(X_vec.shape) is (11314,1000) which is not features in the 20_newsgroup data set. I am thinking am I calculating Information gain in a incorrect way?
This is the code for Information gain:
def information_gain(X, y):
def _calIg():
entropy_x_set = 0
entropy_x_not_set = 0
for c in classCnt:
probs = classCnt[c] / float(featureTot)
entropy_x_set = entropy_x_set - probs * np.log(probs)
probs = (classTotCnt[c] - classCnt[c]) / float(tot - featureTot)
entropy_x_not_set = entropy_x_not_set - probs * np.log(probs)
for c in classTotCnt:
if c not in classCnt:
probs = classTotCnt[c] / float(tot - featureTot)
entropy_x_not_set = entropy_x_not_set - probs * np.log(probs)
return entropy_before - ((featureTot / float(tot)) * entropy_x_set
+ ((tot - featureTot) / float(tot)) * entropy_x_not_set)
tot = X.shape[0]
classTotCnt = {}
entropy_before = 0
for i in y:
if i not in classTotCnt:
classTotCnt[i] = 1
else:
classTotCnt[i] = classTotCnt[i] + 1
for c in classTotCnt:
probs = classTotCnt[c] / float(tot)
entropy_before = entropy_before - probs * np.log(probs)
nz = X.T.nonzero()
pre = 0
classCnt = {}
featureTot = 0
information_gain = []
for i in range(0, len(nz[0])):
if (i != 0 and nz[0][i] != pre):
for notappear in range(pre+1, nz[0][i]):
information_gain.append(0)
ig = _calIg()
information_gain.append(ig)
pre = nz[0][i]
classCnt = {}
featureTot = 0
featureTot = featureTot + 1
yclass = y[nz[1][i]]
if yclass not in classCnt:
classCnt[yclass] = 1
else:
classCnt[yclass] = classCnt[yclass] + 1
ig = _calIg()
information_gain.append(ig)
return np.asarray(information_gain)
Well, after going through the code in detail, I learned more about X.T.nonzero().
Actually it is correct that information gain needs to loop through features.
Also it is correct that the matrix scikit-learn give us here is based on doc-features.
But:
in code it uses X.T.nonzero() which technically transform all the nonzero values into array. and then in the next row loop through the length of that array range(0, len(X.T.nonzero()[0]).
Overall, this part X.T.nonzero()[0] is returning all the none zero features to us :)

Comparing Runtimes - Theoretical to Actual

Firstly, sorry for the long post, but I must be detailed in my explanation here. So here's what I have. I have code that measures the runtime of mergesort and radix sort algorithms for four different sizes of data.
Mergesort runtimes:
N = 10; runtime = 3499 nanoseconds
N = 100; runtime = 39600 nanoseconds
N = 1000; runtime = 470199 nanoseconds
N = 10000; runtime = 6227399 nanoseconds
Radixsort runtimes:
N = 10; runtime = 19200 nanoseconds
N = 100; runtime = 135099 nanoseconds
N = 1000; runtime = 1317799 nanoseconds
N = 10000; runtime = 14208600 nanoseconds
I have also measured the runtime of a single operation to be roughly 1000 nanoseconds on this machine. This was recommended by the professor as a means help convert theoretical runtimes to something that we can compare to the actual runtimes. For mergesort, I have O(n log(n)) as the runtime, and for radixsort I have O(nk), although I'm not entirely sure what the k represents. He suggested we do the following conversion, so I've done it for each one of the mergesorts. I don't know how to do this for radixsort, as I don't know how to factor in the 'k'. My understanding is that 'k' basically refers to the number of digits, but you can essentially stick with whichever will be larger (N or k), so since my N is always larger than k in the cases I'm working with, I'm just going to consider Radix as O(N). K is limited to six digits at the most, where N begins at 10 at the lowest value.
1000ns * theoreticalruntime
For example, 1000ns * 10 log2(10)
Mergesort:
N = 10; 33219.3 nanoseconds
N = 100; 664385.6 nanoseconds
N = 1000; 9.96578428 * 10^6 nanoseconds
N = 10000; 1.3287712379549449 * 10^8 nanoseconds
Radixsort: (1000ns per operation * N)
N = 10; 10000
N = 100; 100000
N = 1000; 1000000
N = 10000; 10000000
So here's where my issue comes in. One, I don't know how to do this calculation for the radixsort theoretical runtime. Two, I don't know exactly how to compare these values using a graph (the requirement).
In class, he was discussing using logs to "normalize" the data. The Y-axis would be N and the X-axis would be time, but he was talking about being able to use logs to change the N values from 10, 100, 1000, and 10000 to where they would show up as N = 1, 2, 3, 4. I have no idea how to do this, and I don't really know what I'd be plotting on the graph. If there's a better place I could be asking this, please point me in that direction. Time runs short.

Resources