Skip to content

Krish01agrawal/PortfolioAllocationQuantAlgorithm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

10 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿš€ PlutoMoney Quant - Portfolio Allocation Algorithm

AI-Powered, Risk-Adjusted Mutual Fund Recommendations

Built with NestJS + TypeScript + MongoDB


๐Ÿ“– Overview

PlutoMoney Quant is a sophisticated portfolio allocation algorithm that:

  1. Scores 1,800+ mutual funds monthly using 27 quantitative & qualitative parameters
  2. Normalizes scores within categories using Z-score methodology
  3. Weights parameters by risk profile (Safety Seeker to Aggressive Explorer)
  4. Constructs personalized portfolios based on SIP amount and risk tolerance
  5. Rebalances monthly to maintain optimal allocation

โœ… Current Status

Phase 1: Data Ingestion - โœ… COMPLETE

  • REST API with 4 endpoints
  • MongoDB Collections 1 & 2 operational
  • Morningstar data ingestion (AS-IS format)
  • Monthly cron scheduler configured
  • 8 funds, 13 snapshots ingested

Next: Phase 2 - Scoring Engine (Collections 3 & 4, Z-scores, Risk weighting)


โšก Quick Start

# 1. Install dependencies
npm install

# 2. Setup environment
cp sample.env .env
# Edit .env: Set MONGODB_URI=mongodb://localhost:27017/plutomoney_quant

# 3. Start MongoDB (choose one)
brew services start mongodb-community                    # macOS
docker run -d -p 27017:27017 --name mongodb mongo:latest # Docker

# 4. Start the API server
npm run start:dev
# Server runs on: http://localhost:3000

# 5. Test via REST API
curl http://localhost:3000/api/mutual-funds | python3 -m json.tool

# 6. Or test via script
npm run test:ingestion

# 7. Verify in MongoDB
mongosh plutomoney_quant --eval "db.mfSchemeTrackRecord.find().pretty()"

See QUICK_API_REFERENCE.md for complete API documentation


๐Ÿ—๏ธ Architecture

Clean Modular Structure

src/
โ”œโ”€โ”€ app/                          # Application root
โ”‚   โ””โ”€โ”€ app.module.ts
โ”‚
โ”œโ”€โ”€ modules/                      # Feature modules
โ”‚   โ”œโ”€โ”€ mutual-fund/              # Collections 1 & 2
โ”‚   โ”‚   โ”œโ”€โ”€ schemas/              # MongoDB models
โ”‚   โ”‚   โ”œโ”€โ”€ dao/                  # Data Access Objects (Repository pattern)
โ”‚   โ”‚   โ”œโ”€โ”€ dtos/                 # Validation
โ”‚   โ”‚   โ”œโ”€โ”€ services/             # Business logic
โ”‚   โ”‚   โ””โ”€โ”€ mutual-fund.module.ts
โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€ morningstar/              # Data source integration
โ”‚   โ”‚   โ”œโ”€โ”€ services/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ morningstar-parser.service.ts
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ morningstar-api.service.ts
โ”‚   โ”‚   โ””โ”€โ”€ morningstar.module.ts
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ cron/                     # Scheduled tasks
โ”‚       โ”œโ”€โ”€ services/
โ”‚       โ”‚   โ””โ”€โ”€ data-ingestion-cron.service.ts
โ”‚       โ””โ”€โ”€ cron.module.ts
โ”‚
โ”œโ”€โ”€ config/                       # Configuration
โ”œโ”€โ”€ database/                     # Database layer
โ”œโ”€โ”€ enums/                        # Global type definitions
โ”œโ”€โ”€ utils/                        # Utilities
โ””โ”€โ”€ main.ts

Design Patterns

  • Module Pattern: Clear feature boundaries
  • DAO Pattern: Repository for data access
  • Service Layer: Business logic separation
  • Dependency Injection: NestJS DI container
  • SOLID Principles: All 5 applied

๐Ÿ“Š Data Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚         MONTHLY DATA INGESTION (1st of Month)        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

1. TRIGGER (Cron: 1st of month, 2 AM IST)
   CronModule.DataIngestionCronService
   โ†“

2. FETCH DATA
   MorningstarModule.MorningstarApiService (future)
   OR Read JSON file (current)
   โ†“

3. PARSE & VALIDATE
   MorningstarModule.MorningstarParserService
   - Validate 27 parameters
   - Check required fields
   - Detect outliers
   โ†’ Returns: FundDataDto[]
   โ†“

4. INGEST TO DATABASE
   MutualFundModule.MutualFundService
   - Upsert master record (Collection 1)
   - Insert/update snapshot (Collection 2)
   - Update reference list
   โ†“

5. RESULT
   IngestionResult {
     success, fundsProcessed, fundsAdded, fundsUpdated, errors
   }

๐Ÿ—„๏ธ Database Collections

Collection 1: mfSchemeTrackRecord

Purpose: Master registry of all mutual funds

{
  _id: ObjectId(),
  fundName: "Axis Bluechip Fund",
  amc: "Axis Mutual Fund",
  schemeCode: "AXIS001",
  status: "Active",
  schemeMonthTrackList: [
    {
      timestamp: ISODate("2025-10-01"),
      mfDataId: ObjectId() // Reference to Collection 2
    }
  ]
}

Collection 2: mfSchemeDataMonthwise

Purpose: Monthly snapshots with 27 parameters

{
  _id: ObjectId(),
  timestamp: ISODate("2025-10-01"),
  fundId: ObjectId(), // Reference to Collection 1
  fundName: "Axis Bluechip Fund",
  fundCategory: "Large Cap Equity",
  
  // 17 Quantitative Parameters
  fiveYearCagrEquity: 13.8,
  sharpeRatio: 1.12,
  alpha: 2.3,
  beta: 0.88,
  maxDrawdown: -11.2,
  expenseRatioEquity: 0.9,
  aumEquity: 18000,
  // ... 10 more
  
  // 5 Qualitative Parameters
  fundHouseReputation: 5,
  fundManagerTenure: 8,
  fundManagerTrackRecord: 4.7,
  amcRiskManagement: 4.5,
  esgGovernance: 3.9,
  
  // 5 Forward-Looking Parameters
  benchmarkConsistency: 4.6,
  peerComparison: 4.3,
  taxEfficiency: 3.8,
  fundInnovation: 4.2,
  forwardRiskMitigation: 4.5
}

๐Ÿงช Testing

Test Scenarios

Scenario 1: Fresh Ingestion

# Clear database
mongosh
use plutomoney_quant
db.dropDatabase()

# Run test
npm run test:ingestion

Expected: fundsAdded = 3, fundsUpdated = 0

Scenario 2: Re-Ingestion (Same Month)

npm run test:ingestion

Expected: fundsAdded = 0, fundsUpdated = 3

Scenario 3: New Month

Edit src/scripts/test-data-ingestion.ts line 165:

const timestamp = new Date('2025-11-01T00:00:00Z'); // November

Run: npm run test:ingestion

Expected: New snapshots added, track list grows

Troubleshooting

Error: Cannot connect to MongoDB

# Check if MongoDB is running
brew services list | grep mongodb

# Start MongoDB
brew services start mongodb-community

Error: Module not found

npm install

๐Ÿ”ง Development

Available Commands

npm run start:dev        # Development mode with watch
npm run start:prod       # Production mode
npm run build            # Build for production
npm run test:ingestion   # Test data ingestion
npm run lint             # Lint code
npm run format           # Format code

Adding New Modules

Example: Add Scoring Engine Module

Step 1: Create structure

mkdir -p src/modules/scoring-engine/{schemas,dao,services}

Step 2: Create service

// src/modules/scoring-engine/services/z-score-calculator.service.ts
@Injectable()
export class ZScoreCalculatorService {
  async calculateForCategory(category: string, timestamp: Date) {
    // Implementation
  }
}

Step 3: Create module

// src/modules/scoring-engine/scoring-engine.module.ts
@Module({
  imports: [MutualFundModule],
  providers: [ZScoreCalculatorService],
  exports: [ZScoreCalculatorService],
})
export class ScoringEngineModule {}

Step 4: Import in AppModule

// src/app/app.module.ts
@Module({
  imports: [
    // ...
    ScoringEngineModule,
  ],
})
export class AppModule {}

๐Ÿ“š Key Concepts

1. DAO Pattern (Repository)

Data access is separated from business logic.

// โœ… Good - Use DAO
const fund = await this.fundDao.findByFundName('Axis');

// โŒ Bad - Direct model access
const fund = await this.fundModel.findOne({ fundName: 'Axis' });

2. Service Layer

Business logic in services, not controllers or DAOs.

// MutualFundService orchestrates workflow
async ingestMonthlyData(funds, timestamp) {
  // 1. Upsert master
  // 2. Insert/update snapshot
  // 3. Update references
}

3. Dependency Injection

All dependencies injected via constructor.

constructor(
  private readonly trackRecordDao: MfSchemeTrackRecordDao,
  private readonly monthwiseDao: MfSchemeDataMonthwiseDao,
) {}

4. Cron Jobs

Scheduled tasks for monthly ingestion.

@Cron('0 2 1 * *') // 1st of month, 2 AM
async handleMonthlyIngestion() {
  // Fetch, parse, ingest
}

๐Ÿ”ฎ Roadmap

Phase 1: Data Ingestion โœ… Complete

  • Collections 1 & 2
  • Morningstar parser
  • Monthly cron job

Phase 2: Scoring Engine ๐Ÿ”œ Next

  • Z-score calculation (category-wise)
  • Group score aggregation (8 parameter groups)
  • Composite score (risk profile weighted)
  • Collections 3 & 4

Phase 3: Portfolio Allocation ๐Ÿ”œ

  • Allocation matrix loader
  • SIP bucket determination
  • Fund selection (top-N by composite score)
  • Constraint application (SIP mins, AMC diversity)

Phase 4: BSE Integration ๐Ÿ”œ

  • BSE Star MFD API client
  • SIP registration
  • Order tracking

๐Ÿ“ฆ Tech Stack

  • Framework: NestJS 10.x
  • Language: TypeScript 5.x
  • Database: MongoDB with Mongoose
  • Validation: class-validator, class-transformer
  • Scheduling: @nestjs/schedule
  • Statistics: simple-statistics

๐ŸŒ Environment Variables

# Node Environment
NODE_ENV=development

# Server
PORT=3000
ALLOWED_ORIGINS=http://localhost:3000

# MongoDB
MONGODB_URI=mongodb://localhost:27017/plutomoney_quant

# Morningstar API (future)
# MORNINGSTAR_API_URL=https://api.morningstar.com
# MORNINGSTAR_API_KEY=your_key

๐Ÿ“ก REST API Endpoints

POST /api/mutual-funds/ingest - Manual Data Ingestion

Ingest fund data directly (perfect for testing before Morningstar is configured)

curl -X POST http://localhost:3000/api/mutual-funds/ingest \
  -H "Content-Type: application/json" \
  -d @test-api-payload.json | python3 -m json.tool

GET /api/mutual-funds - Get All Funds

# All funds
curl http://localhost:3000/api/mutual-funds | python3 -m json.tool

# Filter by category
curl "http://localhost:3000/api/mutual-funds?category=Large%20Cap%20Equity" | python3 -m json.tool

GET /api/mutual-funds/:id - Get Specific Fund

curl http://localhost:3000/api/mutual-funds/LC001 | python3 -m json.tool

GET /api/mutual-funds/:id/history - Get Fund History

curl http://localhost:3000/api/mutual-funds/LC001/history | python3 -m json.tool

Complete API documentation: QUICK_API_REFERENCE.md


๐Ÿ“– Documentation

Getting Started

  • README.md (this file) - Overview & Quick Start
  • QUICK_API_REFERENCE.md - API endpoints reference
  • PHASE_1_COMPLETE.md - Phase 1 implementation summary

Technical Documentation

  • PRD.md - Product Requirements Document
  • Docs/Implementation.md - Step-by-step implementation guide
  • Docs/FINAL_ARCHITECTURE.md - System architecture
  • Docs/DATA_FLOW_PRODUCTION.md - Production data flow
  • Docs/MORNINGSTAR_DATA_ANALYSIS.md - Data format analysis
  • Docs/SCORING_ENGINE_DEEP_DIVE.md - Complete scoring engine explanation (4-step process, risk-profile-specific weights)

AI Context

  • .cursor/rules/*.mdc - AI context for Phase 2 development
    • scoring_context.mdc - Scoring engine logic
    • schema_context.mdc - Database schema definitions
    • allocation_context.mdc - Portfolio allocation logic

๐ŸŽฏ Next Steps (Phase 2)

Immediate Tasks:

  1. Build Schemas - Collections 3 & 4 (with risk_profile_scores array)
  2. Build DAOs - Data access layer for scoring collections
  3. Step 1: Points Assignment Service - Convert raw values โ†’ points (0/3/5/7/10)
  4. Step 2: Category Stats Service - Calculate mean & stdev of points
  5. Step 3: Z-Score Calculator - Normalize points within category
  6. Step 4: Composite Scorer - Apply risk-profile-specific weights (4 scores per fund)
  7. Build Cron Job - Orchestrate scoring after data ingestion

๐Ÿ“– Read first: Docs/SCORING_ENGINE_DEEP_DIVE.md for complete understanding

Future Phases:

  • Phase 3: Portfolio construction & allocation
  • Phase 4: API endpoints for recommendations
  • Phase 5: Frontend integration (see Docs/UI_UX_doc.md)

๐Ÿค Contributing

  1. Follow NestJS best practices
  2. Use DAO pattern for data access
  3. Write unit tests for services
  4. Document complex logic
  5. Follow SOLID principles

๐Ÿ“„ License

UNLICENSED - Private project


๐Ÿ‘ฅ Team

PlutoMoney Team


Built with โค๏ธ for intelligent portfolio management

About

PlutoMoney Quant - AI-Powered Portfolio Allocation System

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published