Я пытаюсь решить очень простую математическую задачу, но не знаю, как преобразовать ее в python. По сути, мне нужно рассчитать среднюю цену входа для сделки, основанную на нескольких записях покупки. Для этого все, что нужно сделать, это вычислить
∑ (entry.amount * entry.price) / ∑ (entry.amount)
Это должна быть переменная total_entry_price2 в конце.
- Где я ошибаюсь в расчете? Как я могу сложить все ∑ вместе?
- Это лучший способ сделать это?
models.py
class Trade(models.Model):
...
class Entry(models.Model):
...
trade = models.ForeignKey(Trade, on_delete=models.CASCADE)
amount = models.FloatField()
price = models.FloatField()
entry_type = models.CharField(max_length=3, choices=ENTRY_TYPE_CHOICES, default=BUY)
views.py
@login_required
def trade_detail_view(request, pk):
logger.info('trade detail view')
if request.method == 'GET':
trade = get_object_or_404(Trade, pk=pk)
entries = Entry.objects.filter(trade=trade)
entries_buy = Entry.objects.filter(trade=trade, entry_type="buy")
patterns = Pattern.objects.filter(trade=trade)
for entry in entries_buy:
total_entry_price = Sum(entry.amount * entry.price)
total_entry_price2 = total_entry_price / entries_buy.aggregate(Sum('amount'))
print(total_entry_price2)
context = {
'trade': trade,
'entries': entries,
'patterns': patterns,
'max_amount': entries_buy.aggregate(Sum('amount')),
'total_fees': entries.aggregate(Sum('fee')),
'entry_price': entries_buy.aggregate(Avg('price'))
}
Текущий вывод терминала:
Sum(Value(60.0)) / Value({'amount__sum': 40.0})
Sum(Value(10.0)) / Value({'amount__sum': 40.0})
Пример данных
Правильный ответ должен быть $ 1,75
(30 * 2 + 10 * 1) / 40 = 1.75
Окончательное решение (добавлено из ответа Олега Русскина)
Я внес следующие изменения:
total_entry_cost = entries_buy.annotate(
s=F('amount') * F('price')
).aggregate(
total_entry_cost=ExpressionWrapper(
Sum(
Cast('s', output_field=models.FloatField())
) / Sum('amount'),
output_field=models.FloatField()
)
)['total_entry_cost']
print(total_entry_cost)