<jupyter_start><jupyter_text>Opyn Transaction and Vault Analysis<jupyter_code>txdf0 = pd.read_csv('oToken-Transactions.csv', dtype = {'value': float})
#txdf = pd.read_csv('oToken-Transactions.csv')
txdf0.columns
txdf0.head()
txdf = txdf0[txdf0.account != '<KEY>'].drop(columns = ['tx', 'minute', 'type'])
txdf.head()
%matplotlib inline
ocDAI = txdf[txdf.token == 'ocDAI'].value
ocUSDC = txdf[txdf.token == 'ocUSDC'].value
oETH = txdf[txdf.token.str.match(r'^oETH')].value
oCRV = txdf[txdf.token == 'oCRV'].value

buydf = txdf[txdf.side == 'buy']

ocDAI_buy = buydf[buydf.token == 'ocDAI'].value
ocUSDC_buy = buydf[buydf.token == 'ocUSDC'].value
oETH_buy = buydf[buydf.token.str.match(r'^oETH')].value
oCRV_buy = buydf[buydf.token == 'oCRV'].value

selldf = txdf[txdf.side == 'sell']

ocDAI_sell = selldf[selldf.token == 'ocDAI'].value
ocUSDC_sell = selldf[selldf.token == 'ocUSDC'].value
oETH_sell = selldf[selldf.token.str.match(r'^oETH')].value
oCRV_sell = selldf[selldf.token == 'oCRV'].value
oETH_sell.median(), oETH_sell.mean(), oETH_buy.median(), oETH_buy.mean()
import matplotlib.ticker as mtick

hist, bins, _ = plt.hist(txdf.value, bins=50, density = False, weights=np.ones(len(txdf.value)) / len(txdf.value))
ax = plt.gca()
ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
plt.ylim(0,.75)
plt.title('Transaction Notional Value Distribution - Total')
plt.xlabel('Transaction Notional Value ($)')
plt.text(.5, .9, 'Bin size = ${}'.format(round(bins[1], 2)), horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)
; 
kwargs = dict(histtype='bar', alpha=.3, bins=np.logspace(np.log10(bins[0]+1),np.log10(bins[-1]),len(bins)))
plt.axvline(txdf.value.median(), label = 'median', color = 'blue')
plt.hist(txdf.value, **kwargs, label = 'value')
plt.text(.4, .9, '$'+str(round(txdf.value.median(),2)), horizontalalignment='center', 
         verticalalignment='center', transform=ax.transAxes, color = 'blue')
plt.xscale('log')
plt.legend()
plt.title('Transaction Notional Value Log Distribution - Total')
plt.xlabel('Transaction Notional Value (log $)');
plt.axvline(buydf.value.median(), label = 'buy_median', color = 'blue')
plt.axvline(selldf.value.median(), label = 'sell_median', color = 'orange')
plt.hist(buydf.value, **kwargs, label = 'buy')
plt.hist(selldf.value, **kwargs, label = 'sell')
plt.xscale('log')
plt.legend()
plt.ylim(0, 140)
plt.title('Buy vs. Sell Transaction Notional Value Distributions - Total')
plt.xlabel('Transaction Notional Value (log $)');
buydf.value.median()
plt.hist(oETH, **kwargs, label = 'oETH')
plt.hist(ocDAI, **kwargs, label = 'ocDAI')
plt.hist(ocUSDC, **kwargs, label = 'ocUSDC')
plt.hist(oCRV, **kwargs, label = 'oCRV')
plt.axvline(oETH.median(), label = 'oETH_median', color = 'blue')
plt.axvline(ocDAI.median(), label = 'ocDAI_median', color = 'orange')
plt.axvline(ocUSDC.median(), label = 'ocUSDC_median', color = 'green')
plt.axvline(oCRV.median(), label = 'oCRV_median', color = 'red')
plt.xscale('log')
plt.legend()
plt.title('Transaction Notional Value Distribution by oToken')
plt.xlabel('Transaction Notional Value (log $)');
plt.hist(oETH_buy, **kwargs, label = 'oETH_buy')
plt.hist(oETH_sell, **kwargs, label = 'oETH_sell')
plt.axvline(oETH_buy.median(), label = 'buy_median', color = 'blue')
plt.axvline(oETH_sell.median(), label = 'sell_median', color = 'orange')
plt.xscale('log')
plt.legend()
plt.ylim(0, 140)
plt.title('Transaction Notional Value Distribution - oETH')
plt.xlabel('Transaction Notional Value (log $)');
plt.hist(ocDAI_buy, **kwargs, label = 'ocDAI_buy')
plt.hist(ocDAI_sell, **kwargs, label = 'ocDAI_sell')
plt.axvline(ocDAI_buy.median(), label = 'buy_median', color = 'blue')
plt.axvline(ocDAI_sell.median(), label = 'sell_median', color = 'orange')
plt.xscale('log')
plt.legend()
plt.title('Transaction Notional Value Distribution - ocDAI')
plt.xlabel('Transaction Notional Value (log $)');
plt.hist(ocUSDC_buy, **kwargs, label = 'ocUSDC_buy')
plt.hist(ocUSDC_sell, **kwargs, label = 'ocUSDC_sell')
plt.axvline(ocUSDC_buy.median(), label = 'buy_median', color = 'blue')
plt.axvline(ocUSDC_sell.median(), label = 'sell_median', color = 'orange')
plt.xscale('log')
plt.legend()
plt.title('Transaction Notional Value Distribution - ocUSDC')
plt.xlabel('Transaction Notional Value (log $)');
plt.hist(oCRV_buy, **kwargs, label = 'oCRV_buy')
plt.hist(oCRV_sell, **kwargs, label = 'oCRV_sell')
plt.axvline(oETH_buy.median(), label = 'buy_median', color = 'blue')
plt.axvline(oETH_sell.median(), label = 'sell_median', color = 'orange')
plt.xscale('log')
plt.legend()
plt.title('Transaction Notional Value Distribution - oCRV')
plt.xlabel('Transaction Notional Value (log $)');<jupyter_output><empty_output><jupyter_text>Account Clusters<jupyter_code>len(txdf.groupby('account'))
txdf.head()
txdf2 = (txdf[txdf.account != '<KEY>'] )
             # that contract is messing up account-based analsysis, so need to remove it
         
s = txdf2.token
txdf2['token_group'] = s.where(s == 'oETH', 'stablecoin')

txdf2 = (txdf2.groupby(['account', 'side', 'token_group']).agg(sum)
         .unstack(level=1).unstack(level=1)
         .fillna(0)
        )
txdf2.head()
len(txdf[txdf.account == '<KEY>'])/len(txdf.account)
from sklearn.cluster import KMeans
wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=10, random_state=0)
    kmeans.fit(txdf2)
    wcss.append(kmeans.inertia_)
plt.plot(range(1, 11), wcss)
plt.title('Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')

kmeans = KMeans(n_clusters=6, init='k-means++', max_iter=300, n_init=10, random_state=0)
kmeans.fit(txdf2)
labels = kmeans.predict(txdf2)

counts = np.bincount(labels)
props = counts/len(labels)

txdf2['cluster'] = labels
clusters = (txdf2.groupby('cluster')
            .agg('mean').astype('int').round(0)
            .assign(proportion = props.round(2), count = counts)
            .sort_values(by=['proportion'], ascending = False)
           )
clusters
acct = txdf2[txdf2.cluster == 3].reset_index().account[0]
txdf0[txdf0.account == acct].sort_values(by='value', ascending = False).hist()
acct2 = txdf2[txdf2.cluster == 1].reset_index().account[0]
a = txdf0[txdf0.account == acct2]
a
a.tx[2180]
acct3 = txdf2[txdf2.cluster == 2].reset_index().account
acct3
acct3 = txdf2[txdf2.cluster == 2].reset_index().account[1]
txdf0[txdf0.account == acct3].tx[2361]
txdf2.columns
txdf3 = txdf2
txdf3['oETH'] = txdf2['value','buy', 'oETH'] + txdf2['value','sell', 'oETH']
txdf3['stablecoin'] = txdf2['value', 'buy', 'stablecoin'] + txdf2['value','sell', 'stablecoin']
txdf3 = txdf3.drop(columns = ['value', 'cluster'])
txdf3.head()
wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=10, random_state=0)
    kmeans.fit(txdf3)
    wcss.append(kmeans.inertia_)
plt.plot(range(1, 11), wcss)
plt.title('Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')

kmeans = KMeans(n_clusters=4, init='k-means++', max_iter=300, n_init=10, random_state=0)
kmeans.fit(txdf3)
labels = kmeans.predict(txdf3)

counts = np.bincount(labels)
props = counts/len(labels)

txdf3['cluster'] = labels
clusters = (txdf3.groupby('cluster')
            .agg('mean').astype('int').round(0)
            .assign(proportion = props.round(2), count = counts)
            .sort_values(by=['proportion'], ascending = False)
           )
clusters
x = txdf3['oETH']
y = txdf3['stablecoin']
colormap = np.array(['r', 'g', 'b', 'k'])

plt.scatter(x, y, c = colormap[txdf3.cluster], alpha = 0.75)
plt.xlabel('oETH Transaction Notional Value')
plt.ylabel('Stablecoin Transaction Notional Value')
plt.title('Transacting Address Clusters - oETH vs. stablecoin')
;
txdf4 = txdf2
txdf4['buy'] = txdf2['value','buy', 'oETH'] + txdf2['value','buy', 'stablecoin']
txdf4['sell'] = txdf2['value', 'sell', 'oETH'] + txdf2['value','sell', 'stablecoin']
txdf4 = txdf4.drop(columns = ['value', 'cluster', 'oETH', 'stablecoin'])
txdf4['both'] = np.where((txdf4.buy > 0) & (txdf4.sell > 0), 1, 0)
sum(txdf4.both) / len(txdf4.both)
wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=10, random_state=0)
    kmeans.fit(txdf4)
    wcss.append(kmeans.inertia_)
plt.plot(range(1, 11), wcss)
plt.title('Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')

kmeans = KMeans(n_clusters=5, init='k-means++', max_iter=300, n_init=10, random_state=0)
kmeans.fit(txdf4)
labels = kmeans.predict(txdf4)

counts = np.bincount(labels)
props = counts/len(labels)

txdf4['cluster'] = labels
clusters = (txdf4.groupby('cluster')
            .agg('mean').astype('int').round(0)
            .assign(proportion = props.round(2), count = counts)
            .sort_values(by=['proportion'], ascending = False)
           )
clusters
colormap = np.array(['r', 'g', 'b', 'k', 'm'])

plt.scatter(txdf4.buy, txdf4.sell, c = colormap[txdf4.cluster], alpha = 0.75)
plt.xlabel('oETH Transaction Notional Value')
plt.ylabel('Stablecoin Transaction Notional Value')
plt.title('Transacting Address Clusters - Buy vs. Sell')
;<jupyter_output><empty_output><jupyter_text>Opyn Vault Analysis<jupyter_code>vdf0 = pd.read_csv('Opyn-Vaults.csv')
vdf0.shape
vdf = vdf0[vdf0['expired'] == 0]
vdf = vdf[vdf['address'] != '0x076c…11e4']

vdf = (vdf[vdf['oToken'] != 'ETH Call $250 05/29/20']
      .drop(columns = ['ratio', 'collateral', 'issued', 'collateral_token', 'expired'])
      .replace(r'ETH.+', 'oETH', regex = True)
      )
vdf.shape
vdf.head()<jupyter_output><empty_output><jupyter_text>Collateral Value<jupyter_code>collat = vdf.collateral_value_current

hist, bins, _ = plt.hist(collat, bins=33, density = False, weights=np.ones(len(collat)) / len(collat))
ax = plt.gca()
ax.yaxis.set_major_formatter(mtick.PercentFormatter(1))
plt.ylim(0,.8)
plt.title('Vault Collateral Value Distribution - Total')
plt.xlabel('Vault Collateral Value ($)')
plt.text(.5, .9, 'Bin size = ${}'.format(round(bins[1], 2)), horizontalalignment='center', verticalalignment='center', transform=ax.transAxes)
; 
kwargs = dict(histtype='bar', alpha=.3, bins=np.logspace(np.log10(bins[0]+1),np.log10(bins[-1]),len(bins)))

plt.axvline(collat.median(), label = 'median', color = 'blue')
plt.hist(collat, **kwargs, label = 'value')
plt.text(.25, .9, '$'+str(round(collat.median(),2)), horizontalalignment='center', 
         verticalalignment='center', transform=ax.transAxes, color = 'blue')
plt.xscale('log')
plt.legend()
plt.title('Vault Collateral Value Log Distribution - Total')
plt.xlabel('Vault Collateral Value (log $)');
# Collateral Value
ocDAI_collat = vdf[vdf.oToken == 'ocDAI'].collateral_value_current
ocUSDC_collat = vdf[vdf.oToken == 'ocUSDC'].collateral_value_current
oETH_collat = vdf[vdf.oToken == 'oETH'].collateral_value_current

stable_collat = vdf[vdf.oToken_group == 'stablecoin'].collateral_value_current
plt.hist(oETH_collat, **kwargs, label = 'oETH')
plt.hist(ocDAI_collat, **kwargs, label = 'ocDAI')
plt.hist(ocUSDC_collat, **kwargs, label = 'ocUSDC')
plt.axvline(oETH_collat.median(), label = 'oETH_median', color = 'blue')
plt.axvline(ocDAI_collat.median(), label = 'ocDAI_median', color = 'orange')
plt.axvline(ocUSDC_collat.median(), label = 'ocUSDC_median', color = 'green')
plt.xscale('log')
plt.legend()
plt.title('Vault Collateral Value Distribution by oToken')
plt.xlabel('Vault Collateral Value (log $)');
plt.hist(oETH_collat, **kwargs, label = 'oETH')
plt.hist(stable_collat, **kwargs, label = 'stablecoins')
plt.axvline(oETH_collat.median(), label = 'oETH_median', color = 'blue')
plt.axvline(stable_collat.median(), label = 'stablecoins_median', color = 'orange')
plt.xscale('log')
plt.legend()
plt.title('Vault Collateral Value Distribution by oToken')
plt.xlabel('Vault Collateral Value (log $)');<jupyter_output><empty_output><jupyter_text>Notional Value<jupyter_code>nv = vdf.notional_value

plt.axvline(nv.median(), label = 'median', color = 'blue')
plt.hist(nv, **kwargs, label = 'value')
plt.text(.25, .9, '$'+str(round(nv.median(),2)), horizontalalignment='center', 
         verticalalignment='center', transform=ax.transAxes, color = 'blue')
plt.xscale('log')
plt.legend()
plt.title('Vault Notional Value Log Distribution - Total')
plt.xlabel('Vault Notional Value (log $)');
# Notional Value

ocDAI_nv = vdf[vdf.oToken == 'ocDAI'].notional_value
ocUSDC_nv = vdf[vdf.oToken == 'ocUSDC'].notional_value
oETH_nv = vdf[vdf.oToken == 'oETH'].notional_value

stable_nv = vdf[vdf.oToken_group == 'stablecoin'].notional_value
plt.hist(oETH_nv, **kwargs, label = 'oETH')
plt.hist(ocDAI_nv, **kwargs, label = 'ocDAI')
plt.hist(ocUSDC_nv, **kwargs, label = 'ocUSDC')
plt.axvline(oETH_nv.median(), label = 'oETH_median', color = 'blue')
plt.axvline(ocDAI_nv.median(), label = 'ocDAI_median', color = 'orange')
plt.axvline(ocUSDC_nv.median(), label = 'ocUSDC_median', color = 'green')
plt.xscale('log')
plt.legend()
plt.title('Vault Notional Value Distribution by oToken')
plt.xlabel('Vault Notional Value (log $)');<jupyter_output><empty_output><jupyter_text>Address Vault Collateral Value Clusters<jupyter_code>vdf2 = (vdf.drop(columns = ['notional_value', 'oToken'])
        .groupby(['address', 'oToken_group']).agg(sum)
         .unstack(level=1)
         .fillna(.0000000000001)
       )
vdf2.shape
vdf2
wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters=i, init='k-means++', max_iter=300, n_init=10, random_state=0)
    kmeans.fit(vdf2)
    wcss.append(kmeans.inertia_)
plt.plot(range(1, 11), wcss)
plt.title('Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
kmeans = KMeans(n_clusters=3, init='k-means++', max_iter=300, n_init=10, random_state=0)
kmeans.fit(vdf2)
labels = kmeans.predict(vdf2)

counts = np.bincount(labels)
props = counts/len(labels)

vdf2['cluster'] = labels
clusters = (vdf2.groupby('cluster')
            .agg('mean').astype('int').round(0)
            .assign(proportion = props.round(2), count = counts)
            .sort_values(by=['proportion'], ascending = False)
           )
clusters
x = vdf2['collateral_value_current','oETH']
y = vdf2['collateral_value_current','stablecoin']
colormap = np.array(['r', 'g', 'b'])

plt.scatter(x, y, c = colormap[vdf2.cluster], alpha = 0.5)
plt.xlabel('oETH Vault Collateral Value')
plt.ylabel('Stablecoin Vault Collateral Value')
plt.title('Vault Owner Clusters')

# ax = plt.gca()
# ax.set_yscale('log')
# ax.set_xscale('log')
# plt.ylim(1, max(y) + 1000)
# plt.xlim(1, 200000)
;
vdf2[vdf2.cluster == 2]
txdf[txdf['account'] == '<KEY>']
vdf0[vdf0.address == '0xff07…5e51']
vdf0[vdf0.address == '0xec43…1215']
vdf3 = vdf2.drop(columns = ['cluster'])
vdf3.head()
vdf3['both'] = np.where((vdf3['collateral_value_current','oETH'] > .0001) 
                        & (vdf3['collateral_value_current', 'stablecoin'] > .0001), 1, 0)
sum(vdf3.both) / len(vdf3.both)
vdf3[vdf3.both == 1]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.18893360160965794, 'fraction_numerical': 0.023205902079141517, 'mean_word_length': 5.740958408679927, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '106937', 'license': 'MIT', 'n_tokens_mistral': 6216, 'n_tokens_neox': 5731, 'n_words': 1024, 'path': 'Opyn_segments.ipynb', 'repo_name': 'slgraham/opyn-analysis', 'size': '15050'}