@@ -19,6 +19,14 @@ class SystemApiView(FlaskView):
1919
2020 def get_x_percentage_of_y (self , x , y ): return float (y / 100 ) * x
2121
22+ def update_system_without_going_offline (self , system , data ):
23+ online = system .online
24+ system .update_data (data )
25+ system .online = online
26+ db .session .add (system )
27+ db .session .commit ()
28+ return system
29+
2230 def get (self ):
2331 now = datetime .now ()
2432
@@ -46,9 +54,6 @@ def get(self):
4654 try :
4755 price_average = float (pynance .price .average (cur1 + cur2 ).json ["price" ])
4856 except AttributeError :
49- # system.online = False
50- # db.session.add(system)
51- # db.session.commit()
5257 chatterer .chat ("UNKNOWN SYMBOL" )
5358 return jsonify ({
5459 "date" : str (datetime .now ().strftime ('%d-%m-%y %H:%M:%S' )),
@@ -57,17 +62,16 @@ def get(self):
5762 "msg" : chatterer .msg
5863 }), 200
5964
60- if model is None : brought_price = price_average
61- else : brought_price = float (model .brought_price )
62-
63- take_profit = float (system .take_profit ) # The percentage to take as profit, cannot be higher then 99
65+ # The work price is or the average price, or the price which we brought for
66+ if model is None : work_price = price_average
67+ else : work_price = float (model .brought_price )
68+ # The percentage to take as profit, cannot be higher then 99
69+ take_profit = float (system .take_profit )
6470
6571 try :
72+ # Check if we can get the fees, which also allows us to check if Binance is available
6673 fees = pynance .price .fees (cur1 + cur2 ).json ['tradeFee' ].pop (0 )
6774 except AttributeError :
68- # system.online = False
69- # db.session.add(system)
70- # db.session.commit()
7175 chatterer .chat ("BINANCE SERVICES ARE UNAVAILABLE AT THIS TIME" )
7276 return jsonify ({
7377 "date" : str (datetime .now ().strftime ('%d-%m-%y %H:%M:%S' )),
@@ -76,99 +80,118 @@ def get(self):
7680 "msg" : chatterer .msg
7781 }), 200
7882
79- fee_maker = 1 + fees ['maker' ] * 100 # Maker -> Buys crypto
80- fee_taker = 1 + fees ['taker' ] * 100 # Taker -> Sells crypto
83+ # Get the fees from the response
84+ fee_maker = fees ['maker' ] # Maker -> Buys crypto
85+ fee_taker = fees ['taker' ] # Taker -> Sells crypto
8186 symbol = fees ['symbol' ]
8287
88+ # Get information about the selected symbol
8389 exchange_info = pynance .exchange_info (symbol )
8490 stepSize = [ i for i in exchange_info ['filters' ] if i ['filterType' ] == 'LOT_SIZE' ].pop (0 )['stepSize' ]
8591 precision = int (round (- math .log (float (stepSize ), 10 ), 0 ))
8692
87- balance = pynance .wallet .balance (cur1 )
88- balance2 = pynance .wallet .balance (cur2 )
89-
90- balance_free = float (balance ['free' ]) # BTC
91- balance_locked = float (balance ['locked' ])
92- balance2_free = float (balance2 ['free' ]) # USDT
93- balance2_locked = float (balance2 ['locked' ])
94- current_price = float (pynance .price .asset (cur1 + cur2 ).json ['price' ])
95-
96- # Price of the fees we paid
97- paid_fees = float (brought_price * balance_free ) * float (fee_taker / 100 )
98- # Price including fees we have paid
99- paid_total = float (brought_price * balance_free ) + paid_fees
100-
101- # Price of the fees if we wouldve brought
102- wouldve_paid_fees = float (current_price * balance_free ) * float (fee_taker / 100 )
103- # Total price including fees if we brought
104- wouldve_paid = float (current_price * balance_free ) + wouldve_paid_fees
105-
106- if model is not None :
107- chatterer .update_price (f"{ float (round (float (current_price ) * float (model .quantity ), 6 ))} - { float (round (current_price , 6 )) } - { model .quantity } " )
108- else : chatterer .update_price (f"0.0 - { float (round (current_price , 6 )) } - 0" )
109-
110- wanted_profit = paid_total * float (take_profit / 100 )
111- sellprice_without_loss_on_fee_plus_profit = float (round (float (paid_total + wanted_profit ), precision ))
112-
113- minimal_money_needed_to_buy = current_price * 0.1 #
114-
115- # If we are in profit or if the bot is panikkin + the price is higher then what we paid; we sell.
116- if wouldve_paid > sellprice_without_loss_on_fee_plus_profit or system .panik and wouldve_paid > paid_total :
117- chatterer .chat (f"SELLING { cur1 } " )
118- quantity = float (round (self .get_x_percentage_of_y (99.9 , balance_free ), precision ))
119- sell_order = pynance .orders .create (symbol , quantity , False , order_id = 'test_api' )
120- if sell_order is not None :
121- data = sell_order .json ['fills' ].pop (0 )
122- # Price of the fees we paid
123- paid_fees = float (float (data ['price' ]) * balance_free ) * float (fee_taker / 100 )
124- # Price including fees we have paid
125- paid_total = float (float (data ['price' ]) * balance_free ) + paid_fees
126- wanted_profit = paid_total * float (take_profit / 100 )
127- sellprice_without_loss_on_fee_plus_profit = float (round (float (paid_total + wanted_profit ), precision ))
128-
129- if model is not None :
130- model .update_data ({
131- 'current' : False ,
132- 'sold_for' : str (wouldve_paid )
133- })
134- chatterer .chat (f"SOLD { cur1 } : { quantity } " )
135- else : chatterer .chat ("NOTHING TO SELL" )
136- else :
93+ # Check for each currency selected what we have available in the wallet
94+ balance = pynance .wallet .balance (cur1 ) # BTC
95+ balance2 = pynance .wallet .balance (cur2 ) # USDT
96+
97+ # Each wallet has free amounts and locked amounts, locked is not usable.
98+ balance_free = float (round (float (balance ['free' ]), 8 )) # BTC
99+ balance_locked = float (round (float (balance ['locked' ]), 8 ))
100+ balance2_free = float (round (float (balance2 ['free' ]), 8 )) # USDT
101+ balance2_locked = float (round (float (balance2 ['locked' ]), 8 ))
102+ current_price = float (round (float (pynance .price .asset (cur1 + cur2 ).json ['price' ]), 8 ))
103+ # Register the current value
104+ system = self .update_system_without_going_offline (system , {'current_value' : str (current_price )})
105+
106+ expected_profit = float (round (float (float (work_price / 100 ) * take_profit ), 8 ))
107+ total_profit_on_each_coin = float (round (float (work_price + expected_profit ), 8 )) # * quantity == sell_target
108+
109+ # Debug stuff
110+ # print(f"The work price is: {work_price}")
111+ # print(f"Take profit: {take_profit}%")
112+ # print(f"Fees limit sell / buy: {fee_maker}")
113+ # print(f"Fees market sell / buy: {fee_taker}")
114+ # print(f"Balance {cur1} -> free {balance_free}, locked {balance_locked}")
115+ # print(f"Balance2 {cur2} -> free {balance2_free}, locked {balance2_locked}")
116+ # print(f"Current price {current_price}")
117+ # print(f"Expected profit: {expected_profit}")
118+ # print(f"Buying? : {system.buying}")
119+
120+ if system .buying :
121+ fees_current_price = float (round (float (float (work_price ) * fee_taker ), 8 ))
122+ price_including_fee = float (round (float (float (balance_free )), 8 ))
123+ price_excluding_fee = float (round (float (float (balance_free - fees_current_price )), 8 ))
124+
137125 if model is None :
138- if balance2_free > minimal_money_needed_to_buy :
139- if system .panik :
140- chatterer .chat ("PANIK, NO NEW BUY ORDER WILL BE PLACED" )
141- else :
142- # Check if the current price is below average
143- if system .only_dip :
144- price_average_would_buy = float (price_average - float (price_average * float (float (take_profit / 100 )/ 10 )))
145- else : price_average_would_buy = price_average
146- if current_price < price_average_would_buy :
147- chatterer .chat (f"BUYING { cur1 } " )
148- quantity = float (f"{ self .get_x_percentage_of_y (100 - take_profit , balance2_free / current_price ):.{precision }f} " )
149- buy_order = pynance .orders .create (symbol , quantity , order_id = 'test_api' )
150- if buy_order is not None :
151- data = buy_order .json ['fills' ].pop (0 )
152- brought_price = float (data ['price' ])
153- model = OrdersModel (
154- symbol = symbol ,
155- currency_1 = cur1 ,
156- currency_2 = cur2 ,
157- quantity = str (quantity ),
158- brought_price = str (brought_price ),
159- fee_maker = str (fee_maker ),
160- fee_taker = str (fee_taker ),
161- )
162- db .session .add (model )
163- db .session .commit ()
164- chatterer .chat (f"BROUGHT: { quantity } " )
165- else : chatterer .chat (f"CURRENT { cur1 } PRICE ({ current_price } ) NOT BELOW AVERAGE ({ price_average_would_buy } ), SKIPPING BUY ORDERS" )
166- else : chatterer .chat ("NOT ENOUGH MONEY TO BUY" )
167- else :
168- if system .panik :
169- chatterer .chat (f"HOLDING { cur1 } STRONG, CURRENT PRICE ({ current_price } ) TO LOW TO SELL, TARGET PRICE ({ paid_total } )" )
126+ if system .panik : chatterer .chat ("PANIK ACTIVE, NO NEW BUY ORDER WILL BE PLACED" )
170127 else :
171- chatterer .chat (f"HOLDING { cur1 } STRONG, CURRENT PRICE ({ current_price } ) TO LOW TO SELL, TARGET PRICE ({ sellprice_without_loss_on_fee_plus_profit } )" )
128+ if system .only_dip : price_entry = float (work_price - float (expected_profit ))
129+ else : price_entry = float (work_price - float (expected_profit / 2 ))
130+
131+ if current_price <= price_entry :
132+ chatterer .chat (f"BUYING { cur1 } " )
133+ quantity = float (float (float (float (balance2_free / current_price ) / 100 ) * float (system .total_entry )))
134+ buy_order = pynance .orders .create (symbol , float (round (float (quantity - float (quantity / 100 )), precision )), order_id = 'test_api' )
135+ if buy_order is not None :
136+ data = buy_order .json ['fills' ].pop (0 )
137+ brought_price = float (round (float (data ['price' ]), 8 ))
138+ model = OrdersModel (
139+ symbol = symbol ,
140+ currency_1 = cur1 ,
141+ currency_2 = cur2 ,
142+ quantity = str (quantity ),
143+ brought_price = str (brought_price ),
144+ fee_maker = str (fee_maker ),
145+ fee_taker = str (fee_taker ),
146+ )
147+ db .session .add (model )
148+ db .session .commit ()
149+ chatterer .chat (f"BROUGHT { quantity } { cur1 } FOR { brought_price } { cur2 } " )
150+ system = self .update_system_without_going_offline (system , {'buying' : False }) # Reset state
151+ else : chatterer .chat (f"UNABLE TO PLACE A BUY ORDER FOR { quantity } { cur1 } " )
152+ else : chatterer .chat (f"CURRENT { cur1 } PRICE ({ current_price } ) NOT AT BUY TARGET ({ price_entry } ), SKIPPING BUY ORDER" )
153+ else :
154+ system = self .update_system_without_going_offline (system , {'buying' : False }) # Reset state
155+ chatterer .chat ("NOT ENOUGH MONEY TO PLACE A BUY ORDER" )
156+ else :
157+ fees_current_price = float (round (float (float (work_price ) * fee_taker ), 8 ))
158+ price_including_fee = float (round (float (float (balance2_free )), 8 ))
159+ price_excluding_fee = float (round (float (float (balance2_free - fees_current_price )), 8 ))
160+
161+ if model is None :
162+ chatterer .chat ("No coin available to sell, you seem to be out of stock!" )
163+ system = self .update_system_without_going_offline (system , {'buying' : True }) # Reset state
164+ return jsonify ({
165+ "date" : str (datetime .now ().strftime ('%d-%m-%y %H:%M:%S' )),
166+ "execution_time" : str (datetime .now ()- now ),
167+ "online" : True ,
168+ "msg" : chatterer .msg
169+ }), 200
170+
171+ quantity = float (round (float (model .quantity ), precision ))
172+ sell_target = float (round (float (float (total_profit_on_each_coin * quantity ) + float (float (total_profit_on_each_coin * quantity ) * fee_taker )), 8 ))
173+
174+ previous_price_order = float (round (float (work_price * quantity ), 8 ))
175+ expected_total_profit = float (round (float (sell_target - previous_price_order ), 8 ))
176+ total_fomo_price = float (round (float (work_price + fees_current_price ), 8 ))
177+ fomo_price = float (round (float (float (total_fomo_price * quantity ) + float (float (total_fomo_price * quantity ) * fee_taker )), 8 ))
178+
179+ if system .panik : chatterer .chat (f"{ quantity } { cur1 } IS { previous_price_order } { cur2 } WORTH - TRYING TO SELL FOR { fomo_price } { cur2 } " )
180+ else : chatterer .chat (f"{ quantity } { cur1 } IS { previous_price_order } { cur2 } WORTH - TRYING TO SELL FOR { sell_target } { cur2 } " )
181+
182+ if current_price > total_profit_on_each_coin or system .panik and current_price > total_fomo_price :
183+ chatterer .chat (f"SELLING { cur1 } " )
184+ sell_order = pynance .orders .create (symbol , float (round (float (quantity - float (quantity / 100 )), precision )), buy = False , order_id = 'test_api' )
185+ if sell_order is not None :
186+ sold_price = float (round (float (current_price * quantity ), 8 ))
187+ if model is not None :
188+ model .update_data ({
189+ 'current' : False ,
190+ 'sold_for' : str (sold_price )
191+ })
192+ chatterer .chat (f"SOLD { quantity } { cur1 } FOR AN AMAZING { sold_price } { cur2 } " )
193+ system = self .update_system_without_going_offline (system , {'buying' : True }) # Reset state
194+ else : chatterer .chat (f"UNABLE TO PLACE A SELL ORDER FOR { quantity } { cur1 } " )
172195
173196 return jsonify ({
174197 "date" : str (datetime .now ().strftime ('%d-%m-%y %H:%M:%S' )),
0 commit comments