
    mj)#                       d dl mZ dZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZmZ  G d d          ZddZ G d de          ZddZddZddZddZddZ ddZ!ddZ"dS )    )annotationsFN)date)Decimal)FrankfurterFxProvider)resolve_fx_rate_to_chf)EquityPriceQuoteFmpEquityPriceProvider)_business_day_agerun_daily_market_valuation)connect_memory)apply_migrations)Fxdatabasec                  *    e Zd ZddZd Zd Zdd	Zd
S )FakeResponsepayloadobjectreturnNonec                    || _         d S N)r   )selfr   s     )tests/unit/test_sprint9_fx_fmp_history.py__init__zFakeResponse.__init__   s        c                    | S r    r   s    r   	__enter__zFakeResponse.__enter__   s    r   c                    dS )NFr   )r   argss     r   __exit__zFakeResponse.__exit__   s    ur   bytesc                Z    t          j        | j                                      d          S )Nzutf-8)jsondumpsr   encoder   s    r   readzFakeResponse.read   s"    z$,''..w777r   Nr   r   r   r   )r   r#   )__name__
__module____qualname__r   r   r"   r(   r   r   r   r   r      sZ               8 8 8 8 8 8r   r   r   r   c                   i fd}|                      d|           t                      }t          |           t          |ddt	                      gd          }|j        t          d          k    sJ d         d	         t          j        k    sJ d
d         v r
dd         v sJ |                    d          	                                }t          |          dk    sJ d S )Nc                   | j         d<   t          |                                           d<   |d<   t          dddddg          S )	Nurlheaderstimeout
2026-07-24EURCHF0.9321)r   basequoterate)full_urldictheader_itemsr   )reqr1   captureds     r   fake_urlopenzitest_frankfurter_sends_transparent_user_agent_and_persists_requested_direction_date.<locals>.fake_urlopen#   sT    ,"3#3#3#5#566%lEE[cddefffr   z+jarvis_finance.fx.providers.request.urlopenr3   r2   F)base_currency	rate_date	providersresolve_fixedr5   r0   z
User-agentzbase=EURr/   z
quotes=CHFzMSELECT base_currency, quote_currency, rate_date, rate, provider FROM fx_rates)r3   r4   r2   r5   frankfurter)setattrr   r   r   r   r8   r   
user_agentexecutefetchonetuple)monkeypatchr>   connresultrowr=   s        @r   Stest_frankfurter_sends_transparent_user_agent_and_persists_requested_direction_daterM       s%   Hg g g g g E|TTTDT#(**+  F ;'(++++++I|,0E0PPPPP%((\Xe_-L-L-LL
,,W hjj  ::NNNNNNNr   c                  :     e Zd Zd fdZdd
Zddd fdZ xZS )HistoricalFmpr   r   r   r   c                v    t                                          d           || _        g | _        g | _        d S )N	synthetic)api_key)superr   r   callsreturned_currencies)r   r   	__class__s     r   r   zHistoricalFmp.__init__?   s:    ---79
.0   r   pathstrparamsdict[str, str]c                r    | j                             ||f           |dk    rt          d          | j        S )N/stable/profilezChistorical price requests must not use the current profile endpoint)rT   appendAssertionErrorr   )r   rW   rY   s      r   	_get_jsonzHistoricalFmp._get_jsonE   s?    
4.)))$$$ !fggg|r   N
price_dateprovider_symbolra   
str | Noner   c                   t                                          ||          }| j                            |j                   |S )Nr`   )rS   	get_pricerU   r]   currency)r   rb   ra   r7   rV   s       r   re   zHistoricalFmp.get_priceK   s=    !!/j!II ''777r   r)   )rW   rX   rY   rZ   r   r   rb   rX   ra   rc   r   r   )r*   r+   r,   r   r_   re   __classcell__)rV   s   @r   rO   rO   >   s        1 1 1 1 1 1    KO            r   rO   c                     t          ddddddddg          } |                     dd          }|j        t          d          k    sJ |j        dk    sJ | j        d	d
dddfgk    sJ d S )N
2026-07-01251.34USDr   closerf   z
2026-06-30z249.00vtir`   z!/stable/historical-price-eod/fullVTIz
2026-06-24)symbolfromto)rO   re   rn   r   price_timestamprT   providerr7   s     r   Ctest_fmp_historical_price_uses_exact_requested_date_without_profilerw   Q   s    eDDeDD  H
 u>>E;'(++++++ L0000>/l,GG	
      r   c                     t          ddddddddddddg          } |                     d	d
          }|j        t          d          k    sJ |j        dk    sJ d S )Nz
2026-07-06999.00rl   rm   z
2026-07-03z250.00z
2026-06-26z240.00rp   z
2026-07-05r`   )rO   re   rn   r   rt   ru   s     r   Otest_fmp_historical_price_uses_latest_prior_trading_day_and_rejects_future_rowsrz   c   s    eDDeDDeDD  H u>>E;'(++++++ L000000r   c                     t          ddddg          } t          ddddg          }t          g           }| ||fD ]<}|                    dd	          }|j        J |j        d
k    sJ |j        dk    sJ =d S )Nz
2026-07-02ry   rl   rm   z
2026-06-23z200.00rp   rj   r`   missingprice_missing)rO   re   rn   quality_statuserror_message)future_onlyoutside_boundaryemptyrv   r7   s        r   Btest_fmp_historical_price_returns_missing_when_no_eligible_historyr   p   s    ,W\!]!] ^__K$|h\a&b&b%cdd"E "2E: 6 6""5\"BB{"""#y0000"o55555	6 6r   c           	     8   t          d          }|                    d                                          d         }|                    d|f           |                    d|f           |                    d           |                                 t	          dd	d
g          }|                    dd          }|j        dk    sJ |                    d|f                                          }t          |          dk    sJ t          |dd|it          ddi          | dz            }|j
        du sJ |j        ddgk    sJ |j        |j        k    sJ |                    d                                          }|rd |D             dhk    sJ d S )NFpolicya4  SELECT m.instrument_id FROM instrument_price_mappings m
           JOIN transactions t ON t.instrument_id=m.instrument_id
           JOIN instruments i ON i.instrument_id=m.instrument_id
           WHERE t.is_confirmed=1 AND t.is_voided=0 AND i.trading_currency='EUR'
           ORDER BY m.mapping_id LIMIT 1r   z9UPDATE instruments SET is_active=0 WHERE instrument_id<>?zaUPDATE instrument_price_mappings SET trading_currency='EUR', currency='EUR' WHERE instrument_id=?zDELETE FROM market_data_runsrj   rk   )r   rn   	SYNTHETICr`    zrSELECT provider,upper(COALESCE(trading_currency,currency,'')) FROM instrument_price_mappings WHERE instrument_id=?)mockr3   r   )r3   rj   z0.93market.lockas_ofprice_providersfx_provider	lock_pathz3SELECT currency,close,price_date FROM market_pricesc                ,    h | ]}t          |          S r   )rH   ).0rL   s     r   	<setcomp>z]test_fmp_historical_price_without_currency_uses_confirmed_mapping_currency.<locals>.<setcomp>   s    000CU3ZZ000r   )r3   rk   rj   )r   rF   rG   commitrO   re   rf   rH   r   r   
idempotentrU   price_storedprice_totalfetchall)tmp_pathrJ   keeprv   direct_quotemapping_staterK   rowss           r   Jtest_fmp_historical_price_without_currency_uses_confirmed_mapping_currencyr   |   s   5!!!D<<	,  hjjD 	LLLtgVVVLLtw{v}~~~LL/000KKMMM|hGGHIIH%%kl%KKL B&&&&LL|	  hjj  ?2222'*-v677]*  F %%%%'B83333&"44444<<MNNWWYYDU0040005T4UUUUUUUr   c                n   t          d          }|                    d           |                                 t          g           }t	          |dd|it          i           | dz            }t	          |dd|it          i           | dz            }|j        dk    sJ d	 |j        D             d
hk    sJ |j        du r|j	        |j	        k    sJ |j        dk    sJ |                    d          
                                d         dk    sJ t          d |j        D                       sJ d S )NFr   z3UPDATE instrument_price_mappings SET provider='fmp'rj   fmpr   r   partialc                    h | ]
}|d          S )reason_coder   )r   items     r   r   zXtest_daily_orchestrator_reports_price_missing_and_rerun_is_idempotent.<locals>.<setcomp>   s    FFFDDFFFr   r}   "SELECT COUNT(*) FROM market_pricesr   c              3  (   K   | ]\  }}|d k    V  dS )r\   Nr   )r   rW   _s      r   	<genexpr>zXtest_daily_orchestrator_reports_price_missing_and_rerun_is_idempotent.<locals>.<genexpr>   s,      GGWT1t((GGGGGGr   )r   rF   r   rO   r   r   statusmissing_instrumentsr   run_idrG   allrT   )r   rJ   rv   firstreplays        r   Etest_daily_orchestrator_reports_price_missing_and_rerun_is_idempotentr      sp   5!!!DLLFGGGKKMMMR  H&)rFF]*  E ()rFF]*  F <9$$$$FFE,EFFF?J[[[[[%%&-5<*G*G*GG=I%%%%<<<==FFHHKqPPPPGGGGGGGGGGGGr   c                j    G d d          }t          d          }t          |dd |            it          i           | dz             t          t	          d	d
d          t	          d	d
d                    dk     sJ |                    d                                          d         dk    sJ d S )Nc                       e Zd ZdZdddd
ZdS )Ktest_daily_orchestrator_never_persists_future_price.<locals>.FutureProviderr   Nr`   rb   rX   ra   rc   r   r   c               N    t          |dt          d          | j        d          S )Nr4   100z2026-07-02T20:00:00+00:00)rb   rf   rn   rv   rt   )r   r   name)r   rb   ra   s      r   re   zUtest_daily_orchestrator_never_persists_future_price.<locals>.FutureProvider.get_price   s0    # /enn ;   r   rg   )r*   r+   r,   r   re   r   r   r   FutureProviderr      s:        NR 	 	 	 	 	 	 	 	r   r   Fr   rj   r   r   r   i           r   r   )r   r   r   r
   r   rF   rG   )r   r   rJ   s      r   3test_daily_orchestrator_never_persists_future_pricer      s    
 
 
 
 
 
 
 
 5!!!D!1!12rFF]*    T$1--tD!Q/?/?@@1DDDD<<<==FFHHKqPPPPPPr   c                    t          |           t                       t                       t                       t	          | dz             t          | dz             t          | dz             d S )Nrf   r|   future)rM   rw   rz   r   r   r   r   )r   rI   s     r   #run_sprint9_fx_fmp_history_contractr      sv    WXcdddGIIISUUUFHHHNxZdOdeeeI(U^J^___788KLLLLLr   )r   r   )#
__future__r   __test__r%   datetimer   decimalr   jarvis_finance.fx.providersr   jarvis_finance.fx.ratesr   !jarvis_finance.market_data.pricesr   r	   +jarvis_finance.services.portfolio_analyticsr
   r   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   "test_portfolio_market_analytics_v1r   r   r   rM   rO   rw   rz   r   r   r   r   r   r   r   r   <module>r      s   " " " " " "              = = = = = = : : : : : : V V V V V V V V e e e e e e e e : : : : : : > > > > > > ; ; ; ; ; ; ; ;8 8 8 8 8 8 8 8O O O O<    *   &   $
1 
1 
1 
1	6 	6 	6 	6"V "V "V "VJH H H H:Q Q Q Q4M M M M M Mr   