smc-screener 0.1.0
A Python package for Smart Money Concepts (SMC) analysis and stock screening
Requires Python: >=3.6
Keywords: finance, smc, stock-analysis, trading

# SMC Screener 📈

A Python package for **Smart Money Concepts (SMC)** analysis and stock screening, designed to identify key market levels such as swing highs/lows, order blocks, fair value gaps (FVGs), and premium/discount zones.

## Features ✨
- **SMC Analysis**: Identifies swing highs/lows, order blocks, FVGs, and market structure breaks using `yfinance` data. 📊
- **Stock Screener**: Screens stocks near key SMC levels based on a proximity percentage. 🔍
- **Visualization**: Generates candlestick charts with SMC levels using `matplotlib`. 📉
- **Output Options**: Saves results to CSV files and/or Google Sheets. 📄📑
- **Interactive CLI**: Choose tasks (analysis, screener, or both) and stock lists (e.g., Nifty 50, F&O). 🖥️

## Installation 🚀

1. **Install via pip**:
   ```bash
   pip install smc-screener
   ```

2. **Install Dependencies**:
   The package requires the following Python libraries:
   - `yfinance>=0.2.44`
   - `pandas>=2.2.2`
   - `numpy>=1.26.4`
   - `matplotlib>=3.9.2`
   - `gspread>=6.1.2` (optional, for Google Sheets)
   - `oauth2client>=4.1.3` (optional, for Google Sheets)
   - `tqdm>=4.66.5`

   Install them manually if needed:
   ```bash
   pip install yfinance pandas numpy matplotlib gspread oauth2client tqdm
   ```

3. **Google Sheets Setup** (optional, for `output_format="google_sheets"` or `"both"`) 📑:
   - Create a Google Cloud project and enable the **Google Sheets API** and **Google Drive API**. 🔧
   - Create a service account and download the JSON credentials file. 🔑
   - Save the JSON file as `Credentials/credentials.json` in your project directory.
   - Share your Google Sheet with the service account’s email (found in the JSON file) with edit access.
   - Update the `spreadsheet_id` in `main_pipeline.py` with your Google Sheet ID (from the URL: `https://docs.google.com/spreadsheets/d/<SPREADSHEET_ID>/edit`).

## Usage 🛠️

### Command-Line Interface
Run the package directly from the command line:
```bash
smc-screener
```
This launches an interactive CLI where you can:
- **Select a task**: SMC Analysis, SMC Screener, or both. 🔄
- **Choose a stock list**: Nifty Top 10, Nifty 50, F&O, or Nifty 500. 📋

Example interaction:
```
Select the task to run:
1. SMC Analysis
2. SMC Screener
3. Both (Analysis + Screener)
Enter your choice (1, 2, or 3): 3

Select the stock list to process:
1. Nifty Top 10
2. Nifty 50
3. F&O
4. Nifty 500
Enter your choice (1, 2, 3, or 4): 1

Selected stock list: Nifty Top 10 (10 stocks)
Step 1: Running SMC Analysis... 📊
Step 2: Running SMC Screener... 🔍
Task 'both' completed for Nifty Top 10! 🎉
```
    nifty_500       = ["360ONE.NS", "ABB.NS", "APLAPOLLO.NS"]                 # add more stocks here

### Programmatic Usage
Run the pipeline programmatically:
```python
import asyncio
import os
from smc_trading.smc_analysis import main as main_analysis
from smc_trading.smc_screener import main as main_screener

async def run_full_pipeline():
    # Create analysis directory
    os.makedirs("analysis", exist_ok=True)

    # Define stock code lists for each option
    indices         = ["^NSEI", "^NSEBANK", "^CNXIT", "^CNXAUTO", "^CNXFMCG", "^CNXMETAL", "^CNXPHARMA", "^CNXREALTY", "^CNXENERGY", "^CNXMEDIA"]

    nifty_top_10    = ["HDFCBANK.NS", "ICICIBANK.NS", "RELIANCE.NS", "INFY.NS", "BHARTIARTL.NS", "LT.NS", "ITC.NS", "SBIN.NS", "AXISBANK.NS", "TCS.NS"]

    nifty_50        = ["360ONE.NS", "ABB.NS", "APLAPOLLO.NS"]                 # add more stocks here

    fn_o_stocks     = ["360ONE.NS", "ABB.NS", "APLAPOLLO.NS"]                 # add more stocks here

    nifty_500       = ["360ONE.NS", "ABB.NS", "APLAPOLLO.NS"]                 # add more stocks here
    
    csv_column_mapping = {
        'OPEN_PRICE': 'open',
        'HIGH_PRICE': 'high',
        'LOW_PRICE': 'low',
        'CLOSE_PRICE': 'close',
        'DATE1': 'Date'
    }

    spreadsheet_id  = "YOUR_SPREADSHEET_ID" # Replace with your Sheet ID

    csv_directory   = "Stocks"
    fetch_csv_data  = False

    period          = "max"                 #   "1d", "5d", "1mo", "3mo", "6mo", "1y", "2y","5y", "10y", "ytd", "max"
    interval        = "1d"                  #   "1m", "2m", "5m", "15m", "30m", "60m"/"1h", "90m",      "1d", "5d", "1wk", "1mo", "3mo"
    auto_adjust     = False                 # Raw prices — unadjusted for splits/dividends.
    visualize       = False                 # If True, plots SMC charts; False skips to save time.
    print_details   = False                 # If True, logs detailed analysis/screener info; False for minimal output.
    output_format   = "csv"                 # Save to csv, google_sheets, or both for analysis and screener results.
    clear           = True                  # Clears existing CSVs and Google Sheets before saving new data.

    use_colab       = False                 # if goole colab use True otherwise False

    distance_percentage = 2.0                       # % threshold for screener to find stocks near SMC levels.
    output_csv          = "screener_results.csv"    # File path for screener results CSV.

    while True:
        print("\n📌 Select the task to run:")
        print("   1️⃣  SMC Analysis")
        print("   2️⃣  SMC Screener")
        print("   3️⃣  Both (Analysis + Screener)")
        print("   0️⃣  Exit")
        try:
            task_choice = input("\n👉 Enter your choice (1, 2, 3, or 0 to exit): ").strip().lower()
            if task_choice in ["1", "2", "3"]:
                break
            elif task_choice == "0" or task_choice == "exit":
                print("\n🛑 Exiting program.")
                return
            print("❌ Invalid choice. Please enter 1, 2, 3, or 0.")
        except KeyboardInterrupt:
            print("\n🛑 Exiting program.")
            return

    # Map task
    task = {"1": "analysis", "2": "screener", "3": "both"}[task_choice]

    stock_codes, stock_list_name = None, None

    # Only ask stock list if Analysis or Both is selected
    if task in ["analysis", "both"]:
        while True:
            print("\n📊 Select the stock list to process:")
            print("   1️⃣  Nifty Top 10")
            print("   2️⃣  Nifty 50")
            print("   3️⃣  F&O")
            print("   4️⃣  Nifty 500")
            print("   5️⃣  Indices")
            print("   0️⃣  Back to task selection")
            try:
                stock_choice = input("\n👉 Enter your choice (1, 2, 3, 4, 5, or 0 to go back): ").strip().lower()
                if stock_choice in ["1", "2", "3", "4", "5"]:
                    break
                elif stock_choice == "0" or stock_choice == "exit":
                    print("\n🔙 Returning to task selection.")
                    return await run_full_pipeline()  # Go back to task selection
                print("❌ Invalid choice. Please enter 1, 2, 3, 4, 5, or 0.")
            except KeyboardInterrupt:
                print("\n🛑 Exiting program.")
                return

        # Map stock list
        stock_codes = {
            "1": nifty_top_10,
            "2": nifty_50,
            "3": fn_o_stocks,
            "4": nifty_500,
            "5": indices
        }[stock_choice]
        stock_list_name = {
            "1": "Nifty Top 10",
            "2": "Nifty 50",
            "3": "F&O",
            "4": "Nifty 500",
            "5": "Indices"
        }[stock_choice]

        print(f"\n✅ Selected Stocks or Indices list: *{stock_list_name}* ({len(stock_codes)} No. of Stocks or Indices)")

    # Execute selected task(s)
    if task in ["analysis", "both"]:
        print("\n🚀 Running SMC Analysis...")
        failed_symbols = await main_analysis(
            stock_codes         = stock_codes,
            csv_directory       = csv_directory,
            fetch_csv_data      = fetch_csv_data,
            csv_column_mapping  = csv_column_mapping,
            spreadsheet_id      = spreadsheet_id,
            period              = period,
            interval            = interval,
            auto_adjust         = auto_adjust,
            visualize           = visualize,
            print_details       = print_details,
            clear               = clear,
            output_format       = output_format,
            use_colab           = use_colab
        )
        print("📈 Analysis completed successfully!")

    if task in ["screener", "both"]:
        print("\n🔎 Running SMC Screener...")
        main_screener(
            proximity_percentage    = distance_percentage,
            output_csv              = output_csv,
            spreadsheet_id          = spreadsheet_id,
            output_format           = output_format,
            clear                   = clear,
            print_details           = print_details,
            use_colab               = use_colab
        )
        print("📊 Screener completed successfully!")

    # Final message
    if stock_list_name:
        print(f"\n🎯 Task *{task.upper()}* completed for *{stock_list_name}*! 🎉")
    else:
        print(f"\n🎯 Task *{task.upper()}* completed successfully! 🎉")

    # Report failed symbols
    if 'failed_symbols' in locals() and failed_symbols:
        print("\n⚠️ Failed to fetch data for the following symbols:")
        for symbol in failed_symbols:
            print(f"   - {symbol}")

if __name__ == "__main__":
    asyncio.run(run_full_pipeline())

# # For Google Colab:
# if __name__ == "__main__":
#     await(run_full_pipeline())

```

### Customizing Parameters
Edit `main_pipeline.py` to customize:
- **Stock Lists**: Modify `nifty_top_10`, `nifty_50`, `fn_o_stocks`, or `nifty_500`. 📋
- **Period/Interval**: Change `period` (e.g., `"1y"`, `"max"`) and `interval` (e.g., `"1d"`, `"1h"`) for `yfinance` data. ⏳
- **Output Format**: Set `output_format` to `"csv"`, `"google_sheets"`, or `"both"`. 📄
- **Proximity Percentage**: Adjust `proximity_percentage` (default `2.0`) for the screener. 📏
- **Visualization**: Set `visualize=True` for charts or `False` for faster execution. 📉
- **Clear Output**: Set `clear=True` to overwrite existing CSV files or Google Sheets. 🗑️

## Output 📈
- **SMC Analysis**:
  - **CSV**: Saves to `analysis/smc_analysis_summaries.csv` (summary data) and `analysis/smc_analysis_levels.csv` (key levels). 📄
  - **Google Sheets**: Saves to `Summaries` and `Levels` worksheets (if enabled). 📑
  - **Visualization**: Candlestick charts with SMC levels (if `visualize=True`). 📉
- **SMC Screener**:
  - **CSV**: Saves to `screener_results.csv` with stocks near SMC levels. 📄
  - **Google Sheets**: Saves to `Screener_Results` worksheet (if enabled). 📑
  - **Console**: Displays a table of stocks near key levels. 🖥️

## Project Structure 🛠️

   ```
   smc_trading/
   ├── smc_trading/
   │   ├── __init__.py
   │   ├── smc_analysis.py
   │   ├── smc_screener.py
   │   └── main_pipeline.py
   ├── Credentials/
   │   └── credentials.json
   ├── pyproject.toml
   ├── README.md
   ├── LICENSE
   └── requirements.txt
   ```

## yfinance Period & Interval Reference 📅
- **Period**: `"1d"`, `"5d"`, `"1mo"`, `"3mo"`, `"6mo"`, `"1y"`, `"2y"`, `"5y"`, `"10y"`, `"ytd"`, `"max"`
- **Interval**: `"1m"`, `"2m"`, `"5m"`, `"15m"`, `"30m"`, `"60m"`, `"90m"`, `"1h"`, `"1d"`, `"5d"`, `"1wk"`, `"1mo"`, `"3mo"`
- **Restrictions**:
  - `"1m"` interval: Only last 7 days max.
  - Intraday intervals (`"1m"`, `"1h"`, etc.): `period ≤ 60d`.
  - Daily/weekly/monthly: Longer periods allowed.

## Troubleshooting 🐞
- **yfinance Rate Limits**: 🕒
- **Google Sheets Errors**: Verify `Credentials/credentials.json` and share the Google Sheet with the service account. 🔑
- **No Data**: Check ticker validity (e.g., `RELIANCE.NS`). Use `yf.Ticker("TICKER").info` to verify. 📊
- **Visualization Issues**: Ensure `matplotlib` is installed and `visualize=True`. 📉
- **Screener Empty**: Run SMC Analysis first to generate `smc_analysis_levels.csv` and `smc_analysis_summaries.csv`. 🔍

## License 📜
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

## Contributing 🤝
Contributions are welcome! Please submit a pull request or open an issue on the repository.

Happy trading! 🎉