def evaluate_amounts_received_after_window_closes(): """ Finds any amount which is - received on or after the Future_Price window closes and - has not yet been returned and - has at least 6 confirmations Return it to itself. """ received_amounts = Received_Amount.objects.filter(confirmations__gte=6, returned_amount__isnull=True, time__gte=F('prediction__future_price__time_window_closes')) for received_amount in received_amounts: returned_amount = { "amount": received_amount.amount, "from_received_amount": received_amount, "to_prediction": received_amount.prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save()
def evaluate_amounts_received_after_window_closes(): """ Finds any amount which is - received on or after the Future_Price window closes and - has not yet been returned and - has at least 6 confirmations Return it to itself. """ received_amounts = Received_Amount.objects.filter( confirmations__gte=6, returned_amount__isnull=True, time__gte=F('prediction__future_price__time_window_closes')) for received_amount in received_amounts: returned_amount = { "amount": received_amount.amount, "from_received_amount": received_amount, "to_prediction": received_amount.prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save()
def evaluate_winners_and_losers(future_price): """ This function creates Returned_Amount objects according to who wins and loses the future_price wager. Winners always get their initial deposit back. The loser payments go to the winners in chronological order, until the winner has received up to their original deposit amount (less commission), and then the next winner begins to receive loser payouts, until there are no more loser payments to make. If there are more losers than winners, the losers who are not paid to winners are returned to the losers. """ winners = [] losers = [] target_price = future_price.target_price try: actual_price_obj = Bitcoin_Price.objects.get(time=future_price.time_to_match_price) except: return # there is no bitcoin price for this time so this future_price cannot be evaluated actual_price = actual_price_obj.price price_is_less_than_target = actual_price < target_price price_is_equal_to_target = target_price == actual_price amounts = Received_Amount.objects.filter( amount__gt=0, prediction__future_price=future_price, time__lt=future_price.time_window_closes ).order_by('time', 'id') # Split into winners and losers for received_amount in amounts: guessed_correctly = (received_amount.prediction.price_will_be_less_than_target and price_is_less_than_target) or \ (not received_amount.prediction.price_will_be_less_than_target and not price_is_less_than_target) if guessed_correctly: # This is a winner returned_amount = { "amount": received_amount.amount, "from_received_amount": received_amount, "to_prediction": received_amount.prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save() winners.append({ "received_amount": received_amount, "from_losers": 0 }) elif price_is_equal_to_target: # Eligible for refund but not for winnings # TODO: If the received amount is not confirmed, it will still be # returned returned_amount = { "amount": received_amount.amount, "from_received_amount": received_amount, "to_prediction": received_amount.prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save() else: # Record this so in the next step this can be allocated to winners losers.append({ "received_amount": received_amount, "to_winners": 0, "commission": 0 }) for loser in losers: # Pay the winners for winner in winners: loser_funds_remaining = loser["received_amount"].amount - loser["to_winners"] - loser["commission"] loser_is_broke = loser_funds_remaining == 0 if loser_is_broke: break winner_received_from_losers = winner["from_losers"] winner_total_owed_from_losers = winner["received_amount"].amount * (1-COMMISSION) amount_remaining_to_pay_winner = winner_total_owed_from_losers - winner_received_from_losers if amount_remaining_to_pay_winner > 0: amount_to_pay_winner = min(amount_remaining_to_pay_winner, loser_funds_remaining * (1-COMMISSION)) commission = amount_to_pay_winner / (1-COMMISSION) * COMMISSION loser["to_winners"] = loser["to_winners"] + amount_to_pay_winner loser["commission"] = loser["commission"] + commission winner["from_losers"] = winner["from_losers"] + amount_to_pay_winner returned_amount = { "amount": amount_to_pay_winner, "from_received_amount": loser["received_amount"], "to_prediction": winner["received_amount"].prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save() commission_amount = { "returned_amount": returned_amount_obj, "amount": commission } commission_amount_obj = Commission_Amount(**commission_amount) commission_amount_obj.save() # Return any amount remaining after all the winners are paid loser_funds_remaining = loser["received_amount"].amount - loser["to_winners"] - loser["commission"] if loser_funds_remaining > 0: returned_amount = { "amount": loser_funds_remaining, "from_received_amount": loser["received_amount"], "to_prediction": loser["received_amount"].prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save()
def evaluate_winners_and_losers(future_price): """ This function creates Returned_Amount objects according to who wins and loses the future_price wager. Winners always get their initial deposit back. The loser payments go to the winners in chronological order, until the winner has received up to their original deposit amount (less commission), and then the next winner begins to receive loser payouts, until there are no more loser payments to make. If there are more losers than winners, the losers who are not paid to winners are returned to the losers. """ winners = [] losers = [] target_price = future_price.target_price try: actual_price_obj = Bitcoin_Price.objects.get( time=future_price.time_to_match_price) except: return # there is no bitcoin price for this time so this future_price cannot be evaluated actual_price = actual_price_obj.price price_is_less_than_target = actual_price < target_price price_is_equal_to_target = target_price == actual_price amounts = Received_Amount.objects.filter( amount__gt=0, prediction__future_price=future_price, time__lt=future_price.time_window_closes).order_by('time', 'id') # Split into winners and losers for received_amount in amounts: guessed_correctly = (received_amount.prediction.price_will_be_less_than_target and price_is_less_than_target) or \ (not received_amount.prediction.price_will_be_less_than_target and not price_is_less_than_target) if guessed_correctly: # This is a winner returned_amount = { "amount": received_amount.amount, "from_received_amount": received_amount, "to_prediction": received_amount.prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save() winners.append({ "received_amount": received_amount, "from_losers": 0 }) elif price_is_equal_to_target: # Eligible for refund but not for winnings # TODO: If the received amount is not confirmed, it will still be # returned returned_amount = { "amount": received_amount.amount, "from_received_amount": received_amount, "to_prediction": received_amount.prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save() else: # Record this so in the next step this can be allocated to winners losers.append({ "received_amount": received_amount, "to_winners": 0, "commission": 0 }) for loser in losers: # Pay the winners for winner in winners: loser_funds_remaining = loser["received_amount"].amount - loser[ "to_winners"] - loser["commission"] loser_is_broke = loser_funds_remaining == 0 if loser_is_broke: break winner_received_from_losers = winner["from_losers"] winner_total_owed_from_losers = winner[ "received_amount"].amount * (1 - COMMISSION) amount_remaining_to_pay_winner = winner_total_owed_from_losers - winner_received_from_losers if amount_remaining_to_pay_winner > 0: amount_to_pay_winner = min( amount_remaining_to_pay_winner, loser_funds_remaining * (1 - COMMISSION)) commission = amount_to_pay_winner / (1 - COMMISSION) * COMMISSION loser[ "to_winners"] = loser["to_winners"] + amount_to_pay_winner loser["commission"] = loser["commission"] + commission winner["from_losers"] = winner[ "from_losers"] + amount_to_pay_winner returned_amount = { "amount": amount_to_pay_winner, "from_received_amount": loser["received_amount"], "to_prediction": winner["received_amount"].prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save() commission_amount = { "returned_amount": returned_amount_obj, "amount": commission } commission_amount_obj = Commission_Amount(**commission_amount) commission_amount_obj.save() # Return any amount remaining after all the winners are paid loser_funds_remaining = loser["received_amount"].amount - loser[ "to_winners"] - loser["commission"] if loser_funds_remaining > 0: returned_amount = { "amount": loser_funds_remaining, "from_received_amount": loser["received_amount"], "to_prediction": loser["received_amount"].prediction, } returned_amount_obj = Returned_Amount(**returned_amount) returned_amount_obj.save()