a
    c                     @   s   d dl mZ d dlmZmZmZ d dlT d dlZd dlZ	dd Z
dd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZG dd dZdS )    CryptoPlatforms)datetimedatetimezone)*Nc                   C   s   t  dS )Nz%m-%d-%Y_%H-%M-%S)r   nowstrftime r
   r
   F/var/www/html/myfo-crypto/python/myfo/crypto/strategies/common/core.pyget_timestamp   s    r   c                 C   s   t dt |  d S )Nz[{}] {})printformatr   )messager
   r
   r   log
   s    r   c                 C   s2   | dkrd}n | dkrd}n| dkr*d}nd}|S )NZBTCgMbP?ZETH{Gz?ZBNB皙?   r
   )spot_symbolcontract_sizer
   r
   r   get_contract_size   s    r   c           	      C   s   t | d }t | d }t |d }t |d }t |d }t |d }|ddg d|ddg< |ddg d|ddg< |ddg d|ddg< |ddg d|ddg< |ddg d|ddg< |ddg d|ddg< ||||||fS Nbuysellsizepricefloat64pd	DataFrameastype)	order_books_callorder_books_putorder_books_perpetualorder_books_call_bidorder_books_call_askorder_books_put_bidorder_books_put_askorder_books_perpetual_bidorder_books_perpetual_askr
   r
   r   format_order_book   s    r*   c                 C   s<  t | d  }t |d  }|j|d |kdf jd | }	| j| d |kdf jd | }
t |d  }|j|d |kdf jd | }t |d  }|j|d |kdf jd | }t |d  }|j|d |kdf jd | }t |d  }|j|d |kdf jd | }|||	|
||||||||fS )Nr   r   r   )floatminmaxlocvalues)r)   r(   r$   r%   r'   r&   r   perpetual_price_askperpetual_price_bidperpetual_size_bidperpetual_size_askcall_price_bidcall_size_bidcall_price_askcall_size_askput_price_askput_size_askput_price_bidput_size_bidr
   r
   r   format_bid_ask)   s          r<   c                 C   s   t | d }t |d }t |d }|ddg d|ddg< |ddg d|ddg< |ddg d|ddg< |||fS r   r   )r!   r"   r#   r$   r'   r)   r
   r
   r   format_order_book_sell9   s    r=   c                 C   s   t | d }t |d }t |d }|ddg d|ddg< |ddg d|ddg< |ddg d|ddg< |||fS )Nr   r   r   r   r   r   )r!   r"   r#   r%   r&   r(   r
   r
   r   format_order_book_buyD   s    r>   c           	      C   s   d}d}d}d}d}| j dgdgd} t| d jd }| j| d |kdf jd | }t| d dkrt| d jd }| j| d |kdf jd | | }t| d jd	 }| j| d |kdf jd | | | }nd}|||||||fS )
NTr   r   F	ascendingr      r      sort_valuesr+   r/   r.   len)	r(   r   order_book_sizeperpetual_price_bid_2perpetual_size_bid_2perpetual_price_bid_3perpetual_size_bid_3perpetual_price_bid_1perpetual_size_bid_1r
   r
   r   
format_bidO   s     $*rM   c           	      C   s   d}d}d}d}d}| j dgdgd} t| d jd }| j| d |kdf jd | }t| d dkrt| d jd }| j| d |kdf jd | | }t| d jd }| j| d |kdf jd | | | }nd	}|||||||fS )
NTr   r   r?   r   rA   r   rB   FrC   )	r)   r   rF   perpetual_price_ask_2perpetual_size_ask_2perpetual_price_ask_3perpetual_size_ask_3perpetual_price_ask_1perpetual_size_ask_1r
   r
   r   
format_askc   s     $*rT   c                 C   s  |j dgdgd}|j dgdgd}|j dgdgd}t|d jd }|j|d |kdf jd | }| |krt|d dkrt|d jd }||j|d |kdf jd | 7 }| |krt|d d	krt|d jd }||j|d |kdf jd | 7 }t|d jd }|j|d |kdf jd | }| |krt|d dkrt|d jd }||j|d |kdf jd | 7 }| |krt|d d	krt|d jd }||j|d |kdf jd | 7 }t|d jd }	|j|d |	kdf jd | }
| |
krt|d dkrt|d jd }	|
|j|d |	kdf jd | 7 }
| |
krt|d d	krt|d jd }	|
|j|d |	kdf jd | 7 }
|||||	|
fS )
Nr   Tr?   Fr   r   rB   r   rA   rC   )
trade_sizer)   r$   r'   r   r0   r3   r4   r5   r8   r9   r
   r
   r   format_bid_ask_sellw   s8     $$ $$ $$rV   c                 C   s  |j dgdgd}|j dgdgd}|j dgdgd}t|d jd }|j|d |kdf jd | }| |krt|d dkrt|d jd }||j|d |kdf jd | 7 }| |krt|d d	krt|d jd }||j|d |kdf jd | 7 }t|d jd }|j|d |kdf jd | }| |krt|d dkrt|d jd }||j|d |kdf jd | 7 }| |krt|d d	krt|d jd }||j|d |kdf jd | 7 }t|d jd }	|j|d |	kdf jd | }
| |
krt|d dkrt|d jd }	|
|j|d |	kdf jd | 7 }
| |
krt|d d	krt|d jd }	|
|j|d |	kdf jd | 7 }
|||||	|
fS )
Nr   Fr?   Tr   r   rB   r   rA   rC   )rU   r(   r%   r&   r   r1   r2   r6   r7   r:   r;   r
   r
   r   format_bid_ask_buy   s8     $$ $$ $$rW   c                 C   s  t |}t |}t |}t |}t |}t |}d}d}	t|}
| dkr|| }||	 }t |t | dk rxt||}n|d }|| | | |
 }|| | |
 }d| |
 | }t ||
 | | | }n|| }||	 }t |t | dkrt||}n|d }|| | | |
 }|| | |
 }d| |
 | }| t ||
  | | }|||  d }|d	|  }t|| }|| }|||||fS 
NrA   r   r   ?rB   iUMu_?ffffff?d   m  r+   r   r-   abs)	spot_sidestrikeperiodr   symbol
spot_price
call_price	put_priceoption_margin_ratiofuture_margin_ratior   call_marginperpetual_margininvestment_margininvestment_contract_adjustedfeesprofit
put_margincurrent_yieldcurrent_apy
investmentr
   r
   r   compute_apy   sB    rs   c                   @   s   e Zd Zd*ddZdd Zdd Zdd	 Zd
d Zdd Zd+ddZ	d,ddZ
d-ddZd.ddZdd Zd/ddZd0ddZdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) ZdS )1UserFc                 C   s   || _ |j|d |kdf jd | _|j|d |kdf jd | _|j|d |kdf jd | _||d |k | _|j|d |kdf jd | _|| _i | _	d| _
d| _d| _d| _d| _d| _d| _d| _d| _d S )Nid	firstnamer   lastnameemailuser_idtrade_threshold)ru   r.   r/   rv   rw   rx   	user_apisrz   testing
connectorstotal_balanceavailable_balancetotal_deposittotal_withdrawtotal_margin
total_feestotal_profitmax_investmenttrading_credit)selfry   users
users_apisr|   r
   r
   r   __init__   s"    zUser.__init__c                 C   s6   | j | j d |k| j d | jk@  }|jr.dS dS d S )Nplatform_idr|   FT)r{   r|   empty)r   r   apir
   r
   r   has_platform_api  s    zUser.has_platform_apic                 C   s   | j sDz.|jdd| j ddgd}|d jd }W n   Y dS 0 |jdd| j g d	d}||d
 dk|d | jk@  }|d  }||d krdS dS )NZusers_balanceszWHERE user_id = z AND platform_id = 2r~   argcolumnsr   Fcrypto_payments)ru   ry   paymentto_payr   ry   r   g?T)r~   getTableru   r/   sum)r   databaseZuser_balancesZuser_balancepaymentsZpayment_sumr
   r
   r   is_payment_uptodate  s    zUser.is_payment_uptodatec                 C   sD   || j v r(| j |  | jkr(| j | S | |s6d S | |S d S N)r}   
is_testingr|   _User__create_connectorget_connector)r   r   r
   r
   r   r      s
    

zUser.get_connectorc                 C   s   |  | }|S r   )r   get_wallet_transactions)r   r   Zaumr
   r
   r   get_aum(  s    zUser.get_aumc                 C   s   |  | | | \}}t| j| j |}d| j }|| }| jdkr\td| j |}n$| jdkrxtd| j |}n|d }|| _|| _| jS )N皙?ia  g{Gz?i  g333333?g?)update_balancesr   get_balancer,   r~   r   r   r   )r   r   balancer   Zminimum_balanceZclient_investmentr
   r
   r   get_investment-  s    



zUser.get_investmentNc              
      s  i }i }|rx|j dd| jd }jr*q|j dddtt|d jd  jrXq d  } fd	d
|D }n| 	|
 }dd
 |D }| D ]}|| d }	|| d }
z| 	||}W n* ty   Y qY n ty   Y qY n0 |d dkrt| 	||d }||d< |
|d< ||d< |
dkrJ|	ddn|	dd |d< |||	< | 	||}|d d |d< q|S )Ncrypto_arbitragesz#WHERE user_id = {} AND accepted = 1)r   crypto_arbitrages_underlyingszWHERE arbitrage_id in ({})z, ru   security_idc                    sD   i | ]<}|  d  |k d j d   d  |k d j d dqS )r   product_symbolr   	is_futurerc   r   )r/   ).0
product_idunderlyingsr
   r   
<dictcomp>W  s
   z&User.get_positions.<locals>.<dictcomp>c                 S   s8   i | ]0}|d  |d d |d d dkr,dnddqS )r   productrc   contract_typeperpetual_futuresr   r   r   r
   )r   orderr
   r
   r   r   ]  s
   
rc   r   r   r   
mark_pricer   USDT -underlying_symbolmargin)r   r   ru   r   joinmapstrr/   uniquer   get_order_historykeysget_positionsUnavailableProductErrorUnsupportedProductErrorr+   
get_tickerreplacesplitget_position_margin)r   r   r   	positionsproducts
arbitragesproduct_idsZorder_historyr   r   r   positionr   Zposition_marginr
   r   r   r   J  sD    ,

(zUser.get_positionsc                    s  d}|s|  ||}dd | D }i }| D ]\}}|d |vri ||d < |d dkrbdnd||d  d< |d dkrdnd||d  d	< q2||d  d  |d dkrdnd7  < ||d  d	  |d dkrdnd7  < q2| D ]*\}}	|	d dks|	d	 d
 dkrd}q|r| D ]  fdd| D }
d}d}|
 D ]>}|drr||
| d 7 }|drR||
| d 7 }qR|| krd}n||  d kr(d}q(|S )NTc                 S   s"   i | ]\}}|d  dkr||qS )r   r   r
   r   keyvaluer
   r
   r   r         z&User.check_hedging.<locals>.<dictcomp>r   r   r   r   futuresoptionsrB   Fc                    s2   i | ]*\}}  d d|v r|d dkr||qS )r   r   r   r   )r   r   future_symbolr
   r   r     r   zC-r   zP-)r   itemsr   
startswith)r   r   r   r   Zhedgedr   Zunderlying_symbolsrc   r   
underlyingr   Z
calls_sizeZ	puts_sizeoption_symbolr
   r   r   check_hedging}  s@     "(*zUser.check_hedgingc                 C   s0  d}d}d}|s|  ||}| D ]\}}t|d }	t|d }
t|d }t|d |	 }t|d }|d	krt|
| }|| |d
< || |d< ||| k s||| krd}q$|
dk r$|d d }t| ||d |	 }t|
| }|| |d
< || |d< ||| k s&||| kr$d}q$|S )NTr   g      ?r   r   r   entry_pricer   r   Zlower_marginZhigher_marginFr   r   r   )r   r   r   r+   r_   r   r   )r   r   r   r   ZmarginedZlower_factorZhigher_factorrc   r   r   r   r   r   r   	thresholdr   Zmark_price_futurer
   r
   r   check_margin  s4    zUser.check_marginc              	   C   s  d}|s|  ||}i }| D ]\}}	||d |	d k }
|
 D ]\}}|d }||vri ||< |d dkr|	d || d< q|	d  || d< qD|d dkr|| d  |	d 7  < qD|| d  |	d 8  < qDq | D ]H\}}|d	d
}||vri ||< |d || d< q|d || d< q| D ]\}}d|vrZtd| d d}nXd|vrztd| d d}n8|d |d kr2td| d|d  d|d   d}q2||fS )NTarbitrage_idru   r   
order_typer   r   r   r   r   r   zSymbol 'z"' not found in database arbitragesFz' not found in positionsz#' has mismatching size (Database : z / Platform : )r   iterrowsr   r   r   )r   r   user_arbitragesZuser_underlyingsr   r   Zmatch_deltaZunderlyings_comparisonindex	arbitrageZarbitrage_underlyingsr   rc   r   Z
comparisonr
   r
   r   check_arbitrages_positions  sB    


"zUser.check_arbitrages_positionsc                 C   s  d}d}|  | \}}|  | }t|}|jrld| _d| _d| _d| _	d| _
d| _d| _d| _d S t|j|d< |d jd|d< t|jjj|d< t||jdk d  }t||jdk d  }t||jdk d  t||jdk d   }	||jd	k d  }
t||jd
k d  }t||jdk d  }| |}d}| D ]\}}d}t|d }|d | }|d dk rt|d | t|  t|d  }n$t|t|d |  t|d  }|d dkrH|d dk r(|t|d t|d  | 7 }n |t|d t|d  | 7 }||7 }|t|d 7 }ql|| _|| _|| _|	| _	|| _
|| | _|| | | _| j| j| j  | j | j	 |
 | _d S )Nr   r   %Y-%m-%ddepositamountZ
withdrawalZtrading_creditsZtrading_credits_paidZfundingliquidation_feeZtrading_fee_creditsr   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r~   r   to_datetimer   dtr	   r_   transaction_typer   r   r   r   r+   )r   r   Ztotal_unrealizedZtotal_premiumr   r   historysum_depositZsum_withdrawZsum_trading_creditsZsum_fundingZsum_liquidation_feesZsum_trading_feesr   r   rc   r   Zunrealized_plr   r   r
   r
   r   r     s^    
4
($" 
zUser.update_balances   c                 C   s~   |j dd| j ddgd}|jr&dS tt }|jt|d | 	 g d j
d }t|| d}||krvdS d	S d S )
Nr   z0WHERE accepted = 1 AND status = 0 AND user_id = ru   
created_atr   Tr   mF)r   ru   r   np
datetime64r   r   r.   r_   idxminr/   timedelta64)r   r   rb   r   r   Zlatestdiffr
   r
   r   is_trade_period_expiredM  s    
&zUser.is_trade_period_expiredc           >      C   s  |d j d }|d j d }|d j d }|d j d }	|d j d }
||d |k d j d }||d |k d j d }||d |k d j d }|d	 j d }|d j d }|d
|  }|d j d }|d j d }|d j d }| ||d }| ||}| ||}t|}||d |k d j d }d}d}|dkrzt|||\}}}W n   Y dS 0 t|||||\}}} }!}"}#td| d|  td|! d|   td|# d|"  ||  }$|| }%t|t| dk rt|%|$}$n|%d }$|"|  |$ |% | }&|dkr4t	
||& }'nt||!|#}'||  |" | }(d| | |' })t|| |( |' |) }*|$}+|},| }-|"}.n<zt|||\}/}0}1W n   Y dS 0 t||1|/|0|\}2}3}4}5}6}7td|3 d|2  td|5 d|4  td|7 d|6  ||6 }8|2| }%t|t|2 dkr<t|%|8}8n|%d }8|4|6 |8 |% | }&|dkrrt	
||& }'nt||5|7}'|4|2 |6 | }(d|2 | |' })|( t||  |' |) }*|8}+|2},|4}-|6}.|*|&|'  d }9|9d
|  }:|d t| d t|	 d d  t|: };|d }<|(| |' }=|&|' }&|
d!kr|:d"k rRtd#|: dS |r~|:d$kr~|'|=|&|:|9|;|%|+|*|,|-|.fS |:|d!|<  k r|:d$k rtd%|:|| dS |'|=|&|:|9|;|%|+|*|,|-|.fS n|'|=|&|:|9|;|%|+|*|,|-|.fS d S )&Nspot_idr   call_idput_idmaturity_daysis_testr   r   target_yieldr]   ra   rr   r   r   r   rA   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   zOrderbook spot: z at zOrderbook call: zOrderbook put: rY   rB   rZ   r[   r\   _strike_period_days_annual_yieldr   
   z*[ERROR] Arbitrage yield is bellow 10% ({})   z7[ERROR] Arbitrage yield is ({}) expecting ({} +/- {} %))r/   r   get_orderbookr   r=   rV   r   r+   r-   r   floorr,   r>   rW   r   r   )>r   r   r   r   Zyield_toleranceZis_super_trader   r   r   rb   r   r   call_symbol
put_symbolZinitial_yieldZinitial_periodZinitial_apyZinitial_strikeZinitial_investmentrU   perpetual_orderbookcall_orderbookput_orderbookr   sidecall_margin_ratioperpetual_margin_ratiocall_orderbook_bidput_orderbook_askperpetual_orderbook_askZcurrent_perpetual_ask_priceZcurrent_perpetual_ask_sizeZcurrent_call_bid_priceZcall_bid_sizeZcurrent_put_ask_priceZput_ask_sizeri   rj   rk   max_leveragerl   rm   rn   Zoption_marginrd   re   rf   call_orderbook_askput_orderbook_bidperpetual_orderbook_bidZcurrent_perpetual_bid_priceZcurrent_perpetual_bid_sizeZcurrent_call_ask_priceZcall_ask_sizeZcurrent_put_bid_priceZput_bid_sizero   rp   rq   
trade_nameZyield_tolerance_factorrr   r
   r
   r   check_yieldb  s    


,

zUser.check_yieldc	                 C   s  t |}t |}t |}t |}t |}t |}d}	d}
t|}|dkr|	| }||
 }t |t | dk rxt||}n|d }|| | | | }|| | | }d| | | }t || | | | }n|	| }||
 }t |t | dkrt||}n|d }|| | | | }|| | | }d| | | }| t ||  | | }|||  d }|d	|  }t|| }|| }|||||fS rX   r^   )r   r`   ra   rb   r   rc   rd   re   rf   rg   rh   r   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   r
   r
   r   rs     sB    zUser.compute_apyc                 C   s   d | j| j| j| jS )Nz{} - {} {} ({}))r   ru   rv   rw   rx   )r   r
   r
   r   	to_string  s    zUser.to_stringc                 C   s   |  |s"td|  | dS | j| jd |k| jd | jk@  d jd }| j| jd |k| jd | jk@  d jd }| | }r|||| j| j|< dS td	t	| d
  dS d S )NzH[ERROR] User [{}] doesn't have API keys configured for platform_id : {}.Fr   r|   api_keyr   
api_secretTz+[ERROR] Connector [{}] isn't available yet.name)
r   r   r   r  r{   r|   r/   _User__connectorr}   r   )r   r   Zuser_api_keyZuser_api_secret	connectorr
   r
   r   Z__create_connector  s,    
zUser.__create_connectorc                 C   s   t | d S )Nr  r   )r   Zconnector_identifierr
   r
   r   Z__connector$  s    zUser.__connectorc                 C   sB  |  }t|}|jdg dd}	|	jdtjddd}	| }
t|
}||d 	|	d	   
 }t|j|d
< ||jtjtjdk }|d
 jd|d
< t|jjj|d
< t|j|d< |d jd|d< t|jjj|d< |d d|d< ||j|k 
 }|d  }||d t|k 
 }|d }||j|k 
 }||jdk d  }||jdk|jdk@  
 }||j|k 
 }||jt k|j|k@  jdu r|
 }||j|d dkdf< ||d 	|d  
 }| }|d }|d D ]}|j|d |kdf jd }t|d t |d d krt |dkr|j|d t|d kdf jd }nd}nd}||krd}||d |k d jd }||d |k d jd }zt|d }W n   t|d }Y n0 t||d |k d jd }|d D ]}z0|j|j!|ddk|j"|k@ df jd }W n0   |j|j!|k|j"|k@ df jd }Y n0 t||t|t | |t |  ||t | ddg}|j#d|j$d d!d" q"qn\|
 }||j|d dkdf< ||d# 	|d  
 }|j% D ]}t|j|j|k|jdk@ df  }t|j|j|k|jd$k@ df  }t|j|j|k|jd%k@ df  }t|j|j|k|jd&k@ df  }|d D ]n}|j|j!|k|j"|k@ df jd }t|||| t | || t | dd'g}|j#d|j$d d!d" qʐq$d S )(Ncrypto_orders_history)ru   r   exchange_id)r   z^\s*$T)regexr   ru   r  r   )tzr   r   r   r   r   r   r   ZDETO_STAKING_POOLZUSDT_STAKING_POOLr   r   r   Zid_index   	meta_dataZcashflowpnlZpaid_commissionr   )r   underlying_idr   r  commissionsstatusappendFcon	if_existsr   contract_fund
settlement
commissionr   )r   r!  r   r"  r#  )&r   r   r   r   r   r   nanfillnar   isincopyr   r   r   r   r   utcr   r	   r   r    r-   r+   r(  r   r   todayr   r.   reset_indexrename_axisr/   rE   r   r   to_sqlenginer   )r   r   platform_connectorZunderlyings_closedr   Zarbitrage_start_dateZarbitrages_closedr   Zall_trades_walletr  Zorders_historyZall_trades_ordersZ	trad_sizerc   Z
all_tradesr   Z
arbs_undericontractZnext_contractZ	total_pnlZ
meta_datasr  r*  Zarbitrage_closedr!  ordersr   r)  r   r
   r
   r   update_order_history'  s    

$&
0*

 &&&&$
zUser.update_order_historyc                 C   s  d}d}|j dg dd|d}|j dg dd|d}td	| |d
 }|d D ]}	t||j|	k d jd }
t||j|	k d jd }||j|	k d jd }||j|k d jd }|dkr||krt|
| dkst|
| dkr|}
|t|
| 7 }|d|
| qZtd|| |d|| || }td|| jd | j | t	
| j|d|dg}|jd|jddd d S )Nr   r   r  )ru   r   r!  r   r#  r"  zWHERE arbitrage_id = '{}')r   r   r   )ru   r   r   z,[Arbitrage {}] - Update pnl for underlyings.r   ru   r   r"  r!  r   g?gffffff?zEUPDATE crypto_arbitrages_underlyings SET `pnl` = '{}' WHERE id = '{}'z#[Arbitrage {}] Final profit is : {}zLUPDATE crypto_arbitrages SET status = 1, final_profit = '{}' WHERE id = '{}'zD[Arbitrage {}] User '{}' will have to pay {} to Myfo for this trade. )ry   r   r   r   r   r$  Fr%  )r   r   r   r+   ru   r/   executerv   rw   r   r   r3  r4  )r   r   r   Zspot_profitrc   Zfinal_profitrm   r8  r   r6  r   r"  r!  r   Z	myfo_feesr   r
   r
   r   compute_pandl  s@     
zUser.compute_pandl)F)N)NN)NN)NN)r   )F)__name__
__module____qualname__r   r   r   r   r   r   r   r   r   r   r   r   r  rs   r  r   r  r9  r<  r
   r
   r
   r   rt      s&   
	
3
4
&
0F

w7lrt   )&myfo.crypto.connector.common.platformsr   r   r   r   myfo.crypto.exceptionspandasr   numpyr   r   r   r   r*   r<   r=   r>   rM   rT   rV   rW   rs   rt   r
   r
   r
   r   <module>   s"   ""7