Cryptocurrency Portfolio Tracker JavaScript, API
👤 Sharing: AI
```javascript
/**
* Cryptocurrency Portfolio Tracker (JavaScript, API)
*
* This program tracks the value of your cryptocurrency portfolio using a
* simple API call to retrieve current market prices. It uses the CoinGecko API
* (https://www.coingecko.com/api/documentations/v3) to get the prices.
*
* Important: You need to have Node.js installed to run this script. Also,
* because this script uses `fetch`, which is a modern browser API,
* you might need to install a package like `node-fetch` if you're running
* in an older Node.js environment. The code comments explain this.
*
* To run:
* 1. Save this code as a `.js` file (e.g., `crypto_tracker.js`).
* 2. Open a terminal or command prompt.
* 3. Navigate to the directory where you saved the file.
* 4. Run the command: `node crypto_tracker.js`
*/
// IMPORTANT: If you get an error like "ReferenceError: fetch is not defined",
// you'll need to install the `node-fetch` package. Uncomment these lines
// and then run `npm install node-fetch` in your terminal.
// import fetch from 'node-fetch'; //Uncomment this import for node
// const fetch = require('node-fetch'); //Uncomment this for node if necessary
// Replace with your actual portfolio data.
const portfolio = {
bitcoin: {
symbol: 'btc', // Cryptocurrency symbol (used by the API)
amount: 0.5, // Amount you own
},
ethereum: {
symbol: 'eth',
amount: 2.0,
},
cardano: {
symbol: 'ada',
amount: 100,
},
};
// API Endpoint (CoinGecko's simple price API)
const apiUrl = `https://api.coingecko.com/api/v3/simple/price?ids=${Object.values(portfolio).map(item => item.symbol).join(',')}&vs_currencies=usd`;
async function getCryptoPrices() {
try {
const response = await fetch(apiUrl); // Make the API call
if (!response.ok) {
throw new Error(`API request failed with status: ${response.status}`);
}
const data = await response.json(); // Parse the JSON response
return data;
} catch (error) {
console.error('Error fetching crypto prices:', error);
return null; // Return null if there's an error
}
}
async function calculatePortfolioValue() {
const prices = await getCryptoPrices();
if (!prices) {
console.log('Could not retrieve prices. Exiting.');
return;
}
let totalPortfolioValue = 0;
for (const crypto in portfolio) {
if (portfolio.hasOwnProperty(crypto)) { // Always a good practice when iterating over objects
const cryptoData = portfolio[crypto];
const symbol = cryptoData.symbol;
if (prices[symbol]) {
const price = prices[symbol].usd; // Get the USD price
const amount = cryptoData.amount;
const cryptoValue = price * amount;
console.log(
`${crypto}: Amount = ${amount}, Price = $${price}, Value = $${cryptoValue}`
);
totalPortfolioValue += cryptoValue;
} else {
console.log(`Price data not found for ${crypto} (symbol: ${symbol})`);
}
}
}
console.log('\n-----------------------------------');
console.log(`Total Portfolio Value: $${totalPortfolioValue.toFixed(2)}`); // Format to 2 decimal places
}
// Main Execution
calculatePortfolioValue();
/*
Explanation:
1. **Setup and Portfolio Definition:**
- The code starts by defining a `portfolio` object. This represents your cryptocurrency holdings.
- Each cryptocurrency is a key in the `portfolio` object (e.g., `bitcoin`, `ethereum`).
- Each crypto entry has a `symbol` (used to identify it in the API) and an `amount` (how much you own). You **must** change this data to match your actual portfolio.
2. **API Endpoint:**
- `apiUrl` is the URL for the CoinGecko API. It's constructed to request the prices of all the cryptocurrencies in your `portfolio` in USD.
- The `ids` parameter is dynamically built using the `symbol` properties from your `portfolio`. This ensures you only request the prices of the coins you own.
- CoinGecko is a popular and relatively free API for cryptocurrency data. Other APIs exist, but this one is straightforward.
3. **`getCryptoPrices()` Function:**
- This `async` function handles the API call.
- `fetch(apiUrl)` makes the request to the CoinGecko API. `fetch` is a modern JavaScript API for making network requests (like getting data from a website).
- `if (!response.ok)`: Checks if the API request was successful. If the status code is not in the 200-299 range (meaning OK), it throws an error.
- `await response.json()`: Parses the JSON response from the API. The API returns data in JSON (JavaScript Object Notation) format, which is a common way to represent data.
- The `try...catch` block handles potential errors during the API request (e.g., network problems, invalid API URL). It's important to handle errors so your program doesn't crash.
- If an error occurs, it logs the error to the console and returns `null`.
4. **`calculatePortfolioValue()` Function:**
- This `async` function calculates the total value of your portfolio.
- `const prices = await getCryptoPrices()`: Calls the `getCryptoPrices()` function to get the latest prices. It waits for the prices to be fetched before proceeding.
- `if (!prices)`: Checks if the `prices` are valid (not `null`). If the API call failed, it exits.
- The code then iterates through the `portfolio` object using a `for...in` loop.
- `if (portfolio.hasOwnProperty(crypto))`: This is a crucial check to ensure you're only iterating over the properties that you explicitly defined in your `portfolio` object and not inherited properties from the object's prototype. This is a best practice when iterating over objects in JavaScript.
- `const price = prices[symbol].usd`: Retrieves the USD price of the current cryptocurrency from the `prices` object. The `prices` object is structured like this: `{ btc: { usd: 30000 }, eth: { usd: 2000 } }`.
- `const cryptoValue = price * amount`: Calculates the value of your holdings for the current cryptocurrency.
- `console.log(...)`: Prints the details of each cryptocurrency (amount, price, value) to the console.
- `totalPortfolioValue += cryptoValue`: Accumulates the value of each cryptocurrency into the `totalPortfolioValue`.
- Finally, it prints the total portfolio value, formatted to two decimal places using `toFixed(2)`.
5. **Main Execution:**
- `calculatePortfolioValue()` is called to start the process. Because this function is `async`, the JavaScript runtime can continue to execute other code while it waits for the API request to complete.
Key Improvements and Considerations:
* **Error Handling:** The code includes error handling to gracefully deal with API request failures.
* **Clear Output:** The output is formatted for readability.
* **Modularity:** The code is structured into functions for better organization and reusability.
* **API Rate Limiting:** Be aware that CoinGecko (and other APIs) may have rate limits. If you make too many requests in a short period, you might get blocked. You can implement error handling for HTTP 429 errors (Too Many Requests) and potentially add delays between API calls. For production use, consider using a paid API plan for higher rate limits.
* **Asynchronous Operations:** The use of `async` and `await` makes the code easier to read and manage when dealing with asynchronous operations (like API calls).
* **Security:** This code doesn't involve user authentication or sensitive data storage, so security concerns are minimal. However, if you were to build a more complex application, you'd need to consider security best practices (e.g., protecting API keys, sanitizing user input).
* **Dependencies (Node.js):** Remember to handle the `node-fetch` dependency if you're running the code in a Node.js environment that doesn't natively support `fetch`.
* **API Key (Optional):** Some APIs require an API key. CoinGecko's basic API doesn't, but if you switch to a different API that does, you'll need to include the API key in the `apiUrl` or as a header in the `fetch` request. Never hardcode API keys directly in your code; use environment variables or configuration files.
* **Data Persistence:** This script only retrieves the portfolio value once. To track changes over time, you would need to store the data in a database or file.
* **UI (Optional):** To make the tracker more user-friendly, you could create a graphical user interface (GUI) using HTML, CSS, and JavaScript (perhaps using a framework like React, Vue, or Angular).
*/
```
👁️ Viewed: 9
Comments