# How to Modify the Stock Analysis Logic in daily_stock_analysis: 5 Proven Methods

> Learn to modify stock analysis logic in daily_stock_analysis. Update configuration, adjust scoring, and customize indicators for precise buy signals. Explore 5 proven methods.

- Repository: [mumu/daily_stock_analysis](https://github.com/ZhuLinsen/daily_stock_analysis)
- Tags: how-to-guide
- Published: 2026-04-30

---

**You modify the stock analysis logic by editing the `StockTrendAnalyzer` class in [`src/stock_analyzer.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/stock_analyzer.py), updating configuration values in [`src/config.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/config.py), and adjusting scoring thresholds in the `_generate_signal` method to customize technical indicators, scoring weights, and buy-signal generation.**

The `ZhuLinsen/daily_stock_analysis` repository implements a modular technical analysis engine that transforms OHLCV market data into actionable buy signals using the `StockTrendAnalyzer` class. To modify the stock analysis logic, you work directly with the calculation methods that handle moving averages, MACD, RSI, and composite scoring. The architecture separates the core algorithm from service orchestration, allowing you to tune the analysis pipeline without affecting notification systems or scheduling components.

## Understanding the Core Architecture

Before modifying logic, identify the key components that process market data:

- **`StockTrendAnalyzer`** ([`src/stock_analyzer.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/stock_analyzer.py)): Encapsulates all technical calculations including MA computation, bias analysis, volume assessment, MACD/RSI generation, and signal scoring.
- **`TrendAnalysisResult`**: Dataclass that stores computed metrics and the final `BuySignal` enumeration.
- **`analyze_stock`**: Convenience wrapper function that instantiates the analyzer and returns formatted results.
- **[`analyzer_service.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/analyzer_service.py)** ([`src/analyzer_service.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/analyzer_service.py)): Service layer that injects configuration and orchestrates the analysis pipeline; typically requires no changes for algorithmic tweaks.
- **`Config`**: Configuration dataclass in [`src/config.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/config.py) that exposes tunable parameters like `bias_threshold`.

## Method 1: Adjust Moving Average Windows

The moving-average windows (5, 10, 20, 60) are hard-coded in the `_calculate_mas` method. To add a custom window (e.g., 8-day MA) or change existing periods, modify the method body:

```python

# src/stock_analyzer.py - _calculate_mas method

def _calculate_mas(self, df: pd.DataFrame) -> pd.DataFrame:
    df = df.copy()
    df['MA5'] = df['close'].rolling(window=5).mean()
    df['MA8'] = df['close'].rolling(window=8).mean()   # ← new line

    df['MA10'] = df['close'].rolling(window=10).mean()
    df['MA20'] = df['close'].rolling(window=20).mean()
    # ...

    return df

```

To make windows configurable via `Config`, add fields to [`src/config.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/config.py) and reference them:

```python

# src/config.py

ma5_window: int = 5
ma8_window: int = 8   # new configurable window

# src/stock_analyzer.py

cfg = get_config()
df['MA5'] = df['close'].rolling(window=cfg.ma5_window).mean()
df['MA8'] = df['close'].rolling(window=cfg.ma8_window).mean()

```

## Method 2: Change the Bias Threshold

The bias calculation compares price deviation from moving averages. The `_generate_signal` method reads `Config.bias_threshold` (default 5%) at line 221. To modify this tolerance globally, set an environment variable:

```bash

# .env file or export in shell

BIAS_THRESHOLD=7

```

For strategy-specific thresholds, extend the configuration:

```python

# src/config.py

bias_threshold_strong: float = 8.0

# src/stock_analyzer.py - inside _generate_signal

effective_threshold = base_threshold
if result.trend_status == TrendStatus.STRONG_BULL:
    effective_threshold = cfg.bias_threshold_strong

```

## Method 3: Re-weight Scoring Components

The final `signal_score` (0-100) aggregates sub-scores across six categories (lines 990-1065). Modify the weight dictionaries in the signal generation logic:

```python

# src/stock_analyzer.py - inside _generate_signal (around line 990)

trend_scores = {
    TrendStatus.STRONG_BULL: 30,
    TrendStatus.BULL: 26,
    TrendStatus.WEAK_BULL: 18,  # Default 18 points

    TrendStatus.CONSOLIDATION: 12,
    TrendStatus.WEAK_BEAR: 8,
    TrendStatus.BEAR: 4,
    TrendStatus.STRONG_BEAR: 0,
}

# Example: Increase weight for weak bullish trends

trend_scores[TrendStatus.WEAK_BULL] = 22   # Increased from 18

```

The scoring system also evaluates volume, support-resistance, MACD, and RSI—each with similar weight dictionaries you can adjust.

## Method 4: Add a New Technical Indicator

To incorporate **ATR** (Average True Range) or custom metrics:

1. Create a calculation method in `StockTrendAnalyzer`
2. Add the field to `TrendAnalysisResult`
3. Reference the value in `_generate_signal`

```python

# src/stock_analyzer.py - new method

def _calculate_atr(self, df: pd.DataFrame, period: int = 14) -> pd.DataFrame:
    df = df.copy()
    df['tr'] = df[['high', 'low', 'close']].apply(
        lambda row: max(
            row['high'] - row['low'],
            abs(row['high'] - row['close'].shift()),
            abs(row['low'] - row['close'].shift())
        ), axis=1)
    df['ATR'] = df['tr'].rolling(window=period).mean()
    return df

# Add to TrendAnalysisResult dataclass

@dataclass
class TrendAnalysisResult:
    # ... existing fields ...

    atr: float = 0.0

```

Insert the calculation into the main analysis flow before signal generation:

```python

# Inside analyze method

df = self._calculate_atr(df)
result.atr = df['ATR'].iloc[-1]

```

## Method 5: Modify Buy-Signal Thresholds

The mapping from `signal_score` to `BuySignal` categories occurs near line 1033. Adjust these cut-offs to make the strategy more aggressive or conservative:

```python

# src/stock_analyzer.py - signal_threshold logic

if score >= 70:                     # Lowered from 75 for more strong signals

    result.buy_signal = BuySignal.STRONG_BUY
elif score >= 55:                   # Lowered from 60

    result.buy_signal = BuySignal.BUY
elif score >= 40:
    result.buy_signal = BuySignal.WEAK_BUY
else:
    result.buy_signal = BuySignal.NO_SIGNAL

```

## Putting the Changes into Practice

After modifying the bias threshold to 7% and adding the 8-day MA, run a custom analysis:

```python
import pandas as pd
from src.stock_analyzer import analyze_stock

# Load historical OHLCV data

df = pd.read_csv('sample_data/600519.csv', parse_dates=['date'])

# Execute analysis with modified logic

result = analyze_stock(df, code='600519')

# Output summary

print(f"Stock: {result.code}")
print(f"Trend Status: {result.trend_status.value}")
print(f"Signal Score: {result.signal_score}")
print(f"Recommendation: {result.buy_signal.value}")
print("Analysis Reasons:")
for reason in result.signal_reasons:
    print(f"  • {reason}")

```

The analyzer reads environment variables at initialization, so ensure `BIAS_THRESHOLD=7` is set before importing the module.

## Summary

- **Primary entry point**: Modify `StockTrendAnalyzer` in [`src/stock_analyzer.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/stock_analyzer.py) to change technical calculation logic.
- **Configuration layer**: Update [`src/config.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/config.py) to expose new tunable parameters like custom MA windows or bias thresholds.
- **Scoring weights**: Adjust dictionaries in `_generate_signal` (lines 990-1065) to reallocate points across trend, volume, MACD, RSI, and support-resistance metrics.
- **Signal thresholds**: Modify the conditional logic near line 1033 to change the score cut-offs that trigger `STRONG_BUY`, `BUY`, or `WEAK_BUY` signals.
- **New indicators**: Add calculation methods to `StockTrendAnalyzer`, extend `TrendAnalysisResult` with new fields, and integrate values into the scoring logic.

## Frequently Asked Questions

### How do I change the moving average periods without editing source code?

Set the periods via environment variables or extend the `Config` dataclass in [`src/config.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/config.py) to read from the environment. Reference these configuration values inside `_calculate_mas` instead of hard-coded integers, allowing runtime modification through your `.env` file or container environment variables.

### Where is the buy signal actually generated?

The buy signal is assigned in the `_generate_signal` method of `StockTrendAnalyzer` (around line 1033 in [`src/stock_analyzer.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/stock_analyzer.py)). This method evaluates the composite `signal_score` against thresholds to determine whether the output should be `STRONG_BUY`, `BUY`, `WEAK_BUY`, or `NO_SIGNAL`.

### Can I add custom technical indicators like Bollinger Bands?

Yes. Create a new calculation method following the pattern of `_calculate_mas` or `_calculate_atr`, add corresponding fields to the `TrendAnalysisResult` dataclass, and invoke your method in the main analysis flow. Update the scoring logic in `_generate_signal` to incorporate your new indicator into the final signal calculation.

### What files should I avoid modifying when tuning analysis logic?

Avoid editing [`analyzer_service.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/analyzer_service.py) unless you need to change pipeline orchestration or notification behavior. This service file handles high-level coordination and dependency injection, while [`src/stock_analyzer.py`](https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/src/stock_analyzer.py) contains the actual algorithmic logic you should modify for technical analysis adjustments.