"""Original fictional return-label replay. Python 3.9+ and IANA timezone data; no network.""" from pathlib import Path from datetime import datetime,timedelta,timezone from decimal import Decimal,localcontext,ROUND_HALF_UP from zoneinfo import ZoneInfo import argparse,csv,hashlib,io,json BASE=Path(__file__).resolve().parent UTC=timezone.utc def iso(value):return value.astimezone(UTC).isoformat(timespec='seconds').replace('+00:00','Z') def parse(value): if not isinstance(value,str) or not value.endswith('Z'):raise ValueError('An explicit UTC Z timestamp is required.') result=datetime.fromisoformat(value[:-1]+'+00:00') if result.tzinfo is None:raise ValueError('Timezone-aware timestamp required.') return result def number(value): if not isinstance(value,str):raise ValueError('Use decimal strings.') result=Decimal(value) if not result.is_finite() or result<=0:raise ValueError('Prices and FX references must be finite and positive.') return result def fmt(value,places=8):return format(value.quantize(Decimal(1).scaleb(-places),rounding=ROUND_HALF_UP),'f') def csv_text(rows): out=io.StringIO(newline='');writer=csv.DictWriter(out,fieldnames=list(rows[0]),lineterminator='\n');writer.writeheader();writer.writerows(rows);return out.getvalue() def calculate(inputs): if not str(inputs.get('kind','')).startswith('synthetic'):raise ValueError('This replay requires explicitly synthetic data.') zone=ZoneInfo(inputs['zone']);prices={};series=[] for record in inputs['series']: stamp=parse(record['at_utc']) if stamp in prices:raise ValueError('Duplicate exact observation time.') value=number(record['ltc_usd']);prices[stamp]=value local=stamp.astimezone(zone) series.append({'kind':'synthetic','at_utc':iso(stamp),'at_warsaw':local.isoformat(timespec='seconds'),'warsaw_fold':local.fold,'ltc_usd':record['ltc_usd']}) series.sort(key=lambda row:row['at_utc']) a,b=parse(inputs['as_of_a_utc']),parse(inputs['as_of_b_utc']) local_a=a.astimezone(zone) utc_midnight=a.replace(hour=0,minute=0,second=0,microsecond=0) local_midnight=local_a.replace(hour=0,minute=0,second=0,microsecond=0).astimezone(UTC) yesterday_wall=(local_a-timedelta(days=1)).astimezone(UTC) prev_local_midnight=(local_a.replace(hour=0,minute=0,second=0,microsecond=0)-timedelta(days=1)).astimezone(UTC) definitions=[('rolling-24h-a',a-timedelta(hours=24),a),('utc-day-to-a',utc_midnight,a),('warsaw-day-to-a',local_midnight,a),('same-local-clock-yesterday-to-a',yesterday_wall,a),('rolling-24h-b',b-timedelta(hours=24),b),('completed-warsaw-day-2026-10-25',prev_local_midnight,local_midnight)] rows=[] with localcontext() as context: context.prec=50 def price(stamp): if stamp not in prices:raise ValueError('No exact synthetic observation exists for '+iso(stamp)) return prices[stamp] for name,start,end in definitions: first,last=price(start),price(end) rows.append({'kind':'synthetic','definition':name,'start_utc':iso(start),'start_warsaw':start.astimezone(zone).isoformat(timespec='seconds'),'start_warsaw_fold':start.astimezone(zone).fold,'end_utc':iso(end),'end_warsaw':end.astimezone(zone).isoformat(timespec='seconds'),'elapsed_seconds':int((end-start).total_seconds()),'ltc_usd_start':str(first),'ltc_usd_end':str(last),'change_pct':fmt((last/first-1)*100)}) fx=inputs['fx'];fx_start,fx_end=parse(fx['start_utc']),parse(fx['end_utc']);f0,f1=number(fx['eur_usd_start']),number(fx['eur_usd_end']);p0,p1=price(fx_start),price(fx_end) fx_rows=[{'kind':'synthetic','start_utc':iso(fx_start),'end_utc':iso(fx_end),'eur_usd_start':str(f0),'eur_usd_end':str(f1),'ltc_usd_start':str(p0),'ltc_usd_end':str(p1),'derived_ltc_eur_start':fmt(p0/f0,20),'derived_ltc_eur_end':fmt(p1/f1,20),'ltc_usd_change_pct':fmt((p1/p0-1)*100),'eur_usd_change_pct':fmt((f1/f0-1)*100),'derived_ltc_eur_change_pct':fmt(((p1/p0)/(f1/f0)-1)*100)}] indexed={row['definition']:row for row in rows} tests={ 'rolling_a_exact_86400_seconds':indexed['rolling-24h-a']['elapsed_seconds']==86400, 'rolling_a_plus_five':indexed['rolling-24h-a']['change_pct']=='5.00000000', 'utc_midnight_half_hour':indexed['utc-day-to-a']['elapsed_seconds']==1800, 'utc_day_minus_1_5625':indexed['utc-day-to-a']['change_pct']=='-1.56250000', 'warsaw_day_ninety_minutes':indexed['warsaw-day-to-a']['elapsed_seconds']==5400, 'warsaw_day_plus_1_61290323':indexed['warsaw-day-to-a']['change_pct']=='1.61290323', 'calendar_subtraction_is_90000_seconds':indexed['same-local-clock-yesterday-to-a']['elapsed_seconds']==90000, 'completed_warsaw_oct25_is_25_hours':indexed['completed-warsaw-day-2026-10-25']['elapsed_seconds']==90000, 'current_price_does_not_change':indexed['rolling-24h-a']['ltc_usd_end']==indexed['rolling-24h-b']['ltc_usd_end']=='63', 'rolling_b_turns_negative':indexed['rolling-24h-b']['change_pct']=='-3.07692308', 'repeated_local_clock_with_different_offsets':parse(indexed['rolling-24h-a']['start_utc']).astimezone(zone).strftime('%Y-%m-%d %H:%M')==parse(indexed['rolling-24h-b']['start_utc']).astimezone(zone).strftime('%Y-%m-%d %H:%M') and indexed['rolling-24h-a']['start_warsaw']!=indexed['rolling-24h-b']['start_warsaw'], 'repeated_hour_folds_zero_and_one':indexed['rolling-24h-a']['start_warsaw_fold']==0 and indexed['rolling-24h-b']['start_warsaw_fold']==1, 'fx_normalized_eur_change_zero':fx_rows[0]['derived_ltc_eur_change_pct']=='0.00000000', 'eight_exact_sparse_observations':len(series)==8, 'six_comparisons':len(rows)==6, } for invalid in ['2026-10-25T02:30:00','2026-10-25T02:30:00+02:00']: try:parse(invalid);tests['rejects_timestamp_'+invalid]=False except ValueError:tests['rejects_timestamp_'+invalid]=True if not all(tests.values()):raise AssertionError('Replay failed: '+str([name for name,ok in tests.items() if not ok])) payload={'kind':inputs['kind'],'version':inputs['version'],'zone':inputs['zone'],'decimal_precision':50,'display_rounding':'ROUND_HALF_UP; percentages 8 decimal places','comparisons':rows,'fx':fx_rows,'checks':tests,'check_count':len(tests)} return {'time-series.csv':csv_text(series),'return-comparisons.csv':csv_text(rows),'fx-normalization.csv':csv_text(fx_rows),'results.json':json.dumps(payload,ensure_ascii=False,indent=2)+'\n'} def main(): parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--verify',action='store_true');parser.add_argument('--write',action='store_true');parser.add_argument('--out',type=Path);args=parser.parse_args() outputs=calculate(json.loads((BASE/'inputs.json').read_text(encoding='utf-8'))) if args.verify: for name,expected in outputs.items(): if (BASE/name).read_bytes()!=expected.encode('utf-8'):raise AssertionError('Calculated output differs: '+name) if (BASE/'SHA256SUMS.txt').is_file(): for line in (BASE/'SHA256SUMS.txt').read_text(encoding='utf-8').splitlines(): checksum,name=line.split(' ',1) if Path(name).name!=name:raise ValueError('Unsafe checksum filename.') if hashlib.sha256((BASE/name).read_bytes()).hexdigest()!=checksum:raise AssertionError('Checksum mismatch: '+name) print(json.dumps({'state':'verified','calculation_files':len(outputs),'checks':json.loads(outputs['results.json'])['check_count'],'network_requests':0})) elif args.write: target=args.out or BASE;target.mkdir(parents=True,exist_ok=True) for name,value in outputs.items():(target/name).write_bytes(value.encode('utf-8')) print(json.dumps({'state':'written','calculation_files':len(outputs),'checks':json.loads(outputs['results.json'])['check_count'],'network_requests':0})) else:parser.error('Choose --verify or --write. No files are changed without --write.') if __name__=='__main__':main()