
    pj                         S r SSKrSSKrSSKrSSKJrJr  SSKJr  \R                  R                  \R                  R                  \5      5      r\R                  R                  \S5      rS r " S S\5      r\S	:X  ao  \" \R(                  5      S
:  a  \" \R(                  S
   5      OSr\R.                  " \5        \" S\4\5      r\" S\ S35        \" S5        \R5                  5         gg)a'  
SwingTrader local HTTP server.

Serves all files in this directory AND handles position writes via POST /api/positions.

Usage:
    python3 server.py           # port 8080 (default)
    python3 server.py 9000      # custom port

Then open: http://localhost:8080/swingtrader_dashboard_v2.1.html
    N)SimpleHTTPRequestHandler
HTTPServer)datezpositions.jsonc                   ^ [        [        S5       n[        R                  " U5      nS S S 5        U R	                  S5      =(       d    SR                  5       R                  5       nU R	                  S5      =(       d    SR                  5       R                  5       m[        R                  " 5       R                  5       nT(       d  [        S5      eUS:X  a  U R	                  S5      =(       d    Un[        U S   5      n[        U S	   5      nUS
::  a  [        S5      eUS:  a  [        S5      eTU R	                  SS5      UUUS S S S SSSS
U R	                  SS5      S.nWR                  S/ 5      R                  U5        GOUS:X  Ga7  WR	                  S/ 5      n	[!        U4S jU	 5       S 5      n
U
c  [        T S35      eU R	                  S5      =(       d    Un[        U R	                  SU
S   5      5      n[        U R	                  S	S
5      5      nUS
:X  a  [        S5      eUS
::  a  [        S5      eU
S	   U-   nUS
::  a  [        SU S35      eUS
:  a"  U
S	   U
S   -  X-  -   U-  n[#        US5      U
S'   XS	'   SU SUS S US! 3nU
R	                  S5      =(       d    SS"-   U-   R%                  S#5      U
S'   OUS$:X  a  WR	                  S/ 5      n	[!        U4S% j['        U	5       5       S 5      nUc  [        T S35      eU R	                  S&5      =(       d    Un[        U R	                  S'S
5      5      nUS
::  a  [        S(5      eU	R)                  U5      n
0 U
EUS)US! S*3S+.EnUR                  S,/ 5      R                  U5        O[        S-U S.35      eXBS/'   [        [        S05       n[        R*                  " X!S1S29  S S S 5        S3US4.$ ! , (       d  f       GN= f! , (       d  f       N%= f)5Nraction tickerzticker is requiredadd
entry_dateentry_price_cadsharesr   zentry_price_cad must be > 0   zshares must be >= 1companyFnotes)r
   r   r   r   r   stop_loss_cadtarget_1_cadtarget_2_cadtarget_3_cadtarget_1_hittarget_2_hit
setup_type	days_heldr   open_positionsmodifyc              3      >#    U  H4  oR                  S 5      =(       d    SR                  5       T:X  d  M0  Uv   M6     g7fr
   r	   Ngetupper).0pr
   s     '/media/usb/claude/SwingTrader/server.py	<genexpr>(apply_position_change.<locals>.<genexpr>?   s.     Ux!EE(O,Ar+H+H+Jf+TAAxs   /?	?z not found in open_positionsmodification_datemodification_price_cadz*share change (shares delta) cannot be zeroz"modification_price_cad must be > 0zResult would be z8 shares. Use Remove action to close a position entirely.   z	Modified z: z+dzsh @ $z.2fz | z |removec              3      >#    U  H7  u  pUR                  S 5      =(       d    SR                  5       T:X  d  M3  Uv   M9     g7fr   r   )r!   ir"   r
   s      r#   r$   r%   _   s5     \.41155?3Hb2O2O2QU[2[QQ.s
   2A	A	exit_dateexit_price_cadzexit_price_cad must be > 0zExited at $z CAD)
close_dateclose_reasonclosed_positionszUnknown action "z ". Expected: add, modify, removelast_updatedw   )indentT)okr1   )openPOSITIONS_FILEjsonloadr   lowerstripr    r   today	isoformat
ValueErrorfloatint
setdefaultappendnextroundlstrip	enumeratepopdump)payloadfdatar   r<   r   r   r   new_posopen_posposmod_date	mod_pricedelta
new_sharesavgnote_suffixidxr,   
exit_priceclosedr
   s                        @r#   apply_position_changerX      s   	nc	"ayy| 
# kk(#)r00288:Fkk(#)r00288:FZZ\##%E-..!++l3<u
(9 :;gh/0a:;;A:233$%kk)R8(.$""""## %kk'26
  	("-44W=	8	88,b1UxUW[\;x'CDEEKK 34='++&>DU@VWX	Ha01A:IJJ>ABB]U*
?":, /B B 
 19x=3'8#99E<MMQ[[C%*3]C!""H!(2eBZvi_M)/R58;FNNtTG	8	88,b1\9X.\
 ;x'CDEE[[-6	7;;'7;<
?9::ll3

%)*S)9>

 	*B/66v> +F83STUU 	nc	"a		$!$ 
# ..C 
#	"| 
#	"s   O4O)
O&)
O7c                   @   ^  \ rS rSrS rS rS rS rU 4S jrSr	U =r
$ )SwingTraderHandler}   c                 F    U R                  S5        U R                  5         g )N   )_cors_headersend_headers)selfs    r#   
do_OPTIONSSwingTraderHandler.do_OPTIONS~   s    3    c                 ,   U R                   S:X  au  [        U R                  R                  SS5      5      nU R                  R                  U5      n [        R                  " U5      n[        U5      nU R                  SU5        g U R                  S5        U R!                  5         g ! [        [        [        4 a'  nU R                  SS[        U5      05         S nAg S nAf[         a'  nU R                  SS[        U5      05         S nAg S nAff = f)	Nz/api/positionsContent-Lengthr   r]   i  errori  i  )pathr@   headersr   rfilereadr8   loadsrX   _json_responseKeyError	TypeErrorr>   str	Exceptionsend_responser_   )r`   lengthbodyrI   resultes         r#   do_POSTSwingTraderHandler.do_POST   s    99(())*:A>?FZZ__V,D<**T*/8##C0 s# i4 <##C'3q6):;; <##C'3q6):;;<s$   3B( (D=CD,DDc                     U R                  U5        U R                  SS5        U R                  SS5        U R                  SS5        g )NzAccess-Control-Allow-Origin*zAccess-Control-Allow-MethodszGET, POST, OPTIONSzAccess-Control-Allow-HeadersContent-Type)rq   send_header)r`   codes     r#   r^    SwingTraderHandler._cors_headers   sD    4 6=79MN7Hrc   c                 0   [         R                  " U5      R                  5       nU R                  U5        U R	                  SS5        U R	                  S[        [        U5      5      5        U R                  5         U R                  R                  U5        g )Nrz   zapplication/jsonre   )
r8   dumpsencoder^   r{   ro   lenr_   wfilewrite)r`   r|   objrs   s       r#   rl   !SwingTraderHandler._json_response   sn    zz#%%'4 +=>)3s4y>:

rc   c                 ~   > U(       a5  [        US   5      R                  S5      (       a  [        TU ]  " U/UQ76   g g g )Nr   POST)ro   
startswithsuperlog_message)r`   fmtargs	__class__s      r#   r   SwingTraderHandler.log_message   s7    CQL++F33G+d+ 44rc    )__name__
__module____qualname____firstlineno__ra   rv   r^   rl   r   __static_attributes____classcell__)r   s   @r#   rZ   rZ   }   s"     I, ,rc   rZ   __main__r   i  z0.0.0.0u(   SwingTrader server → http://localhost:z /swingtrader_dashboard_v2.1.htmlzPress Ctrl+C to stop.)__doc__r8   ossyshttp.serverr   r   datetimer   rg   dirnameabspath__file__BASEjoinr7   rX   rZ   r   r   argvr@   portchdirserverprintserve_foreverr   rc   r#   <module>r      s   
  	 
 < !:;d$45b/J&,1 &,R z"388}q03sxx{dDHHTND)+=>F	4TF:Z
[\	
!"
 rc   