@@ -58,28 +58,6 @@ class TradeResult(base):
5858 req = db .relationship ('TradeRequest' , foreign_keys = [req_id ],
5959 backref = 'results' )
6060
61- def distribute (self , payable_amount ):
62- # calculate user payouts based on percentage of the total
63- # exchanged value
64- if self .type == "sell" :
65- portions = {c .id : c .amount for c in credits }
66- elif self .type == "buy" :
67- portions = {c .id : c .sell_amount for c in credits
68- if c .payable is False }
69-
70- amts_copy = portions .copy ()
71- amounts = distributor (payable_amount , amts_copy , scale = 50 )
72-
73- for credit in credits :
74- if self .type == "sell" :
75- assert credit .sell_amount is None
76- credit .sell_amount = amounts [credit .id ]
77- elif self .type == "buy" :
78- if credit .payable is False :
79- credit .buy_amount = amounts [credit .id ]
80- # Mark the credit ready for payout to users
81- credit .payable = True
82-
8361
8462class TradeRequest (base ):
8563 """
@@ -141,81 +119,87 @@ def update(self, quantity, source_quantity, fees):
141119 "Nothing to update, quantity and source_quantity have not changed" )
142120 return
143121
144- new_tr = TradeResult (quantity = source_quantity - source_total ,
145- exchanged_quantity = quantity - destination_total ,
146- fees = fees - fee_total )
147- db .session .add (new_tr )
122+ new_result = TradeResult (quantity = source_quantity - source_total ,
123+ exchanged_quantity = quantity - destination_total ,
124+ fees = fees - fee_total )
125+ db .session .add (new_result )
148126
149- distribute_amount = new_tr .exchanged_quantity
127+ distribute_amount = new_result .exchanged_quantity
150128 # If we're not covering exchange fees, remove them from the amount
151129 # we distribute
152130 if not current_app .config .get ('cover_autoex_fees' , False ):
153- distribute_amount -= new_tr .fees
131+ distribute_amount -= new_result .fees
154132
155133 # If the upaid credits sum up to more than the amount of the
156134 # TradeResult then we're going to have to split the credit objects so
157135 # we can perform a partial credit
158- if total_unpaid > new_tr .exchanged_quantity :
159- credit_amts = {credit .id : credit .amount for credit in unpaid_credits }
160- # Distributing the amount that we'll be paying
161- curr_distrib = distributor (distribute_amount , credit_amts )
162- amount_distrib = distributor (new_tr .quantity , credit_amts )
163-
164- # Split a few values evenly based on the ratio between stuck amount
165- # and payable amount
166- amts = {'traded' : payable_amount + self .fees ,
167- 'remaining' : stuck_quantity }
168- if self .type == "sell" :
169- btc_distrib = distributor (self .quantity , amts .copy ())
170-
171- # Calculate the BTC distribution, based on the stuck currency
172- # amounts
173- new_btc_distrib = distributor (btc_distrib ['new' ], amts .copy ())
174-
175- with decimal .localcontext (decimal .BasicContext ) as ctx :
176- # A sufficiently large number that we don't cause rounding
177- # error
178- ctx .prec = 50
179-
180- i = 0
181- # Loop + add a new credit for each old credit
182- while i < len (credits ):
183- credit = credits [i ]
184-
185- # subtract the credits cut from the old credit's amount
186- credit .amount -= new_btc_distrib [credit .id ]
187- credit .sell_amount -= new_btc_distrib [credit .id ]
188- # Create a new credit for the remaining cut
189- new_credit_amt = new_btc_distrib [credit .id ]
190-
191- cr = CreditExchange (
192- user = credit .user ,
193- sharechain_id = credit .sharechain_id ,
194- amount = new_credit_amt ,
195- sell_amount = new_credit_amt ,
196- buy_amount = curr_distrib [credit .id ],
197- sell_req = None ,
198- buy_req = self ,
199- currency = credit .currency ,
200- address = credit .address ,
201- fee_perc = credit .fee_perc ,
202- pd_perc = credit .pd_perc ,
203- block = credit .block )
204-
205- db .session .add (cr )
206- i += 1
207-
208- current_app .logger .info (
209- "Successfully updated trade request {:,} making "
210- "amount {:,} payable and {:,} stuck." .
211- format (self .id , payable_amount , stuck_quantity ))
212-
213- if source_quantity == self .quantity :
136+ if total_unpaid > distribute_amount :
137+ ratio = {'traded' : total_unpaid - distribute_amount , 'remaining' : distribute_amount }
138+
139+ payable_credits = []
140+ for credit in unpaid_credits :
141+ # Copy the original credit's metadata
142+ split_credit = CreditExchange (
143+ user = credit .user ,
144+ sharechain_id = credit .sharechain_id ,
145+ sell_req = credit .sell_req ,
146+ buy_req = credit .sell_req ,
147+ currency = credit .currency ,
148+ address = credit .address ,
149+ fee_perc = credit .fee_perc ,
150+ pd_perc = credit .pd_perc ,
151+ block = credit .block )
152+
153+ # Calculate the new CreditExchange's amount, and sell amount if
154+ # this is a buy trade request
155+ new_amounts = distributor (credit .amount , ratio )
156+ if self .type == "buy" :
157+ new_sell_amounts = distributor (credit .sell_amount , ratio )
158+ split_credit .amount = new_amounts ['traded' ]
159+ split_credit .sell_amount = new_sell_amounts ['traded' ]
160+ credit .amount = new_amounts ['remaining' ]
161+ credit .sell_amount = new_sell_amounts ['remaining' ]
162+
163+ db .session .add (split_credit )
164+ payable_credits .append (split_credit )
165+
166+ # Populate the id values of the new credits
167+ db .session .flush ()
168+ current_app .logger .info ("Successfully split {:,} credits."
169+ .format (len (unpaid_credits )))
170+ self ._status = 5
171+ elif total_unpaid == distribute_amount :
214172 self ._status = 6
173+ payable_credits = unpaid_credits
215174 else :
216- self ._status = 5
175+ raise ValueError ("We have been told that more currency was "
176+ "traded then what we requested!" )
177+
178+ # Set the trade result object
179+ for credit in payable_credits :
180+ if self .type == "buy" :
181+ credit .buy_result = new_result
182+ credit .payable = True
183+ else :
184+ credit .sell_result = new_result
217185
218- db .session .flush ()
186+ # calculate user payouts based on percentage of the total
187+ # exchanged value
188+ if self .type == "sell" :
189+ portions = {c .id : c .amount for c in payable_credits }
190+ elif self .type == "buy" :
191+ portions = {c .id : c .sell_amount for c in payable_credits }
192+ amounts = distributor (new_result .exchanged_quantity , portions )
193+
194+ for credit in credits :
195+ if self .type == "sell" :
196+ assert credit .sell_amount is None
197+ credit .sell_amount = amounts [credit .id ]
198+ elif self .type == "buy" :
199+ if credit .payable is False :
200+ credit .buy_amount = amounts [credit .id ]
201+ # Mark the credit ready for payout to users
202+ credit .payable = True
219203
220204 current_app .logger .info (
221205 "Successfully pushed trade result for request id {:,} and "
@@ -559,16 +543,16 @@ class CreditExchange(Credit):
559543 sell_req_id = db .Column (db .Integer , db .ForeignKey ('trade_request.id' ))
560544 sell_req = db .relationship ('TradeRequest' , foreign_keys = [sell_req_id ],
561545 backref = 'sell_credits' )
562- sell_res_id = db .Column (db .Integer , db .ForeignKey ('trade_result.id' ))
563- sell_res = db .relationship ('TradeResult' , foreign_keys = [buy_req_id ],
564- backref = 'sell_credits' )
546+ # sell_res_id = db.Column(db.Integer, db.ForeignKey('trade_result.id'))
547+ # sell_res = db.relationship('TradeResult', foreign_keys=[buy_req_id],
548+ # backref='sell_credits')
565549 sell_amount = db .Column (db .Numeric )
566550 buy_req_id = db .Column (db .Integer , db .ForeignKey ('trade_request.id' ))
567551 buy_req = db .relationship ('TradeRequest' , foreign_keys = [buy_req_id ],
552+ #buy_res_id = db.Column(db.Integer, db.ForeignKey('trade_result.id'))
568553 backref = 'buy_credits' )
569- buy_res_id = db .Column (db .Integer , db .ForeignKey ('trade_result.id' ))
570- buy_res = db .relationship ('TradeResult' , foreign_keys = [buy_req_id ],
571- backref = 'buy_credits' )
554+ #buy_res = db.relationship('TradeResult', foreign_keys=[buy_req_id],
555+ # backref='buy_credits')
572556 buy_amount = db .Column (db .Numeric )
573557
574558 @property
0 commit comments