# 4-2. Moving Volume Weighted Average Price (MVWAP)
In this "MVWAP" data process demonstration, in addition to logic writing, we will be focusing on the ++**design thinking of the entire process**++ and the ++**use of agents**++.
## Before LOC Setup
- At the beginning of the entire process, we need to go through the analysis process(BA/SA) to clarify the needs to help developers build up data processes.
- After we specify our requirements in BA/SA process, we have designed where/what/how users can get MVWAP index and mapped these requirements back to design:
- What **Trigger** point does the user use to execute a data process?
- Which **Data Source** should the user read/write?
- Finally, what kind of **Output** does user want?
*Here since we do not introduced the event concept, there is no setup in Reference.*

- We know that users want to be able to obtain the specific stock MVWAP index. Based on this requirement, we use the expected API as a starting point to design the whole data process.

- After designing the data process, we can start to setup it with LOC.
---
## Step 1. Initiate New Data Process Template File
At the beginning, let us start the whole journey by
```
loc login
```
And
```
loc new [template name]
```
---
## Step 2. Edit API Route yaml file

- After designing and planning, we can know the API schema that we expect to build and users expect to access. That we can set it in the `api-route-config.yaml` first.
- API Route: You need to
(1) change to POST method to bring payload to the generic logic to parse value;
(2) rename the API route name that you favour, such as **MVWAP_sample**;
(3) create your own path, such as **/sample/getMVWAP**;
and leave the rest unchanged.
```yaml=
method: Post
mode: Sync
encapsulation: false
name: MVWAP_sample
path: /sample/getMVWAP
dataProcessPids:
- pid: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
revision: latest
```
---
## Step 3. Create Generic Logic
- To build a "MVWAP" data process, we need to:
(1) parse the payload that users key in;
(2) get necessary data that we need through DB agent;
(3) calculate the index (MVWAP); and
(4) print out the result of calculations.
- **3.1 Parse API Payload**
```javascript=
export async function run(ctx) {
// checking input from api
if ("event" in ctx.payload || "messageQueue" in ctx.payload) {
throw new Error("this logic accept http payload only");
}
// a function that transforms byte array to string
function UTF8ArrToStr(aBytes) {
let utf8decoder = new TextDecoder();
return utf8decoder.decode(new Uint8Array(aBytes));
}
const getHttpBodyJson = JSON.parse(UTF8ArrToStr(ctx.payload.http.body));
// parse payload body
const data_payload = getHttpBodyJson;
// checking the payload is as defined
const days = parseInt(data_payload.days ?? "0");
const stock_code = data_payload.stock_code ?? "";
if (stock_code == ""){
throw "please enter the correct stock code."
}
if (days !== 20 && days !== 50 && days !== 100) {
throw "days should be 20 | 50 | 100";
}
```
> Check whether the input of days is 20, 50 or 100 days.
> Check whether users search with a correct stock_code.
- **3.2 Connect DB and Query Data**
```javascript=31
// mysql authorized access
const database = process.env.db1_database;
const table = process.env.db1_table4;
let connection = new Saffron.Database.MySqlParameters({
host: process.env.db1_host,
port: parseInt(process.env.db1_port ?? "3306"),
database,
username: process.env.db1_username,
password: process.env.db1_password,
});
let db = await ctx.agents.database?.connect({
databaseDriver: Saffron.Database.Driver.MySql,
connection,
});
let sql = `SELECT stock_code, close, volume, date \
FROM ${table} \
WHERE stock_code = '${stock_code}' \
ORDER BY date DESC \
LIMIT ${days};`
let resp = await db?.query(sql, []);
```
> `process.env` means to get the information in `profile.yaml`
- **3.3 Calculate MVWAP**
```javascript=56
// calculate MVWAP
let numerator_vwap = 0;
let denominator_vwap = 0;
resp?.rows.forEach((row) => {
numerator_vwap += Number(row["close"] * row["volume"])
denominator_vwap += Number(row["volume"]);
})
let vwap = Number(numerator_vwap) / Number(denominator_vwap);
let mvwap = Number(vwap) / Number(days);
```
- **3.4 API Response**
```javascript=66
// push result in array
let data = [];
data.push({stock_code: stock_code, MVWAP: mvwap, VWAP: vwap, Numerator: numerator_vwap, Denominator: denominator_vwap});
await ctx.agents.sessionStorage.putJson("result", data)
}
//////////////////////////////////////////////////
export async function handleError(ctx, error) {
ctx.agents.logging.error(error.message);
}
```
---
## Step 4. Create Aggregator Logic
- Finalise and aggregate the result that we need to show up in the API response.
```javascript=
export async function run(ctx) {
let result = {
Status: 200,
Message: 'Calling API success.',
API_calling_details: await ctx.agents.sessionStorage.get("result"),
};
ctx.agents.result.finalize(result);
}
export async function handleError(ctx, error) {
ctx.agents.logging.error(error.message);
let result = {
status: 500,
errorMessage: `An error occurs when calling API. Error: ${error.message}`,
};
ctx.agents.result.finalize(result);
}
```
:::info
ADDITIONAL
Edit Configuration
- Configuration: You can also edit your `config.yaml` for readable
(1) rename the configuration name that you favour, such as **MVWAP_sample**;
(2) rename the logic names that you favour, such as **MVWAP_sample_code.js**;
```yaml=
version: 0.1.0
name: MVWAP_sample
description: description
timeoutSeconds: 180
aggregatorLogic:
name: aggregator
file: aggregator-logic.js
genericLogics:
- name: MVWAP_sample
file: MVWAP_sample_code.js
```
:::
---
## Step 5. Deploy Data Process and API Route
- Once the setting above is completed, we can deploy "MVWAP" ++data process++ and ++API route++ at the same time by using command:
`loc deploy [template name] -ar`.
Here we use
`loc deploy MVWAP_sample_code -ar`.

---
## Step 6. Trigger API Route with Payload
Here we use ++Postman++ to demonstrate.
- Select ```POST``` and use the endpoint path we set in ```api-route-config.yaml``` with domain URL.
Afterwards, use the JSON payload as below to get the data that we need:
++**payload**++
```json=
{
"days":20,
"stock_code":"1301"
}
```
- Click `Send` , here is the response that you can expect, in which to get the `MVWAP` index of `stock_code:1301`, with lots of additional information.

---
###### tags: `Workshop`