
    aj                         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	 d dl
mZmZ d dlmZ d dlmZ d d	lmZ  G d
 d          Zd ZddZddZddZddZddZddZddZdS )    )annotationsDecimal)add_equity_initial_snapshot)resolve_fx_rate_to_chf)store_market_price)_position_statuslist_equity_positions)refresh_equity_fx)connect_memory)apply_migrationsc                  "    e Zd Zddd
ZdddZdS )ProviderNnamestrrateDecimal | NoneerrorException | NonereturnNonec                >    || _         || _        || _        g | _        d S N)r   r   r   calls)selfr   r   r   s       0tests/unit/test_fx_frankfurter_primary_hotfix.py__init__zProvider.__init__   s"    		
8:


    base_currencyquote_currency	rate_date
str | Nonec                f    | j                             |||f           | j        r| j        | j        S r   )r   appendr   r   r   r   r    r!   s       r   get_ratezProvider.get_rate   s9    
=.)DEEE: 	*yr   )NN)r   r   r   r   r   r   r   r   r   r   r   r    r   r!   r"   )__name__
__module____qualname__r   r&    r   r   r   r      sF        ; ; ; ; ;      r   r   c                 @    t                      } t          |            | S r   )r   r   conns    r   
setup_connr/      s     DTKr   r   r   c                    |                      d           |                      d           |                                  dS )NzINSERT INTO platforms(platform_id, name, platform_type, country, default_currency, created_at) VALUES ('p1', 'PostFinance', 'broker', 'CH', 'CHF', '2026-01-01')zINSERT INTO accounts(account_id, platform_id, account_name, account_type, currency, created_at) VALUES ('a1', 'p1', 'Depot', 'brokerage', 'CHF', '2026-01-01')a1)executecommitr-   s    r   seed_accountr4   "   sR    LL  t  u  u  uLL  r  s  s  sKKMMM4r   r   c                    t                      } |                     d           t          dt          d                    }t          dt          d                    }t	          | dd||gd	          }|j        d
k    sJ |j        dk    sJ |j        t          d          k    sJ |j        dgk    sJ |j        g k    sJ |                     d          	                                }|d         dk    sJ |d         dk    sJ d S )NzINSERT INTO fx_rates(fx_rate_id, base_currency, quote_currency, rate_date, rate, provider, rate_type, quality_status, created_at) VALUES ('old', 'EUR', 'CHF', '2026-05-19', '0.9000', 'cache_fixture', 'close', 'fresh', '2026-05-19')frankfurterz0.9700
twelvedataz0.9600EUR
2026-05-20Tr   r!   	providerspersistok)r8   CHFr9   zSELECT rate, provider FROM fx_rates WHERE base_currency='EUR' AND quote_currency='CHF' ORDER BY rate_date DESC, created_at DESC LIMIT 1providerr   )
r/   r2   r   r   r   statussourcer   r   fetchone)r.   r6   r7   resultlatests        r   Itest_resolve_fx_uses_frankfurter_before_stale_cache_and_before_twelvedatarE   )   sV   <<DLL  {  |  |  |='(*;*;<<K,(9(9::J#Dbmoyaz  EI  J  J  JF=D    =M))));'(++++++!= >>>>>r!!!!\\  d  e  e  n  n  p  pF*....&>X%%%%%%r   c                    t                      } |                     d           t          dt          d                    }t          dt          d                    }t	          | dd||gd	
          }|j        dk    sJ |j        dk    sJ |j        t          d          k    sJ |j	        dgk    sJ |j	        g k    sJ |j
        J d S )NzINSERT INTO fx_rates(fx_rate_id, base_currency, quote_currency, rate_date, rate, provider, rate_type, quality_status, created_at) VALUES ('cached', 'USD', 'CHF', '2026-05-20', '0.8800', 'frankfurter', 'close', 'fresh', '2026-05-20')r6   frankfurter_provider_error)r   r7   twelvedata_provider_errorUSDr9   Tr:   r=   zcache:frankfurterz0.8800)rI   r>   r9   )r/   r2   r   RuntimeErrorr   r@   rA   r   r   r   warning)r.   r6   r7   rC   s       r   Ltest_resolve_fx_uses_cache_after_frankfurter_failure_before_twelvedata_noiserL   ;   s   <<DLL  |  }  }  }==Y0Z0Z[[[K,l;V.W.WXXXJ#Dbmoyaz  EI  J  J  JF=D    =/////;'(++++++!= >>>>>r!!!!>!!!!!r   c                     t                      } t          | dd          }|j        dk    sJ |j        t	          d          k    sJ |j        dk    sJ d S )Nr>   r9   )r   r!   
not_needed1)r/   r   r@   r   r   rA   )r.   rC   s     r   /test_chf_resolution_is_not_needed_with_rate_onerP   K   sd    <<D#DVVVF=L((((;'#,,&&&&=L((((((r   c                x   t                      }t          |          }t          ||ddddddddd	d
dd          }t          ||j        dt          d          ddddd	  	         |                                  G d d           G d d          |                     dfd           |                     dfd           t          ||j                  }t          |          }t          d |D                       }|d         dk    sJ |d          g k    sJ |j        d!k    sJ |j        d"k    sJ d S )#Nstock
Apple Inc.US0378331005APCXETRAr>   2300
2026-01-01Corez-synthetic Apple CHF cost basis, EUR valuationT
account_idasset_classr   isintickerexchangecurrencyquantity_textcost_basis_original_textsnapshot_datecategorynoteconfirmr9   100r8   fixturezAPC.DEfreshinstrument_id
price_dateclosera   r?   provider_symbolprovider_marketquality_statusc                      e Zd ZdZd	d
dZdS )^test_apple_eur_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.Frankfurterr6   Nr   r   r    r!   r"   c                4    ||fdk    sJ t          d          S )N)r8   r>   z0.95r   r%   s       r   r&   zgtest_apple_eur_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.Frankfurter.get_ratek   $    !>2nDDDD6??"r   r   r'   r(   r)   r*   r   r&   r+   r   r   Frankfurterrs   i   2        	# 	# 	# 	# 	# 	# 	#r   rw   c                      e Zd ZdZd ZdS )]test_apple_eur_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.TwelveDatar7   c                     t          d          )Nz7TwelveData must not be called when Frankfurter succeeds)AssertionError)r   argskwargss      r   r&   zftest_apple_eur_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.TwelveData.get_rateq   s     !Z[[[r   Nrv   r+   r   r   
TwelveDatarz   o   s-        	\ 	\ 	\ 	\ 	\r   r   1jarvis_finance.fx.providers.FrankfurterFxProviderc                                   S r   r+   rw   s   r   <lambda>z[test_apple_eur_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.<lambda>t       U`U`UbUb r   z0jarvis_finance.fx.providers.TwelveDataFxProviderc                                   S r   r+   )r   s   r   r   z[test_apple_eur_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.<lambda>u   s    T^T^T`T` r   c              3  0   K   | ]}|j         d k    |V  dS rS   Nr   .0rows     r   	<genexpr>z\test_apple_eur_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.<genexpr>y   s.      AAL(@(@(@(@(@(@AAr   updated   warningsBewertetz190.00)r/   r4   r   r   rl   r   r3   setattrr   r
   nextr@   market_value_chf)	monkeypatchr.   r\   snaprC   rowsapplerw   r   s	          @@r   Itest_apple_eur_valuation_fx_recheck_gets_chf_market_value_via_frankfurterr   S   s   <<Dd##J&!&"<  D  t4+=,^efk^l^lw|  HQ  ck  }D  U\  ]  ]  ]  ]KKMMM# # # # # # # #\ \ \ \ \ \ \ \
 KMbMbMbMbcccJL`L`L`L`aaatT%788F &&DAAAAAAAE)!!!!*####<:%%%%!X------r   c                
   t                      }t          |          }t          ||ddddddddd	d
dd          }t          ||j        dt          d          ddddd	  	         |                                  G d d          |                     dfd           t          ||j                  }t          d t          |          D                       }|d         g k    sJ |j        dk    sJ |j        dk    sJ d S )NrR   rS   rT   AAPLNASDAQr>   rW   rX   rY   rZ   z-synthetic Apple CHF cost basis, USD valuationTr[   r9   200rI   ri   rj   rk   c                      e Zd ZdZd	d
dZdS )^test_apple_usd_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.Frankfurterr6   Nr   r   r    r!   r"   c                4    ||fdk    sJ t          d          S )N)rI   r>   z0.90r   r%   s       r   r&   zgtest_apple_usd_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.Frankfurter.get_rate   ru   r   r   r'   rv   r+   r   r   rw   r      rx   r   rw   r   c                                   S r   r+   r   s   r   r   z[test_apple_usd_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.<lambda>   r   r   c              3  0   K   | ]}|j         d k    |V  dS r   r   r   s     r   r   z\test_apple_usd_valuation_fx_recheck_gets_chf_market_value_via_frankfurter.<locals>.<genexpr>   s.      XXsx<?W?W?W?W?W?WXXr   r   r   z360.00)r/   r4   r   r   rl   r   r3   r   r   r   r
   r@   r   )r   r.   r\   r   rC   r   rw   s         @r   Itest_apple_usd_valuation_fx_recheck_gets_chf_market_value_via_frankfurterr      sz   <<Dd##J&!&"<  D  t4+=,^efk^l^lw|  HQ  ci  {C  T[  \  \  \  \KKMMM# # # # # # # # KMbMbMbMbccctT%788FXX 5d ; ;XXXXXE*####<:%%%%!X------r   c                 v    ddddddd} t          |           dk    sJ d| d<   t          |           d	k    sJ d S )
Nr=   
missing_fxz100.00rK   )price_status	fx_statusr   quality_warningsdata_quality_statusvaluation_statusu   Einstand unvollständig r   u   FX fehlt für Bewertung)r	   )r   s    r   Ktest_valuation_status_does_not_show_fx_missing_when_market_value_chf_existsr      sg    !$((% C C  $===== CC  $=======r   N)r   r   )r   r   )
__future__r   decimalr   jarvis_finance.equity.manager   jarvis_finance.fx.ratesr   !jarvis_finance.market_data.pricesr   &jarvis_finance.services.equity_servicer	   r
   &jarvis_finance.services.market_servicer   jarvis_finance.storage.databaser   !jarvis_finance.storage.migrationsr   r   r/   r4   rE   rL   rP   r   r   r   r+   r   r   <module>r      s|   " " " " " "       D D D D D D : : : : : : @ @ @ @ @ @ Z Z Z Z Z Z Z Z D D D D D D : : : : : : > > > > > >            & & & &$" " " " ) ) ) )+. +. +. +.\#. #. #. #.L> > > > > >r   