---
# System prepended metadata

title: Jam 08 - Exercise 4
tags: ["2 \U0001F4DD in writing", "3 \U0001F9EA in testing", "4 \U0001F973 done"]

---

---
title: "Jam 08 - Exercise 4"
tags: 
  - 2 📝 in writing
  - 3 🧪 in testing
  - 4 🥳 done
---
<!-- markdownlint-disable line-length single-h1 no-inline-html -->
<!-- markdownlint-configure-file { "ul-indent": { "indent": 4 }, "link-fragments": {"ignore_case": true} } -->

{%hackmd dJZ5TulxSDKme-3fSY4Lbw %}

# Exercise 4 - Technical Analysis and Advanced Visualization

## Overview - Exercise 4

In this exercise, you'll enhance your stock market visualizer with technical analysis features. You'll learn about key financial indicators and how they help investors make decisions. This exercise combines programming with practical financial concepts.

:::info
🔑 **Key Concepts**

- Technical analysis indicators (Moving Averages, RSI)
- Volume analysis and its importance
- Data visualization best practices
- JavaFX chart customization
- Utility class design patterns

:::

## Understanding Technical Analysis

Technical analysis is a method of evaluating securities by analyzing statistics generated by market activity. It's based on three assumptions:

1. **Market Discounts Everything**: All known information is reflected in the price
2. **Prices Move in Trends**: Prices tend to move in persistent trends
3. **History Repeats Itself**: Market psychology tends to repeat

We'll implement two key indicators:

### Moving Averages

Moving averages help identify trends by smoothing out price fluctuations. They're calculated by averaging prices over a specific period.

Example:

- 5-day moving average = (Day1 + Day2 + Day3 + Day4 + Day5) / 5
- Each day, we drop the oldest price and add the newest

### Relative Strength Index (RSI)

RSI measures the speed and magnitude of price movements. It helps identify:

- Overbought conditions (price too high, might fall)
- Oversold conditions (price too low, might rise)

## Required Steps - Exercise 4

### Part 1: Technical Analysis Utility Class

First, let's create a utility class for our technical analysis calculations:

```java
public final class TechnicalAnalysis {
    private TechnicalAnalysis() {
        throw new AssertionError("Utility class - do not instantiate");
    }

    /**
     * Calculates the Simple Moving Average (SMA) for a given period.
     * *
     * @param data List of stock data points
     * @param period Number of days to average
     * @return The moving average value
     */
    public static double calculateMovingAverage(List<Stock> data, int period) {
        return data.stream()
                    .limit(period)
                    .mapToDouble(s -> s.getClosePrice().doubleValue())
                    .average()
                    .orElse(0.0);
    }

    /**
     * Calculates the Relative Strength Index (RSI).
     * *
     * RSI is a momentum indicator that measures the speed and magnitude of price movements.
     * It helps identify overbought (price too high) and oversold (price too low) conditions.
     * *
     * The calculation involves:
     * 1. Calculating price changes between consecutive days
     * 2. Separating gains (positive changes) and losses (negative changes)
     * 3. Computing average gain and average loss over the period
     * 4. Calculating RS (Relative Strength) = Average Gain / Average Loss
     * 5. Using the formula: RSI = 100 - (100 / (1 + RS))
     * *
     * Interpretation:
     * - RSI > 70: Stock may be overbought (consider selling)
     * - RSI < 30: Stock may be oversold (consider buying)
     * - RSI = 50: Neutral condition
     * *
     * Example:
     * Let's say we have 5 days of closing prices: [100, 102, 101, 103, 105]
     * *
     * 1. Calculate price changes:
     *    Day 1-2: +2 (gain)
     *    Day 2-3: -1 (loss)
     *    Day 3-4: +2 (gain)
     *    Day 4-5: +2 (gain)
     * *
     * 2. Separate gains and losses:
     *    Gains: [2, 2, 2]
     *    Losses: [1]
     * *
     * 3. Calculate averages:
     *    Average Gain = (2 + 2 + 2) / 5 = 1.2
     *    Average Loss = (1) / 5 = 0.2
     * *
     * 4. Calculate RS:
     *    RS = Average Gain / Average Loss = 1.2 / 0.2 = 6.0
     * *
     * 5. Calculate RSI:
     *    RSI = 100 - (100 / (1 + 6.0)) = 85.7
     * *
     * This high RSI value (85.7) suggests the stock might be overbought,
     * as there have been more gains than losses recently.
     * *
     * @param data List of stock data points
     * @param period Number of days to consider (typically 14)
     * @return The RSI value (0-100).  If the list size is less than 2, it returns `50.0`
     */
    public static double calculateRSI(List<Stock> data, int period) {
        // TODO: Implement RSI calculation
        // Hint: Use Streams to calculate price changes.  You will probably use more than one stream for various step
        //       (I used four)
        // Hint: Calculate price changes between consecutive days
        // Hint: Separate gains and losses
        // Hint: Calculate average gain and loss
        // Hint: If the average gain/loss is zero, return 100 (or risk a divide by zero error!)
        // Hint: Use the RSI formula: 100 - (100 / (1 + RS))
        return 0.0;
    }
}
```

:::info
🔧 **Implementation Tips**

- Use Streams for efficient data processing
- Handle edge cases (empty lists, insufficient data)
- Consider using BigDecimal for precise calculations
- Add proper error handling and validation

:::

:::note
**What You Just Built: Technical Analysis Utility Class**

- You've created a utility class that follows the Single Responsibility Principle
- The class handles only technical analysis calculations, making it easy to test and maintain
- You're using Streams for clean, functional programming instead of traditional loops
- This is exactly how professional applications structure their analysis code

:::

### Part 2: Volume Analysis

Volume analysis helps confirm price trends. Let's add a volume chart to the `StockView` class:

```java
private BarChart<String, Number> createVolumeChart(List<Stock> data) {
    // Create axes
    CategoryAxis xAxis = new CategoryAxis();
    xAxis.setLabel("Date");
    NumberAxis yAxis = new NumberAxis();
    yAxis.setLabel("Volume");

    // Create chart
    BarChart<String, Number> chart = new BarChart<>(xAxis, yAxis);
    chart.setTitle("Trading Volume");

    // Add volume data
    XYChart.Series<String, Number> volumeSeries = new XYChart.Series<>();
    volumeSeries.setName("Volume");

    // TODO: Add data points
    // Hint: For each stock:
    // - Add date as x-value
    // - Add volume as y-value

    chart.getData().add(volumeSeries);

    // TODO: Set bar color based on price movement (green for up, red for down)

    return chart;
}
```

:::info
📊 **Volume Analysis Tips**

- Color bars based on price movement:
    - Green: Price went up that day
    - Red: Price went down that day
- Bar height shows number of shares traded
- High volume often confirms price trends

:::

:::note
**What You Just Built: Professional Volume Chart**

- You're creating a professional-grade chart component with proper axes and labels
- The chart will transform raw data into visual elements using Streams
- You're using CSS for styling, following the professional practice of separating style from structure
- This is exactly how real financial applications display trading volume

:::

### Part 3: Technical Indicators Visualization

Now, let's add our technical indicators to the price chart in the `StockView` class:

```java
private void addTechnicalIndicators(List<Stock> data) {
    // Add moving average line
    XYChart.Series<String, Number> maSeries = new XYChart.Series<>();
    maSeries.setName("20-day MA");

    // TODO: Calculate and add moving average points
    // Hint: Use TechnicalAnalysis.calculateMovingAverage()
    // Hint: Add points for each day

    // Add RSI line
    XYChart.Series<String, Number> rsiSeries = new XYChart.Series<>();
    rsiSeries.setName("RSI");

    // TODO: Calculate and add RSI points
    // Hint: Use TechnicalAnalysis.calculateRSI()
    // Hint: Add points for each day

    // Add the series to the chart
    priceChart.getData().addAll(Arrays.asList(maSeries, rsiSeries));
}
```

:::info
🔍 **Technical Analysis Tips**

- Moving averages help identify trends
- RSI helps spot overbought/oversold conditions
- Combine indicators for better analysis
- Use different colors for each indicator

:::

:::note
**What You Just Built: Multiple Chart Series**

- You're implementing real financial analysis with moving averages and RSI
- The ability to show multiple indicators simultaneously is a key feature of professional trading platforms
- This demonstrates how flexible JavaFX charts are for complex data visualization

:::

### Part 4: UI Integration

Finally, let's add controls to toggle between different views **(remember to declare any new UI elements at the top of the class)**:

```java
private void setupControls() {
    // ... existing control setup ...

    // TODO: Add chart type toggle button
    // Hint: Use ToggleButton for switching between chart types
    // Hint: Set up event handler using setOnAction() that runs a toggleChart() method you will add next
    // Hint: Add button to controls VBox

    // TODO: Add technical indicators checkbox
    // Hint: Use CheckBox for toggling indicators
    // Hint: Set up event handler using setOnAction() that runs a toggleIndicators() method you will add next
    // Hint: Add checkbox to controls VBox
}

private void toggleChart() {
    // TODO: Toggle between different chart types
    if (toggleChartButton.isSelected()) {
        // Hint: Use stockTable.getItems() to get the current data
        // Hint: Use createVolumeChart() to create a new chart
        // Hint: Use root.setCenter() to switch between charts
    } else {
        // Restore the price chart
        root.setCenter(priceChart);
    }
}

private void toggleIndicators() {
    // TODO: Show/hide technical indicators
    // Hint: If showIndicators is selected:
    // Hint:     Use stockTable.getItems() to get the current data
    // Hint:     Use addTechnicalIndicators() to add MA and RSI
    // Hint: If showIndicators is not selected:
    // Hint:     Use priceChart.getData().get(0) to keep only the first series (price data) and remove others (MA and RSI)
    // Hint:     Clear the data and reset the data to what was in priceChart.getData().get(0)
}
```

:::info
**What You Just Built: Interactive Controls**

- You're creating a professional user interface with interactive controls
- The ToggleButton for switching views is a common pattern in financial applications
- Using CheckBox for optional features follows good UX principles
- This gives users control over their data visualization without overwhelming them

:::

:::info
🎯 **UI Design Tips**

- Use clear, descriptive labels
- Group related controls together
- Provide visual feedback for changes
- Consider using tooltips for explanations

:::

> 🔍 **Checkpoint**: Exercise 4
>
> - TechnicalAnalysis utility class is implemented
> - Moving average calculation works correctly
> - RSI calculation handles edge cases
> - Volume chart shows price-based coloring
> - Technical indicators are properly displayed
> - UI controls work as expected

## Save Your Work - Exercise 4

Verify what files are uncommitted:

```bash
git status
```

Stage your changes:

Use `git add` to add needed files

Commit your work:

```bash
git commit -m "jam08: Implement technical analysis and advanced visualization"
```

:::success
🔑 **Key Takeaways**

- Technical analysis helps identify market trends
- Volume analysis confirms price movements
- Moving averages smooth price data
- RSI identifies overbought/oversold conditions
- Proper visualization enhances analysis
- Utility classes centralize calculations

:::
