
    #j;              
      b   d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	 ddl
m
Z
mZ ddlmZ g dZh dZd	d
dddddddd	ZdddddddddZddddddd d!d"Ze G d# d$                      Zd% Zd9d'Zd9d(Zd:d*Zd+ Zd;d-Zd. Zd/ Zd0 Zd1 Zd2 Zd3 Zd<d6Z d7 Z!e"d8k    r e!             dS dS )=zLive-ish market timing engine for the account growth agent.

Uses yfinance public data. Broker quotes and broker FX must override this for
actual order placement.
    )annotationsN)	dataclassasdict)datetimetimezone)Path)SPYQQQIWMSMHSOXXSOXLSOXSNVDAAVGOAMDMUTSMASMLRDWMRVLAAOIGNTA>   QLDSSOr   r   SPXLSPXSSQQQTECLTECSTQQQUPROu   상승 추세u   추세 회복u   조정u   추세 손상u   추세 이탈u   장중 약세u   혼조u   데이터 필요u   오류)	UPTRENDREPAIRPULLBACKDAMAGEDTREND BREAKINTRADAY WEAKCHOPDATA NEEDEDERRORu   매수 가능u!   매수 후보지만 추격 금지u   반등 감시u   인버스 매수 후보u   일부 축소 감시u   이탈/청산 감시u   우위 없음)	BUY SETUPBUY SETUP - DO NOT CHASEREBOUND WATCHINVERSE BUY SETUP
TRIM WATCH
EXIT WATCHNO EDGEr*   u   공격u   제한적 공격u   방어u   수익실현u   수익실현/방어u   휴식/대기u   대기)ATTACKGUARDED ATTACKDEFENSEDEFENDHARVESTHARVEST / GUARDREST / WAITWAITc                      e Zd ZU ded<   ded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   dS )	TimingRowstrtickerzfloat | Noneprice
prev_closeday_change_pctsma20sma50sma200rsi14	atr14_pctvolume_ratiovwap_intradayvwap_gap_pcttrend_labeltiming_labelaction_labelentry_triggerstop_or_invalidationtarget_1target_2notesN)__name__
__module____qualname____annotations__     $outputs/live_market_timing_engine.pyr<   r<   L   s         KKK    MMMMMMJJJJJrW   r<   c                p    |                                  }|j        rd S t          |j        d                   S )N)dropnaemptyfloatiloc)seriescleans     rX   
last_validra   d   s2    MMOOE{ tB   rW      c                t   |                                  }|                    d                              |                                          }|                    d                               |                                          }||                    dt
          j                  z  }ddd|z   z  z
  S )Nr   )lower)upperd      )diffcliprollingmeanreplacemathnan)closewindowdeltagainlossrss         rX   rsiru   k   s    JJLLE::A:&&v..3355DZZaZ   ))&116688D	Q))	)B#R.!!rW   c                t   | d         }| d         }| d         }|                     d          }||z
                      d          }||z
                                  |d<   ||z
                                  |d<   |                    d                              |                                          }||z  S )	NHighLowCloserg   hlhclc)axis)shiftto_frameabsmaxrj   rk   )dfrp   highlowro   r@   tratrs           rX   atr_pctr   s   s    f:D
U)CwKEQJ
*		t	$	$Bz!&&((BtHj %%''BtH
&&a&..
 
 
(
(
-
-
/
/C;rW      c                P    | | | k    rd S t          t          |           |          S )N)roundr]   )valuedigitss     rX   
safe_roundr      s*    }tuv&&&rW   c                    | | | k    rdS | dS )NNEEDS LIVE PRICE.2frV   )r   s    rX   format_pricer      s    }!!>>rW   rowc                   t          |           }t                              | j        | j                  |d<   t                              | j        | j                  |d<   t                              | j        | j                  |d<   |S )Ntrend_label_kotiming_label_koaction_label_ko)r   TREND_KOgetrJ   	TIMING_KOrK   	ACTION_KOrL   )r   datas     rX   row_to_dictr      sm    #;;D%\\#/3?KKD	'mmC,<c>NOOD	'mmC,<c>NOOD	KrW   c                    | ||dS | |k    }| |k    }|d uo| |k    }|r|r|r
|pddk     rdS |r|rdS |s|rdS |s
|| |k    rdS || |k     rdS ||d	k     rd
S dS )Nr*   2   H   r#   r$   r%   r&   r'   g      r(   r)   rV   )	r?   rB   rC   rD   	rsi_valuevwap_gapabove20above50above200s	            rX   classify_trendr      s    }}emGemGT!4efnH 7 x Y_",B,By 7 x w z v)efnnyefnn}46rW   c           
        |dS |r||z  dz
  dz  nd }|d uo|dk    }|d uo|dk    }|d uo|dk    }|	d uo|	dk    }|	d uo|	dk    }|pd	}|dt          d
t          d|dz                      z
  z  }|dt          d	t          d|dz                      z   z  }|dt          dt          d|dz                      z   z  }|
dv r,|r*|s(||dk    r|rddd|d|d|ddfS ddd|d|d|ddfS |
dk    r|s|rddd|d|d|ddfS |
d v r$| d!v r|rd"d#d$|d|d|dd%fS d&d#d'|d|d|dd(fS |r|rd)d*d+|d|d|dd,fS d-dd.|d|d|dd/fS )0N)r*   r:   u   실시간 가격 확인 필요r   r   r   u5   실시간 가격 없이는 행동하지 않습니다.rg   rf   r   "   g      ?r   g333333g{Gz?g?g?g333333?gQ?g{Gz?gQ?gffffff@   r$   r#      r-   r:   u    눌림 또는 VWAP 지지 확인r   u8   강하지만 단기 과열입니다. FOMO 진입 금지.r,   r3   u   주요 추세선과 VWAP 위uJ   분할 진입만 검토합니다. 수량은 계좌 모드에 따릅니다.r%   r.   u   SMA20 또는 장중 VWAP 회복u<   반등 가능성은 있지만 아직 확정은 아닙니다.>   r&   r'   >   r   r   r   r    r/   r6   u$   하락 확인 및 인버스 VWAP 위uC   본계좌 전용입니다. 시간 손절을 반드시 정합니다.r1   u   지지선 또는 추세 이탈u)   추세 회복 전까지 물타기 금지.r0   r7   u   RSI/거래량 과열u#   수익 잠금 또는 리셋 대기.r2   u   명확한 트리거 없음u   현금도 포지션입니다.)r   min)r>   r?   r@   rB   rC   rD   r   	atr_valuerG   r   rJ   
day_change	stretchedwashedhigh_volume
above_vwap
below_vwapr   stoprO   rP   s                        rX   classify_timingr      s   }
 
 6@I5:%)S00TJ%9)r/Id"6yBFd*B|s/BK%7(a-J%:(d*:J

tCAE3tS3Y#7#78889DCc$c	&:&:;;;<HCc$c	&:&:;;;<H+++
+9+!j1nnn.8Z_c\i\invk|k|  BJ  P  P  RL  M  MX'E$}}YaVgVgltiziz  }I  J  	Jj    )JtMM^f[l[lqynn  B@  A  	A000555*5'3Y^b[h[hmuj{j{  AI  ~O  ~O  QV  W  Wh(HT--\dYjYjowl}l}  @k  l  	l ][ ]i)?DS[PaPafnctct  w\  ]  	]v;]]xL]L]bj_p_p  sR  S  SrW   c                ~    dd l }|                    | ddddd          }|                    | ddddd          }||fS )	Nr   1y1dTF)periodintervalauto_adjustprogressthreads5d5m)yfinancedownload)r>   yfdailyintradays       rX   	fetch_oner      sV    KKtdW\fkKllE{{6$4Z_in{ooH(?rW   c                    | | j         r| S t          | j        d          r[| j        j        dk    rK|| j                            d          v r|                     |dd          } nd | j        D             | _        | S )Nnlevelsrg   rZ   )r}   levelc                    g | ]
}|d          S )r   rV   ).0cols     rX   
<listcomp>z%flatten_if_needed.<locals>.<listcomp>   s    777S#a&777rW   )r\   hasattrcolumnsr   get_level_valuesxs)r   r>   s     rX   flatten_if_neededr      s    	zRXz	rz9%% 8"**<q*@*@RZ004444vAR00BB77BJ777BJIrW   c                   t          |           \  }}t          ||           }t          ||           }||j        sd|vr"t          | d d d d d d d d d d d dddddddd          S |d                                         }t          |          }t          |          dk    rt          |j        d                   nd }|r|r||z  d	z
  d
z  nd }t          |	                    d          
                                          }t          |	                    d          
                                          }t          |	                    d          
                                          }	t          t          |d                    }
h d                    |j                  rt          t          |d                    nd }d }d|v rt          |d                                                   dk    rt          |d                                         j        d                   }t          |d                                         j        dd         
                                          }|r||z  }d }d }||j        sh d                    |j                  r|                                                    d
          }|d         |d         z   |d         z   dz  }|d                             dt"          j                  }|                                }|r:||k    r4t          ||z                                  |z            }|r||z  d	z
  d
z  }t)          ||||	|
|          }t+          | |||||	|
||||          \  }}}}}}}| t,          v r|dz   }t          d.i d| dt/          |          dt/          |          dt/          |          dt/          |          dt/          |          d t/          |	          d!t/          |
          d"t/          |r|d
z  nd           d#t/          |          d$t/          |          d%t/          |          d&|d'|d(|d)|d*|d+|d,|d-|S )/Nry   r*   r:   zlive/daily data unavailabler   
No action.r   rg   rf      r      rb   >   rx   rw   ry   Volume   rZ   i>   rx   rw   ry   r   rw   rx      r   u    본계좌 전용.r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rV   )r   r   r\   r<   r[   ra   lenr]   r^   rj   rk   ru   issubsetr   r   tailrl   rm   rn   sumr   r   	LEVERAGEDr   )r>   r   r   ro   r?   r@   rA   rB   rC   rD   rE   atr14rG   last_volume
avg_volumerH   r   same_daytypicalvoldenomrJ   timingactiontriggerr   target1target2rQ   s                                rX   analyze_tickerr      s2   ''OE8eV,,E 622H}}we';';tT4tT4QUW[]acpr  BH  Jg  i{  }O  Qc  eq  r  r  	r'N!!##EuE*-e**//uz"~&&&tJ9>W:Wuz)A-44SWNu}}R((--//00Eu}}R((--//00Ec**//1122Fs5"~~&&E.F.F.F.O.OPUP].^.^hJwub))***dhEL5Sx!7!7!9!9::b@@E(O22449"=>>5?11338R@EEGGHH
 	4&3LMHHN7Y7Y7Y7b7bckcs7t7t??$$))#..F#huo58IIQNx ((DH55		 	=Ue^^!7S="5"5"7"7%"?@@M =!M1A5< ufeXNNK=Lz5%|U]_j> >:FFGT7GU ,,   v j))) ".111	
   &!!!  e=eckk>>>  --- !///  )))  K V V  g!" "T#$ %& '( e) rW   c                   d | D             }|                     d          }|                     d          p|                     d          }|                     d          }|                     d          }d | D             }d | D             }d	 | D             }|r|r|j        d
v r|j        d
v r|rdnd}	n|r|r|j        dk    rd}	n|rd}	nd}	t          | d           d d         }
|	t                               |	|	                              dd          d |
D             |rt          |          nd |rt          |          nd dS )Nc                    i | ]
}|j         |S rV   )r>   r   r   s     rX   
<dictcomp>z$summarize_market.<locals>.<dictcomp>)  s    111SS111rW   r
   r   r   r   r   c                (    g | ]}|j         d k    |S )r3   rL   r   s     rX   r   z$summarize_market.<locals>.<listcomp>/  %    CCCsc&6(&B&Bs&B&B&BrW   c                (    g | ]}|j         d k    |S )r6   r   r   s     rX   r   z$summarize_market.<locals>.<listcomp>0  r   rW   c                (    g | ]}|j         d k    |S )r7   r   r   s     rX   r   z$summarize_market.<locals>.<listcomp>1  s%    EEEs'79'D'D'D'D'DrW   r   r3   r4   r/   r5   r8   r9   c                B    ddddd                     | j        d          S )Nr   rg   r   r   )r3   r6   r7   r:      )r   rL   )r   s    rX   <lambda>z"summarize_market.<locals>.<lambda><  s)    !qUV`a/b/b/f/fgjgwyz/{/{ rW   )keyr   z / /c                ,    g | ]}t          |          S rV   r   r   s     rX   r   z$summarize_market.<locals>.<listcomp>@  s     @@@SC((@@@rW   )modemode_kotop_actionssoxl_statussoxs_status)r   rJ   rK   sortedr   rl   r   )rows	by_tickerqqqsmhsoxlsoxsattacksdefendsharvestsr   r   s              rX   summarize_marketr	  (  s   11D111I
--

C
--


7)--"7"7C==  D==  DCCdCCCGCCdCCCGEEtEEEH
 s s*???COWlDlDl"8xx(8	 T d/3FFF	  #{#{|||}~}  AK==t,,44UC@@@@K@@@,0:{4(((d,0:{4(((d  rW   out_dirr   c                h   |dz  }|dz  }|dz  }|                     dd          5 }t          j        |t          t	          | d                                                                       }|                                 |                    d	 | D                        d d d            n# 1 swxY w Y   t          j	        t          j                                                  d
|d | D             d}|                    t          j        |dd                     ddd|d          dd|                    d|d                    d|d          ddddddg
}	|d         D ]v}
|	                    d|
d          dt%          |
d                     d|
d!          d|
d"          d|
d#          d|
d$          d|
d%          d|
d&          d|
d'          d(           w|	                    dd)dd*d+d,d-dd.dd/| d0d1| d0g           |                    d2                    |	          d2z              d S )3Nzlive_timing_snapshot.csvzlive_timing_snapshot.jsonzlive_timing_snapshot.mdw )newliner   )
fieldnamesc                ,    g | ]}t          |          S rV   r   r   s     rX   r   z!write_outputs.<locals>.<listcomp>N  s     ;;;s+c**;;;rW   zDyfinance public quote/history; broker quote must override for ordersc                ,    g | ]}t          |          S rV   r   r   s     rX   r   z!write_outputs.<locals>.<listcomp>T  s     222cS!!222rW   )timestamp_utcsourcesummaryr   Fr   ensure_asciiindentu   # 실시간 타이밍 스냅샷z- Timestamp UTC: r  zV- Source: yfinance public quote/history; broker quote must override for actual orders.u   - 현재 모드: `r   r   z` (`z`)u   ## 우선 확인ua   | 티커 | 가격 | 추세 | 타이밍 | 행동 | 조건 | 손절/무효화 | 목표1 | 목표2 |z;| --- | ---: | --- | --- | --- | --- | ---: | ---: | ---: |r   z| r>   z | r?   r   r   r   rM   rN   rO   rP   z |u	   ## 규칙uz   - `공격(ATTACK)`: 매수 후보가 있어도 계좌 모드, 현금, 목표가, 손절, 수량 확인이 필요합니다.uy   - `방어(DEFEND)`: 노출 축소 또는 인버스 검토. 본계좌 적격성과 손절/시간제한이 필요합니다.uP   - `수익실현(HARVEST)`: 일부 축소, 수익 잠금, 과열 감시입니다.uJ   - `대기(WAIT)`: 우위가 부족합니다. 현금도 포지션입니다.u	   ## 파일z- CSV: ``z	- JSON: `
)opencsv
DictWriterlistr   keyswriteheader	writerowsr   nowr   utc	isoformat
write_textjsondumpsr   appendr   extendjoin)r   r  r
  csv_path	json_pathmd_pathhandlewriterpayloadlinesr   s              rX   write_outputsr1  F  sv   33H55I11G	sB	'	' =64DG8L8L8Q8Q8S8S3T3TUUU;;d;;;<<<= = = = = = = = = = = = = = = "hl33==??X22T222	 G G%JJJKKK 	*
6GO466`]W[[GFODD]]'RX/]]]

kEE }% 
 
 sX  s  s<G#=#=  s  s#FVBW  s  s\_`q\r  s  swz  |M  xN  s  s  SV  Wf  Sg  s  s  lo  pF  lG  s  s  LO  PZ  L[  s  s  `c  dn  `o  s  s  s	
 	
 	
 	
 
LL

 	E 	DZT

8 I       tyy''$./////s   A<B//B36B3c                 |   t          j                    } |                     ddt                     |                     dd           |                                 }g }|j        D ]}	 |                    t          |                                                     8# t          $ r^}|                    t          |                                d d d d d d d d d d d ddd	t          |          d
d
d
d                     Y d }~d }~ww xY wt          |          }t          t                                                    j        }t#          |||           |d |D             d}|j        r&t'          t%          j        |dd                     d S t'          d|                    d|d                    d|d          d           |d         D ]n}t'          |d          d|d          d|d          d|d          d|d          dt-          |d                     d!|d"          d#|d$          d%|d&                     od S )'Nz	--tickers*)nargsdefaultz--json
store_true)r   r+   r*   r:   r   r   c                ,    g | ]}t          |          S rV   r   r   s     rX   r   zmain.<locals>.<listcomp>  s     +M+M+MK,<,<+M+M+MrW   )r  r   Fr   r  u   현재모드=r   r   z ()r   r>   z: r   (rK   z) / r   rL   u   ) / 가격=r?   u
    / 손절=rN   u    / 목표1=rO   u    / 목표2=rP   )argparseArgumentParseradd_argumentDEFAULT_TICKERS
parse_argstickersr'  r   re   	Exceptionr<   r=   r	  r   __file__resolveparentr1  r%  printr&  r   r   )	parserargsr   r>   excr  r
  r/  r   s	            rX   mainrH  y  sp   $&&F
3HHH
666DD, i i	iKKv||~~667777 	i 	i 	iKK	&,,..$dD$PTVZ\`bfhlnrt{  ~K  MS  UX  Y\  U]  U]  _q  sE  GY  [g  h  h  i  i  i  i  i  i  i  i	i t$$G8nn$$&&-G$)))!+M+M+M+M+MNNGy NdjuQ???@@@@@[gkk)WV_EE[[QW[[[\\\=) 	N 	NCS]  M  Mc*;&<  M  Ms>?R  M  MX[\mXn  M  Mqt  vD  rE  M  M  R^  _b  cj  _k  Rl  Rl  M  M  x{  |R  xS  M  M  `c  dn  `o  M  M  |  @J  |K  M  M  N  N  N  N	N 	Ns   (4B
D'AD  D__main__)rb   )r   )r   r<   )r
  r   )#__doc__
__future__r   r:  r  r%  rm   dataclassesr   r   r   r   pathlibr   r=  r   r   r   r   r<   ra   ru   r   r   r   r   r   r   r   r   r   r	  r1  rH  rR   rV   rW   rX   <module>rN     si    # " " " " "  



   ) ) ) ) ) ) ) ) ' ' ' ' ' ' ' '        ( cbb	 "$%
 
 ! C$2((%	 		 (,"	 		        .! ! !" " " "	 	 	 	' ' ' '       *(S (S (SV    ? ? ?D  <00 00 00 00fN N N0 zDFFFFF rW   