
    hj                       d dl mZ d dlZd dlmZmZ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mZmZmZ  ed          ZdddZdddZdddZddZddZdddZi d d!d"d#d$d!d%d&d'd(d)d*d+d,d-d.d/d0d1d!d2d3d4d5d6d7d8d7d9d.d:d;d<d=d=d>d?d@dAdBdCZ ddEZ!ddHZ"ddIZ#ddMZ$ddNZ%ddQZ&ddRddUZ'dVdWdd[Z(dd]Z)dd`Z*ddeZ+ddVdfddiZ,dVdWddjZ-ddkZ.dldVdmddddnddtZ/dVdlduddvZ0dVdWddwZ1dVdlduddxZ2dVdlduddzZ3dVdWdd{Z4dVdWdd|Z5dVdWdd~Z6dVdWddZ7dVdWddZ8dVdWddZ9ddZ:dddZ;ddZ<ddZ=ddZ>ddZ?ddZ@ddZAdddZBddZCddZDdddZEdddZFddZGdddZHddZIdddZJddZKdddZLddZMddZNdddZOddZPdddZQddZRddZSddZTdddZUddZVdddZWddZXddZYddZZddZ[ddZ\dddZ]ddddZ^ddZ_dS )    )annotationsN)ROUND_HALF_UPDecimalInvalidOperation)Path)
Connection)Settings)calculate_crypto_holdings)Positioncalculate_positions)is_price_stale)latest_audited_market_values%latest_official_postfinance_positions)post_snapshot_postfinance_quantity_deltaspostfinance_account_roles0.010valueobjectdefaultstrreturnr   c                    | %t          |                                           dk    rt          |          S 	 t          t          |                     S # t          $ r t          |          cY S w xY wN )r   stripr   r   )r   r   s     /home/agent/.hermes/worktrees/FinanceManager-sprint16-smart-household-inbox-real-data-onboarding-v2/src/jarvis_finance/dashboard/data.pydr      sy    }E

((**b00w s5zz"""      w s   A A0/A0Decimal | int | str | Noneplaces
str | Nonec                    | dS t          |           } |r)|                     t          |          t                    } t	          | d          S )Nr   )roundingf)r   quantizer   r   format)r   r    s     r   dec_textr'      sK    }reHHE HwvGG%    Decimal | int | strc                t   t          | |          }|                    d          \  }}}|                    d          rdnd}|                    d          }g }|r)|                    |dd                     |d d         }|)|r"d                    t          |                    nd}| | |rd|z   nd S )N.-r   'r   )r'   	partition
startswithlstripappendjoinreversed)	r   r    textwhole_fracsigngroupsgroupeds	            r   grouped_numberr<   (   s    E6""D^^C((NE1d""3''/33RDLLEF
 eBCCj!!!crc
   -3;chhx''(((G;G;T9cDjjr;;;r(   c                .    | dS dt          |            S )Nnicht bewertetzCHF )r<   r   s    r   chf_textr@   5   s#    }).'')))r(   c                |    | sdS t          |           }d|v r|                    dd          d         S |d d         S )Nr   T   r   
   )r   split)r   raws     r   	date_textrG   ;   sI     r
e**C
czzyya  ##ss8Or(   CHFDecimal | Nonecurrencyc                    |                                 dk    rt          |           S | d| S t          | d           d| S )NrH   zn/a r    )upperr@   r'   )r   rJ   s     r   
money_textrN   D   sT    ~~5  } h   uf%%22222r(   missing_market_pricezPreis fehltmissing_provider_symbolzMapping fehltmissing_price
missing_fxFX-Kurs fehltcost_basis_uncertain   Einstand unvollständig
incompleteu   Unvollständigsnapshot_onlyzSnapshot-onlyfreshAktuellstaleVeraltetmissingunknown
   Ungeklärtmapped
Zugeordnet	confirmedu
   Bestätigtuser_confirmedokwarningHinweiscriticalKritischWichtigInfoAktivInaktivVerifiziert)kritischwarnunginfoactiveinactiveverifiedstatusc                    | sdS t                               t          |           t          |                               dd                                                    S )Nr^   r7   rL   )STATUS_LABELSgetr   replace
capitalizers   s    r   translate_statusrz   g   sM     |S[[#f++*=*=c3*G*G*R*R*T*TUUUr(   r5   boolc                r    | sdS |                                  g d}t          fd|D                       S )NF)z)productive initial crypto snapshot importzno wallet address from xlsxzinitial crypto snapshot importc              3      K   | ]}|v V  	d S N ).0markerlowereds     r   	<genexpr>z$is_technical_note.<locals>.<genexpr>r   s(      77Vv 777777r(   )lowerany)r5   markersr   s     @r   is_technical_noter   m   sK     ujjllG|||G7777w777777r(   c                ,    t          |           rdn| pdS r   )r   )r5   s    r   	user_noter   u   s    "4((:22tzr:r(   rowdict[str, str]	list[str]c                (    h dfd| D             S )N>   rule_idasset_idraw_json	dedup_key	entity_id	source_id	wallet_id
account_idfingerprinthedge_statusinstrument_idprovider_symbol_statusc                F    g | ]}|                     d           |v|S )r7   )r0   )r   khiddens     r   
<listcomp>z(visible_user_columns.<locals>.<listcomp>{   s/    HHH!!,,s"3"3HAr(   r   )r   r   s    @r   visible_user_columnsr   y   s1     }  }  }FHHHHsHHHHr(   c                0    | dS t          | d           dS )Nr   r   %r'   r?   s    r   percent_textr   ~   s%    }ruf%%((((r(   pricedict[str, str] | Nonec                8    | sdS |                      d          pdS )Nr\   quality_statusrv   )r   s    r   price_statusr      s'     y99%&&3)3r(   )rJ   connr   c                   |                      d|                                f                                          }|r|d         r|d         ndS )Nz
        SELECT COALESCE(MAX(provider_timestamp), MAX(fetched_at)) AS ts
        FROM crypto_prices WHERE price_currency=?
        tsr   )executerM   fetchone)r   rJ   r   s      r   _latest_price_timer      sX    
,,	 
		  hjj  1D	13t99r1r(   iQ price_max_age_secondsr   intlist[dict[str, object]]c               r  
 t          |           }g }t          |j                                                  D ]\  
}|                     d
f                                          }|s1t          | 
d|          }|r|d         rt          |d                   nd }|
|j        |z  nd }
fd|j	                                        D             }	|
                    
|d         |d         |d         pd	|j        ||t          |	          t          |          |r|d
         p|d         nd	d
           |S )N,SELECT * FROM crypto_assets WHERE asset_id=?rH   max_age_secondsr   c                B    h | ]\  \  }}}|k    |j         d k    |S r   quantity)r   widaidwhr   s       r   	<setcomp>z%_crypto_value_rows.<locals>.<setcomp>   s<    vvv>:CrQTX`Q`Q`egeptueueu3eueueur(   	coin_namesymbolcoingecko_idr   provider_timestamp
fetched_at)
r   coinr   r   r   r   r   wallet_countr   last_price_update)r
   sortedtotal_by_assetitemsr   r   latest_crypto_pricer   r   wallet_holdingsr2   lenr   )r   r   holdingsrowsholdingassetr   	price_decr   walletsr   s             @r   _crypto_value_rowsr      sn   (..H$&D#H$;$A$A$C$CDD  'Kh[YYbbdd 	#D(EK`aaa).K5>KAeGn%%%t	090E 9,,4vvvvX-E-K-K-M-Mvvv +&Ho!.17R(LL(//Y^!f%(<"="T|ATdf
 
 	 	 	 	 Kr(   list[dict[str, str]]c                    d | D             S )Nc                P    g | ]"fd                                  D             #S )c                P    i | ]"}||         dnt          |                   #S r   r   r   r   r   s     r   
<dictcomp>z'rowdicts.<locals>.<listcomp>.<dictcomp>   s1    LLLAQs1v~3s1v;;LLLr(   )keysr   r   s    @r   r   zrowdicts.<locals>.<listcomp>   s7    ]]]QTLLLLLLL]]]r(   r   )r   s    r   rowdictsr      s    ]]X\]]]]r(   path
str | Pathc                h    t          |                                                                           S r~   )r   
expanduserexists)r   s    r   	db_existsr      s&    ::  ""))+++r(   settingsr	   	repo_rootr   c                    	 | j         j                                                            |                                           dS # t          $ r Y dS w xY w)NFT)runtime_pathsbase_dirresolverelative_to
ValueError)r   r   s     r   runtime_outside_repor      s`    '//11==i>O>O>Q>QRRRu   tts   AA 
AAr   r   r   c               V   |                      d||                                f                                          }|sd S t          |          }|                    d          p|                    d          }|                    d          dk    rt          ||          rd|d<   |S )Na  
        SELECT price, price_currency, fetched_at, provider_timestamp, quality_status, provider
        FROM crypto_prices
        WHERE asset_id=? AND price_currency=?
        ORDER BY COALESCE(provider_timestamp, fetched_at, '') DESC, fetched_at DESC LIMIT 1
        r   r   r   rX   r   rZ   )r   rM   r   dictrv   r   )r   r   rJ   r   r   itemr   s          r   r   r      s    
,,	 
8>>##$  hjj   t99D	&	'	'	A488L+A+ABxx !!W,,Tc1d1d1d,!(Kr(   c          
        t          | |          }t          |           }t          d |D             t          d                    }t          d |D                       }t          d |D                       }d |j                                        D             }|dk    r|dk    rdn|s|rd	nd}t          |          t          t          |                    t          t          |                    t          t          d
 |j        	                                D                                 t          |          t          |          t          |           |dS )Nr   c              3  6   K   | ]}|d          
|d          V  dS r   Nr   r   rs     r   r   z+get_crypto_summary_cards.<locals>.<genexpr>   s/      JJa1W:3Iqz3I3I3I3IJJr(   r   c              3  2   K   | ]}|d          dk    dV  dS )r   r\   rC   Nr   r   s     r   r   z+get_crypto_summary_cards.<locals>.<genexpr>   s1      DDQ~%6)%C%C!%C%C%C%CDDr(   c              3  2   K   | ]}|d          dk    dV  dS )r   rZ   rC   Nr   r   s     r   r   z+get_crypto_summary_cards.<locals>.<genexpr>   s1      @@a1^#4#?#?#?#?#?#?@@r(   c                4    h | ]\  \  }}}|j         d k    |S r   r   )r   r   _aidr   s       r   r   z+get_crypto_summary_cards.<locals>.<setcomp>   s0    www%9[c4'ahaquvavavSavavavr(   r   rc   rd   c              3  0   K   | ]}|j         d k    dV  dS )r   rC   Nr   )r   hs     r   r   z+get_crypto_summary_cards.<locals>.<genexpr>   s1       a aqQRQ[_`Q`Q`Q`Q`Q`Q` a ar(   )total_value_chf
coin_countwallets_with_holdingsholding_countcoins_without_pricestale_price_countlast_price_update_atdata_quality_status)r   r
   sumr   r   r   r'   r   r   valuesr   )	r   r   r   r   total_valuer\   rZ   r   rs   s	            r   get_crypto_summary_cardsr     sX   d:OPPPD(..HJJ4JJJGTWLLYYKDDTDDDDDG@@4@@@@@EwwX=U=[=[=]=]www\\eqjjTTG7^u7^yyZ^F#K00#d))nn!$S)>%?%?!@!@S a aH,D,K,K,M,M a a aaabb"7|| ZZ 24 8 8%	 	 	r(   c                4   t          |           }g }|j                                        D ]_\  \  }}}||k    rQ|j        dk    rF|                     d|f                                          }|r|                    |d                    `t          |          S )Nr   8SELECT wallet_name FROM crypto_wallets WHERE wallet_id=?wallet_name)r
   r   r   r   r   r   r2   r   )r   r   r   namesr   r   r   r   s           r   _wallet_names_for_assetr     s    (..HE%-%=%C%C%E%E 1 1!C'(??w/144,,Y\e[ghhqqssC 1S/000%==r(   FWert absteigend)
admin_moder   sort_bysearchstatus_filterwallet_filterr  r  r  r  r  c               ~   t          | |          }t          d |D             t          d                    }g }	t          |d d          D ]}
|
d         }||r||z  t          d          z  nd }t	          |
d	                   t	          |
d
                   t          |
d                   |
d         t          |
d                   nd|t          |          ndt          |          t	          |
d                   t          t	          |
d                             t          |pt          d          d          t          t	          |
d                             t	          |
d                   d
                    t          | t	          |
d                                       d}|rf|                    t	          |
d                   t	          |
d                   t	          |
d                   t	          |
d                   d           |	                    |           |r"|                                fd|	D             }	rdk    rfd|	D             }	rdk    rfd|	D             }	d d d d d d  d!}|d"v }t          |	|                    ||d#                   |          S )$Nr   c              3  6   K   | ]}|d          
|d          V  dS r   r   r   s     r   r   z*get_crypto_coin_summary.<locals>.<genexpr>   s/      CCAgJ,B7,B,B,B,BCCr(   r   c                0    | d         pt          d          S Nr   z-1r   r   s    r   <lambda>z)get_crypto_coin_summary.<locals>.<lambda>   s    $w-*H74== r(   Tkeyreverser   100r   r   r   r   r>   r   r   r   r   r   z | )r   r   gesamtmengekurs_chfgesamtwert_chfanteilr   rs   _sort_value_chf_last_price_update	_asset_id_wallet_namesr   )r   r   r   r   c                    g | ]<}|d                                           v s|d                                          v :|=S )r   r   r   )r   r   needles     r   r   z+get_crypto_coin_summary.<locals>.<listcomp>  sP    fffsVs6{/@/@/B/B%B%BfPST\P]PcPcPePeFeFesFeFeFer(   Allec                ,    g | ]}|d          k    |S ry   r   )r   r   r  s     r   r   z+get_crypto_coin_summary.<locals>.<listcomp>  s'    DDDsS]m%C%Cs%C%C%Cr(   c                D    g | ]}|                     d d          v |S )r$  r   r   )r   r   r  s     r   r   z+get_crypto_coin_summary.<locals>.<listcomp>  s1    SSSs]cggor6R6R%R%Rs%R%R%Rr(   c                <    t          | d                   | d         fS Nr!  r   r   r   s    r   r  z)get_crypto_coin_summary.<locals>.<lambda>  s    #.?*@(A(A3v;'O r(   c                <    t          | d                   | d         fS r,  r-  r.  s    r   r  z)get_crypto_coin_summary.<locals>.<lambda>  s    3/@+A)B)BCK(P r(   c                6    | d                                          S )Nr   r&  r.  s    r   r  z)get_crypto_coin_summary.<locals>.<lambda>  s    #f+"3"3"5"5 r(   c                d    t          | d                             dd                    | d         fS )Nr   r   r   r   )r   rw   r.  s    r   r  z)get_crypto_coin_summary.<locals>.<lambda>  s+    qX!6!6sB!?!?@@#f+N r(   c                <    t          | d                   | d         fS )Nr   r   r   r.  s    r   r  z)get_crypto_coin_summary.<locals>.<lambda>  s    c#i.&9&93v;%G r(   c                "    | d         | d         fS )Nrs   r   r   r.  s    r   r  z)get_crypto_coin_summary.<locals>.<lambda>  s    s8}c&k: r(   )r  zWert aufsteigendu
   Name A–ZAnteilWallet-AnzahlStatus>   r5  r6  r  r  )r   r  r   r   r   r'   r@   r   rz   rG   r3   r  updater2   r   rv   )r   r  r   r  r  r  r  rF   totaloutr   r   sharer   sortersr  r'  s        ``         @r   get_crypto_coin_summaryr=     s0    T9N
O
O
OCCCSCCCWS\\RRE "CCHHRVWWW  '
6;6GE6G%%-75>>11W[&	NN!H+&&#AjM2201'
0F7,,,L\161BhuoooHX"5))1^,--&s1^+<'='=>>'(=vFF"+C2E0F,G,G"H"HQz]++"ZZ(?c!J-FXFX(Y(YZZ
 
  	|KKS:%7%7Q~M^I_I_qtuv  xF  vG  rH  rH  _b  cd  ex  cy  _z  _z  {  {  |  |  |

4 gffffcfff E&00DDDDcDDD T&00SSSScSSSOOPP55NNGG:: G GGG#7;;w8I0JKKU\]]]]r(   r   r  c                  t          |           }t          | d|          }|r|d         rt          |d                   nd }t          fd|j                                        D             t          d                    }g }t          |j                                                  D ]3\  \  }	}
}|
k    s|j        dk    r| 	                    d|	f          
                                }|
|j        |z  nd }|r|j        |z  t          d          z  nd }|r|d	         n|	|r|d
         ndt          |j                  |t          |          ndt          |          t          |j                  t!          |j                  t%          |r|d         r|d         nd          |	d
}|r|                    |	d           |                    |           5|S )NrH   r   r   c              3  >   K   | ]\  \  }}}|k    |j         V  d S r~   r   )r   r   r   r   r   s       r   r   z1get_crypto_coin_wallet_details.<locals>.<genexpr>)  s9      iiMJS#Y\`hYhYhQZYhYhYhYhiir(   r   r   z_SELECT wallet_name, wallet_type, platform_provider, notes FROM crypto_wallets WHERE wallet_id=?r  r	  wallet_typer   r>   notes)
wallettypmengewert_chfr   letzte_verifikationrs   notiz
_wallet_idr#  )r   r   )r
   r   r   r  r   r   r   r   r   r   r   r'   r@   r   rG   last_verified_atrz   verification_statusr   r8  r2   )r   r   r   r  r   r   r   	total_qtyr   r   r   r   rC  r   r;  r   s    `              r   get_crypto_coin_wallet_detailsrM  %  s-   (..HhG\]]]E%*GuW~G%.!!!4IiiiiX5M5S5S5U5UiiikrsvkwkwxxI!#D%+H,D,J,J,L,L%M%M  !C'(??g.!33  CL  BN  O  O  X  X  Z  Z090E 9,,4CLV!I->>RV/5Df]++9,2:6-((g.//+0+<BR"5))#,W-E#F#F&w'BCC&TVG_TvgRTUU#!
 
  	HKKiXFFGGGDKr(   c                  t          | |          }t          d |D             t          d                    }t          d |D                       }t          t	          |                    t          |          t          |          dS )Nr   c              3  @   K   | ]}t          |d                    V  dS )_numeric_value_chfNr-  r   s     r   r   z,get_wallet_overview_cards.<locals>.<genexpr>E  s0      @@aq/011@@@@@@r(   r   c              3  D   K   | ]}|                     d           dV  dS )rJ  rC   Nr   r   s     r   r   z,get_wallet_overview_cards.<locals>.<genexpr>F  s4      PPQaee<N6O6OPqPPPPPPr(   )r   r   wallets_missing_verification)get_wallet_user_overviewr  r   r   r   r'   )r   r   r   r  missing_verifications        r   get_wallet_overview_cardsrU  C  s    #D@UVVVD@@4@@@'#,,OOKPP$PPPPPD		NNx?T?Tvy  {O  wP  wP  Q  Q  Qr(   c                  t          |           }g }|                     d                                          D ]}t          d          }d}t	                      }|j                                        D ]\  \  }	}
}|	|d         k    s|j        dk    r |                    |
           t          | |
d|          }|r6|
                    d          r!||j        t          |d                   z  z  }d	}|d
         |d         |d         pd|st          |          nt          |           dt          t          |                    t          |d                   t!          t#          |d         pd          rdnd          dt%          |d          |d         d
}|r|d         |d<   |                    |           |S )Nz1SELECT * FROM crypto_wallets ORDER BY wallet_namer   Fr   r   rH   r   r   Tr	  rA  platform_providerr   z + unbewertetrJ  	is_activerp   rq   u6   Öffnen · Coin hinzufügen · Korrigieren · Transferr   )
r	  rA  providerr   r   rJ  rs   actionsrP  rI  )r
   r   fetchallr   setr   r   r   addr   rv   r   r@   r   r   rG   rz   r   r'   r2   )r   r   r  r   r   rC  r   has_missing_pricecoinsr   r   r   r   r   s                 r   rS  rS  J  s   (..H!#D,,RSS\\^^  !%%.6.F.L.L.N.N 	) 	)*!Y7F;///73Cq3H3HIIh'hOdeeeE )7++ ))AeGn,=,===$(!!!-0!-0239r6GnxPXY^P_P_MnMnMnc%jj// )&1C*D E E&3vk7J7Oa3P3P'`xxV`aaO"*5&"9"9 -
 
  	4 &{ 3DDKr(   r   c          
        t          |           }g }t          |j                                                  D ]\  \  }}}||k    s|j        dk    r|                     d|f                                          }	t          | |d|          }
|
r|
d         rt          |
d                   nd }|
|j        |z  nd }|	r|	d         n||	r|	d         ndt          |j                  |t          |          nd	t          t          |
                    d
||d}|r|                    ||d           |                    |           |S )Nr   <SELECT coin_name, symbol FROM crypto_assets WHERE asset_id=?rH   r   r   r   r   r   r>   u<   Bestand korrigieren · Transfer aus Wallet · Audit anzeigen)r   r   rE  rF  rs   rZ  r#  rI  )r   r   )r
   r   r   r   r   r   r   r   r   r'   r@   rz   r   r8  r2   )r   r   r   r  r   r   r   r   r   r   r   r   r   r   s                 r   get_wallet_coin_detailsrb  l  s~   (..H!#D$*8+C+I+I+K+K$L$L   h)w/144[^f]hiirrtt#D(EK`aaa).K5>KAeGn%%%t	090E 9,,4*/=E+&&X).6eHooBg.//+0+<BR&|E':':;;U!#	
 	
  	HKKXIFFGGGDKr(   c                   t          | |          }g }t          |d d          D ]I}|d         ?|                    t          |d                   t	          |d         d          d           J|S )	Nr   c                0    | d         pt          d          S r  r  r  s    r   r  z2get_crypto_coin_allocation_chart.<locals>.<lambda>  s    4=+IGDMM r(   Tr  r   r   r   label	value_chf)r   r   r2   r   r'   )r   r   r   r:  r   s        r    get_crypto_coin_allocation_chartrh    s    d:OPPPD
CDIISWXXX ] ]W:!JJQvYhqzSY>Z>Z[[\\\Jr(   c                   t          | |          }g }|D ]I}|d         }t          |          dk    r,|                    |d         t          |d          d           Jt	          |d d	          S )
Nr   rP  r   r	  r   re  c                ,    t          | d                   S Nrg  r-  r  s    r   r  z4get_crypto_wallet_allocation_chart.<locals>.<lambda>  s    ${*;(<(< r(   Tr  )rS  r   r2   r'   r   )r   r   r   r:  r   r   s         r   "get_crypto_wallet_allocation_chartrl    s    #D@UVVVD
C \ \()U88a<<JJ]!3(5RXBYBYZZ[[[#<<dKKKKr(   dict[str, object]c               z   t          fdt          | |          D             d           }|si S t          d t          | |          D             t          d                    }|d         }||r||z  t          d          z  nd }t	          | d|          }t          |d	                   t          |d
                   t          |d                   |t          |          nd|d         t          |d                   ndt          |          t          t          |d                             t          t          |d                             |r$t          |                    d          pd          nd|rdnd|                    d          rd|d          ndt          | |          g ddS )Nc              3  4   K   | ]}|d          k    |V  dS )r   Nr   )r   r   r   s     r   r   z)get_crypto_coin_detail.<locals>.<genexpr>  s5      ~~adefpdqu}d}d}d}d}d}d}~~r(   r   c              3  6   K   | ]}|d          
|d          V  dS r   r   r   s     r   r   z)get_crypto_coin_detail.<locals>.<genexpr>  sR        J  JArst{r|  sIQwZ  sI  sI  sI  sI  J  Jr(   r   r   r  rH   r   r   r   r   r>   r   r   r   rY  	unbekanntzlokaler Cachezkein lokaler Preisr   z#https://www.coingecko.com/en/coins/r   )u   Bestand hinzufügenBestand korrigierenTransferzBestand auf 0 setzenzAudit / Verlauf anzeigen)r   r   r  r  r  r   preisstatusletzte_preisaktualisierungpreisquellecache_statuscoingecko_linkr   rZ  )nextr   r  r   r   r   r'   r@   r   rz   rG   rv   rM  )r   r   r   r   	all_valuer   r;  latest_prices    `      r   get_crypto_coin_detailr|    s   
~~~~-dJ_```~~~  AE  F  FC 	  J  J);DXm)n)n)n  J  J  J  LS  TW  LX  LX  Y  YILE494E)4EUY//Y]E&tXuNcdddLCK  c(m$$J00-2->(5///DT.1'l.FHS\***L\u%%'C,?(@(@AA&/C8K4L0M0M&N&NKWhs<++J77F;GGG]h+7Q=QY\Y`Y`aoYpYpxUN@SUUUvx1$Xmnnn B  B  B  r(   c               *   t          fdt          | |d          D             d           }|si S |d         |d         |d         |d         t          | |          |d	         t          |                    d
d                    |d         g dd	S )Nc              3  N   K   | ]}|                     d           k    |V   dS )r   Nr   )r   wr   s     r   r   z$get_wallet_detail.<locals>.<genexpr>  sz        _  _~  D  D  EP  Q  Q  U^  ^  ^1  ^  ^  ^  ^  _  _r(   Tr>  r	  rA  rY  r   r   rJ  rB  r   rs   )u   Coin in Wallet hinzufügenrr  zTransfer aus WalletzWallet verifizierenzWallet bearbeitenzWallet deaktivieren)	r	  rD  rY  r  r_  rG  notizenrs   rZ  )ry  rS  rb  r   rv   )r   r   r   rC  s    `  r   get_wallet_detailr    s      _  _  _  _6tShuyzzz  _  _  _  ae  f  fF 	m,m$:& !23(yPefff%&89VZZ4455" c  c  c
 
 
r(   c               P   t          |           }g }t          |j                                                  D ]\  }}|j        }|                     d|f                                          }|s8t          | |d|          }|r|d         rt          |d                   nd }	|	||	z  nd }
|	                    ||d         |d         |d         pdt          |          |	t          |	d	          nd|
t          |
d	          nd|r|d
         nd|r|d         ndd	           |S )Nr   rH   r   r   r   r   r   r   r   r   r\   r   )	r   r   r   r   r   latest_price_chfmarket_value_chfprice_qualityr   )r
   r   r   r   r   r   r   r   r   r2   r'   )r   r   r   r   r   r   qtyr   r   r   r   s              r   get_crypto_overviewr    sj   (..H!#D#H$;$A$A$C$CDD  'Kh[YYbbdd 	#D(EK`aaa).K5>KAeGn%%%t	#,#8id {+Ho!.17R ?H?TF ; ; ;Z\;@;L 7 7 7RT8=LU#344916>%--B

 

 
	 
	 
	 
	 Kr(   c                  t          |           }g }t          |j                                                  D ]S\  \  }}}|                     d|f                                          }|                     d|f                                          }t          | |d|          }	|	r|	d         rt          |	d                   nd }
|

|j        |
z  nd }|	                    ||r|d         n||r|d         nd|r|d	         nd|r|d
         n||r|d         nd|r|d         ndt          |j                  |t          |d          nd|t          |d          nd|	r|	d         nd|	r|	d         nd|j        |j        pdd           U|S )NzXSELECT wallet_name, wallet_type, platform_provider FROM crypto_wallets WHERE wallet_id=?zJSELECT coin_name, symbol, coingecko_id FROM crypto_assets WHERE asset_id=?rH   r   r   r	  rA  r   rW  r   r   r   r   r   r\   r   )r   r	  rA  rY  r   r   r   r   r  wallet_value_chfr  price_fetched_atrK  rJ  )r
   r   r   r   r   r   r   r   r   r2   r'   rK  rJ  )r   r   r   r   r   r   r   rC  r   r   r   r   s               r   get_crypto_by_walletr    s   (..H!#D*01I1O1O1Q1Q*R*R  &Hwx  |E  {G  H  H  Q  Q  S  Siltkvww  A  A  C  C#D(EK`aaa).K5>KAeGn%%%t	090E 9,,4"4:I6-00	4:B6-007=E2332/4B{++().6eHooB5:BE.11 !122;@;L 7 7 7RT;@;L 7 7 7RT8=LU#34497< Dl 3 3"#*#> ' 8 >B
 
 	 	 	 	  Kr(   c                j    t          |                     d                                                    S )Nz
        SELECT wallet_id, wallet_name, wallet_type, platform_provider AS provider,
               network_chain, last_verified_at, is_active, notes
        FROM crypto_wallets ORDER BY wallet_name
        r   r   r[  r   s    r   get_walletsr    s4    DLL	  hjj  r(      limitc                n    t          |                     d|f                                                    S )NaF  
        SELECT ct.transaction_datetime, ct.transaction_type, ca.symbol, ct.quantity, ct.fee_quantity,
               fw.wallet_name AS from_wallet, tw.wallet_name AS to_wallet, ct.currency_original,
               ct.amount_chf, ct.confirmation_status, ct.source
        FROM crypto_transactions ct
        LEFT JOIN crypto_assets ca ON ca.asset_id=ct.asset_id
        LEFT JOIN crypto_wallets fw ON fw.wallet_id=ct.from_wallet_id
        LEFT JOIN crypto_wallets tw ON tw.wallet_id=ct.to_wallet_id
        ORDER BY ct.transaction_datetime DESC, ct.created_at DESC LIMIT ?
        r  r   r  s     r   get_latest_crypto_transactionsr    s;    DLL		 X  hjj  r(   c                j    t          |                     d                                                    S )Na  
        SELECT p.name AS platform, p.platform_type, a.account_name, a.account_type, a.currency,
               a.performance_included, a.is_active
        FROM accounts a JOIN platforms p ON p.platform_id=a.platform_id
        ORDER BY p.name, a.account_name
        r  r  s    r   get_platform_overviewr    4    DLL	  hjj  r(   c                8    ddl m} d  ||           D             S )Nr   )list_cash_positionsc           
     x    g | ]7}|j         |j        |j        |j        |j        |j        |j        d k    rdndd8S )zAbgleich offenrc   partial)r   platformaccount_namerJ   amount_original
amount_chfr   )r   r  account_labelrJ   amountused_value_chfrs   )r   positions     r   r   z%get_cash_overview.<locals>.<listcomp>!  sh         #- )$2 )'"1&.o9I&I&Iddy	
 	
  r(   )$jarvis_finance.services.cash_servicer  )r   r  s     r   get_cash_overviewr    sE     IHHHHH  ,+D11   r(   c                   t          | d          }t          |           }t          | |          }t          |           }t	          |           }|                    d          }d |D             }t          |j                  D ]2}|d         |k    r$|d         |v r|j                            |           3|	                                D ]9\  }}	|j        
                    |t          |	j        |	j                             :g }
t          |j        	                                          D ]4\  \  }}}|                     d||f                                          }|                    ||f          }	|	r+|	j        |                    |t%          d	                    z   n|j        }|	r|dk    r|                    ||f          }t'          |o|	 p|j        |	j        k              }|	rF|sD|}|	j        }|	j        r|	j        |z  |	j        z  nt%          d	          }|	j        }|	j        }d
}d}n|rC|rA|}|j        }|j        r|j        |z  |j        z  n|j        }|j        }|j        }|j        }d}nH|j        }|j        }|j        }|r|d         nd}t=          |r|d         nd          }|r|d         nd}d}|
                    i d|d|d|r|d         ndd|r|d         n|d|r|d         ndd|r|d         n|d|r|d         ndd|r|d         nddtA          |          dtA          |j!        d          d|tA          |d          ndd|d|d |d!|tA          |d          ndd"|d#nd$d%|||                     d&|f                                          rd'nd(|r|d)         n|j"        |r|d*         n|j#        |r|d+         n|j$        d,|j%        vrd#nd,|d#nd$|j&        |r|d-         n|j'        |j(        |j)        tA          |j)        d          nd|j)        d.nd/d0*                    |j%                  |j+        d1           6|
S )2NF)persist_alertsetrading_cashc                    h | ]
}|d          S )rC   r   )r   r  s     r   r   z get_positions.<locals>.<setcomp>6  s    777sCF777r(   r   rC   )r   r   aT  
            SELECT a.account_name, p.name AS platform, i.name, i.ticker, i.isin, i.asset_class, i.currency,
                   i.hedge_status, i.instrument_status, i.valuation_policy, i.corporate_action_status,
                   mp.close AS latest_price, mp.currency AS latest_price_currency, mp.price_date AS latest_price_date,
                   mp.provider AS latest_price_provider
            FROM accounts a JOIN platforms p ON p.platform_id=a.platform_id
            JOIN instruments i ON i.instrument_id=?
            LEFT JOIN market_prices mp ON mp.market_price_id = (
                SELECT market_price_id FROM market_prices
                WHERE instrument_id=i.instrument_id AND quality_status IN ('fresh','ok')
                ORDER BY price_date DESC, created_at DESC LIMIT 1
            )
            WHERE a.account_id=?
            r   zPostFinance official snapshotpostfinance_official_importaudited_market_runlatest_price_currencyr   latest_price_datelatest_price_providercanonical_ledger_marketr   r   r  r  asset_classnametickerisinr   cost_basis_chfr   market_price_originalprice_currency
price_dateprice_providerr  r   rc   rO   valuation_sourcezSELECT 1 FROM instrument_price_mappings WHERE instrument_id=? AND mapping_status IN ('mapped','confirmed','user_confirmed') AND provider_symbol IS NOT NULL LIMIT 1r_   rP   r   instrument_statusvaluation_policyrR   corporate_action_statuscompleterV   ,)valuation_as_ofr   r   r  r  	fx_statusmarket_price_statusvaluation_timestamp_statusr  valuation_statustotal_return_chftotal_return_statusquality_warningsr  ),r   r   r   r   r   rv   list	positionspopr   
setdefaultr   r   r   r   r   r   r   r   r{   as_ofsnapshot_dater  r  r  valuation_atcloserg  rJ   rY  rG   r2   r'   r  r   r  r  r  r  r  r  r  r3   r  )r   resultofficialpost_snapshot_deltasauditedrolestrading_cash_idofficial_instrumentsr  overrider   r   r   posr   effective_quantitymarket_valueuse_market_runr   market_pricer  r  r  r  r  s                            r   get_positionsr  /  s+    e<<<F4T::HDT8TT*400G%d++Eii00O77h777F$%% & &q6_$$Q3G)G)G   %%%!)) 
 
X##X%8H^___	
 	
 	
 	
 "$D,263C3I3I3K3K,L,L _ _(#]Sll J'
 
  (**! 	" <<] ;<< H 4 8 8PS U UUU 	
  	*a//{{J#>?? NL!3h6L!L
 
  	9N 	9)H#9L $"),>>ARRRS\\ 
 &4N!.J<N< 	9 	9)H'-L  (,&);;l>SSS!+ 
 *2N%+J)2N3|H4L"3=@HS!899bN"s#J3':#;#;KKJ=@HS!899bN8  
* 
] 
 36JB 
 3FC//J	 

 <3}--" 
 39CKKM 
 s2c(mm 
 3.CKKB 
 ** 
 hs'96BB 
 $|G_XlF%C%C%Ceg 
 n 
 * 
 n 
 FVFb)96 B B Bhj 
  L$<DDBX! 
"  0# 
$  *26,,  @e  hu  gw  3x  3x  3A  3A  3C  3C  'bhh  Ib36LC//C<L=@![%8!9!9cF[;> X$6 7 7CDX!-S5I!I!I|+7+C44I_*-*HIL'ms+D'E'ERURm # 4JMJ^Jj)=v F F Fpr141E1Q::Wc #)= > >#&#:? 
  
  
  	  	  	  	B Kr(   c                   g }t          |           D ]}|                    dd                                          dvr.|                    |                    dd          |                    dd          |                    dd          |                    dd          |                    dd                                          dk    rd	nd
|                    dd          |                    d          pd|                    dd          |                    d          r"t	          |                    d                    nd|                    d          r"t	          |                    d                    nd|                    d          r"t	          |                    d                    ndt          |                    d          p|                    d                    d           |S )Nr  r   >   etfstockequityr  r  r  r  r  ETFAktier   r  u   Preis noch nicht verfügbarr  r  r>   r  u   unvollständigr  znicht berechenbarr   r  )r  r  r  depotassettyprE  kurskurswaehrungmarktwert_chfeinstand_chfp_l_chfrs   )r  rv   r   r2   r@   rz   )r   r   r   s      r   get_portfolio_positions_userr    s   !#DT""  77="%%++--5OOOGGFB''ggh++GGFB''WW^R00!$!;!;!A!A!C!Cu!L!LRYWWZ,,GG344U8UGG$4b99FIggN`FaFawXcgg.@&A&ABBBgwCF77K[C\C\rHSWW-=%>%>???br@CHZ@[@[tx(: ; ;<<<at&sww~'>'>'`#''J_B`B`aa
 
 	 	 	 	 Kr(   c                `    t          |           }d|d         dd|d         dd|d         dgS )NCryptocrypto_total_chfre  z
Aktien/ETFequity_etf_total_chfCashcash_total_chf)get_command_center_summary)r   summarys     r   get_portfolio_asset_class_chartr    sL    (..G1C)DEEW5K-LMMw/?'@AA r(   c                   i }t          |           D ]W}|                    |d         t          d                    t          |                    d                    z   ||d         <   Xt	          |           D ]W}|                    |d         t          d                    t          |                    d                    z   ||d         <   Xt          t          |           d                   }|r)|                    dt          d                    |z   |d<   d t          |                                d d	
          D             S )Nr  r   r  r  r   zCrypto Walletsc                :    g | ]\  }}|t          |d           dS )r   re  r   r   r   vs      r   r   z,get_platform_value_chart.<locals>.<listcomp>  s@      G  G  Gtq!ahq&&9&9::  G  G  Gr(   c                    | d         S )NrC   r   r  s    r   r  z*get_platform_value_chart.<locals>.<lambda>  s    ostuov r(   Tr  )r  rv   r   r   r  r  r   r   )r   totalsr   crypto_totals       r   get_platform_value_chartr    sb   !#F && g g"(**S_gcll"K"KaPSPWPWXdPePeNfNf"fs:T"" m m"(**S_gcll"K"KaPSPWPWXjPkPkNlNl"ls:-d334EFGGL ]#)::.>#M#MP\#\  G  Gvfllnnbvbv  AE  HF  HF  HF  G  G  G  Gr(      c                n    t          |                     d|f                                                    S )NaJ  
        SELECT t.trade_date, p.name AS platform, a.account_name, t.transaction_type,
               i.name AS instrument, i.ticker, t.quantity, t.gross_amount_original,
               t.net_amount_original, t.currency_original, t.fx_status, t.quality_status,
               t.source_type, t.source_id
        FROM transactions t
        LEFT JOIN accounts a ON a.account_id=t.account_id
        LEFT JOIN platforms p ON p.platform_id=a.platform_id
        LEFT JOIN instruments i ON i.instrument_id=t.instrument_id
        ORDER BY t.trade_date DESC, t.created_at DESC LIMIT ?
        r  r  s     r   get_ledger_transactionsr    s;    DLL
	 X  hjj  r(   c                j    t          |                     d                                                    S )NzSELECT name, asset_class, reason, status, target_entry_price, target_entry_currency, investment_case, bear_case, next_review_date FROM watchlist ORDER BY namer  r  s    r   get_watchlistr     sG    DLL  "B  C  C  L  L  N  N  O  O  Or(   entity_typer   c                   |s|pdS |dk    s"t          |                              d          rQ|                     d|f                                          }|r$|d         r|d          d|d          dn|d         S d	S |d
k    r?|                     d|f                                          }|r|d          d|d          dS |dk    r3|                     d|f                                          }|r|d         S |pdS )N	Portfolio
instrumentinstrument-z:SELECT name, ticker FROM instruments WHERE instrument_id=?r  r  z ()zUnbekanntes Instrumentcrypto_assetra  r   r   crypto_walletr  r	  )r   r0   r   r   )r   r  r   r   s       r   resolve_alert_entity_labelr	    sB    *)k)l""c)nn&?&?&N&N"llWZcYeffooqq 	X9<XWc&k55S]5555CPVKW''n$$llY\e[ghhqqss 	;+&::#h-::::o%%llUXaWcddmmoo 	&}%%%+%r(   r   r   messageentityc                |    ddddddddd	d
ddd}|                     | t          |                     }|r| d| n|S )NrS   zFX-Kurs veraltetzMarktpreis fehltzMarktpreis veraltetzMarktdaten-Zuordnung fehltu   Manueller FX-Kurs nötigzHistorischer FX-Kurs fehltu   Mapping muss geprüft werdenrU   zNur Snapshot-Historie vorhandenzCrypto-Preis fehlt)rR   stale_fxrO   stale_market_pricerP   manual_fx_override_requiredhistorical_fx_unavailablecandidate_review_requiredrT   rW   missing_crypto_pricecrypto_price_missingu    für )rv   rz   )r   r
  r  labelstitles        r   alert_titler    sn    %& 23#?'A%A%C 9: 4 4 F JJw 0 9 9::E'-8e##6###58r(   c           	     t    ddddddddd	}|                     | |r|                    d
d          nd          S )NuI   Ein historischer FX-Kurs fehlt. CHF-Performance ist daher unvollständig.z8Ein FX-Kurs ist veraltet und sollte aktualisiert werden.uR   Für diese Position fehlt ein lokaler Marktpreis. Bewertung bleibt unvollständig.uA   Der lokale Marktpreis ist veraltet. Bitte Preisupdate ausführen.uO   Für diese Position fehlt oder fehlt noch die bestätigte Marktdaten-Zuordnung.uE   Es gibt Marktdaten-Kandidaten, die manuell bestätigt werden müssen.u9   Die Kaufhistorie oder Einstandsdaten sind unvollständig.zLDiese Position basiert auf einem Snapshot und nicht auf kompletter Historie.)rR   r  rO   r  rP   r  rT   rW   r7   rL   u    Bitte im Review-Bereich prüfen.)rv   rw   )r   r
  descriptionss      r   alert_descriptionr  	  sW    aN ta#t%l [g	 	L G'%qW__S#%>%>%>Oqrrrr(   c                    |                      d                                          }dddd}|D ]]}|d         dk    rdn|d         dk    rdnd}t          t          ||                   t          |d         pd	          z             ||<   ^|S )
NRSELECT priority, COUNT(*) AS c FROM alerts WHERE status='active' GROUP BY priorityr   )rm   wichtigro   priorityrm   ro   r  cr   )r   r[  r   r   )r   r   r:  r   r  s        r   get_alert_summary_cardsr    s    <<lmmvvxxDsC
8
8C ; ;
Oz99jj#j/]cJcJcirs3s8}}s3s8=q'9'99::CJr(      c                   |                      d|f                                          }g }|D ]}t          | |d         |d                   }|                    |d         t	          |d         |d         |          t          |d         |d                   |t          |d                   t          |d                   d	d
           |S )Na4  
        SELECT alert_id, priority, category, entity_type, entity_id, rule_id, message, occurrence_count, last_seen_at
        FROM alerts WHERE status='active'
        ORDER BY CASE priority WHEN 'kritisch' THEN 0 WHEN 'warnung' THEN 1 ELSE 2 END, last_seen_at DESC, created_at DESC
        LIMIT ?
        r  r   alert_idr   r
  r  last_seen_atu    Prüfen · Ignorieren · Details)	_alert_idr  descriptionaffectedseverity	last_seenrZ  )r   r[  r	  r2   r  r  rz   rG   )r   r  r   cardsr   r&  s         r   get_alert_cardsr*     s    <<	 
  hjj 	 E 
 
-dC4FKHXYYZ YYJJ,S^S^LL (Z99"3~#6779
 
 	 	 	 	 Lr(   c                j    t          |                     d                                                    S )NaN  
        SELECT priority, status, category, entity_type, entity_id, rule_id, message,
               occurrence_count, last_seen_at, resolved_at, muted_until, fingerprint, dedup_key, created_at
        FROM alerts
        ORDER BY CASE priority WHEN 'kritisch' THEN 0 WHEN 'warnung' THEN 1 ELSE 2 END, status, created_at DESC
        r  r  s    r   
get_alertsr,  9  r  r(   c                   |                      d|f                                          }g }|D ]fd                                D             }dD ]T}||         rJ	 t          j        t          j        ||                   ddd          ||<   ?# t          j        $ r Y Pw xY wU|                    |           |S )Nz
        SELECT timestamp, source, action, entity_type, entity_id, old_values_json, new_values_json,
               confirmed, created_by, quality_status
        FROM audit_log ORDER BY timestamp DESC LIMIT ?
        c                P    i | ]"}||         dnt          |                   #S r   r   r   s     r   r   z$get_audit_events.<locals>.<dictcomp>N  s1    OOOq#a&.BBc#a&kkOOOr(   )old_values_jsonnew_values_jsonF   T)ensure_asciiindent	sort_keys)r   r[  r   jsondumpsloadsJSONDecodeErrorr2   )r   r  r   r:  r   r  r   s         @r   get_audit_eventsr9  D  s    <<	 X  hjj 	 !#C  OOOOCHHJJOOO9 	 	CCy  $
4:d3i+@+@u]^jn o o oDII+   D
 	

4Js   3BB$#B$c                <   g }g d}|D ]t\  }}}|                      |                                          }|rt          |d         pd          nd}|r|nd}|                    |t	          |          |d           ut          |           D ]L}	t          |	d         pd          }|                    d|	d          t	          |          |rd	ndd           Mt          |           D ]Z}
t          |
d
         pd          }|
d         dv rdn|rd	nd}|                    d|
d          t	          |          |d           [t          |           D ]\}t          |d         pd          rCt          |d         pd          dk    r(|                    d|d          |d         d	d           ]|                      d                                          }|rt          |d         pd          nd}|                    dt	          |          |rd	ndd           |S )N)-)zfehlende FXz@SELECT COUNT(*) AS c FROM transactions WHERE fx_status='missing'rm   )zfehlende/stale FX AlertszSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id IN ('missing_fx','stale_fx','historical_fx_unavailable','manual_override_required')rm   )zhistorical FX unavailablez^SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='historical_fx_unavailable'rm   )zmanual override requiredz]SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='manual_override_required'rm   )zfehlende Provider-Symbole\SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='missing_provider_symbol'rn   )zprovider lookup unavailablez`SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='provider_lookup_unavailable'rn   )ambiguous_provider_mappingz_SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='ambiguous_provider_mapping'rn   )multiple_listings_same_isina  SELECT COUNT(*) AS c FROM (SELECT isin FROM instrument_price_mapping_candidates WHERE COALESCE(isin,'')<>'' AND review_status IN ('proposed','needs_manual_review') GROUP BY isin HAVING COUNT(DISTINCT COALESCE(candidate_exchange,'') || ':' || COALESCE(candidate_currency,''))>1)rn   )currency_mismatchzSELECT COUNT(*) AS c FROM instrument_price_mapping_candidates WHERE review_status IN ('proposed','needs_manual_review') AND risk_flags LIKE '%currency_mismatch%'rn   )hedge_status_unknownYSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='hedge_status_unknown'rn   )instrument_status_unknown^SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='instrument_status_unknown'rn   )provider_symbol_missingr;  rn   )r  z^SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='candidate_review_required'rn   )valuation_not_readyzSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id IN ('missing_provider_symbol','missing_market_price','missing_fx','hedge_status_unknown','instrument_status_unknown','candidate_review_required')rn   )zinstrument status unknownrB  rn   )zmanual FX override requiredzSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id IN ('manual_override_required','manual_fx_override_required')rm   )zfehlende Market PriceszYSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='missing_market_price'rn   )zstale Market PriceszWSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='stale_market_price'rn   )zambiguous Instrument MappingzaSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='ambiguous_instrument_mapping'rn   )zprice currency mismatchz\SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='price_currency_mismatch'rn   )zhedge status unknownr@  rn   )zstale valuationzTSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='stale_valuation'rn   )zcorporate action suspectedz_SELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='corporate_action_suspected'rn   )zsplit/corporate action reviewznSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='split_or_corporate_action_review_required'rn   )zdelisted/suspendedzZSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='delisted_or_suspended'rn   )zsnapshot_only AlertszRSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='snapshot_only'ro   )zcost_basis_uncertain AlertszYSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='cost_basis_uncertain'rn   )zfehlende CoinGecko-IDzVSELECT COUNT(*) AS c FROM crypto_assets WHERE coingecko_id IS NULL OR coingecko_id='' rn   )zfehlende Crypto-PreisezSELECT COUNT(*) AS c FROM crypto_assets ca LEFT JOIN crypto_prices cp ON cp.asset_id=ca.asset_id WHERE cp.crypto_price_id IS NULLrn   )zfehlende ISINzSELECT COUNT(*) AS c FROM instrument_mappings WHERE asset_class IN ('equity','etf') AND (isin IS NULL OR isin='') AND mapping_status!='ignored'rn   )zCatalog Instrumente ohne ISINzSELECT COUNT(*) AS c FROM instrument_catalog_entries WHERE asset_class IN ('equity','stock','etf') AND (isin IS NULL OR isin='')rn   )zCatalog Ticker ohne ExchangezoSELECT COUNT(*) AS c FROM instrument_catalog_entries WHERE COALESCE(ticker,'')<>'' AND COALESCE(exchange,'')=''rn   )z&Catalog mehrere Listings gleicher ISINSELECT COUNT(*) AS c FROM (SELECT isin FROM instrument_catalog_entries WHERE COALESCE(isin,'')<>'' GROUP BY isin HAVING COUNT(DISTINCT COALESCE(exchange,'') || ':' || COALESCE(trading_currency,''))>1)ro   )zManual Review neededzYSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id='manual_review_needed'rn   )u   Mapping-Kandidaten unbestätigtzwSELECT COUNT(*) AS c FROM instrument_price_mapping_candidates WHERE review_status IN ('proposed','needs_manual_review')rn   )z+Instrumente mit mehreren Mapping-KandidatenzSELECT COUNT(*) AS c FROM (SELECT instrument_id FROM instrument_price_mapping_candidates WHERE review_status IN ('proposed','needs_manual_review') GROUP BY instrument_id HAVING COUNT(*) > 1)rn   )zValuation not readyzSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id IN ('missing_provider_symbol','missing_market_price','missing_fx','hedge_status_unknown','instrument_status_unknown')rn   )zfehlende FX in Import-ReviewszxSELECT COUNT(*) AS c FROM instrument_mappings WHERE quality_flags_json LIKE '%missing_fx%' AND mapping_status!='ignored'rn   )zsnapshot_only Positionenz{SELECT COUNT(*) AS c FROM instrument_mappings WHERE quality_flags_json LIKE '%snapshot_only%' AND mapping_status!='ignored'ro   )rT   zSELECT COUNT(*) AS c FROM instrument_mappings WHERE quality_flags_json LIKE '%cost_basis_uncertain%' AND mapping_status!='ignored'rn   )u)   Instrument Import Kandidaten unbestätigtzkSELECT COUNT(*) AS c FROM instrument_import_candidates WHERE mapping_status NOT IN ('confirmed','rejected')rn   )z&Instrument Import Kandidaten ohne ISINzSELECT COUNT(*) AS c FROM instrument_import_candidates WHERE COALESCE(proposed_isin, raw_isin, '')='' AND mapping_status!='rejected'rn   )zaktive Alertsz6SELECT COUNT(*) AS c FROM alerts WHERE status='active'rn   )zresolved Alertsz8SELECT COUNT(*) AS c FROM alerts WHERE status='resolved'rc   )zalte aktive AlertszdSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND last_seen_at < datetime('now', '-7 days')ro   r  r   rc   )checkcountr'  
open_itemszReview Flag: quality_flagrn   rG  readiness_status>   ignoredready_for_importzReview Readiness: r9  rL  zQuelle ohne ready_for_import: source_platformzUSELECT COUNT(*) AS c FROM broker_import_dry_runs WHERE snapshot_date_status='missing'zDry Runs ohne Snapshot Date)r   r   r   r2   r   get_review_quality_flag_countsget_review_readiness_countsget_ready_for_import_by_source)r   r   checksrf  sqlr'  r   rG  sevflag_rowreadysourcemissing_snapshots                r   get_data_qualityrX  Y  s   "$E. . .F^ !' M MsHll3((**&)0CHM"""q)hhTus5zzsKKLLLL2488 K KH\*/a00Ix/GIITWX]T^T^y~  mIlulu  EI  J  J  	K  	K  	K  	K,T22 x xE'N'a((./3RRRddfkYuYbYbquOE:L4MOOZ]^cZdZdruvvwwww066 S Svg#!$$ 	SV4F-G-L1)M)MQR)R)RLL#_FK\D]#_#_jpqxjy  HQ  R  R  S  S  S||${||  F  F  H  H/?FC %*+++QE	LL83u::hm[w[d[dswxxyyyLr(   queryr  c                2   |rddl m} d  || ||          D             S d}g }|r,|dz  }|                    |                                           |dz  }t	          |                     |t          |                                                              S )Nr   )search_local_catalogc                    g | ]	}|j         
S r   )__dict__r   s     r   r   z2get_instrument_catalog_entries.<locals>.<listcomp>  s    SSSq
SSSr(   aI  
        SELECT catalog_entry_id, asset_class, name, isin, ticker, exchange, trading_currency,
               instrument_currency, provider, provider_symbol, provider_market, hedge_status,
               instrument_status, valuation_policy, source, source_confidence, last_verified_at
        FROM instrument_catalog_entries
    z WHERE asset_class=?z4 ORDER BY name, exchange, trading_currency LIMIT 100)"jarvis_finance.market_data.catalogr[  r2   r   r   r   tupler[  )r   rY  r  r[  rR  paramss         r   get_instrument_catalog_entriesra    s     TKKKKKKSS$8$8uk$R$RSSSSC F +%%k''))***AACDLLeFmm44==??@@@r(   c                   |                      d                                          d         }|                      d                                          d         }|                      d                                          d         }|                      d                                          d         }t          |pd          t          |pd          t          |pd          t          |pd          dS )Nz4SELECT COUNT(*) AS c FROM instrument_catalog_entriesr  rE  z[SELECT COUNT(*) AS c FROM instrument_catalog_entries WHERE COALESCE(provider_symbol,'')='' zSELECT COUNT(*) AS c FROM alerts WHERE status='active' AND rule_id IN ('manual_review_needed','missing_provider_symbol','ambiguous_provider_mapping')r   )catalog_entriesmultiple_listingswithout_provider_symbolmanual_review_requiredr   r   r   )r   r9  multino_providermanuals        r   get_instrument_catalog_summaryrk    sY   LLOPPYY[[\_`ELL  d  e  e  n  n  p  p  qt  uE,,|}}  G  G  I  I  JM  NK\\  r  s  s  |  |  ~  ~  B  CF"5:ASRS__qt  vA  vF  EF  rG  rG  cf  gm  gr  qr  cs  cs  t  t  tr(   c                n    |                      d                                          }t          |          S )Na  
        SELECT i.instrument_id, i.isin, i.name, i.ticker, i.exchange, i.currency,
               i.hedge_status, i.instrument_status, i.valuation_policy,
               COALESCE(m.mapping_status, 'missing_provider_symbol') AS mapping_status,
               COALESCE(m.provider, '') AS provider,
               COALESCE(m.provider_symbol, '') AS provider_symbol,
               COUNT(c.candidate_id) AS candidate_count
        FROM instruments i
        JOIN transactions t ON t.instrument_id=i.instrument_id
        LEFT JOIN instrument_price_mappings m ON m.instrument_id=i.instrument_id AND m.mapping_status='mapped'
        LEFT JOIN instrument_price_mapping_candidates c ON c.instrument_id=i.instrument_id AND c.review_status IN ('proposed','needs_manual_review')
        WHERE t.transaction_type='initial_position_snapshot'
          AND t.source_type='broker_import_reviewed_snapshot'
          AND COALESCE(t.is_voided,0)=0
        GROUP BY i.instrument_id
        ORDER BY i.isin, i.name
        r   r[  r   r   r   s     r   get_instrument_mapping_reviewro    s6    <<	 $ hjj% 	& D>>r(   c                    d}g }|r|dz  }|                     |           |dz  }t          |                     |t          |                                                              S )NaU  
        SELECT candidate_id, source_file, platform, account, source_row_number,
               raw_name, raw_ticker, raw_isin, raw_currency,
               CASE WHEN COALESCE(raw_quantity,'')<>'' THEN '<present>' ELSE '' END AS raw_quantity_present,
               raw_asset_class, extracted_by, extraction_confidence,
               proposed_name, proposed_ticker, proposed_isin, proposed_exchange,
               proposed_currency, proposed_asset_class, provider, provider_symbol,
               mapping_status, review_note, created_at, updated_at
        FROM instrument_import_candidates
    z WHERE mapping_status=?z ORDER BY CASE mapping_status WHEN 'needs_manual_review' THEN 0 WHEN 'probable' THEN 1 WHEN 'exact_isin_match' THEN 2 WHEN 'confirmed' THEN 3 ELSE 4 END, platform, source_row_number)r2   r   r   r_  r[  )r   rs   rR  r`  s       r    get_instrument_import_candidatesrq    st    	C F ((f  C  CCDLLeFmm44==??@@@r(   c                     d fd} |d           |d           |d           |d           |d	           |d
           |d           |d           |d           |d          d
S )Nwherer   r   c                                         d|                                            }t          |d         pd          S )Nz=SELECT COUNT(*) AS n FROM instrument_import_candidates WHERE nr   rg  )rs  r   r   s     r   r  z2get_instrument_import_candidate_summary.<locals>.c  s@    llb[`bbccllnn3s8=q!!!r(   z1=1z)COALESCE(proposed_isin, raw_isin, '')<>''z(COALESCE(proposed_isin, raw_isin, '')=''z-COALESCE(proposed_ticker, raw_ticker, '')<>''z1COALESCE(proposed_currency, raw_currency, '')<>''z!mapping_status='exact_isin_match'zmapping_status='probable'z$mapping_status='needs_manual_review'zmapping_status='confirmed'zmapping_status!='confirmed')
candidates_total	with_isinwithout_isinwith_tickerwith_currencyexact_isin_matchprobableneeds_manual_reviewra   blocked)rs  r   r   r   r   )r   r  s   ` r   'get_instrument_import_candidate_summaryr    s    " " " " " " AeHHQBCCDEEqHIINOOAABBA122 q!GHHQ3441233  r(   r   c                    |r*|                      d|f                                          }n'|                      d                                          }t          |          S )Na  
            SELECT candidate_id, instrument_id, isin, candidate_provider, candidate_provider_symbol,
                   candidate_exchange, candidate_currency, candidate_name, candidate_asset_class,
                   candidate_is_hedged, candidate_hedged_to_currency, candidate_hedge_status,
                   candidate_instrument_status, candidate_valuation_policy, confidence,
                   ranking_score, ranking_reason, risk_flags, recommended_action,
                   CASE
                       WHEN recommended_action='select_candidate' OR ranking_score >= 75 THEN 'wahrscheinlich passend'
                       WHEN recommended_action='reject_candidate' OR ranking_score < 40 THEN 'wahrscheinlich falsch'
                       ELSE 'unsicher'
                   END AS ranking_mark,
                   candidate_currency AS closing_currency,
                   evidence_source, evidence_note, review_status, created_at
            FROM instrument_price_mapping_candidates WHERE instrument_id=?
            ORDER BY ranking_score DESC, CASE confidence WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END, candidate_provider
            a{  
            SELECT candidate_id, instrument_id, isin, candidate_provider, candidate_provider_symbol,
                   candidate_exchange, candidate_currency, candidate_name, candidate_asset_class,
                   candidate_is_hedged, candidate_hedged_to_currency, candidate_hedge_status,
                   candidate_instrument_status, candidate_valuation_policy, confidence,
                   ranking_score, ranking_reason, risk_flags, recommended_action,
                   CASE
                       WHEN recommended_action='select_candidate' OR ranking_score >= 75 THEN 'wahrscheinlich passend'
                       WHEN recommended_action='reject_candidate' OR ranking_score < 40 THEN 'wahrscheinlich falsch'
                       ELSE 'unsicher'
                   END AS ranking_mark,
                   candidate_currency AS closing_currency,
                   evidence_source, evidence_note, review_status, created_at
            FROM instrument_price_mapping_candidates
            ORDER BY instrument_id, ranking_score DESC, CASE confidence WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END, candidate_provider
            rm  )r   r   r   s      r   !get_instrument_mapping_candidatesr    sp     &||  #
 
$ (**% 	( ||
 
" (**# 	$ D>>r(   c                n    |                      d                                          }t          |          S )Na(  
        SELECT t.currency_original AS base_currency, 'CHF' AS quote_currency, t.trade_date AS rate_date,
               COUNT(DISTINCT t.instrument_id) AS instrument_count,
               CASE WHEN fr.fx_rate_id IS NULL THEN 'missing_fx' ELSE fr.quality_status END AS fx_status
        FROM transactions t
        LEFT JOIN fx_rates fr ON fr.base_currency=t.currency_original AND fr.quote_currency='CHF' AND fr.rate_date=t.trade_date
        WHERE t.transaction_type='initial_position_snapshot'
          AND t.source_type='broker_import_reviewed_snapshot'
          AND COALESCE(t.is_voided,0)=0
          AND t.currency_original IS NOT NULL
          AND t.currency_original <> 'CHF'
        GROUP BY t.currency_original, t.trade_date, fx_status
        ORDER BY t.currency_original, t.trade_date
        rm  rn  s     r   get_fx_override_requirementsr     s6    <<	  hjj 	  D>>r(   c                $    ddl m}  ||           S )Nr   )build_import_wizard_summary)%jarvis_finance.imports.broker_mappingr  )r   r  s     r   get_import_wizard_summaryr  4  s%    QQQQQQ&&t,,,r(   c                $    ddl m}  ||           S )Nr   )get_manual_review_queue)r  r  )r   r  s     r   get_manual_review_itemsr  :  s%    MMMMMM""4(((r(   c                (    ddl m}  || |          S )Nr   )get_dry_run_sessionsr  )r  r  )r   r  r  s      r   get_broker_dry_runsr  @  s*    JJJJJJE2222r(   c                t    |                      d                                          }dd|r|d         nddddS )	Nz^SELECT created_at FROM audit_log WHERE action LIKE '%backup%' ORDER BY created_at DESC LIMIT 1Runtimez	Read-only
created_atu   nicht verfügbaru   zuletzt OK / CLI prüfenu!   Echte Daten liegen außerhalb Git)db_mode
write_modelast_backup_atgit_safety_statusdata_location)r   r   )r   backups     r   get_safe_mode_statusr  F  sZ    \\z{{  E  E  G  GF!28P&..>P7<  r(   d   c                $    ddl m}  || fd|i|S )Nr   )get_broker_review_itemsr  )r  r  )r   r  filters_itemss       r   r  r  Q  s1    WWWWWW6$//e/w///r(   c                $    ddl m}  ||           S )Nr   )rO  )r  rO  r   _countss     r   rO  rO  W  s"    \\\\\\74==r(   c                $    ddl m}  ||           S )Nr   )rP  )r  rP  r  s     r   rP  rP  ]  s"    ______74==r(   c                v    ddl m} d t           ||                                                     D             S )Nr   )aggregate_review_quality_flagsc                8    g | ]\  }}|t          |          d S ))rI  rH  r   r  s      r   r   z2get_review_quality_flag_counts.<locals>.<listcomp>f  s*    www$!QQc!ff55wwwr(   )r  r  r   r   )r   r  s     r   rN  rN  c  sI    TTTTTTww&IgIghlImImIsIsIuIuBvBvwwwwr(   r  c                t    t          |                     d                    }|dk    rt          |          ndS )Nr  r   noch nicht bewertet)r   rv   r@   )r  r   s     r   equity_etf_user_labelr  i  s5    gkk01122E#aii8E???-BBr(   c                    t          |                     d                    dk    o|                     d          dk    S )Nr  r   r  rc   r   rv   )r  s    r   equity_etf_is_user_readyr  n  s:    W[[/0011A5d'++F[:\:\`d:ddr(      c                   g }t          |           }t          |          dk    r|                    d           t          |           }t	          |                    d                    dk    r|                    d           nQt	          |                    d                    dk    r|                    d           n|                    d           t          | |	          D ]O}|d
         t          fddD                       s|                               t          |          |k    r nP|d |         S )Nr  u$   Aktien/ETF: Bewertung unvollständigr   r   u(   Crypto-Preise fehlen für einzelne Coinsr   z Crypto-Preise teilweise veraltetzCrypto-Preise aktuellr  r  c              3      K   | ]}|v V  	d S r~   r   )r   r   r5   s     r   r   z%get_top_user_hints.<locals>.<genexpr>  s'      qqf6T>qqqqqqr(   )r   r   r  r   r   )	r  r  r2   r  r   rv   r*  r   r   )r   r  hintsr  cryptoalertr5   s         @r   get_top_user_hintsr  r  sN   E(..GW%%)>>>;<<<%d++F)	*	*++a//?@@@@	
6::)**	+	+a	/	/78888,--- U333  W~qqqq0pqqqqq 	LLu::E %=r(   rD   r  r   c                   t          | d d          }t          |          |k    r|S |d |         }t          d ||d          D             t          d                    }|dk    r&|                    dt          |d          d	           |S )
Nc                F    t          |                     d                    S rk  r  r.  s    r   r  z$compact_chart_rows.<locals>.<lambda>  s    1SWW[-A-A+B+B r(   Tr  c              3  Z   K   | ]&}t          |                    d                     V  'dS )rg  Nr  r   s     r   r   z%compact_chart_rows.<locals>.<genexpr>  s6      DDS377;''((DDDDDDr(   r   r   Anderer   re  )r   r   r  r   r2   r'   )r   r  orderedheadothers        r   compact_chart_rowsr    s    TBBDQQQG
7||u6E6?DDDGEFFODDDgcllSSEqyyhXeV5L5LMMNNNKr(   c                   t          |           }t          |           }d t          |           D             }t          d |D                       }t	          |d                   }d |D             }d |D             }t          d |D                       }t          d |D                       }	||	z   }
t          d |D                       }t          d	 |D                       }t          d
 |D                       }||z   }t          d |D             d          }|                     d                                          }t          d |D                       }t          |           }t          d |D                       rdnt          d |D                       rdnd}||z   |
z   }i dddt          |d          dt          |d          dt          |d          dt          |	d          dt          |
d          dt          t          |                    dt          |          dt          |          d t          |          d!t          |          d"t          |d          dt          |d          d#t          |          d$d%                    d& |D                       pd'd(|d)t          |                    d)d          |g          |                    d)d          |d*S )+Nc                    g | ]Z}|                     d d                                          dv ,|                     dd                                          dk    X|[S )r  r   >   r  r  r  r  rq   rv   r   r   s     r   r   z.get_command_center_summary.<locals>.<listcomp>  s      l  l  lq1553K3K3Q3Q3S3SWq3q3qvwv{v{  }P  RT  wU  wU  w[  w[  w]  w]  ak  wk  wk  wk  wk  wkr(   c              3  P   K   | ]!}|d          
t          |d                    V  "dS )r  Nr-  r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  s7      NNAaoNQq''NNNNNNr(   r   c                f    g | ].}|                     d d                                          dv ,|/S )r  r   >   r  r  r  r   s     r   r   z.get_command_center_summary.<locals>.<listcomp>  s=    bbb!%%r*B*B*H*H*J*JNa*a*a!*a*a*ar(   c                j    g | ]0}|                     d d                                          dk    .|1S )r  r   r  r  r   s     r   r   z.get_command_center_summary.<locals>.<listcomp>  s<    RRRamR(@(@(F(F(H(HE(Q(Q(Q(Q(Qr(   c              3  j   K   | ].}|                     d           t          |d                    V  /dS r  Nrv   r   r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  sB      ``1aeeL^F_F_`a,-..``````r(   c              3  j   K   | ].}|                     d           t          |d                    V  /dS r  r  r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  sB      \\!%%HZB[B[\Aa*+,,\\\\\\r(   c              3  D   K   | ]}|                     d           dV  dS )r  rC   Nr   r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  s4      YYA!%%@W:X:XYaYYYYYYr(   c              3  L   K   | ]}|                     d           dk    dV   dS )r  rR   rC   Nr   r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  s8      VV1553E3E3U3U13U3U3U3UVVr(   c              3  v   K   | ]4}d |                     d          pdv s|                     d          0dV  5dS )rT   r  r   r  rC   Nr   r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  sx         T   Ta8NSTSXSXYkSlSlSrpr8s8s{|  |A  |A  BR  |S  |S8s8s8s8s8s   T   Tr(   c              3  D   K   | ]}|                     d           pdV  dS )r  r   Nr   r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  s3      LLQquu\228bLLLLLLr(   r   )r   r  c              3  \   K   | ]'}|d          dk    t          |d         pd          V  (dS )r  rm   r  r   Nr3  r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  s@      YYQz]j=X=X3qv{##=X=X=X=XYYr(   c              3  F   K   | ]}|d          dk    o|d         dk    V  dS )r'  rm   rG  r   Nr   r   is     r   r   z-get_command_center_summary.<locals>.<genexpr>  s:      ^^QR1Z=J6L1W:;L^^^^^^r(   rm   c              3  F   K   | ]}|d          dk    o|d         dk    V  dS )r'  rn   rG  r   Nr   r  s     r   r   z-get_command_center_summary.<locals>.<genexpr>  s        vy  vy  lmvw  yC  wD  HQ  wQ  wg  VW  X_  V`  dg  Vg  vy  vy  vy  vy  vy  vyr(   rn   rc   base_currencyrH   r  r   r  stock_total_chfetf_total_chfr  equity_position_countunvalued_position_countmissing_price_countmissing_fx_countincomplete_cost_counttotal_portfolio_chfcritical_alert_countactive_alertsz, c              3  <   K   | ]}|d           d|d          V  dS )r  z: r  Nr   r   s     r   r   z-get_command_center_summary.<locals>.<genexpr>  s8      "V"VAa
m#?#?qv#?#?"V"V"V"V"V"Vr(   r   r  r  )crypto_price_data_as_ofequity_price_data_as_of)r  r  r  r  r   maxr   r[  rX  r   r'   r   r   r3   rv   )r   	cash_rowscrypto_summaryr  
cash_totalr  
stock_rowsetf_rowsstock_total	etf_totalequity_totalr  r  r  unvalued_countlatest_equity_pricealert_countsrf   qualitydqr9  s                        r   r  r    s   !$''I-d33N l  lM$//  l  l  lINNNNNNNJ^$5677LbbYbbbJRR9RRRH``
`````K\\h\\\\\I*LYYYYYYYVViVVVVV   T   T9   T   T   T  T  T(+;;NLL)LLLVXYYY<< tuu~~  A  ALYY\YYYYYHt$$G^^V]^^^^^  
Dru  vy  vy  qx  vy  vy  vy  sy  sy  fCenen  CB%4E(:v66 	H\6:: 	8K88	
 	)V44 	v > > 	 S^^!4!4 	"3~#6#6 	s#677 	C 011 	 %:!;!; 	xv66 	8E622 	H 	"V"V"V"V"VVV]Z]  	r!" 	^%7%78NPR%S%SUh$i j j#$ $2#5#56Lb#Q#Q#6'   r(   )r   )r   r   r   r   r   r   r~   )r   r   r    r!   r   r   )r   )r   r)   r    r   r   r   )r   r   r   r   )r   r!   r   r   )rH   )r   rI   rJ   r   r   r   )rs   r!   r   r   )r5   r!   r   r{   )r5   r!   r   r   )r   r   r   r   )r   rI   r   r   )r   r   r   r   )r   r   rJ   r   r   r   )r   r   r   r   r   r   )r   r   )r   r   r   r{   )r   r	   r   r   r   r{   )
r   r   r   r   rJ   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r  r{   r   r   r  r   r  r!   r  r!   r  r!   r   r   )
r   r   r   r   r   r   r  r{   r   r   )r   r   r   r   r  r{   r   r   )
r   r   r   r   r   r   r  r{   r   r   )r   r   r   r   r   r   )r   r   r   r   r   r   r   rm  )r   r   r   r   r   r   r   rm  )r   r   r   r   )r  )r   r   r  r   r   r   )r  )r   r   r  r!   r   r!   r   r   )r   r   )r   r   r
  r   r  r   r   r   )r   )r   r   r
  r   r   r   )r   r   r   r   )r   )NN)r   r   rY  r!   r  r!   r   r   )r   r   rs   r!   r   r   )r   r   r   r!   r   r   )r  )r  r   r   r   )r  r   r   r{   )r  )r   r   r  r   r   r   )r   r   r  r   r   r   )`
__future__r   r5  decimalr   r   r   pathlibr   sqlite3r   jarvis_finance.config.settingsr	   jarvis_finance.crypto.holdingsr
   jarvis_finance.ledger.positionsr   r   jarvis_finance.market.providersr   -jarvis_finance.services.portfolio_aggregationr   r   r   r   MONEYr   r'   r<   r@   rG   rN   ru   rz   r   r   r   r   r   r   r   r   r   r   r   r  r  r=  rM  rU  rS  rb  rh  rl  r|  r  r  r  r  r  r  r  r  r  r  r  r  r   r	  r  r  r  r*  r,  r9  rX  ra  rk  ro  rq  r  r  r  r  r  r  r  r  rO  rP  rN  r  r  r  r  r  r   r(   r   <module>r     s)	   " " " " " "  < < < < < < < < < <             3 3 3 3 3 3 D D D D D D I I I I I I I I : : : : : :            	             
< 
< 
< 
< 
<* * * *   3 3 3 3 3M ] /	
 5 " _ Y Z } | l  l 	)  y!" 
#$ /  6V V V V8 8 8 8; ; ; ;I I I I
) ) ) )4 4 4 4 =B 2 2 2 2 2 2 JP      4^ ^ ^ ^, , , ,   jp      & PV      (    !'$ $ $1^ 1^ 1^ 1^ 1^ 1^h ek  @E      < QW Q Q Q Q Q Q PVjo      D _ey~      4 X^       Z` L L L L L L ]c      2 Y_      " KQ      2 LR      8             &r r r rj   ,   	G 	G 	G 	G     O O O O& & & &&9 9 9 9 9&s s s s s       2       *C C C CLA A A A A$t t t t   .A A A A A&   $( ( ( ( (V   (- - - -) ) ) )3 3 3 3 3   0 0 0 0 0      x x x xC C C C
e e e e    * DF      ) ) ) ) ) )r(   