136 lines
4.6 KiB
Python
136 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
||
"""Integration test: feed .nb bars through PyO3 observer, compare with Python reference output."""
|
||
|
||
import sys
|
||
import os
|
||
import struct
|
||
|
||
import chanlun
|
||
|
||
|
||
def read_nb_bars(path, max_bars=None):
|
||
"""Read bars from .nb file (48 bytes each: 6 × f64 big-endian)."""
|
||
bars = []
|
||
with open(path, "rb") as f:
|
||
i = 0
|
||
while True:
|
||
data = f.read(48)
|
||
if not data:
|
||
break
|
||
ts, o, h, l, c, v = struct.unpack(">6d", data)
|
||
bars.append((int(ts), o, h, l, c, v))
|
||
i += 1
|
||
if max_bars and i >= max_bars:
|
||
break
|
||
return bars
|
||
|
||
|
||
def main():
|
||
nb_path = "/home/moscow/chanlun.rs/btcusd-300-1761327300-1776327900.nb"
|
||
ref_dir = "/home/moscow/chanlun.rs/Py_btcusd:300_1761327300_1776327900"
|
||
out_dir = "/tmp/chanlun_py_test_output"
|
||
|
||
# Read all bars
|
||
print("Reading bars from .nb file...")
|
||
bars = read_nb_bars(nb_path)
|
||
print(f" Read {len(bars)} bars")
|
||
|
||
# Create observer (default config)
|
||
print("Creating observer...")
|
||
obs = chanlun.观察者("btcusd", 300)
|
||
print(f" Observer: {obs.标识}, period={obs.周期}")
|
||
|
||
# Feed bars
|
||
print("Feeding bars...")
|
||
for i, (ts, o, h, l, c, v) in enumerate(bars):
|
||
k = chanlun.K线.创建普K(f"btcusd_{i}", ts, o, h, l, c, v, i, 300)
|
||
obs.增加原始K线(k)
|
||
if i % 10000 == 0:
|
||
print(f" Fed {i}/{len(bars)} bars")
|
||
|
||
print(f" Done. {len(obs.普通K线序列)} normal K lines, {len(obs.缠论K线序列)} Chan K lines")
|
||
|
||
# Save output
|
||
print(f"Saving data to {out_dir}...")
|
||
os.makedirs(out_dir, exist_ok=True)
|
||
obs.测试_保存数据(out_dir)
|
||
|
||
# Find the actual output subdirectory created by 测试_保存数据
|
||
subdirs = [d for d in os.listdir(out_dir) if os.path.isdir(os.path.join(out_dir, d))]
|
||
if not subdirs:
|
||
print("ERROR: No output subdirectory found!")
|
||
return 1
|
||
actual_out_dir = os.path.join(out_dir, subdirs[0])
|
||
out_files = sorted(os.listdir(actual_out_dir))
|
||
print(f" Output dir: {actual_out_dir}")
|
||
print(f" Output files ({len(out_files)}): {out_files}")
|
||
|
||
# Compare with Python reference
|
||
print("\nComparing with Python reference...")
|
||
ref_files = sorted(os.listdir(ref_dir))
|
||
|
||
match_count = 0
|
||
diff_count = 0
|
||
all_match = True
|
||
for fname in ref_files:
|
||
ref_path = os.path.join(ref_dir, fname)
|
||
out_path = os.path.join(actual_out_dir, fname)
|
||
|
||
if not os.path.exists(out_path):
|
||
print(f" MISSING: {fname}")
|
||
all_match = False
|
||
continue
|
||
|
||
with open(ref_path) as f:
|
||
ref_lines = f.readlines()
|
||
with open(out_path) as f:
|
||
out_lines = f.readlines()
|
||
|
||
if ref_lines == out_lines:
|
||
print(f" MATCH: {fname} ({len(ref_lines)} lines)")
|
||
match_count += 1
|
||
else:
|
||
print(f" DIFF: {fname} (ref={len(ref_lines)} lines, out={len(out_lines)} lines)")
|
||
for j, (rl, ol) in enumerate(zip(ref_lines, out_lines)):
|
||
if rl != ol:
|
||
print(f" Line {j}:")
|
||
print(f" REF: {rl.rstrip()}")
|
||
print(f" OUT: {ol.rstrip()}")
|
||
break
|
||
if len(ref_lines) != len(out_lines):
|
||
print(f" Line count differs")
|
||
diff_count += 1
|
||
all_match = False
|
||
|
||
# Also compare extra files against Rust reference
|
||
rust_ref_dir = "/home/moscow/chanlun.rs/chanlun/Rust_btcusd:300_1761327300_1776327900"
|
||
extra_files = set(out_files) - set(ref_files)
|
||
if extra_files:
|
||
print("\nComparing extra files with Rust reference...")
|
||
for fname in sorted(extra_files):
|
||
out_path = os.path.join(actual_out_dir, fname)
|
||
rust_ref_path = os.path.join(rust_ref_dir, fname)
|
||
if os.path.exists(rust_ref_path):
|
||
with open(rust_ref_path) as f:
|
||
ref_lines = f.readlines()
|
||
with open(out_path) as f:
|
||
out_lines = f.readlines()
|
||
if ref_lines == out_lines:
|
||
print(f" MATCH: {fname} (vs Rust ref, {len(ref_lines)} lines)")
|
||
match_count += 1
|
||
else:
|
||
print(f" DIFF: {fname} (vs Rust ref)")
|
||
diff_count += 1
|
||
|
||
print(f"\nSummary: {match_count} match, {diff_count} differ")
|
||
if all_match:
|
||
print("All Python reference files match!")
|
||
return 0
|
||
else:
|
||
print("Some files differ (see above)")
|
||
return 1
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|