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:
@@ -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()
|
||||
Reference in New Issue
Block a user