Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jounger committed Nov 18, 2021
0 parents commit d5c2379
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace

# Local History for Visual Studio Code
.history/

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide

# Support for Project snippet scope
!.vscode/*.code-snippets

# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode
52 changes: 52 additions & 0 deletions background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
let symbol = '';
let fundamental = {};
let financial = {};
let rows = [];

chrome.runtime.onInstalled.addListener(() => {
chrome.storage.sync.set({ rows });
});

chrome.runtime.onMessage.addListener((msg, sender, response) => {
if (msg.name === "getData") {
symbol = msg.symbol.trim();
if (!symbol) {
return false;
}
const baseUrl = `https://restv2.fireant.vn/symbols/${symbol}`;
const fundamental_url = `${baseUrl}/fundamental`;
const financial_url = `${baseUrl}/financial-reports?type=IS&period=Q&compact=true&offset=0&limit=5`;
(async() => {
fundamental = await fetchData(fundamental_url);
financial = await fetchData(financial_url);
response({ fundamental: fundamental, financial: financial });
})();
return true; // keep the messaging channel open for response
}
if (msg.name === "resetData") {
symbol = '';
}
if (msg.name === "onload") {
response({ symbol: symbol, fundamental: fundamental, financial: financial });
}
});

async function fetchData(url = '') {
const token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkdYdExONzViZlZQakdvNERWdjV4QkRITHpnSSIsImtpZCI6IkdYdExONzViZlZQakdvNERWdjV4QkRITHpnSSJ9.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmZpcmVhbnQudm4iLCJhdWQiOiJodHRwczovL2FjY291bnRzLmZpcmVhbnQudm4vcmVzb3VyY2VzIiwiZXhwIjoxODg5NjIyNTMwLCJuYmYiOjE1ODk2MjI1MzAsImNsaWVudF9pZCI6ImZpcmVhbnQudHJhZGVzdGF0aW9uIiwic2NvcGUiOlsiYWNhZGVteS1yZWFkIiwiYWNhZGVteS13cml0ZSIsImFjY291bnRzLXJlYWQiLCJhY2NvdW50cy13cml0ZSIsImJsb2ctcmVhZCIsImNvbXBhbmllcy1yZWFkIiwiZmluYW5jZS1yZWFkIiwiaW5kaXZpZHVhbHMtcmVhZCIsImludmVzdG9wZWRpYS1yZWFkIiwib3JkZXJzLXJlYWQiLCJvcmRlcnMtd3JpdGUiLCJwb3N0cy1yZWFkIiwicG9zdHMtd3JpdGUiLCJzZWFyY2giLCJzeW1ib2xzLXJlYWQiLCJ1c2VyLWRhdGEtcmVhZCIsInVzZXItZGF0YS13cml0ZSIsInVzZXJzLXJlYWQiXSwianRpIjoiMjYxYTZhYWQ2MTQ5Njk1ZmJiYzcwODM5MjM0Njc1NWQifQ.dA5-HVzWv-BRfEiAd24uNBiBxASO-PAyWeWESovZm_hj4aXMAZA1-bWNZeXt88dqogo18AwpDQ-h6gefLPdZSFrG5umC1dVWaeYvUnGm62g4XS29fj6p01dhKNNqrsu5KrhnhdnKYVv9VdmbmqDfWR8wDgglk5cJFqalzq6dJWJInFQEPmUs9BW_Zs8tQDn-i5r4tYq2U8vCdqptXoM7YgPllXaPVDeccC9QNu2Xlp9WUvoROzoQXg25lFub1IYkTrM66gJ6t9fJRZToewCt495WNEOQFa_rwLCZ1QwzvL0iYkONHS_jZ0BOhBCdW9dWSawD6iF1SIQaFROvMDH1rg';
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'accept': 'application/json, text/plain, */*',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
'authorization': 'Bearer ' + token,
'origin': 'https://fireant.vn'
},
redirect: 'follow',
referrerPolicy: 'no-referrer'
});
return response.json();
}
Binary file added images/get_started128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/get_started16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/get_started32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/get_started48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "Stock Valuation",
"description": "Stock valuation by P/E method",
"version": "1.0.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"permissions": ["storage", "activeTab", "scripting"],
"action": {
"default_popup": "popup/index.html",
"default_icon": {
"16": "/images/get_started16.png",
"32": "/images/get_started32.png",
"48": "/images/get_started48.png",
"128": "/images/get_started128.png"
}
},
"icons": {
"16": "/images/get_started16.png",
"32": "/images/get_started32.png",
"48": "/images/get_started48.png",
"128": "/images/get_started128.png"
}
}
77 changes: 77 additions & 0 deletions popup/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html>

<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>

<body>
<div class="container">
<h4>Stock Valuation</h4>
<form class="mb-2">
<div class="form-group">
<label for="symbol">Stock symbol</label>
<div class="input-group mb-3">
<input type="text" id="symbol" class="form-control" placeholder="VND" aria-label="Stock symbol" aria-describedby="btnGetData">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button" id="btnGetData">Get Data</button>
</div>
</div>
</div>

<div class="form-group">
<label for="netProfit">Net Profit (5 quarters)</label>
<input type="text" class="form-control" id="netProfit" aria-describedby="netProfitHelp" placeholder="1.01;20.02;300.03;4000.04;50000.05">
<small id="netProfitHelp" class="form-text text-muted">Split by ';'</small>
</div>

<div class="form-row">
<div class="form-group col-6">
<label for="sharesOutstanding">Shares Outstanding</label>
<input type="number" class="form-control" id="sharesOutstanding" aria-describedby="Shares Outstanding" placeholder="100000000">
</div>

<div class="form-group col-6">
<label for="unit">Unit (profit):</label>
<select class="form-control" id="unit">
<option value="1000">1000</option>
<option value="1000000" selected>1.000.000</option>
<option value="1000000000">1.000.000.000</option>
</select>
</div>
</div>


<div class="form-row">
<div class="form-group col-6">
<label for="pe">P/E</label>
<input type="number" class="form-control" id="pe" placeholder="0">
</div>
<div class="form-group col-6">
<label for="industryPe">Industry P/E</label>
<input type="number" class="form-control" id="industryPe" aria-describedby="industryPeRef" placeholder="0">
<small id="industryPeRef" class="form-text text-muted">
<a href="https://www.stockbiz.vn/Industries.aspx" target="_blank">www.stockbiz.vn/Industries</a>
</small>
</div>
</div>
<button class="btn btn-primary" type="button" id="btnCalcData">Calculate</button>
<button class="btn btn-outline-primary" type="reset" id="btnResetData">Reset</button>
</form>
<table class="table table-sm">
<caption>List of lastest calculations</caption>
<thead>
<tr>
<th>Symbol</th>
<th>Low (price)</th>
<th>High (price)</th>
</tr>
</thead>
<tbody id="history"></tbody>
</table>
</div>
<script src="script.js"></script>
</body>

</html>
60 changes: 60 additions & 0 deletions popup/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
let btnCalcDataHTML = document.getElementById("btnCalcData");
let btnGetDataHTML = document.getElementById("btnGetData");
let btnResetDataHTML = document.getElementById("btnResetData");

const symbolHTML = document.getElementById("symbol");
const sharesOutstandingHTML = document.getElementById("sharesOutstanding");
const netProfitHTML = document.getElementById("netProfit");
const unitHTML = document.getElementById("unit");
const peHTML = document.getElementById("pe");
const industryPeHTML = document.getElementById("industryPe");
const historyHTML = document.getElementById("history");

chrome.runtime.sendMessage({ name: "onload" }, (response) => {
if (response.symbol) {
symbolHTML.value = response.symbol;
fillDataHTML(response);
}
});

chrome.storage.sync.get("rows", ({ rows }) => setHistoryTable(rows));

btnGetDataHTML.addEventListener("click", () => {
chrome.runtime.sendMessage({ name: "getData", symbol: symbol.value }, (response) => fillDataHTML(response));
});

btnResetDataHTML.addEventListener("click", () => {
chrome.runtime.sendMessage({ name: "resetData" });
});

btnCalcDataHTML.addEventListener("click", () => {
const netProfit = netProfitHTML.value.replace(/\s+/g, '').split(";");
const sumNetProfit = netProfit.reduce((p, c) => parseInt(p) + parseInt(c), 0);
const lowPrice = calcStockValuation(sumNetProfit, sharesOutstandingHTML.value, peHTML.value, unitHTML.value);
const highPrice = calcStockValuation(sumNetProfit, sharesOutstandingHTML.value, industryPeHTML.value, unitHTML.value);
const row = `<tr><td>${symbolHTML.value}</td><td>${lowPrice.toFixed(2)}</td><td>${highPrice.toFixed(2)}</td></tr>`;
chrome.storage.sync.get("rows", ({ rows }) => {
rows.push(row);
if (rows.length > 5) {
rows.shift();
}
chrome.storage.sync.set({ rows });
setHistoryTable(rows);
});
});

function calcStockValuation(sumNetProfit, sharesOutstanding, pe, unit) {
return sumNetProfit / sharesOutstanding * pe * unit;
}

function setHistoryTable(rows) {
historyHTML.innerHTML = rows.reverse().reduce((accumulator, item) => `${accumulator}${item}`, '');
}

function fillDataHTML(response) {
sharesOutstandingHTML.value = response.fundamental.sharesOutstanding;
peHTML.value = response.fundamental.pe.toFixed(2);
netProfitHTML.value = response.financial.rows[3].filter(x => !isNaN(x))
.map(y => (parseInt(y) / unit.value).toFixed(2))
.reduce((accumulator, item, i) => `${accumulator}${i ? ';' : ''}${item}`, '');
}
3 changes: 3 additions & 0 deletions popup/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body {
width: 330px;
}

0 comments on commit d5c2379

Please sign in to comment.