"""
FX Cash Toolkit - Integration Test Suite
Tests all implemented chapters working together.
"""

import sys
import os
import numpy as np
from datetime import datetime, timedelta

# Add the toolkit to the path
toolkit_path = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, toolkit_path)

def test_foundations():
 """Test Part I: Foundations."""
 print("Testing Part I: Foundations")
 print("-" * 50)

 try:
 # Test Chapter 2: VWAP Execution
 from part_i_foundations.chapter_02_vwap_execution import VWAPExecutionEngine

 # Create VWAP engine with proper parameters
 start_time = datetime.now()
 end_time = start_time + timedelta(hours=2)

 engine = VWAPExecutionEngine(
 currency_pair="EURUSD",
 order_size=10_000_000,
 side="BUY",
 start_time=start_time,
 end_time=end_time
 )

 # Test execution strategy
 result = engine.execute_vwap_strategy(initial_price=1.0850)

 print(f"✓ Chapter 2 VWAP: Executed {result['num_slices']} slices, VWAP: {result['vwap']:.4f}")

 # Test Chapter 3: Quote Management
 from part_i_foundations.chapter_03_quote_management import QuoteManager, FXQuote, CurrencyPair

 qm = QuoteManager()
 pair = CurrencyPair("EUR", "USD")
 quote = FXQuote(pair, 1.0850, 1.0851, datetime.now())
 qm.add_quote(quote)

 # Test basic quote functionality
 print(f"✓ Chapter 3 Quotes: Added quote for {pair.base_currency}{pair.quote_currency}")

 print("✓ Part I: Foundations - ALL TESTS PASSED\n")
 return True

 except Exception as e:
 print(f"✗ Part I: Foundations - ERROR: {e}\n")
 return False


def test_spot_fx():
 """Test Part II: Spot FX."""
 print("Testing Part II: Spot FX")
 print("-" * 50)

 try:
 # Test Chapter 4: Spot Pricing Engine
 from part_ii_spot_fx.chapter_04_spot_pricing import SpotPricingEngine, LiquidityRegime

 engine = SpotPricingEngine()
 engine.add_currency_pair('EURUSD')

 # Add some test data
 from datetime import datetime, timedelta
 import numpy as np

 base_time = datetime.now()
 for i in range(50):
 timestamp = base_time + timedelta(minutes=i)
 spread_pips = 1.8 + np.random.normal(0, 0.2)
 spread = spread_pips * 0.0001
 mid = 1.0850 + np.random.normal(0, 0.0002)
 bid = mid - spread / 2
 offer = mid + spread / 2
 engine.update_price('EURUSD', bid, offer, timestamp)

 # Test liquidity classification
 regime, explanation = engine.spread_monitors['EURUSD'].classify_liquidity_regime()
 print(f"✓ Chapter 4 Pricing: Liquidity regime = {regime.value}")

 # Test Chapter 6: Risk Management
 from part_ii_spot_fx.chapter_06_spot_risk_management import PortfolioRiskManager, Position

 rm = PortfolioRiskManager()

 # Add test position
 position = Position("EURUSD", 1_000_000, 1.0850, "LONG")
 rm.add_position("test_pos", position)

 # Add mock historical data
 np.random.seed(42)
 returns = np.random.normal(0.0001, 0.008, 250)
 rm.set_historical_returns("EURUSD", returns)

 # Calculate VaR
 var_result = rm.calculate_parametric_var(confidence_level=0.95)
 print(f"✓ Chapter 6 Risk: 95% VaR = ${var_result['var']:,.2f}")

 # Test Chapter 9: Corporate Hedging Applications
 from part_ii_spot_fx.chapter_09_corporate_hedging import (
 CorporateHedgePortfolio, ExposureAnalyzer, ForeignCurrencyExposure,
 ExposureType, HedgeRatioOptimizer
 )

 # Create corporate portfolio
 corp_portfolio = CorporateHedgePortfolio("Test Corp", "USD")
 exposure_analyzer = ExposureAnalyzer()
 hedge_optimizer = HedgeRatioOptimizer()

 # Add sample exposure
 today = datetime.now()
 eur_exposure = ForeignCurrencyExposure(
 exposure_id="TEST001",
 exposure_type=ExposureType.TRANSACTION,
 currency_pair="EUR/USD",
 notional_amount=5_000_000,
 exposure_date=today,
 settlement_date=today + timedelta(days=90),
 certainty_level=1.0,
 business_unit="European Sales",
 description="Test EUR receivable"
 )

 exposure_analyzer.add_exposure(eur_exposure)
 corp_portfolio.add_exposure(eur_exposure)

 # Test hedge ratio calculation
 hedge_ratio = hedge_optimizer.policy_based_ratio(
 ExposureType.TRANSACTION, 1.0, 90
 )

 print(f"✓ Chapter 9 Corporate Hedging: Policy hedge ratio = {hedge_ratio:.0%}")

 print("✓ Part II: Spot FX - ALL TESTS PASSED\n")
 return True

 except Exception as e:
 print(f"✗ Part II: Spot FX - ERROR: {e}\n")
 return False


def test_forwards():
 """Test Part III: Forwards."""
 print("Testing Part III: Forwards")
 print("-" * 50)

 try:
 # Test Chapter 7: Forward Fundamentals
 from part_iii_forwards.chapter_07_forward_fundamentals import ForwardContract, ForwardCalculator, ForwardValuator, SettlementMethod

 # Create forward contract
 trade_date = datetime.now()
 value_date = trade_date + timedelta(days=90)

 contract = ForwardContract(
 trade_date=trade_date,
 value_date=value_date,
 currency_pair="EURUSD",
 notional_base=1_000_000,
 forward_rate=1.0825,
 side="BUY",
 settlement_method=SettlementMethod.PHYSICAL_DELIVERY
 )

 # Test MTM
 valuator = ForwardValuator()
 mtm = valuator.mtm(contract, current_forward_rate=1.0810)

 print(f"✓ Chapter 7 Forward: MTM P&L = ${mtm['pnl_present_value']:,.2f}")

 # Test Chapter 8: Forward Pricing CIP
 from part_iii_forwards.chapter_08_forward_pricing_cip import ForwardPricingCalculator, DayCountConvention

 calc = ForwardPricingCalculator()

 # Calculate forward rate using correct parameters
 spot_rate = 1.0850
 r_base = 0.03 # 3% EUR (base currency)
 r_quote = 0.05 # 5% USD (quote currency)
 days = 90

 result = calc.calculate_forward_rate(
 spot_rate=spot_rate,
 r_base=r_base,
 r_quote=r_quote,
 days=days,
 currency_pair="EURUSD"
 )

 print(f"✓ Chapter 8 Forward: 90d forward rate = {result['forward_rate']:.4f}")

 # Test arbitrage detection
 market_forward = 1.0900 # Misaligned with theory
 arbitrage = calc.detect_arbitrage(
 spot_rate=spot_rate,
 market_forward=market_forward,
 r_base=r_base,
 r_quote=r_quote,
 days=days,
 currency_pair="EURUSD"
 )

 print(f"✓ Chapter 8 Arbitrage: Opportunity detected = {arbitrage['arbitrage_exists']}")

 # Test Chapter 10: Hedge Accounting
 from part_iii_forwards.chapter_10_hedge_accounting import HedgeAccountingSystem, HedgeType, EffectivenessMethod, AccountingStandard

 system = HedgeAccountingSystem(AccountingStandard.ASC_815)

 hedged_item = {
 'description': 'Forecasted EUR 10M purchase',
 'notional': 10_000_000,
 'currency': 'EUR',
 'maturity_date': datetime.now() + timedelta(days=90),
 'risk': 'FX rate variability'
 }

 hedging_instrument = {
 'description': 'EUR/USD Forward',
 'notional': 10_000_000,
 'currency': 'EUR',
 'maturity_date': datetime.now() + timedelta(days=90),
 'forward_rate': 1.0850
 }

 designation = system.designate_hedge_relationship(
 hedge_id="TEST_HEDGE_001",
 hedge_type=HedgeType.CASH_FLOW,
 hedged_item=hedged_item,
 hedging_instrument=hedging_instrument,
 effectiveness_method=EffectivenessMethod.DOLLAR_OFFSET
 )

 print(f"✓ Chapter 10 Hedge: Designated hedge {designation['hedge_id']}")

 # Test Chapter 11: Settlement Operations
 from part_iii_forwards.chapter_11_settlement_operations import SettlementManagementSystem, ForwardTrade, SettlementType

 settlement_system = SettlementManagementSystem()

 # Create test SSI data
 import pandas as pd
 ssi_data = pd.DataFrame([
 {
 'counterparty': 'TEST_BANK',
 'currency': 'EUR',
 'beneficiary_name': 'Test Bank Euro',
 'account_number': 'EUR123',
 'bank_name': 'Test Bank',
 'swift_code': 'TESTEUR'
 },
 {
 'counterparty': 'TEST_BANK',
 'currency': 'USD',
 'beneficiary_name': 'Test Bank USD',
 'account_number': 'USD456',
 'bank_name': 'Test Bank',
 'swift_code': 'TESTUSD'
 }
 ])

 settlement_system.load_ssi_database(ssi_data)

 # Create test forward trade
 test_trade = ForwardTrade(
 trade_id="TEST_FWD_001",
 trade_date=datetime.now(),
 value_date=datetime.now() + timedelta(days=30),
 currency_pair="EUR/USD",
 buy_currency="EUR",
 sell_currency="USD",
 buy_amount=1_000_000,
 sell_amount=1_085_000,
 forward_rate=1.0850,
 counterparty="TEST_BANK"
 )

 settlement_system.register_forward_trade(test_trade, SettlementType.CLS)

 print(f"✓ Chapter 11 Settlement: Registered trade {test_trade.trade_id}")

 # Test Chapter 12: Enhanced FX Swaps
 from part_iii_forwards.chapter_12_fx_swaps import FXSwapPricingEngine, ShortDatedSwapPricer

 # Test standard swap pricing
 swap_engine = FXSwapPricingEngine()
 swap_engine.set_market_data(
 currency_pair='EURUSD',
 spot_rate=1.0850,
 domestic_rates={'3M': 0.0525},
 foreign_rates={'3M': 0.0375}
 )

 # Calculate swap points
 swap_calc = swap_engine.calculate_swap_points('EURUSD', '3M', 90)

 # Test short-dated swaps (NEW!)
 short_pricer = ShortDatedSwapPricer()
 short_pricer.set_market_data('EURUSD', 1.0850, 0.0525, 0.0375, 2.5)

 tn_swap = short_pricer.price_tom_next_swap('EURUSD', 10_000_000, 'buy_base')

 print(f"✓ Chapter 12 FX Swaps: Priced swap with {swap_calc['swap_points_pips']:.2f} pips")

 print("✓ Part III: Forwards - ALL TESTS PASSED\n")
 return True

 except Exception as e:
 print(f"✗ Part III: Forwards - ERROR: {e}\n")
 return False


def test_ndfs():
 """Test Part V: NDFs."""
 print("Testing Part V: NDFs")
 print("-" * 50)

 try:
 # Test Chapter 16: NDF Markets
 from part_v_ndfs.chapter_16_ndf_markets import NDFPricer, NDFContract

 pricer = NDFPricer()

 # Test NDF pricing
 ndf_pricing = pricer.calculate_ndf_rate('USD/CNY', 90)
 print(f"✓ Chapter 16 NDF Markets: 90D USD/CNY rate = {ndf_pricing['ndf_rate']:.4f}")

 # Test NDF contract settlement
 ndf_contract = NDFContract(
 currency_pair='USD/CNY',
 notional_usd=1_000_000,
 ndf_rate=7.2800,
 fixing_date=datetime.now() + timedelta(days=25),
 settlement_date=datetime.now() + timedelta(days=27),
 fixing_source='CFETS',
 contract_date=datetime.now()
 )

 settlement = pricer.calculate_settlement_amount(ndf_contract, 7.3500)
 print(f"✓ Chapter 16 Settlement: ${settlement['settlement_usd']:,.2f} USD settlement")

 # Test Chapter 18: NDF Risk Management
 from part_v_ndfs.chapter_18_ndf_risk_management import NDFRiskManager

 risk_manager = NDFRiskManager()

 # Add sample NDF position
 risk_manager.add_ndf_position(
 trade_id='TEST-NDF-001',
 currency_pair='USDKRW',
 notional=1_000_000, # 1M USD
 forward_rate=1320.50,
 fixing_date=datetime.now() + timedelta(days=30),
 settlement_date=datetime.now() + timedelta(days=32),
 side='BUY'
 )

 # Calculate settlement exposure
 current_rates = {"USDKRW": 1325.75}
 exposures = risk_manager.calculate_settlement_exposure(current_rates)
 settlement_amount = exposures.iloc[0]['settlement_amount'] if not exposures.empty else 0
 print(f"✓ Chapter 18 NDF Risk Management: Settlement exposure = ${settlement_amount:,.2f}")

 # Test Chapter 17: NDF Basis Analysis
 from part_v_ndfs.chapter_17_ndf_basis_analysis import NDFBasisAnalyzer, NDFLiquidityAnalyzer

 basis_analyzer = NDFBasisAnalyzer()

 # Add sample basis observations
 test_date = datetime.now()
 basis_analyzer.add_observation(test_date, "USDCNY", 30, 7.32, 7.30)
 basis_analyzer.add_observation(test_date - timedelta(days=1), "USDCNY", 30, 7.31, 7.29)
 basis_analyzer.add_observation(test_date - timedelta(days=2), "USDCNY", 30, 7.30, 7.28)

 # Calculate basis statistics
 basis_stats = basis_analyzer.calculate_basis_statistics("USDCNY", 30)
 print(f"✓ Chapter 17 NDF Basis Analysis: Mean basis = {basis_stats['mean_basis_bps']:.2f} bps")

 # Test arbitrage detection
 arbitrage_result = basis_analyzer.identify_arbitrage_opportunity("USDCNY", 30, 15.0)
 arbitrage_available = arbitrage_result.get('arbitrage_available', False)
 print(f"✓ Chapter 17 Arbitrage Detection: Arbitrage available = {arbitrage_available}")

 print("✓ Part V: NDFs - ALL TESTS PASSED\n")
 return True

 except Exception as e:
 print(f"✗ Part V: NDFs - ERROR: {e}\n")
 return False


def test_cross_module_integration():
 """Test integration between different modules."""
 print("Testing Cross-Module Integration")
 print("-" * 50)

 try:
 # Use VWAP execution with risk management
 from part_i_foundations.chapter_02_vwap_execution import VWAPExecutionEngine
 from part_ii_spot_fx.chapter_06_spot_risk_management import PortfolioRiskManager, Position
 from part_iii_forwards.chapter_08_forward_pricing_cip import ForwardPricingCalculator

 # 1. Execute VWAP strategy
 start_time = datetime.now()
 end_time = start_time + timedelta(hours=2)

 engine = VWAPExecutionEngine(
 currency_pair="EURUSD",
 order_size=25_000_000,
 side="BUY",
 start_time=start_time,
 end_time=end_time
 )

 vwap_result = engine.execute_vwap_strategy(initial_price=1.0850)
 avg_price = vwap_result['vwap']

 # 2. Add position to risk manager
 rm = PortfolioRiskManager()
 position = Position("EURUSD", 25_000_000, avg_price, "LONG")
 rm.add_position("vwap_position", position)

 # Add historical data
 np.random.seed(42)
 returns = np.random.normal(0.0001, 0.008, 250)
 rm.set_historical_returns("EURUSD", returns)

 # Calculate risk metrics
 var_result = rm.calculate_parametric_var()

 # 3. Calculate hedging forward
 calc = ForwardPricingCalculator()
 hedge_result = calc.calculate_forward_rate(
 spot_rate=avg_price,
 r_base=0.03, # EUR rate
 r_quote=0.05, # USD rate
 days=30,
 currency_pair="EURUSD"
 )

 print(f"✓ Integrated Workflow:")
 print(f" VWAP Avg Price: {avg_price:.4f}")
 print(f" Position VaR: ${var_result['var']:,.2f}")
 print(f" 30d Hedge Forward: {hedge_result['forward_rate']:.4f}")

 print("✓ Cross-Module Integration - ALL TESTS PASSED\n")
 return True

 except Exception as e:
 print(f"✗ Cross-Module Integration - ERROR: {e}\n")
 return False


def main():
 """Run all integration tests."""
 print("=" * 80)
 print("FX CASH TOOLKIT - COMPREHENSIVE INTEGRATION TEST")
 print("=" * 80)
 print()

 results = []

 # Run all test suites
 results.append(("Foundations", test_foundations()))
 results.append(("Spot FX", test_spot_fx()))
 results.append(("Forwards", test_forwards()))
 results.append(("NDFs", test_ndfs()))
 results.append(("Integration", test_cross_module_integration()))

 # Summary
 print("=" * 80)
 print("TEST RESULTS SUMMARY")
 print("=" * 80)

 passed = 0
 total = len(results)

 for test_name, result in results:
 status = "PASS" if result else "FAIL"
 print(f"{test_name:<20} {status}")
 if result:
 passed += 1

 print(f"\nOverall: {passed}/{total} test suites passed")

 if passed == total:
 print("🎉 ALL TESTS PASSED - Toolkit is ready for production!")
 else:
 print("⚠️ Some tests failed - Check implementations")

 print("=" * 80)


if __name__ == "__main__":
 main()