Complete Phase 2: Market Analysis, Filtering & Documentation

This commit implements all Phase 2 functionality with architectural
improvements over the original plan.

## Phase 2.1: Property Valuation Data 
- filter_deals_by_criteria() with comprehensive filtering
- calculate_deal_statistics() for statistical aggregations
- _extract_floor_number() for Hebrew floor parsing
- _calculate_std_dev() helper function
- MCP tools: get_valuation_comparables, get_deal_statistics

## Phase 2.2: Market Activity & Investment Analysis 
- calculate_market_activity_score() - deal frequency & velocity
  * Activity score (0-100), trend analysis, monthly distribution
  * Classifies markets: very_high, high, moderate, low, very_low
- analyze_investment_potential() - price trends & stability
  * Price appreciation rate via linear regression
  * Volatility score using coefficient of variation
  * Investment score combining appreciation & stability
- get_market_liquidity() - turnover & liquidity metrics
  * Quarterly/monthly breakdowns, velocity scoring
  * Trend direction, most active periods
- MCP tool: get_market_activity_metrics (unified tool)

## Phase 2.3: Enhanced Deal Filtering 
- Property type, room count, price, area, floor filtering
- All integrated into existing tools
- Hebrew floor number parsing support

## Testing 
- Added 15 comprehensive unit tests (all passing)
- Coverage: market activity, investment analysis, liquidity, filtering
- Edge cases: empty data, invalid dates, insufficient data

## Documentation 
- Created CLAUDE.md (~250 lines) - AI agent guidance
  * Development commands, architecture overview
  * Product vision from USECASES.md
  * Available tools with status indicators
- Updated TASKS.md - Phase 2 marked 100% complete

## Architectural Improvements
- 1 unified MCP tool instead of 6 separate tools (simpler API)
- 1 flexible filtering function instead of 3 (more composable)
- All logic in govmap.py (no new files, better cohesion)
- ~955 lines added with comprehensive documentation

## Design Principles Followed
 MCP provides data, LLM provides intelligence
 No predictions - only statistical calculations
 Comprehensive error handling & input validation
 Well-documented with detailed docstrings

Phase 2 Progress: 100% complete (60% overall project completion)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Nitzan Pomerantz
2025-10-24 18:51:50 +03:00
parent 53e730ea66
commit 2968711307
5 changed files with 999 additions and 37 deletions
+76
View File
@@ -678,6 +678,82 @@ def get_deal_statistics(
logger.error(f"Error in get_deal_statistics: {e}")
return f"Error calculating deal statistics: {str(e)}"
@mcp.tool()
def get_market_activity_metrics(
address: str,
years_back: int = 2,
radius_meters: int = 100
) -> str:
"""Get comprehensive market activity and investment potential analysis.
This tool provides detailed market liquidity, activity scores, and investment
potential metrics. It combines activity scoring, liquidity analysis, and
investment potential into a single comprehensive report.
Args:
address: The address to analyze (in Hebrew or English)
years_back: How many years back to analyze (default: 2)
radius_meters: Search radius in meters (default: 100)
Returns:
JSON string containing:
- Market activity score and trends
- Market liquidity and velocity metrics
- Investment potential analysis
- Price appreciation and volatility
"""
try:
# Get deals for the address
deals = client.find_recent_deals_for_address(address, years_back, radius_meters)
if not deals:
return json.dumps({
"address": address,
"error": "No deals found for analysis",
"years_back": years_back,
"radius_meters": radius_meters
}, ensure_ascii=False, indent=2)
# Calculate market activity score
try:
activity_metrics = client.calculate_market_activity_score(deals)
except ValueError as e:
activity_metrics = {"error": str(e)}
# Calculate market liquidity
try:
liquidity_metrics = client.get_market_liquidity(deals)
except ValueError as e:
liquidity_metrics = {"error": str(e)}
# Analyze investment potential
try:
investment_metrics = client.analyze_investment_potential(deals)
except ValueError as e:
investment_metrics = {"error": str(e)}
# Combine all metrics
return json.dumps({
"address": address,
"years_back": years_back,
"radius_meters": radius_meters,
"total_deals_analyzed": len(deals),
"market_activity": activity_metrics,
"market_liquidity": liquidity_metrics,
"investment_potential": investment_metrics,
"summary": {
"activity_level": activity_metrics.get("activity_level", "unknown"),
"liquidity_rating": liquidity_metrics.get("liquidity_rating", "unknown"),
"investment_score": investment_metrics.get("investment_score", 0),
"price_trend": investment_metrics.get("price_trend", "unknown"),
"market_stability": investment_metrics.get("market_stability", "unknown")
}
}, ensure_ascii=False, indent=2)
except Exception as e:
logger.error(f"Error in get_market_activity_metrics: {e}")
return f"Error analyzing market activity: {str(e)}"
# Run the server
if __name__ == "__main__":
mcp.run()