Skip to content

Commit

Permalink
Updated README.md with technical details
Browse files Browse the repository at this point in the history
  • Loading branch information
aritroCoder committed Dec 11, 2023
1 parent 059329b commit 8190d40
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 10 deletions.
41 changes: 31 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,39 @@ Congratulations! You are now ready to experience the power of Snaptos. Access yo

- **On-chain Account Creation:** Behind the scenes, Aptos Wallet leverages smart contract interactions to securely and efficiently create Aptos accounts directly on-chain.

- **Advanced APT to USD prediction model:** The forecasting engine is built using a Bidirectional LSTM model, which is trained on historical data to predict future Aptos price movements. We have trained the model on more than 500 continuous data points which we scraped ourselves from the internet through multiple sources/price feeds. The various model hyperparameters are:
- **Advanced APT to USD prediction model:** The forecasting engine is built using a Bidirectional LSTM model, which is trained on historical data to predict future Aptos price movements. We have trained the model on more than 500 continuous data points which we scraped ourselves from the internet through multiple sources/price feeds.

- **Number of LSTM layers:** 1
- **Optimizer:** Adam
- **Loss function:** Mean Squared Error
- **Number of epochs:** 100
- **Batch size:** 9
- **Learning rate:** 0.001
- **Lookback period:** 16 time units

## Architecture
## Solution Architecture
![Snaptos Architecture](./assets/APTOS_architecture.png)
The main components of the solution are:
- **Metamask Snap:** The Metamask Snap is a browser extension that allows users to interact with the Aptos blockchain. It is a lightweight extension of the Metamask browser extension and is built using Typescript. The Metamask Snap is responsible for generating the Aptos wallet keypair using the seed phrase associated with ethereum. It uses metamask's `snap_getBip32Entropy` method to generate the `rootNode` by using the derive path `[m, 44', 637']` and uses this to derive the keypair using the [SLIP algorithm](https://github.com/satoshilabs/slips/blob/master/slip-0010.md). It also stores the key pair in the secure storage provided by metamask, so that on subsequent logins with the password, it can be fetched directly. The snap also acts as the interface through which operations like coin transfer, faucet funding, viewing transaction history, etc can be done.

- **Proxy backend server:** As Metamask Snaps operate in a sandboxed environment, they are not able to make requests to external APIs. Thus, we have created a proxy backend server that acts as a bridge between the snap and the external APIs. The snap makes requests to the proxy server, which then forwards the request to the external API and returns the response back to the snap. The proxy server is built using Node.js and Express.js in Typescript. It also acts as the interface between the snap and the forecasting engine. The proxy server uses the cutting-edge [aptos-ts-sdk](https://github.com/aptos-labs/aptos-ts-sdk) to interact with the Aptos blockchain. The proxy server performs important functionalities like faucet funding, coin transfer, transaction history, account balance etc. It also provides the snap with real time APT to USD conversion rates by making requests to multiple coin feeds (discussed below).

- **BiLSTM Forecasting Model:** The forecasting engine is built using a Bidirectional LSTM(Long Short Term Memory) model, which is trained on historical data to predict future Aptos price movements. We have trained the model on more than 500 continuous data points which we scraped ourselves from the internet through multiple sources/price feeds. The different data feeds we used are:
- Binance: https://www.binance.com/api/v3/ticker/price?symbol=APTUSDT
- Bitfinex: https://api-pub.bitfinex.com/v2/tickers?symbols=tAPTUSD
- Coinbase: https://api.coinbase.com/v2/prices/APT-USD/spot
- Huobi: https://api.huobi.pro/market/detail/merged?symbol=aptusdt
- Mexc: https://www.mexc.com/open/api/v2/market/ticker?symbol=APT_USDT

A sample code to ping these APIs at regular intervals for price data is given in [data_collection.py](./additional/data_collection.py).

The values these feeds provide can be combined with different individual weights, but here we have give all a equal weight of 1.

The various model hyperparameters of the BiLSTM are:
- **Number of LSTM layers:** 1
- **Optimizer:** Adam
- **Loss function:** Mean Squared Error
- **Number of epochs:** 100
- **Batch size:** 9
- **Learning rate:** 0.001
- **Lookback period:** 16 time units

The model, when trained, gives us a training error of 0.01 and a validation error in the range of 0.01 to 0.03 (MSE Loss).

The entire forcasting model is dockerized to avoid installing all the libraries manually and thus provides a fast and convinient way to deploy the solution.
- **Frontend Client:** The frontend client is built using React.js and Typescript. It is responsible for providing the user with a seamless and intuitive experience. It shows the account address, user's balance, and provides the user with the option to transfer Aptos to other accounts. It is responsible for fetching the real time APT to USD conversion rates from the proxy server and displaying it to the user along with forecasting data. It also fetches the transaction history from the proxy server, provides the user with the option to create an Aptos account on-chain, allows switching between mainnet, testnet and devnet, and also provides the user with the option to fund their account with test and dev Aptos using the faucet.
## Why LSTM?
- Given the highly volatile nature of the crypto market, we need a model that can capture the non-linearities and complexities of the data. Simple statistical algorithms like ARIMA and SARIMA are not suitable for this task as they are not able to capture the non-linearities and complexities of the data. CNNs, RNNs and their variations have proved to be very effective in forecasting complex time series data. We have used LSTM as it is a very powerful variation of RNNs and is able to capture long term dependencies in the data. We have used a Bidirectional LSTM as it is able to capture the dependencies in both the directions of the time series data.
Expand Down
82 changes: 82 additions & 0 deletions additional/data_collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
"""
This code, when run generates a text file called 'data.txt' with the current price of APT/USD in each new line,
where it appends new price every minute. This is used to collect data for the price of APT/USD for the past 24 hours.
"""
import requests
import schedule
import time


def getBinance():
current_price = 0
response = requests.get(
"https://www.binance.com/api/v3/ticker/price?symbol=APTUSDT"
)
json_data = response.json()
current_price += float(json_data["price"])
return current_price


def getBitfinex():
current_price = 0
response = requests.get("https://api-pub.bitfinex.com/v2/tickers?symbols=tAPTUSD")
json_data = response.json()
current_price += (
float(json_data[0][1]) + float(json_data[0][3]) + float(json_data[0][7])
)
return current_price / 3


def getCoinbase():
current_price = 0
response = requests.get("https://api.coinbase.com/v2/prices/APT-USD/spot")
json_data = response.json()
current_price += float(json_data["data"]["amount"])
return current_price


def getHuobi():
current_price = 0
response = requests.get("https://api.huobi.pro/market/detail/merged?symbol=aptusdt")
json_data = response.json()
current_price += float(json_data["tick"]["bid"][0]) + float(
json_data["tick"]["ask"][0]
)
return current_price / 2


def getMexc():
current_price = 0
response = requests.get(
"https://www.mexc.com/open/api/v2/market/ticker?symbol=APT_USDT"
)
json_data = response.json()
current_price += (
float(json_data["data"][0]["ask"])
+ float(json_data["data"][0]["bid"])
+ float(json_data["data"][0]["last"])
)
return current_price / 3


def append_number_to_textfile(number, output_file):
try:
with open(output_file, "a") as file:
file.write("\n" + str(number))
print(f"Number {number} successfully appended to {output_file}")
except Exception as e:
print(f"An error occurred: {e}")


def getAllData():
price = getBinance() + getBitfinex() + getCoinbase() + getHuobi()
price = price / 4
append_number_to_textfile(price, "data.txt")


schedule.every(1).minutes.do(getAllData)

while True:
schedule.run_pending()
time.sleep(1)

0 comments on commit 8190d40

Please sign in to comment.