Categories
Automations Crypto Python

Aggregate Iconomi crypto strategy details

Choosing crypto currencies to invest in can be a puzzling task. Investor can look at graphs, news or read expert opinions on Twitter. A popular vehicle for delegating investing decisions is Iconomi, where people have a choice of hundreds of investment strategies. A good indicator of the total market sentiment would be the average weight of assets in these strategies.

Create the API with AWS Lambda

An easy way to create a REST API is with AWS Chalice. The framework hides the complexity of creating a Lambda function and REST methods behind a few lines of shell and Python code.

Create a project

AWS Chalice prerequisites are Python3 and a configured AWS command line interface. Here are instructions to install the CLI. Chalice itself is installed with pip3 install chalice.

Next, the developer can create a new project via Terminal

$ chalice new-project iconomi-aggregator

The project already includes a basic API with a root route /, and can be deployed with chalice deploy

$ chalice deploy

Creating deployment package.
Creating IAM role: iconomi-aggregator-dev
Creating lambda function: iconomi-aggregator-dev
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:us-east-1:592662443111:function:iconomi-aggregator-dev
  - Rest API URL: https://keu9eawt54.execute-api.us-east-1.amazonaws.com/api/

// or locally

$ chalice local

Then the client can call the GET method on the URL, and get a 200 OK result

Connect to Iconomi

To get the strategy details, the Lambda function needs to connect to the Iconomi API.

The developer can create API keys at https://www.iconomi.com/settings/api-keys. The API documentation is available here.

Authentication

Iconomi authentication is overly complicated, requiring manual hashing and Base64 encoding. However when the developer follows the example code, she can define a base method for both POST and GET requests. These get()and post() methods can then be used for all of the future Iconomi requests.

def generate_signature(payload, request_type, request_path, timestamp):
    data = ''.join([timestamp, request_type.upper(),
                   request_path, payload]).encode()
    signed_data = hmac.new(ICONOMI_API_SECRET.encode(), data, hashlib.sha512)
    return base64.b64encode(signed_data.digest())


def get(api):
    return call('GET', api, '')


def post(api, payload):
    return call('POST', api, payload)


def call(method, api, payload):
    timestamp = str(int(time.time() * 1000.0))

    jsonPayload = payload
    if method == 'POST':
        jsonPayload = json.dumps(payload)

    requestHeaders = {
        'ICN-API-KEY': ICONOMI_API_KEY,
        'ICN-SIGN': generate_signature(jsonPayload, method, api, timestamp),
        'ICN-TIMESTAMP': timestamp
    }

    if method == 'GET':
        response = requests.get(API_URL + api, headers=requestHeaders)
        if response.status_code == 200:
            return json.loads(response._content)
        else:
            return ('Request did not succeed: ' + response.reason)
    elif method == 'POST':
        response = requests.post(
            API_URL + api, json=payload, headers=requestHeaders)
        if response.status_code == 200:
            return json.loads(response._content)
        else:
            return ('Request did not succeed: ' + response.reason)

Define a strategy structure route

If the project is compiling, the developer can then define a route that will fetch a single Iconomi strategy structure.

@app.route('/strategies/{ticker}')
def detail(ticker):
    assets = get("/v1/strategies/" + ticker + "/structure")["values"]
    return assets 

The result is an array of crypto tickers and weights

Get the top 10 portfolios

When single strategy details are useful, then combining top 10 strategy details can give even a better picture of total market sentiment. To achieve this, the developer needs to manually get the strategy names, query them in a loop, and combine the results.

Query the top 10 strategies

On the Iconomi website, strategies can be ordered by their ACS(collective pool amount). Developer can choose the top 10 from this list and add their tickers to an array

tickers = ["BLX", "CAR", "ECA", "CCC", "ADVERTO", "MAV", "LONGTERMFUNDAMENTALS", "RISKYBISCUITS", "KNEPALA", "JUMPSTART", "INCGROWTH"]

Then strategy details can be queried for each of these via the /strategies/{ticker}/structure method.

@app.route('/top-ten')
def top_ten():
    assets = []

    for ticker in tickers:
        assets.append(get("/v1/strategies/" + ticker + "/structure"))

The resulting assets array contains strategy names (ticker) and their asset weights(rebalancedWeight):

[
  {
    "ticker": "BLX",
    "values": [
      {
        "rebalancedWeight": 0.4,
        "assetTicker": "BTC",
      },
      {
        "rebalancedWeight": 0.3,
        "assetTicker": "ETH",
      },
			...
		]
	},
		"ticker": "CAR",
		"values": [
			...

Find and rank the most used currencies

While the combined results are useful, another helpful indicator would be the average of the asset weights. These will give the investor a better overview about the asset’s popularity.

To do this, the distinct assetTicker values need to be made as keys to a new dictionary. The values for these keys will be the weights of the tickers in the strategies.

{
  "BTC": {
    "BLX": 0.4,
    "CAR": 0.1,
    .. etc weights in all of the strategies    

Python code:

for strategy in self.strategies:
    # fill the assets with asset tickers and their weights in strategies
    strategy_name = strategy["ticker"]
    strategy_assets = strategy["values"]

    for asset in strategy_assets:
        weight = asset["rebalancedWeight"]
        asset_ticker = asset["assetTicker"]

        if asset_ticker in assets:
            assets[asset_ticker][strategy_name] = weight
        else:
            assets[asset_ticker] = {strategy_name: weight}

Finally, the program calculates the combined weight by dividing the sum of asset weights by the strategy count.

for asset in assets.values():
  # calculate the average weight
  asset["combined_weight"] = sum(asset.values()) / len(self.strategies)

The final result looks like this:

{
  "BTC": {
    "BLX": 0.4,
    "CAR": 0.1,
    "ECA": 0.3,
    ...
    "combined_weight": 0.22103636363636364
  },
  "LUNA": {
    "BLX": 0.0119,
    "CAR": 0.1,
    "ECA": 0.6,
    ...
    "combined_weight": 0.17817272727272726
  },
  ...
}

Conclusion

Iconomi can be a good source of information when trying to understand the market sentiment. Programmers can use their skills to manipulate the data and get even more insight about popular crypto currencies. All she needs to do is query the Iconomi data, transform it by calculations and combine the result as an API response.

Please note that this combined data should not necessarily be taken as investment advice. Investor should do her own research about the currencies she is investing in.

Source code