Blog

  • JavaScript Finance: Monte Carlo simulation

    Why Randomness is Your Ally in Financial Predictions

    Imagine you’re tasked with predicting the future price of a stock. The market is volatile, and there are countless variables at play—economic trends, company performance, global events. How do you account for all this uncertainty? Enter the Monte Carlo simulation: a mathematical technique that uses randomness to model and predict outcomes. It might sound counterintuitive, but randomness, when harnessed correctly, can be a powerful tool for making informed financial decisions.

    Monte Carlo simulations are widely used in finance to estimate risks, calculate expected returns, and evaluate the sensitivity of models to changes in input variables. Whether you’re a financial analyst, a data scientist, or a developer building financial tools, understanding and implementing Monte Carlo simulations can give you a significant edge.

    In this article, we’ll dive deep into how to implement Monte Carlo simulations in JavaScript, explore the math behind the method, and discuss practical considerations, including performance and security. By the end, you’ll not only understand how to write the code but also how to apply it effectively in real-world scenarios.

    What is a Monte Carlo Simulation?

    At its core, a Monte Carlo simulation is a way to model uncertainty. It works by running a large number of simulations (or trials) using random inputs, then analyzing the results to estimate probabilities, expected values, and risks. The name comes from the Monte Carlo Casino in Monaco, a nod to the randomness inherent in gambling.

    For example, if you’re trying to predict the future price of a stock, you could use a Monte Carlo simulation to generate thousands of possible outcomes based on random variations in key factors like market volatility and expected return. By analyzing these outcomes, you can estimate the average future price, the range of possible prices, and the likelihood of extreme events.

    Before We Dive In: Security and Performance Considerations

    🔐 Security Note: While Monte Carlo simulations are powerful, they rely heavily on random number generation. In JavaScript, the built-in Math.random() function is not cryptographically secure. If you’re building a financial application that handles sensitive data or requires high levels of accuracy, consider using a more robust random number generator, such as the crypto.getRandomValues() API.
    ⚠️ Gotcha: Monte Carlo simulations can be computationally expensive, especially when running thousands or millions of trials. Be mindful of performance, particularly if you’re working in a browser environment or on resource-constrained devices. We’ll discuss optimization techniques later in this article.

    Building a Monte Carlo Simulation in JavaScript

    Let’s start with a simple example: estimating the future price of a stock. We’ll assume the stock’s price is influenced by its current price, an expected return rate, and market volatility. Here’s how we can implement this in JavaScript:

    Step 1: Define the Model

    The first step is to define a function that models the stock price. This function will take the current price, expected return, and volatility as inputs, then use random sampling to calculate a possible future price.

    // Define the stock price model
    function stockPrice(currentPrice, expectedReturn, volatility) {
      // Randomly sample return and volatility
      const randomReturn = (Math.random() * 2 - 1) * expectedReturn;
      const randomVolatility = (Math.random() * 2 - 1) * volatility;
    
      // Calculate the future price
      const futurePrice = currentPrice * (1 + randomReturn + randomVolatility);
    
      return futurePrice;
    }
    

    In this function, we use Math.random() to generate random values for the return and volatility. These values are then used to calculate the future price of the stock.

    Step 2: Run the Simulation

    Next, we’ll run the simulation multiple times to generate a range of possible outcomes. We’ll store these outcomes in an array for analysis.

    // Run the Monte Carlo simulation
    const simulations = 1000;
    const results = [];
    
    for (let i = 0; i < simulations; i++) {
      const result = stockPrice(100, 0.1, 0.2); // Example inputs
      results.push(result);
    }
    

    Here, we’re running the stockPrice function 1,000 times with a starting price of $100, an expected return of 10%, and a volatility of 20%. Each result is added to the results array.

    Step 3: Analyze the Results

    Once we have our simulation results, we can calculate key metrics like the average future price and the range of possible outcomes.

    // Analyze the results
    const averagePrice = results.reduce((sum, price) => sum + price, 0) / simulations;
    const minPrice = Math.min(...results);
    const maxPrice = Math.max(...results);
    
    console.log(`Average future price: $${averagePrice.toFixed(2)}`);
    console.log(`Price range: $${minPrice.toFixed(2)} - $${maxPrice.toFixed(2)}`);
    

    In this example, we calculate the average future price by summing all the results and dividing by the number of simulations. We also find the minimum and maximum prices using Math.min() and Math.max().

    Optimizing Your Simulation

    While the example above works, it’s not particularly efficient. Here are some tips for optimizing your Monte Carlo simulations:

    • Use Typed Arrays: If you’re running simulations with large datasets, consider using Float32Array or Float64Array for better performance.
    • Parallel Processing: In Node.js, you can use the worker_threads module to run simulations in parallel. In the browser, consider using Web Workers.
    • Pre-generate Random Numbers: Generating random numbers on the fly can be a bottleneck. Pre-generating them and storing them in an array can speed up your simulations.

    Real-World Applications

    Monte Carlo simulations have a wide range of applications beyond stock price prediction. Here are a few examples:

    • Portfolio Optimization: Estimate the risk and return of different investment portfolios.
    • Risk Management: Assess the likelihood of extreme events, such as market crashes.
    • Project Management: Predict project timelines and budget overruns.
    • Game Development: Simulate player behavior and outcomes in complex systems.

    Conclusion

    Monte Carlo simulations are a versatile and powerful tool for modeling uncertainty and making data-driven decisions. By leveraging randomness, you can estimate risks, calculate expected values, and explore the sensitivity of your models to changes in input variables.

    Key takeaways:

    • Monte Carlo simulations rely on random sampling to model uncertainty.
    • JavaScript’s Math.random() is sufficient for basic simulations but may not be suitable for high-stakes applications.
    • Optimizing your simulations can significantly improve performance, especially for large datasets.
    • Monte Carlo simulations have applications in finance, project management, game development, and more.

    Ready to take your simulations to the next level? Try implementing a Monte Carlo simulation for a problem you’re currently working on. Share your results in the comments below!

  • JavaScript Finance: Calculate ichimoku value

    Looking to enhance your trading strategy with JavaScript? The Ichimoku Kinko Hyo indicator, commonly known as the Ichimoku Cloud, is a powerful tool for identifying market trends and support/resistance levels. In this article, we’ll walk through how to calculate Ichimoku values in JavaScript and use them to make buy/sell decisions.

    Ichimoku Kinko Hyo is a comprehensive technical analysis indicator comprised of several components: Tenkan-sen (Conversion Line), Kijun-sen (Base Line), Senkou Span A (Leading Span A), Senkou Span B (Leading Span B), and Chikou Span (Lagging Span). Each component helps traders visualize momentum, trend direction, and potential reversal points.

    To compute Ichimoku values for a stock, you need to specify several parameters: the time frame, the number of periods for each component, and the stock price data. Here’s how you might define these parameters in JavaScript:

    // Define the time frame to use for the Ichimoku indicator (e.g. daily, hourly, etc.)
    const timeFrame = 'daily';
    
    // Define the number of periods to use for each of the Ichimoku components
    const conversionPeriod = 9;
    const basePeriod = 26;
    const spanAPeriod = 52;
    const spanBPeriod = 26;
    
    // Define the stock price for which to calculate the Ichimoku values
    const price = 123.45;
    
    // Initialize the Ichimoku Kinko Hyo indicator with the given parameters
    const ichimoku = initializeIchimoku({
      timeFrame,
      conversionPeriod,
      basePeriod,
      spanAPeriod,
      spanBPeriod,
    });
    

    With these parameters set, you can calculate the Ichimoku values for a given stock price. Below is an example implementation in JavaScript:

    const ichimoku = {
      // Define the Ichimoku parameters (fictional example)
      tenkanSen: 9,
      kijunSen: 26,
      senkouSpanB: 52,
      
      // Calculate the Ichimoku values for the given stock price
      calculate(params) {
        const { stock} = params;
        
        // Calculate the Tenkan-sen and Kijun-sen values
        const tenkanSen = (stock.highValues.slice(-this.tenkanSen).reduce((a, b) => a + b, 0) / this.tenkanSen)
        const kijunSen = (stock.lowValues.slice(-this.kijunSen).reduce((a, b) => a + b, 0) / this.kijunSen)
        
        // Calculate the Senkou Span A value
        const senkouSpanA = ((tenkanSen + kijunSen) / 2)
        
        // Calculate the Senkou Span B value
        const senkouSpanB = (stock.highValues.slice(-this.senkouSpanB).reduce((a, b) => a + b, 0) / this.senkouSpanB)
        
        // Calculate the Chikou Span value
        const chikouSpan = (this.prices[-this.senkouSpanB])
        
        // Return the calculated Ichimoku values
        return { tenkanSen, kijunSen, senkouSpanA, senkouSpanB, chikouSpan };
      }
    };
    
    // Calculate the Ichimoku values for the given stock price
    const ichimokuValues = ichimoku.calculate({ price });
    
    // Output the calculated Ichimoku values
    console.log('Tenkan-sen:', ichimokuValues.tenkanSen);
    console.log('Kijun-sen:', ichimokuValues.kijunSen);
    console.log('Senkou Span A:', ichimokuValues.senkouSpanA);
    console.log('Senkou Span B:', ichimokuValues.senkouSpanB);
    console.log('Chikou Span:', ichimokuValues.chikouSpan);
    

    In this example, the ichimoku.calculate() function receives an object containing the stock price and returns an object with the computed Ichimoku values. The function leverages the parameters defined in the ichimoku object and uses fictional historical data (such as this.highs and this.lows) for its calculations.

    To interpret the Ichimoku Cloud indicator and make trading decisions, focus on these key values:

    • Tenkan-sen: The average of the highest high and lowest low over the past 9 periods. If the price is above Tenkan-sen, the trend is up; below, the trend is down.
    • Kijun-sen: The average of the highest high and lowest low over the past 26 periods. Price above Kijun-sen indicates an uptrend; below signals a downtrend.
    • Senkou Span A: The average of Tenkan-sen and Kijun-sen, shifted forward 26 periods. Price above Senkou Span A suggests an uptrend; below, a downtrend.
    • Senkou Span B: The average of the highest high and lowest low over the past 52 periods, shifted forward 26 periods. Price above Senkou Span B means uptrend; below, downtrend.
    • Chikou Span: The current price shifted back 26 periods. If Chikou Span is above the price, it signals an uptrend; below, a downtrend.

    Traders typically look for a combination of these signals. For instance, if the price is above both Tenkan-sen and Kijun-sen, and Chikou Span is above the price, this is considered bullish—a potential buy signal. Conversely, if the price is below Tenkan-sen and Kijun-sen, and Chikou Span is below the price, it’s bearish—a potential sell signal. Remember, interpretations may vary among traders.

    function buySellDecision(ichimokuValues) {
    if (ichimokuValues.tenkanSen > ichimokuValues.kijunSen && ichimokuValues.chikouSpan > ichimokuValues.senkouSpanA) {
    return "buy";
    } else if (ichimokuValues.tenkanSen < ichimokuValues.kijunSen && ichimokuValues.chikouSpan < ichimokuValues.senkouSpanA) {
    return "sell";
    } else {
    return "hold";
    }
    }
    
    const decision = buySellDecision(ichimokuValues);
    console.log('Buy/Sell decision:', decision);
    
  • JavaScript Finance: Calculate RSI value

    Looking for a reliable way to spot market momentum and potential buy or sell signals? The Relative Strength Index (RSI) is a popular technical indicator that helps traders gauge whether an asset is overbought or oversold. In this article, you’ll learn how to calculate RSI using JavaScript, with clear explanations and practical code examples.

    To calculate the RSI value, you first need to compute the average gain and average loss over a specified number of periods. These values are then used to determine the relative strength and, ultimately, the RSI using the following formula:

    RSI = 100 – 100 / (1 + (average gain / average loss))

    Start by determining the price change for each period. If the price increases, the change is positive and added to the total gain. If the price decreases, the change is negative and added to the total loss. Calculate the average gain and average loss by dividing the total gain and total loss by the number of periods used for the RSI.

    For example, if you’re calculating RSI over 14 periods, compute the price change for each of the last 14 periods. If the price increased by $1 in a period, add that to the total gain; if it decreased by $1, add that to the total loss. Divide each total by 14 to get the average gain and average loss, then use the formula above to calculate the RSI.

    Remember, RSI is an oscillator that fluctuates between 0 and 100. An RSI above 70 is considered overbought, while below 30 is considered oversold. These thresholds can help identify potential buying and selling opportunities.

    function rsi(prices, period) {
      const gains = [];
      const losses = [];
    
      for (let i = 1; i < prices.length; i++) {
        const change = prices[i] - prices[i - 1];
        if (change > 0) {
          gains.push(change);
        } else {
          losses.push(change);
        }
      }
    
      const avgGain = average(gains.slice(0, period));
      const avgLoss = average(losses.slice(0, period).map(Math.abs));
      const rs = avgGain / avgLoss;
    
      return 100 - (100 / (1 + rs));
    }
    
    function average(values) {
      return values.reduce((total, value) => total + value) / values.length;
    }

    The code above calculates the RSI value for a given list of prices over a specified period. It computes the gains and losses for each price change, calculates the average gain and average loss, then determines the relative strength (RS) as the ratio of average gain to average loss. Finally, it calculates the RSI value using the standard formula.

    To use this code, simply call the rsi function with your price list and desired period, for example:

    const prices = [100, 105, 110, 115, 120, 130, 135];
    const period = 5;
    const rsiValue = rsi(prices, period);

    This will calculate the RSI value for the provided prices array over a period of 5. The resulting rsiValue will be a number between 0 and 100, indicating the relative strength of the asset. Values below 30 suggest oversold conditions, while values above 70 indicate overbought conditions.

    function rsiBuySellDecision(rsi) {
      if (rsi < 30) {
        return 'BUY';
      } else if (rsi > 70) {
        return 'SELL';
      } else {
        return 'HOLD';
      }
    }
    

    Keep in mind, this is a basic example and RSI thresholds for buy or sell decisions may vary depending on your trading strategy. RSI should not be used in isolation; it’s best combined with other indicators and market analysis for more reliable results.

  • Calculate the SHA-256 hash of a string in JavaScript without library

    Ever wondered how to generate a SHA-256 hash in JavaScript without relying on external libraries? This post walks you through a pure JavaScript implementation of the SHA-256 algorithm, helping you understand each step and the underlying logic.

    The SHA-256 (Secure Hash Algorithm 256) is a widely used cryptographic hash function that produces a fixed-size output for any given input. It is commonly used to verify the integrity of data. In this post, we will learn how to implement the SHA-256 hash function in JavaScript without using any external libraries.

    function sha256(string) {
      // Initialize the SHA-256 hash
      var hash = new Uint32Array(8);
      hash[0] = 0x6a09e667;
      hash[1] = 0xbb67ae85;
      hash[2] = 0x3c6ef372;
      hash[3] = 0xa54ff53a;
      hash[4] = 0x510e527f;
      hash[5] = 0x9b05688c;
      hash[6] = 0x1f83d9ab;
      hash[7] = 0x5be0cd19;
    
      // Convert the string to a byte array
      var stringBytes = toUTF8Bytes(string);
    
      // Pad the byte array to a multiple of 64 bytes
      var paddedBytes = padToMultipleOf(stringBytes, 64);
    
      // Process the padded byte array in blocks of 64 bytes
      for (var i = 0; i < paddedBytes.length; i += 64) {
        processBlock(paddedBytes.slice(i, i + 64), hash);
      }
    
      // Return the final hash as a hexadecimal string
      return toHexString(hash);
    }
    

    The hexadecimal values 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, and 0x5be0cd19 are the initial values of the eight 32-bit words used in the SHA-256 algorithm. These values are defined in the SHA-2 standard and serve as the starting state of the hash calculation. They are commonly referred to as the “initial hash values” or the “initial digest.”

    This function calculates the SHA-256 hash of a given string by first initializing the hash with the default initial values, then converting the string to a byte array, padding the byte array to a multiple of 64 bytes, and finally processing the padded byte array in blocks of 64 bytes.

    The toUTF8Bytes, padToMultipleOf, processBlock, and toHexString functions are helper functions used to convert the string to a byte array, pad the byte array, process the blocks of bytes, and convert the final hash to a hexadecimal string, respectively.

    Here are the implementations of these helper functions:

    function toUTF8Bytes(str) {
      var bytes = [];
      for (var i = 0; i < str.length; i++) {
        var codePoint = str.charCodeAt(i);
        if (codePoint < 0x80) {
          bytes.push(codePoint);
        } else if (codePoint < 0x800) {
          bytes.push(0xc0 | codePoint >> 6);
          bytes.push(0x80 | codePoint & 0x3f);
        } else if (codePoint < 0x10000) {
          bytes.push(0xe0 | codePoint >> 12);
          bytes.push(0x80 | codePoint >> 6 & 0x3f);
          bytes.push(0x80 | codePoint & 0x3f);
        } else {
          bytes.push(0xf0 | codePoint >> 18);
          bytes.push(0x80 | codePoint >> 12 & 0x3f);
          bytes.push(0x80 | codePoint >> 6 & 0x3f);
          bytes.push(0x80 | codePoint & 0x3f);
        }
      }
      return bytes;
    }
    

    This function converts the given string to a UTF-8 encoded byte array by iterating over the string and converting each character to a code point using charCodeAt. It then encodes the code point as a sequence of bytes in the array, depending on the value of the code point. If the code point is less than 0x80, it is encoded as a single byte. If it is between 0x80 and 0x800, it is encoded as two bytes. If it is between 0x800 and 0x10000, it is encoded as three bytes. Otherwise, it is encoded as four bytes. The function returns the resulting byte array.

    Here is the complete implementation of padToMultipleOf and processBlock:

    function padToMultipleOf(bytes, multiple) {
      var padding = bytes.length % multiple;
      if (padding > 0) {
        padding = multiple - padding;
      }
      for (var i = 0; i < padding; i++) {
        bytes.push(i === 0 ? 0x80 : 0x00);
      }
      return bytes;
    }
    
    function processBlock(bytes, hash) {
      // Initialize the word array
      var words = new Uint32Array(64);
      for (var i = 0; i < 64; i++) {
        words[i] = bytes[i * 4] << 24 | bytes[i * 4 + 1] << 16 | bytes[i * 4 + 2] << 8 | bytes[i * 4 + 3];
      }
    
      // Initialize the working variables
      var a = hash[0];
      var b = hash[1];
      var c = hash[2];
      var d = hash[3];
      var e = hash[4];
      var f = hash[5];
      var g = hash[6];
      var h = hash[7];
    
      // Process the words in the block
      for (var i = 0; i < 64; i++) {
        var s0 = rotateRight(a, 2) ^ rotateRight(a, 13) ^ rotateRight(a, 22);
        var maj = (a & b) ^ (a & c) ^ (b & c);
        var t2 = s0 + maj;
        var s1 = rotateRight(e, 6) ^ rotateRight(e, 11) ^ rotateRight(e, 25);
        var ch = (e & f) ^ (~e & g);
        var t1 = h + s1 + ch + K[i] + words[i];
    
        h = g;
        g = f;
        f = e;
        e = d + t1;
        d = c;
        c = b;
        b = a;
        a = t1 + t2;
      }
    
      // Update the hash with the final values of the working variables
      hash[0] += a;
      hash[1] += b;
      hash[2] += c;
      hash[3] += d;
      hash[4] += e;
      hash[5] += f;
      hash[6] += g;
      hash[7] += h;
    }
    

    The padToMultipleOf function pads the given byte array so that its length becomes a multiple of the specified value. It calculates the required padding, adds a 0x80 byte followed by 0x00 bytes as needed, and returns the padded array.

    function padToMultipleOf(bytes, multiple) {
      var padding = bytes.length % multiple;
      if (padding > 0) {
        padding = multiple - padding;
      }
      for (var i = 0; i < padding; i++) {
        bytes.push(i === 0 ? 0x80 : 0x00);
      }
      return bytes;
    }
    

    Implementation of the toHexString helper function:

    function toHexString(hash) {
      var hex = "";
      for (var i = 0; i < hash.length; i++) {
        hex += (hash[i] >>> 0).toString(16);
      }
      return hex;
    }
    

    The toHexString function converts the hash (an array of 32-bit unsigned integers) to a hexadecimal string by iterating over the array and converting each element to its hexadecimal representation.

    Here is an example of how the sha256 function can be used to calculate the SHA-256 hash of a given string:

    var hash = sha256("Hello, world!");
    // The value of "hash" is now "7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"
    
  • Make a Microsoft graph call using javascript

    Unlocking Microsoft 365 Data with JavaScript

    Imagine this: your team is building a productivity app that needs to pull in user calendars, emails, or OneDrive files from Microsoft 365. You’ve heard of Microsoft Graph, the unified API endpoint for accessing Microsoft 365 data, but you’re not sure where to start. The documentation feels overwhelming, and you just want to see a working example in JavaScript. Sound familiar?

    Microsoft Graph is a goldmine for developers. It allows you to interact with Microsoft 365 services like Outlook, Teams, OneDrive, and more—all through a single API. But getting started can be tricky, especially when it comes to authentication and managing API calls securely. In this guide, I’ll walk you through how to set up and make your first Microsoft Graph API call using JavaScript. Along the way, I’ll share some hard-earned lessons, gotchas, and tips to ensure your implementation is both functional and secure.

    Before We Dive In: Security Implications

    Before writing a single line of code, let’s talk security. Microsoft Graph requires OAuth 2.0 for authentication, which means you’ll need to handle access tokens. These tokens grant access to sensitive user data, so mishandling them can lead to serious security vulnerabilities.

    🔐 Security Note: Never hardcode sensitive credentials like client secrets or access tokens in your codebase. Use environment variables or a secure secrets management service to store them.

    Additionally, always request the minimum set of permissions (scopes) your app needs. Over-permissioning is not only a security risk but also a violation of Microsoft’s best practices.

    Step 1: Setting Up the Microsoft Graph JavaScript Client Library

    The easiest way to interact with Microsoft Graph in JavaScript is by using the official @microsoft/microsoft-graph-client library. This library simplifies the process of making HTTP requests and handling responses.

    First, install the library via npm:

    npm install @microsoft/microsoft-graph-client

    Once installed, you’ll also need an authentication library to handle OAuth 2.0. For this example, we’ll use msal-node, Microsoft’s official library for authentication in Node.js:

    npm install @azure/msal-node

    Step 2: Authenticating with Microsoft Graph

    Authentication is the trickiest part of working with Microsoft Graph. You’ll need to register your application in the Azure portal to get a client_id and client_secret. Here’s how:

    1. Go to the Azure Portal and navigate to “App Registrations.”
    2. Click “New Registration” and fill in the required details.
    3. Once registered, note down the Application (client) ID and Directory (tenant) ID.
    4. Under “Certificates & Secrets,” create a new client secret. Store this securely; you’ll need it later.

    With your app registered, you can now authenticate using the msal-node library. Here’s a basic example:

    const msal = require('@azure/msal-node');
    
    // MSAL configuration
    const config = {
      auth: {
        clientId: 'YOUR_APP_CLIENT_ID',
        authority: 'https://login.microsoftonline.com/YOUR_TENANT_ID',
        clientSecret: 'YOUR_APP_CLIENT_SECRET',
      },
    };
    
    // Create an MSAL client
    const cca = new msal.ConfidentialClientApplication(config);
    
    // Request an access token
    async function getAccessToken() {
      const tokenRequest = {
        scopes: ['https://graph.microsoft.com/.default'],
      };
    
      try {
        const response = await cca.acquireTokenByClientCredential(tokenRequest);
        return response.accessToken;
      } catch (error) {
        console.error('Error acquiring token:', error);
        throw error;
      }
    }
    

    In this example, we’re using the “client credentials” flow, which is ideal for server-side applications. If you’re building a client-side app, you’ll need to use a different flow, such as “authorization code.”

    Step 3: Making Your First Microsoft Graph API Call

    Now that you have an access token, you can use the Microsoft Graph client library to make API calls. Let’s fetch the authenticated user’s profile using the /me endpoint:

    const { Client } = require('@microsoft/microsoft-graph-client');
    require('isomorphic-fetch'); // Required for fetch support in Node.js
    
    async function getUserProfile(accessToken) {
      // Initialize the Graph client
      const client = Client.init({
        authProvider: (done) => {
          done(null, accessToken);
        },
      });
    
      try {
        const user = await client.api('/me').get();
        console.log('User profile:', user);
      } catch (error) {
        console.error('Error fetching user profile:', error);
      }
    }
    
    // Example usage
    (async () => {
      const accessToken = await getAccessToken();
      await getUserProfile(accessToken);
    })();
    

    This code initializes the Microsoft Graph client with an authentication provider that supplies the access token. The api('/me').get() call retrieves the user’s profile information.

    💡 Pro Tip: Use the select query parameter to fetch only the fields you need. For example, client.api('/me').select('displayName,mail').get() will return only the user’s name and email.

    Step 4: Handling Errors and Debugging

    Working with APIs inevitably involves error handling. Microsoft Graph uses standard HTTP status codes to indicate success or failure. Here are some common scenarios:

    • 401 Unauthorized: Your access token is invalid or expired. Ensure you’re refreshing tokens as needed.
    • 403 Forbidden: Your app lacks the required permissions. Double-check the scopes you’ve requested.
    • 404 Not Found: The endpoint you’re calling doesn’t exist. Verify the API URL.

    To debug issues, enable logging in the Microsoft Graph client:

    const client = Client.init({
      authProvider: (done) => {
        done(null, accessToken);
      },
      debugLogging: true, // Enable debug logging
    });
    

    Step 5: Scaling Your Implementation

    Once you’ve mastered the basics, you’ll likely want to scale your implementation. Here are some tips:

    • Batch Requests: Use the /$batch endpoint to combine multiple API calls into a single request, reducing latency.
    • Pagination: Many Microsoft Graph endpoints return paginated results. Use the @odata.nextLink property to fetch additional pages.
    • Rate Limiting: Microsoft Graph enforces rate limits. Implement retry logic with exponential backoff to handle 429 Too Many Requests errors.

    Conclusion

    By now, you should have a solid understanding of how to make Microsoft Graph API calls using JavaScript. Let’s recap the key takeaways:

    • Use the @microsoft/microsoft-graph-client library to simplify API interactions.
    • Authenticate securely using the msal-node library and environment variables for sensitive credentials.
    • Start with basic API calls like /me and gradually explore more advanced features like batching and pagination.
    • Always handle errors gracefully and implement retry logic for rate-limited requests.
    • Request only the permissions your app truly needs to minimize security risks.

    What will you build with Microsoft Graph? Share your thoughts and questions in the comments below!

  • How to start edge browser with work profile in command line.

    Imagine this: It’s Monday morning, you’ve just sat down at your desk, coffee in hand, ready to tackle your inbox. You hit your shiny new Stream Deck button to launch Outlook in Microsoft Edge, expecting your work profile to appear—only to be greeted by your personal account, memes and shopping carts included. Frustrating, right? If you’re juggling multiple profiles in Edge, you know the pain of always landing in the wrong one. Let’s fix that for good.

    Why Profiles Matter in Microsoft Edge

    Edge does a stellar job separating work and personal profiles, keeping your professional life distinct from your weekend browsing. But when you launch Edge from the command line (or automate it with tools like Stream Deck), it defaults to your personal profile. Not ideal if you’re trying to keep your work and personal worlds apart.

    The Command That Gets You There

    After some digging (and a few choice words), I found the solution. You can specify which profile Edge should use when launching a site. Here’s the magic command:

    start msedge --profile-directory="Profile 1" https://outlook.office.com/owa/

    How It Works

    • start msedge: Launches Microsoft Edge from the command line.
    • --profile-directory="Profile 1": Tells Edge which profile to use. “Profile 1” is usually your first added profile, but it can vary.
    • https://outlook.office.com/owa/: Opens Outlook Web Access directly in your chosen profile.

    Practical Tips & Gotchas

    • Find Your Profile Name: The profile directory name isn’t always obvious. To check yours, go to %LOCALAPPDATA%\Microsoft\Edge\User Data and look for folders like Profile 1, Profile 2, etc. Match the folder to your desired profile.
    • Spaces in Paths: If your profile name has spaces, keep the quotes around it. Otherwise, Edge will get confused.
    • Automating with Shortcuts: You can put this command in a batch file or use it with automation tools like Stream Deck, AutoHotkey, or Windows Task Scheduler.
    • Multiple Profiles: If you have more than two profiles, make sure you’re using the correct directory name. “Profile 1” is not always your work profile!

    My Take

    If you care about keeping your work and personal lives separate (and you should), this command is a must-have in your productivity toolkit. Don’t settle for Edge’s default behavior—take control and make your workflow seamless.

    Bonus: Open Any Site with Any Profile

    Want to open any site with a specific profile? Just swap out the URL:

    start msedge --profile-directory="Profile 2" https://github.com/

    Now go automate your day like a pro.

  • How to always show full right click menu in windows 11

    Picture this: You’re deep in code, right-clicking to quickly edit a file, only to be greeted by Windows 11’s minimalist context menu. The option you need? Hidden behind a “Show more options” click. Frustrating, right? As a developer, every extra click slows you down. Luckily, there’s a straightforward fix to bring back the classic, full right-click menu—no more hunting for your favorite commands.

    Why Did Microsoft Change the Menu?

    Windows 11 introduced a cleaner, more modern UI, but at the cost of burying many useful context menu options. While the intention was to reduce clutter, for power users and developers, this means extra steps for basic tasks like “Edit” or “Open with Notepad.” If you value speed and efficiency over aesthetics, restoring the full menu is a no-brainer.

    How to Restore the Full Context Menu

    You can revert to the classic right-click menu with a simple registry tweak. Here’s how:

    reg add "HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32" /f /ve
    taskkill /f /im explorer.exe
    start explorer.exe
    

    Step-by-Step Instructions

    1. Open Command Prompt as Administrator: Hit Win + S, type “cmd”, right-click and choose “Run as administrator.”
    2. Run the Registry Command: Paste the first line above. This creates a registry key that tells Windows to use the old menu.
    3. Restart Windows Explorer: The next two commands kill and restart Explorer, applying your changes instantly.

    Practical Tips & Gotchas

    • Backup Your Registry: Registry edits are powerful but risky. Always back up before making changes.
    • Reverting the Change: To undo, simply delete the {86ca1aa0-34aa-4e8b-a509-50c905bae2a2} key in the registry and restart Explorer.
    • Windows Updates: Major updates may reset this tweak. If your menu reverts, just repeat the steps.
    • Why Not Use Third-Party Tools? Registry edits are cleaner, don’t require extra software, and are less likely to break with updates.

    Final Thoughts

    Windows 11’s streamlined context menu might look pretty, but for those of us who live and breathe efficiency, it’s a step backward. Don’t settle for extra clicks—take control and restore your workflow. If you run into trouble, drop me a line; I’m always happy to help fellow devs cut through the nonsense.

  • How to use AZ command to control VMs

    Imagine this: your boss needs a new web server spun up right now—and you’re the go-to person. You could click around in the Azure portal, but let’s be honest, that’s slow and error-prone. Real pros use the az CLI to automate, control, and dominate their Azure VMs. If you want to move fast and avoid mistakes, this guide is for you.

    Step 1: Create a Resource Group

    Resource groups are the containers for your Azure resources. Always start here—don’t be the person who dumps everything into the default group.

    az group create --name someRG --location eastus
    • Tip: Pick a location close to your users for lower latency.
    • Gotcha: Resource group names must be unique within your subscription.

    Step 2: Create a Linux VM

    Now, let’s launch a VM. Ubuntu LTS is a solid, secure choice for most workloads.

    az vm create --resource-group someRG --name someVM --image UbuntuLTS --admin-username azureuser --generate-ssh-keys
    • Tip: Use --generate-ssh-keys to avoid password headaches.
    • Gotcha: Don’t forget --admin-username—the default is not always what you expect.

    Step 3: VM Lifecycle Management

    VMs aren’t fire-and-forget. You’ll need to redeploy, start, stop, and inspect them. Here’s how:

    az vm redeploy --resource-group someRG --name someVM
    az vm start --resource-group someRG --name someVM
    az vm deallocate --resource-group someRG --name someVM
    az vm show --resource-group someRG --name someVM
    • Tip: deallocate stops billing for compute—don’t pay for idle VMs!
    • Gotcha: Redeploy is your secret weapon for fixing weird networking issues.

    Step 4: Get the Public IP Address

    Need to connect? Grab your VM’s public IP like a pro:

    az vm show -d -g someRG -n someVM --query publicIps -o tsv
    • Tip: The -d flag gives you instance details, including IPs.
    • Gotcha: If you don’t see an IP, check your network settings—public IPs aren’t enabled by default on all VM images.

    Step 5: Remote Command Execution

    SSH in and run commands. Here’s how to check your VM’s uptime:

    ssh azureuser@<VM_PUBLIC_IP> 'uptime'
    • Tip: Replace <VM_PUBLIC_IP> with the actual IP from the previous step.
    • Gotcha: Make sure your local SSH key matches the one on the VM, or you’ll get locked out.

    Final Thoughts

    The az CLI is your ticket to fast, repeatable, and reliable VM management. Don’t settle for point-and-click—automate everything, and keep your cloud under control. If you hit a snag, check the official docs or run az vm --help for more options.

  • How to install python pip on CentoOS Core Enterprise

    Imagine this: You’ve just spun up a fresh CentOS Core Enterprise server for your next big project. You’re ready to automate, deploy, or analyze—but the moment you try pip install, you hit a wall. No pip. No Python package manager. Frustrating, right?

    CentOS Core Enterprise keeps things lean and secure, but that means pip isn’t available out of the box. If you want to install Python packages, you’ll need to unlock the right repositories first. Let’s walk through the process, step by step, and I’ll share some hard-earned tips so you don’t waste time on common pitfalls.

    Step 1: Enable EPEL Repository

    The Extra Packages for Enterprise Linux (EPEL) repository is your gateway to modern Python tools on CentOS. Without EPEL, pip is nowhere to be found.

    sudo yum install epel-release

    Tip: If you’re running on a minimal install, make sure your network is configured and yum is working. EPEL is maintained by Fedora and is safe for enterprise use.

    Step 2: Install pip for Python 2 (Legacy)

    With EPEL enabled, you can now install pip for Python 2. But let’s be real: Python 2 is obsolete. Only use this if you’re stuck maintaining legacy code.

    sudo yum install python-pip

    Gotcha: This will install pip for Python 2.x. Most modern packages require Python 3. If you’re starting fresh, skip ahead.

    Step 3: Install Python 3 and pip (Recommended)

    For new projects, Python 3 is the only sane choice. Here’s how to get both Python 3 and its pip:

    sudo yum install python3-pip
    sudo pip3 install --upgrade pip

    Pro Tip: Always upgrade pip after installing. The default version from yum is often outdated and may not support the latest Python packages.

    Final Thoughts

    CentOS Core Enterprise is rock-solid, but it makes you work for modern Python tooling. Enable EPEL, choose Python 3, and always keep pip up to date. If you run into dependency errors or missing packages, double-check your repositories and consider using virtualenv for isolated environments.

    Now you’re ready to install anything from requests to flask—and get back to building something awesome.

  • How to make requests via tor in Python

    Why Route HTTP Requests Through Tor?

    Imagine you’re working on a web scraping project, and suddenly, your IP gets blocked. Or maybe you’re building a privacy-focused application where user anonymity is paramount. In both scenarios, Tor can be a game-changer. Tor (The Onion Router) is a network designed to anonymize internet traffic by routing it through multiple servers (or nodes), making it nearly impossible to trace the origin of a request.

    But here’s the catch: using Tor isn’t as simple as flipping a switch. It requires careful setup and an understanding of how to integrate it with your Python code. In this guide, I’ll walk you through two approaches to making HTTP requests via Tor: using the requests library with a SOCKS5 proxy and leveraging the stem library for more advanced control.

    🔐 Security Note: While Tor provides anonymity, it doesn’t encrypt your traffic beyond the Tor network. Always use HTTPS for secure communication.

    Setting Up Tor on Your Machine

    Before diving into the code, you need to ensure that Tor is installed and running on your machine. Here’s how you can do it:

    • Linux: Install Tor using your package manager (e.g., sudo apt install tor on Ubuntu). Start the service with sudo service tor start.
    • Mac: Use Homebrew: brew install tor, then start it with brew services start tor.
    • Windows: Download the Tor Expert Bundle from the official Tor Project website and run the Tor executable.

    By default, Tor runs a SOCKS5 proxy on 127.0.0.1:9050. We’ll use this proxy to route our HTTP requests through the Tor network.

    Method 1: Using the requests Library with a SOCKS5 Proxy

    The simplest way to route your HTTP requests through Tor is by configuring the requests library to use Tor’s SOCKS5 proxy. Here’s how:

    Step 1: Install Required Libraries

    First, ensure you have the requests library installed. If not, install it using pip:

    pip install requests[socks]

    Step 2: Create a Tor Session

    Next, create a function to configure a requests session to use the SOCKS5 proxy:

    import requests
    
    def get_tor_session():
        session = requests.session()
        session.proxies = {
            'http': 'socks5h://127.0.0.1:9050',
            'https': 'socks5h://127.0.0.1:9050'
        }
        return session
    

    Notice the use of socks5h instead of socks5. The socks5h scheme ensures that DNS resolution is performed through the Tor network, adding an extra layer of privacy.

    Step 3: Test Your Tor Session

    To verify that your requests are being routed through Tor, you can make a request to a service that returns your IP address:

    session = get_tor_session()
    response = session.get("http://httpbin.org/ip")
    print("Tor IP:", response.text)
    

    If everything is set up correctly, the IP address returned by httpbin.org should differ from your actual IP address.

    💡 Pro Tip: If you encounter issues, ensure that the Tor service is running and listening on 127.0.0.1:9050. You can check this by running netstat -an | grep 9050 (Linux/Mac) or netstat -an | findstr 9050 (Windows).

    Method 2: Using the stem Library for Advanced Control

    While the requests library with a SOCKS5 proxy is straightforward, it doesn’t give you much control over the Tor connection. For more advanced use cases, such as changing your IP address programmatically, the stem library is a better choice.

    Step 1: Install the stem Library

    Install stem using pip:

    pip install stem

    Step 2: Connect to the Tor Controller

    The Tor controller allows you to interact with the Tor process, such as requesting a new identity. Here’s how to connect to it:

    from stem.control import Controller
    
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password='your_password')  # Replace with your control port password
        print("Connected to Tor controller")
    

    By default, the Tor control port is 9051. You may need to configure a password in your torrc file to enable authentication.

    ⚠️ Gotcha: If you see an authentication error, ensure that the ControlPort and HashedControlPassword options are set in your torrc file. Restart the Tor service after making changes.

    Step 3: Change Your IP Address

    To request a new IP address, send the SIGNAL NEWNYM command to the Tor controller:

    from stem import Signal
    from stem.control import Controller
    
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password='your_password')
        controller.signal(Signal.NEWNYM)
        print("Requested new Tor identity")
    

    Step 4: Make a Request via Tor

    Combine the stem library with the requests library to make HTTP requests through Tor:

    import requests
    from stem import Signal
    from stem.control import Controller
    
    def get_tor_session():
        session = requests.session()
        session.proxies = {
            'http': 'socks5h://127.0.0.1:9050',
            'https': 'socks5h://127.0.0.1:9050'
        }
        return session
    
    with Controller.from_port(port=9051) as controller:
        controller.authenticate(password='your_password')
        controller.signal(Signal.NEWNYM)
    
        session = get_tor_session()
        response = session.get("http://httpbin.org/ip")
        print("New Tor IP:", response.text)
    

    Performance Considerations

    Routing requests through Tor can significantly impact performance due to the multiple hops your traffic takes. In my experience, response times can range from 500ms to several seconds, depending on the network’s current load.

    💡 Pro Tip: If performance is critical, consider using a mix of Tor and direct connections, depending on the sensitivity of the data you’re handling.

    Security Implications

    While Tor enhances anonymity, it doesn’t guarantee complete security. Here are some key points to keep in mind:

    • Always use HTTPS to encrypt your data.
    • Be cautious of exit nodes, as they can see unencrypted traffic.
    • Regularly update your Tor installation to patch security vulnerabilities.
    🔐 Security Note: Avoid using Tor for illegal activities. Law enforcement agencies can still trace activity under certain conditions.

    Conclusion

    Integrating Tor into your Python projects can unlock powerful capabilities for anonymity and bypassing restrictions. Here’s a quick recap:

    • Use the requests library with a SOCKS5 proxy for simplicity.
    • Leverage the stem library for advanced control, such as changing your IP address.
    • Always prioritize security by using HTTPS and keeping your Tor installation up to date.

    What use cases are you exploring with Tor? Share your thoughts in the comments below!