Refine Amazon ZA daily tracker
This commit is contained in:
@@ -23,12 +23,14 @@ unit_price_zar = 49.5
|
||||
fx_zar_per_usd = 16.5
|
||||
|
||||
spend = defaultdict(float)
|
||||
repostback_installs = defaultdict(int)
|
||||
with (root / "source-delivery.csv").open(encoding="utf-8-sig", newline="") as f:
|
||||
for row in csv.DictReader(f):
|
||||
if row.get("广告包") == package and row.get("国家") == geo:
|
||||
day = row.get("日期", "")
|
||||
if len(day) == 8 and day.isdigit():
|
||||
spend[day] += float(row.get("平台消耗") or 0)
|
||||
repostback_installs[day] += int(float(row.get("归因安装") or 0))
|
||||
|
||||
events = defaultdict(lambda: defaultdict(int))
|
||||
with (root / "source-events.csv").open(encoding="utf-8-sig", newline="") as f:
|
||||
@@ -38,7 +40,7 @@ with (root / "source-events.csv").open(encoding="utf-8-sig", newline="") as f:
|
||||
if len(row) < 7 or row[2] != package or row[3] != geo:
|
||||
continue
|
||||
name, day = row[0], row[1]
|
||||
if name not in {"af_app_opened", "event1", "event2"}:
|
||||
if name not in {"event1", "event2"}:
|
||||
continue
|
||||
# The source export leaves its last three headers blank. The second
|
||||
# numeric column after midas_campaign_id is the repostback count.
|
||||
@@ -46,8 +48,7 @@ with (root / "source-events.csv").open(encoding="utf-8-sig", newline="") as f:
|
||||
repostback = int(float(row[6] or 0))
|
||||
except (ValueError, TypeError):
|
||||
repostback = 0
|
||||
key = "install" if name == "af_app_opened" else name
|
||||
events[day][key] += repostback
|
||||
events[day][name] += repostback
|
||||
|
||||
source_days = sorted(set(spend) | set(events))
|
||||
data_cutoff = source_days[-1] if source_days else None
|
||||
@@ -58,7 +59,7 @@ while cursor <= launch_end:
|
||||
cursor += timedelta(days=1)
|
||||
daily = []
|
||||
for day in days:
|
||||
install = events[day]["install"]
|
||||
install = repostback_installs[day]
|
||||
event1 = events[day]["event1"]
|
||||
event2 = events[day]["event2"]
|
||||
conversions = event1 + event2
|
||||
@@ -123,8 +124,30 @@ budget = {
|
||||
"required_daily_events": round(remaining_budget_zar / remaining_days / unit_price_zar) if remaining_days else 0,
|
||||
"projected_month_spend_zar": round(projected_month_spend, 2),
|
||||
"projected_month_variance_zar": round(monthly_budget_zar - projected_month_spend, 2),
|
||||
"mtd_expected_ffr": round(min(datetime.now().day, 31) / 31 * 100, 2),
|
||||
}
|
||||
|
||||
weeks = []
|
||||
for row in actual_daily:
|
||||
row_date = datetime.strptime(row["date"], "%Y-%m-%d").date()
|
||||
week_start = row_date - timedelta(days=row_date.weekday())
|
||||
week_end = week_start + timedelta(days=6)
|
||||
label_start = max(week_start, launch_start)
|
||||
label_end = min(week_end, launch_end)
|
||||
key = week_start.isoformat()
|
||||
if not weeks or weeks[-1]["key"] != key:
|
||||
weeks.append({"key": key, "label": f"{label_start.strftime('%b %d')}–{label_end.strftime('%b %d')}", "install": 0, "event1": 0, "event2": 0, "e1e2": 0, "payable_spend": 0.0, "midas_spend": 0.0})
|
||||
week = weeks[-1]
|
||||
for metric in ("install", "event1", "event2", "e1e2"):
|
||||
week[metric] += row[metric]
|
||||
week["payable_spend"] += row["payable_spend"]
|
||||
week["midas_spend"] += row["midas_spend"]
|
||||
for week in weeks:
|
||||
week["e1e2_rate"] = round(week["e1e2"] / week["install"] * 100, 2) if week["install"] else None
|
||||
week["payable_spend"] = round(week["payable_spend"], 2)
|
||||
week["midas_spend"] = round(week["midas_spend"], 2)
|
||||
week.pop("key", None)
|
||||
|
||||
payload = {
|
||||
"meta": {
|
||||
"package": package,
|
||||
@@ -134,7 +157,7 @@ payload = {
|
||||
"date_end": daily[-1]["date"] if daily else None,
|
||||
"data_cutoff": f"{data_cutoff[:4]}-{data_cutoff[4:6]}-{data_cutoff[6:]}" if data_cutoff else None,
|
||||
"currency": "USD",
|
||||
"install_definition": "af_app_opened repostback",
|
||||
"install_definition": "delivery repostback (attributed installs); af_app_opened excluded",
|
||||
"event_definition": "event1/event2 repostback",
|
||||
"rate_definition": "(event1 + event2) / Install",
|
||||
"payable_definition": "(event1 + event2) × $3",
|
||||
@@ -142,6 +165,7 @@ payload = {
|
||||
"totals": totals,
|
||||
"budget": budget,
|
||||
"daily": daily,
|
||||
"weekly": weeks,
|
||||
}
|
||||
|
||||
tmp = root / "data.json.tmp"
|
||||
|
||||
Reference in New Issue
Block a user