我正在尝试做一个非常简单的数学问题,但是我不知道如何将其转换为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
最终解决方案(由Oleg Russkin的答案添加)
我所做的修订如下:
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)
答案 0 :(得分:2)
用于计算所需值的示例查询。
如果function scrollTime(){
location.href = "#";
location.href = "#projects";
window.scrollBy(0, -108);
}
的结果是浮点数而不是Cast()
,则可以避免 Sum
浮点数。
integer
OP更新的答案
这个答案几乎使我们一路走好。我不清楚我在寻找的确切答案是什么。我在末尾更新了我的问题以反映它。
我所做的修订如下:
from django.db import models
from django.db.models import ExpressionWrapper, F, Sum
from django.db.models.functions import Cast
total_entry_price2 = Entry.objects.annotate(
s=F('amount')+F('price')
).aggregate(
price2=ExpressionWrapper(
Sum(
Cast('s',output_field=models.FloatField())
) / Sum('amount'),
output_field=models.FloatField()
)
)['price2']
# Actual result of the query is dictioanry
# so we get the key
# {'price2': 0.59633706227207}