Event Driven Push Notification - Step 2

Description

In this Example we are going to modify the previous exercise by adding some rest calls to alphavantage finance API.

In particular, we want to study the performance of a stock through the 50-day average value and quickly report the best times to buy or sell the title under exam. The 50-day average value is a popular technical indicator which investors use to analyze price trends. You can calculate the 50-day moving average by taking the average of closing price over the last 50 days [(Day 1 + Day 2 + Day 3 + … + Day 49 + Day 50)/50].

When the current value of a title falls below the 50-day average value it’s a sign of a crisis for that title and it’s necessary to sell as soon as possible to avoid further losses. Conversely, when the value exceeds the 50-day average value, it’s convenient to buy before further increases.

System setup

We have to set up two rest-call elements to Alphavantage finance API in order to retrive the quotation trend and the historical quotes. But first, we need to define a new System:


Create a new System called “Finance” and a new Channel with the following attributes:

  • endpoint = https://www.alphavantage.co
  • type = RESTAdapter
  • id-channel = ApiFinance

rest-call: HistoricalQuotes

This rest call has the task to retrive from Alphavantage finance API the last 50 daily adjusted close values.

  • Insert into the channel “ApiFinance” a rest-call operation and name it HistoricalQuotes
  • Now set HistoricalQuotes’s attributes:
    • type = call
    • method = GET
    • name = HistoricalQuotes
    • request-uri = /query
  • Set up HistoricalQuotes subelements:
    • parameters
      • param(name: symbol, value: MSFT)
      • param(name: outputsize, value: compact)
      • param(name: function, value: TIME_SERIES_DAILY_ADJUSTED)
      • param(name: apikey, value: YOUR_FREE_ALPHAVANTAGE_API_KEY)
        Click here to get your ALPHAVANTAGE_API_KEY

rest-call: QuotationTrend

This rest call has the task to retrive the last two values in order to know if the title is rising or falling.

  • Insert into the channel “ApiFinance” a rest-call operation and name it QuotationTrend.
  • Now set QuotationTrend’s attributes:
    • type = call
    • method = GET
    • name = QuotationTrend
    • request-uri = /query
  • Set up QuotationTrend subelements:
    • parameters
      • param(name: symbol, value: MSFT)
      • param(name: outputsize, value: compact)
      • param(name: function, value: TIME_SERIES_INTRADAY)
      • param(name: apikey, value: YOUR_FREE_ALPHAVANTAGE_API_KEY)
      • param(name: interval, value: 1min)

Flow setup

Once the System Finance is created we can start to build up the flow. So, create a new Service called FinanceService, a new Operation called Threshold, then open the flow editor.

Now you have to create a flow like this:

Flow nodes

getToken (ChangeGVBufferNode)

This node has the task to extract data from the incoming json and setup FCM_DEVICE_TOKEN property thet we need to send notifications:

  • id = getToken
  • input = input
  • next-node-id = getQuotationTrend
  • ChangeGVBufferNode:
    • PropertyDef:
      • name = FCM_DEVICE_TOKEN

      • value = json{{fcm_device_token}}

getQuotationTrend (GVOperationNode)

This node makes rest call to Alphavantage finance API to retrive the two last values of the index under exam, using QuotationTrend operation in the Finance System created before:

  • id = getQuotationTrend
  • id-channel = ApiFinance
  • id-system = Finance
  • input = input
  • next-node-id = check1
  • operation-name = QuotationTrend
  • op-type = call
  • OutputService (OutputService)
    • retrive (script-service)
      • retrive (script-call)
        • Script (Script)
          var str = new java.lang.String(data.getObject());
          var payload = JSON.parse(str);
          var s = payload["Time Series (1min)"];
          var keys = [];
        
          for(var k in s) keys.push(k);
         
          var last = keys[0];
          var prev = keys[1];
          var x = parseFloat(payload["Time Series (1min)"][last]["4. close"]);
          var y = parseFloat(payload["Time Series (1min)"][prev]["4. close"]);
        
          data.setProperty('DATE', last);
          data.setProperty('LAST_TICK', x);
          data.setProperty('PREV_TICK', y);
        

check1 (GVNodeCheck)

This node just check if the previous operation it was successful:

  • default-id = getHistoricalQuotes
  • id = check1
  • input = input
  • on-exception-id = error

getHistoricalQuotes (GVOperationNode)

This node makes rest call to Alphavantage finance API to retrive the average of the last 50 adjusted close daily values, using Historical Quotes operation in the Finance System created before:

  • id = getHistoricalQuotes
  • id-channel = ApiFinance
  • id-system = Finance
  • input = input
  • next-node-id = check2
  • operation-name = HistoricalQuotes
  • op-type = call
  • OutputService (OutputService)
    • script (script-service)
      • script (script-call)
        • Script (Script)
          var str = new java.lang.String(data.getObject());
          var payload = JSON.parse(str);
          var s = payload["Time Series (Daily)"];
          var keys = [];
          var daysCD = 0;
          var total = 0;
        
          for(var k in s) keys.push(k);
        
          for(var k in s){
              daysCD+=1;
              if(daysCD<=50){
                  total+=parseFloat(payload["Time Series (Daily)"][k]["5. adjusted close"]);
              }
          }
        
          data.setProperty('AVG', (total/50));
        

check2 (GVNodeCheck)

This node just check if the previous operation it was successful:

  • default-id = comparator
  • id = check2
  • input = input
  • on-exception-id = error

error (GVEndNode)

This node return the result of the operation in case of failure:

  • id = error
  • output = input

comparator (ChangeGVBufferNode)

This node contains the logic to determinate if the index under exam should be bought, or be sold it. In the other cases it will returns Nothing to report.

  • id = comparator
  • input = input
  • next-node-id = prepareJson
  • ChangeGVBufferNode:
    • Script:
      var lastTick = parseFloat(data.getProperty('LAST_TICK'));
      var prevTick = parseFloat(data.getProperty('PREV_TICK'));
      var avg = parseFloat(data.getProperty('AVG'));
    
      if ( lastTick > prevTick && lastTick>avg && prevTick<avg) {
              data.setProperty('MESSAGE', 'Buy!');
    	} else if  (lastTick < prevTick && lastTick<avg && prevTick>avg){
              data.setProperty('MESSAGE', 'Sell!');
    	} else {
          data.setProperty('MESSAGE', 'Nothing to report.')
      }
    

prepareJson (ChangeGVBufferNode)

This node has the task to build the json file that will be sent to PushNotification service:

  • id = prepareJson
  • input = input
  • next-node-id = pushNotificationCall
  • ChangeGVBufferNode:
    • Script:
      var js = {
              "date":data.getProperty('DATE'),
              "message":data.getProperty('MESSAGE'),
              "fcm_device_token":data.getProperty('FCM_DEVICE_TOKEN')
          };
          data.setObject(JSON.stringify(js));
    

pushNotificationCall (GVCoreCall)

This node just send the json to PushNotification service:

  • id = pushNotificationCall
  • id-service = PushNotification
  • input = input
  • next-node-id = end
  • operation = Send

end (GVEndNode)

This node return the result of the operation in case of success.

  • id = end
  • output = input

Testing with GV Console

Now you are able to test your VulCon Service from the GV Console® once exported the configuration.

So, let’s start GreenVulcano® ESB, access to the GV Console and deploy your Vulcon project setting your apikey.


Once the configuration is deployed you can finally test it. Go to Execute section end select Threshold operation. To send a notify you have to insert a Json string. The device token is the code that you can find in the web app:

{ "fcm_device_token":"YOUR_FCM_DEVICE_TOKEN" }

Now you can reiceve notifications by your Android App:


Note: In case of error or exceptions you can check the file GVCore.log situated in the folder GV_HOME/data/log/.

Download

Here you can download the configuration: