
    mj)#                    &   d dl mZ d dlZd dlmc 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 )    )annotationsNF)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     R/home/agent/.hermes/repos/FinanceManager/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        }d}t          |          }||k    }|st          j        d|fd	||f          d
t          j
                    v st          j        |          rt          j        |          nd
t          j        |          dt          j
                    v st          j        t                    rt          j        t                    ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}x}}d         d         }
t          j        }|
|k    }|st          j        d|fd|
|f          t          j        |
          dt          j
                    v st          j        t                    rt          j        t                    ndt          j        |          dz  }dd|iz  }t          t          j        |                    d x}
x}}g }d}d         }||v }|}
|rd}d         }||v }|}
|
st          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }|                    |           |r`t          j        d|fd||f          t          j        |          t          j        |          dz  }d d!|iz  }|                    |           t          j        |d"          i z  }d#d$|iz  }t          t          j        |                    d x}
x}x}x}x}x}x}}|                    d%                                          }t)          |          }d&}||k    }|st          j        d|fd'||f          d(t          j
                    v st          j        t(                    rt          j        t(                    nd(d)t          j
                    v st          j        |          rt          j        |          nd)t          j        |          t          j        |          d*z  }d+d|iz  }t          t          j        |                    d x}x}}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   ==)zJ%(py2)s
{%(py2)s = %(py0)s.rate
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}resultr   py0py2py4py6py8assert %(py10)spy10r0   z
User-agent)z2%(py1)s == %(py5)s
{%(py5)s = %(py3)s.user_agent
}r   )py1py3py5assert %(py7)spy7zbase=EURr/   z
quotes=CHF)in)z%(py3)s in %(py6)s)rO   rJ   z%(py8)srK   )z%(py11)s in %(py14)s)py11py14z%(py16)spy16r   zassert %(py19)spy19zMSELECT base_currency, quote_currency, rate_date, rate, provider FROM fx_rates)r3   r4   r2   r5   frankfurterz0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)stuplerowrG   rN   rO   rJ   assert %(py8)s)setattrr   r   r   r   r8   r   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation
user_agentappend_format_boolopexecutefetchonerZ   )monkeypatchr>   connrE   @py_assert1@py_assert5@py_assert7@py_assert3@py_format9@py_format11@py_assert0@py_assert4@py_assert2@py_format6@py_format8@py_assert10@py_assert13@py_assert12@py_format7@py_format15@py_format17@py_format18@py_format20r[   r=   s                           @r   Stest_frankfurter_sends_transparent_user_agent_and_persists_requested_direction_dater       s   Hg g g g g E|TTTDT#(**+  F ;+(+'(+++;+++++++++++;+++++++++++++6+++++6++++++;+++++++++++'+++++'++++++(++++++++++++++++++++++++++++++++++I|,P0E0PP,0PPPPPPPPPPP,0PPPPPP,PPPPPPPPPPP0EPPPPP0EPPPPPP0PPPPPPPPPPPPPPPPPPPPPPPPPPPPLL:L%L:(LLLLL\LXe_L\_-LLLLLLLLLLLL:LLLLL:LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL\_LLLLL\LLLL_LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
,,W hjj  ::NNN:NNNNNNNNNNN:NNNNNNNNNNNNN5NNNNN5NNNNNNNNNNNNNNNNNNNNNNNN:NNNNNNNNNNNNNNNNNNNNNNNNNNN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)r   rh   re   r   )r   r   r   s      r   	_get_jsonzHistoricalFmp._get_jsonE   s?    
4.)))$$$ !fggg|r   N
price_dateprovider_symbolr   
str | Noner   c                   t                                          ||          }| j                            |j                   |S )Nr   )r   	get_pricer   rh   currency)r   r   r   r7   r   s       r   r   zHistoricalFmp.get_priceK   s=    !!/j!II ''777r   r)   )r   r   r   r   r   r   r   r   r   r   r   r   )r*   r+   r,   r   r   r   __classcell__)r   s   @r   r   r   >   s        1 1 1 1 1 1    KO            r   r   c                    t          ddddddddg          } |                     dd          }|j        }d}t          |          }||k    }|st	          j        d	|fd
||f          dt          j                    v st	          j        |          rt	          j	        |          ndt	          j	        |          dt          j                    v st	          j        t                    rt	          j	        t                    ndt	          j	        |          t	          j	        |          dz  }dd|iz  }t          t	          j        |                    d x}x}x}}|j        }d}||k    }|st	          j        d	|fd||f          dt          j                    v st	          j        |          rt	          j	        |          ndt	          j	        |          t	          j	        |          dz  }	dd|	iz  }
t          t	          j        |
                    d x}x}}| j        }dddddfg}||k    }|st	          j        d	|fd||f          dt          j                    v st	          j        |           rt	          j	        |           ndt	          j	        |          t	          j	        |          dz  }	dd|	iz  }
t          t	          j        |
                    d x}x}}d S )N
2026-07-01251.34USDr   closer   z
2026-06-30z249.00vtir   rC   zK%(py2)s
{%(py2)s = %(py0)s.close
} == %(py8)s
{%(py8)s = %(py4)s(%(py6)s)
}r7   r   rF   rL   rM   z7%(py2)s
{%(py2)s = %(py0)s.price_timestamp
} == %(py5)srG   rH   rP   rQ   rR   z!/stable/historical-price-eod/fullVTIz
2026-06-24)symbolfromto)z-%(py2)s
{%(py2)s = %(py0)s.calls
} == %(py5)sprovider)r   r   r   r   r_   r`   ra   rb   rc   rd   re   rf   price_timestampr   r   r7   rn   ro   rp   rq   rr   rs   ru   rw   rx   s              r   Ctest_fmp_historical_price_uses_exact_requested_date_without_profiler   Q   s   eDDeDD  H
 u>>E;+(+'(+++;+++++++++++;+++++++++++++5+++++5++++++;+++++++++++'+++++'++++++(++++++++++++++++++++++++++++++++++ 0L0 L0000000000 L0000000000005000005000000 0000L000000000000000000000000000> /l,GG	
 >      
   >      
    
     
      
    
              
             r   c                 N   t          ddddddddddddg          } |                     d	d
          }|j        }d}t          |          }||k    }|st	          j        d|fd||f          dt          j                    v st	          j        |          rt	          j	        |          ndt	          j	        |          dt          j                    v st	          j        t                    rt	          j	        t                    ndt	          j	        |          t	          j	        |          dz  }dd|iz  }t          t	          j        |                    d x}x}x}}|j        }d}||k    }|st	          j        d|fd||f          dt          j                    v st	          j        |          rt	          j	        |          ndt	          j	        |          t	          j	        |          dz  }	dd|	iz  }
t          t	          j        |
                    d x}x}}d S )Nz
2026-07-06999.00r   r   z
2026-07-03z250.00z
2026-06-26z240.00r   z
2026-07-05r   rC   r   r7   r   rF   rL   rM   r   r   rQ   rR   )r   r   r   r   r_   r`   ra   rb   rc   rd   re   rf   r   r   s              r   Otest_fmp_historical_price_uses_latest_prior_trading_day_and_rejects_future_rowsr   c   sy   eDDeDDeDD  H u>>E;+(+'(+++;+++++++++++;+++++++++++++5+++++5++++++;+++++++++++'+++++'++++++(++++++++++++++++++++++++++++++++++ 0L0 L0000000000 L0000000000005000005000000 0000L00000000000000000000000000000r   c                 8   t          ddddg          } t          ddddg          }t          g           }| ||fD ][}|                    dd	          }|j        }d }||u }|st          j        d
|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|j        }d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}|j        }d}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}}]d S )Nz
2026-07-02r   r   r   z
2026-06-23z200.00r   r   r   is)z-%(py2)s
{%(py2)s = %(py0)s.close
} is %(py5)sr7   r   rQ   rR   missingrC   )z6%(py2)s
{%(py2)s = %(py0)s.quality_status
} == %(py5)sprice_missing)z5%(py2)s
{%(py2)s = %(py0)s.error_message
} == %(py5)s)r   r   r   r_   r`   ra   rb   rc   rd   re   rf   quality_statuserror_message)
future_onlyoutside_boundaryemptyr   r7   rn   ru   rq   rw   rx   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{"d"{d""""""""""{d""""""""""""u"""""u""""""{""""d"""""""""""""""""""""""""""#0y0#y0000000000#y000000000000u00000u000000#0000y000000000000000000000000000"5o5"o5555555555"o555555555555u55555u555555"5555o5555555555555555555555555555	6 6r   c           	     j   t          d          }|                    d                                          d         }|                    d|f           |                    d|f           |                    d           |                                 t	          dd	d
g          }|                    dd          }|j        }d}||k    }|st          j        d|fd||f          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}|                    d|f                                          }
t          |
          }d}||k    }|st          j        d|fd||f          dt          j
                    v st          j        t                    rt          j        t                    nddt          j
                    v st          j        |
          rt          j        |
          ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}}t!          |dd|it#          ddi          | dz             }|j        }d}||u }|st          j        d!|fd"||f          d#t          j
                    v st          j        |          rt          j        |          nd#t          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}|j        }ddg}||k    }|st          j        d|fd$||f          d%t          j
                    v st          j        |          rt          j        |          nd%t          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}|j        }|j        }||k    }|st          j        d|fd&||f          d#t          j
                    v st          j        |          rt          j        |          nd#t          j        |          d#t          j
                    v st          j        |          rt          j        |          nd#t          j        |          d'z  }dd|iz  }t          t          j        |                    d x}x}}|                    d(                                          }g }|}|rd) |D             }d*h}||k    }|}|sd+d,d-t          j
                    v st          j        |          rt          j        |          nd-iz  }|                    |           |r`t          j        d|fd.||f          t          j        |          t          j        |          d/z  }d0d1|iz  }|                    |           t          j        |d          i z  }d2d3|iz  }t          t          j        |                    d x}x}x}x}}d S )4NF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_runsr   r   )r   r   	SYNTHETICr    rC   )z0%(py2)s
{%(py2)s = %(py0)s.currency
} == %(py5)sdirect_quoter   rQ   rR   zrSELECT provider,upper(COALESCE(trading_currency,currency,'')) FROM instrument_price_mappings WHERE instrument_id=?)mockr3   rY   rZ   mapping_stater\   r]   rK   r   )r3   r   z0.93market.lockas_ofprice_providersfx_provider	lock_pathr   )z2%(py2)s
{%(py2)s = %(py0)s.idempotent
} is %(py5)srE   )z;%(py2)s
{%(py2)s = %(py0)s.returned_currencies
} == %(py5)sr   )zU%(py2)s
{%(py2)s = %(py0)s.price_stored
} == %(py6)s
{%(py6)s = %(py4)s.price_total
})rG   rH   rI   rJ   z3SELECT currency,close,price_date FROM market_pricesc                ,    h | ]}t          |          S r   )rZ   ).0r[   s     r   	<setcomp>z]test_fmp_historical_price_without_currency_uses_confirmed_mapping_currency.<locals>.<setcomp>   s    000CU3ZZ000r   )r3   r   r   z%(py2)srH   rows)z%(py5)s == %(py8)s)rP   rK   z%(py10)srM   zassert %(py13)spy13)r   rj   rk   commitr   r   r   r_   r`   ra   rb   rc   rd   re   rf   rZ   r   r   
idempotentr   price_storedprice_totalfetchallrh   ri   )tmp_pathrm   keepr   r   rn   ru   rq   rw   rx   r   rv   ro   r|   rr   rE   r   rt   rp   @py_assert6@py_format3rs   @py_format12@py_format14s                           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& B&&&&&&&&&& B&&&&&&&&&&&&<&&&&&<&&&&&& &&&&B&&&&&&&&&&&&&&&&&&&&&&&&&&&LL|	  hjj  2?2?2222222222?22222222222252222252222222222222222222222222222?222222222222222222222222222'*-v677]*  F %%%%%%%%%%%%%%%%%%%%%%%%6%%%%%6%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'3B83'83333333333'83333333333338333338333333'333383333333333333333333333333334&"44"44444444444"4444444444444644444644444444444444444&44444&444444"4444444444444444444444444444<<MNNWWYYDUU4U4U004000U5T4UU04UUUUUUUUUUUUUUUUUU4UUUUU4UUUUUUUUUUUUUU4UUUUUUU04UUUUUU0UUUU4UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUr   c                   t          d          }|                    d           |                                 t          g           }t	          |dd|it          i           | dz            }t	          |dd|it          i           | dz            }|j        }d}||k    }|st          j        d	|fd
||f          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}d |j        D             }
dh}|
|k    }|slt          j        d	|fd|
|f          t          j        |
          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}
x}}g }|j        }d}||u }|}
|r|j        }|j        }||k    }|}
|
st          j        d|fd||f          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }	dd|	iz  }|                    |           |rt          j        d	|fd||f          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }|                    |           t          j        |d          i z  }d d!|iz  }t          t          j        |                    d x}
x}x}x}x}x}x}}|j        }d}||k    }|st          j        d	|fd
||f          dt          j
                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}}|                    d"                                          d         }
d}|
|k    }|slt          j        d	|fd|
|f          t          j        |
          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}
x}}d# |j        D             }t-          |          }|sd$d%t          j
                    v st          j        t,                    rt          j        t,                    nd%t          j        |          t          j        |          d&z  }t          t          j        |                    d x}}d S )'NFr   z3UPDATE instrument_price_mappings SET provider='fmp'r   fmpr   r   partialrC   )z.%(py2)s
{%(py2)s = %(py0)s.status
} == %(py5)sfirstr   rQ   rR   c                    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   z%(py1)s == %(py4)srN   rI   assert %(py6)srJ   r   )z2%(py4)s
{%(py4)s = %(py2)s.idempotent
} is %(py7)sreplay)rH   rI   rR   z%(py9)spy9)zP%(py13)s
{%(py13)s = %(py11)s.run_id
} == %(py17)s
{%(py17)s = %(py15)s.run_id
})rT   r   py15py17z%(py19)srW   r   zassert %(py22)spy22"SELECT COUNT(*) FROM market_pricesc              3  (   K   | ]\  }}|d k    V  dS )r   Nr   )r   r   _s      r   	<genexpr>zXtest_daily_orchestrator_reports_price_missing_and_rerun_is_idempotent.<locals>.<genexpr>   s,      GGWT1t((GGGGGGr   z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}all)rG   rH   rI   )r   rj   r   r   r   r   statusr_   r`   ra   rb   rc   rd   re   rf   missing_instrumentsr   run_idrh   ri   rk   r   r   )r   rm   r   r   r   rn   ru   rq   rw   rx   rt   rv   @py_format5r|   r   ro   r{   @py_assert16@py_assert14@py_format10r   r   @py_format21@py_format23s                           r   Etest_daily_orchestrator_reports_price_missing_and_rerun_is_idempotentr      s   5!!!DLLFGGGKKMMMR  H&)rFF]*  E ()rFF]*  F <$9$<9$$$$$$$$$$<9$$$$$$$$$$$$5$$$$$5$$$$$$<$$$$9$$$$$$$$$$$$$$$$$$$$$$$$$$$FFE,EFFF[?J[[FJ[[[[[[[[[[[FJ[[[[[[F[[[[J[[[[[[[[[[[[[[[[[[[[[[[[[[[[GG6GG%GGGGG&-G5<G-<*GGGGGGGGGGGGGGGGGGGGGGGG6GGGGG6GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG-<GGGGGGGGGGGG&GGGGG&GGGGGG-GGGGGGGGGGG5GGGGG5GGGGGG<GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG=%I%=I%%%%%%%%%%=I%%%%%%%%%%%%6%%%%%6%%%%%%=%%%%I%%%%%%%%%%%%%%%%%%%%%%%%%%%<<<==FFHHKPqPKqPPPPPPPPPPKqPPPPPKPPPPqPPPPPPPPPPPPPPPPPPPPPPPPPPPGGGGGG3GGGGGGGGGGGGGGGG3GGGGG3GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGr   c                d    G d d          }t          d          }t          |dd |            it          i           | dz             d	}d
}d}t          |||          }d	}d
}d}	t          |||	          }
t	          ||
          }d}||k     }|st          j        d|fd||f          dt          j                    v st          j	        t                    rt          j
        t                    nddt          j                    v st          j	        t                    rt          j
        t                    ndt          j
        |          t          j
        |          t          j
        |          t          j
        |          dt          j                    v st          j	        t                    rt          j
        t                    ndt          j
        |          t          j
        |          t          j
        |	          t          j
        |
          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}x}x}x}x}x}	x}
x}x}}|                    d                                          d         }d}||k    }|slt          j        d|fd||f          t          j
        |          t          j
        |          dz  }dd|iz  }t          t          j        |                    d x}x}}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   r   r   r   r   r   r   c               N    t          |dt          d          | j        d          S )Nr4   100z2026-07-02T20:00:00+00:00)r   r   r   r   r   )r   r   name)r   r   r   s      r   r   zUtest_daily_orchestrator_never_persists_future_price.<locals>.FutureProvider.get_price   s0    # /enn ;   r   r   )r*   r+   r,   r   r   r   r   r   FutureProviderr      s:        NR 	 	 	 	 	 	 	 	r   r   Fr   r   r   r   r   i           r   )<)z%(py20)s
{%(py20)s = %(py0)s(%(py9)s
{%(py9)s = %(py1)s(%(py3)s, %(py5)s, %(py7)s)
}, %(py18)s
{%(py18)s = %(py10)s(%(py12)s, %(py14)s, %(py16)s)
})
} < %(py23)sr
   r   )rG   rN   rO   rP   rR   r   rM   py12rU   rV   py18py20py23zassert %(py25)spy25r   rC   r   r   r   rJ   )r   r   r   r   r
   r_   r`   ra   rb   rc   rd   re   rf   rj   rk   )r   r   rm   rv   ru   r   @py_assert8@py_assert11rz   @py_assert15@py_assert17@py_assert19@py_assert22@py_assert21@py_format24@py_format26rt   rq   r   r|   s                       r   3test_daily_orchestrator_never_persists_future_pricer     s   
 
 
 
 
 
 
 
 5!!!D!1!12rFF]*    #'DD1DT$1--DDD!DQDtD!Q/?/?D-/?@@D1D@1DDDDDDDDDD@1DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDTDDDDDTDDDDDD$DDDDDDDD1DDDD-DDDDDDDDDDDtDDDDDtDDDDDDDDDDD!DDDDQDDDD/?DDDD@DDDD1DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD<<<==FFHHKPqPKqPPPPPPPPPPKqPPPPPKPPPPqPPPPPPPPPPPPPPPPPPPPPPPPPPPPPr   c                    t          |           t                       t                       t                       t	          | dz             t          | dz             t          | dz             d S )Nr   r   future)r   r   r   r   r   r   r  )r   rl   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   builtinsra   _pytest.assertion.rewrite	assertionrewriter_   __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   r   r   r   r   r   r   r   r  r  r   r   r   <module>r$     s   " " " " " "              5              = = = = = = : : : : : : 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   