
    pja                    D   d Z ddlmZ ddlZddlZddlmZmZ ddlmZ ddl	m
Z
 ddlmZ  ed      Zdd	Zdd
ZddZddZddd	 	 	 	 	 	 	 	 	 	 	 ddZddZd d!dZddd	 	 	 	 	 	 	 	 	 	 	 	 	 d"dZdd	 	 	 	 	 	 	 d#dZdd	 	 	 	 	 	 	 	 	 	 	 d$dZ	 d 	 	 	 	 	 	 	 d%dZy)&zDPer-strategy daily entry ledger and run mutex (atomic JSON on disk).    )annotationsN)datedatetime)Path)Any)ZoneInfozAmerica/New_Yorkc                6    | d| d|j                          dz  S )Nentry_ledger__.json)	isoformat)	state_dirstrategy_idtodays      5/opt/rentech/trading_bot/RenTech/live/entry_ledger.py_ledger_pathr      s$    {m1U__5F4GuMMM    c                    | d| dz  S )N	run_lock_r    )r   r   s     r   
_lock_pathr      s    ;-u555r   c                    | j                   j                  dd       | j                  d      }|j                  t	        j
                  |d      dz   d       |j                  |        y )	NTparentsexist_okz.tmp   )indent
utf-8encoding)parentmkdirwith_suffix
write_textjsondumpsreplace)pathpayloadtmps      r   _atomic_write_jsonr,      sU    KKdT2


6
"CNN4::ga047'NJKKr   c                b   | j                         s|j                         |ddddg dS 	 t        j                  | j	                  d            }t        |t              r+t        |j                  d            |j                         k7  r|j                         |ddddg dS |j                  d|       |j                  dd       |j                  d	d       |j                  d
d       |j                  dd       |j                  dg        |S # t        j
                  t        f$ r i }Y w xY w)Nr    )r   r   entries_submittedentries_reservedrunslast_run_identriesr   r    r   r   r/   r0   r1   r2   r3   )is_filer   r&   loads	read_textJSONDecodeErrorOSError
isinstancedictstrget
setdefault)r)   r   r   datas       r   _load_ledgerr?      s   <<>OO%&!" !
 	
zz$..'.:; dD!S&)9%:eoo>O%OOO%&!" !
 	
 	OOM;/OO'+OO&*OOFAOOM2&OOIr"K%   '* s   %D D.-D.i,  g      ?)ttl_secpoll_secc                  | j                  dd       t        | |      }t        j                         }	 |j                         r{	 t	        j
                  |j                  d            }t        |t              rDt        |j                  dd            }t        |j                  dd            }	||k(  s||	z
  |k\  rn,n+n*t        j                  |       t        j                         }||t        j                         t        j                   t"              j%                         d	}
t'        ||
       t)        d
| d|        y# t        j                  t        f$ r i }Y w xY w)zWBlock until this run_id holds the strategy run lock (stale locks expire after ttl_sec).Tr   r   r    run_idr.   tsr   )r   rC   rD   acquired_atz$[LEDGER] run lock acquired strategy= run_id=N)r#   r   timer4   r&   r5   r6   r7   r8   r9   r:   r;   r<   floatsleepr   nowNYr   r,   print)r   r   rC   r@   rA   lock_prJ   curholderrD   r*   s              r   acquire_run_lockrP   @   s7    OOD4O0	;/F
))+C
>>jj!1!17!1!CD #t$SWWXr233774+,V#bW'<

8iik! & #iik||B'113	G vw'	0XfX
NO+ (('2 s   %E E%$E%c                r   t        | |      }|j                         sy 	 t        j                  |j	                  d            }t        |t              rCt        |j                  dd            |k(  r$|j                  d       t        d| d|        y y y # t        j
                  t        f$ r i }Y qw xY w)	Nr   r    rC   r.   T)
missing_okz$[LEDGER] run lock released strategy=rF   )r   r4   r&   r5   r6   r7   r8   r9   r:   r;   r<   unlinkrL   )r   r   rC   rM   rN   s        r   release_run_lockrT   h   s    	;/F>>jj))7);< #tSWWXr%:!;v!E&4[M&RS "F   '* s   %B B65B6c                    |xs t        j                         }t        | ||      }t        |||      }t	        |j                  dd            dz   |d<   ||d<   t        ||       y)zGIncrement daily run count and set last_run_id (no entry slot consumed).r1   r      r2   Nr   r   r   r?   intr<   r,   )r   r   rC   r   r)   ledgers         r   touch_run_ledgerrZ   u   s`    !TZZ\E	;6D$U3FFA./!3F6N"F=tV$r   F)dry_runr   c               B   |xs t        j                         }|dk  ryt        | ||      }t        |||      }t	        |j                  dd            }t	        |j                  dd            }	||	z   }
|
|k\  rdd|
 d| dfS |ry	|	d
z   |d<   ||d<   t        ||       y)z8Reserve one entry slot for today if under the daily cap.r   )Fzmax_new_entries_per_day is zeror/   r0   Fzdaily entry cap reached (/z submitted+reserved))Tzdry_run: slot availablerV   r2   )TreservedrW   )r   r   rC   max_new_entries_per_dayr[   r   r)   rY   	submittedr^   useds              r   check_and_reserve_entryrb      s     !TZZ\E!#7	;6D$U3FFJJ2A67I6::0!45HxD&&'vQ/F.GG[\
 	
 .!)AF"F=tV$r   )r   c                   |xs t        j                         }t        | ||      }t        |||      }t	        |j                  dd            }|dkD  r|dz
  |d<   t        ||       yy)z;Return one reserved slot (e.g. failed order after reserve).r0   r   rV   NrW   )r   r   r   r)   rY   r^   s         r   release_entry_reservationrd      sk     !TZZ\E	;6D$U3F6::0!45H!|%-\!"4( r   c               2   |xs t        j                         }t        | ||      }t        |||      }t	        |j                  dd            }|dkD  r|dz
  |d<   t	        |j                  dd            dz   |d<   ||d<   |j                  d      }t        |t              sg }|t        j                  t              j                         d}	|	j                  |       |j                  |	       ||d<   t        ||       t        d| d	|d    d
|        y)z>Commit one reserved slot to submitted (call after order sent).r0   r   rV   r/   r2   r3   )rC   rD   z![LEDGER] entry recorded strategy=z submitted=rF   N)r   r   r   r?   rX   r<   r9   listr   rJ   rK   r   updateappendr,   rL   )
r   r   rC   r   entry_fieldsr)   rY   r^   r3   rows
             r   record_entry_submittedrk      s    !TZZ\E	;6D$U3F6::0!45H!|%-\!""%fjj1Da&H"IA"MF"F=jj#Ggt$ll2((*C JJ|NN3F9tV$	
+K= 9/01&	Cr   c                    |xs t        j                         }t        | ||      }t        |||      }t	        |j                  dd            S )Nr/   r   )r   r   r   r?   rX   r<   )r   r   r   r)   rY   s        r   count_entries_submitted_todayrm      sG    
 !TZZ\E	;6D$U3Fvzz-q122r   )r   r   r   r;   r   r   returnr   )r   r   r   r;   rn   r   )r)   r   r*   dict[str, Any]rn   None)r)   r   r   r;   r   r   rn   ro   )r   r   r   r;   rC   r;   r@   rH   rA   rH   rn   rp   )r   r   r   r;   rC   r;   rn   rp   )N)
r   r   r   r;   rC   r;   r   date | Nonern   rp   )r   r   r   r;   rC   r;   r_   rX   r[   boolr   rq   rn   ztuple[bool, str])r   r   r   r;   r   rq   rn   rp   )r   r   r   r;   rC   r;   r   rq   ri   r   rn   rp   )r   r   r   r;   r   rq   rn   rX   )__doc__
__future__r   r&   rG   r   r   pathlibr   typingr   zoneinfor   rK   r   r   r,   r?   rP   rT   rZ   rb   rd   rk   rm   r   r   r   <module>rx      s   J "   #    !N6N %P%P%P %P
 %P %P 
%PP
T%    !	   J 	))) 	)
 
)*  
   
J 333 3 		3r   