@oracle-agent/oracle 0.35.40 → 0.35.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/agent-sessions.mjs +17 -17
  2. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  3. package/dist/bin/desk-server.mjs +28 -28
  4. package/dist/bin/oracle-data-mcp.mjs +19 -19
  5. package/dist/bin/oracle-gateway.mjs +44 -44
  6. package/dist/bin/oracle-investigate.mjs +5 -5
  7. package/dist/bin/oracle-launch-radar-shadow.mjs +6 -6
  8. package/dist/bin/oracle-mev-arb-shadow.mjs +6 -6
  9. package/dist/bin/oracle-mev-shadow.mjs +6 -6
  10. package/dist/bin/oracle-public-server.mjs +5 -5
  11. package/dist/bin/oracle-route.mjs +31 -31
  12. package/dist/bin/oracle-scan.mjs +11 -11
  13. package/dist/bin/oracle.mjs +1 -1
  14. package/dist/cli/commands/agent-session.mjs +20 -20
  15. package/dist/cli/commands/airdrop.mjs +8 -8
  16. package/dist/cli/commands/auth.mjs +5 -5
  17. package/dist/cli/commands/chat.mjs +218 -217
  18. package/dist/cli/commands/doctor.mjs +9 -9
  19. package/dist/cli/commands/eval.mjs +204 -217
  20. package/dist/cli/commands/extension-policy.mjs +3 -3
  21. package/dist/cli/commands/farm.mjs +17 -17
  22. package/dist/cli/commands/follow.mjs +17 -17
  23. package/dist/cli/commands/harness.mjs +7 -7
  24. package/dist/cli/commands/mint.mjs +10 -10
  25. package/dist/cli/commands/model.mjs +222 -221
  26. package/dist/cli/commands/portfolio-risk.mjs +1 -1
  27. package/dist/cli/commands/project.mjs +7 -7
  28. package/dist/cli/commands/quickstart.mjs +6 -6
  29. package/dist/cli/commands/receipt.mjs +12 -12
  30. package/dist/cli/commands/resolve.mjs +7 -7
  31. package/dist/cli/commands/setup.mjs +13 -13
  32. package/dist/cli/commands/sign.mjs +4 -4
  33. package/dist/cli/commands/signer.mjs +14 -14
  34. package/dist/cli/commands/snipe.mjs +9 -9
  35. package/dist/cli/commands/strategy.mjs +4 -4
  36. package/dist/cli/commands/swap.mjs +14 -14
  37. package/dist/cli/commands/venues.mjs +2 -2
  38. package/dist/cli/project-access.mjs +3 -0
  39. package/dist/data/desk-data.mjs +26 -26
  40. package/dist/data/names.mjs +3 -3
  41. package/dist/data/providers/farming.mjs +2 -2
  42. package/dist/data/providers/lp-destination-discovery.mjs +4 -4
  43. package/dist/index.mjs +44 -44
  44. package/dist/investigator/index.mjs +2 -2
  45. package/dist/launch-radar/index.mjs +5 -5
  46. package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
  47. package/dist/local-signer/index.mjs +2 -2
  48. package/dist/local-signer/runtime.mjs +8 -8
  49. package/dist/nft/universal-mint-router.mjs +4 -4
  50. package/dist/notifications/index.mjs +8 -8
  51. package/dist/portfolio-risk.mjs +1 -1
  52. package/dist/router/index.mjs +3 -3
  53. package/dist/router/prepare-bridge.mjs +2 -2
  54. package/dist/router/prepare-route.mjs +3 -3
  55. package/dist/scanner/index.mjs +4 -4
  56. package/dist/strategy/index.mjs +3 -3
  57. package/dist/tui/standalone-client.mjs +86 -85
  58. package/package.json +5 -4
  59. package/public/eval-report.json +1 -1
  60. package/public/oracle-splash/_variants/ice.html +2 -4
  61. package/public/oracle-splash/_variants/ivory.html +2 -4
  62. package/public/oracle-splash/assets/fonts/LICENSE-Cormorant-Garamond.txt +93 -0
  63. package/public/oracle-splash/assets/fonts/LICENSE-IBM-Plex-Mono.txt +93 -0
  64. package/public/oracle-splash/assets/fonts/LICENSE-Outfit.txt +93 -0
  65. package/public/oracle-splash/assets/fonts/LICENSE-UnifrakturCook.txt +94 -0
  66. package/public/oracle-splash/assets/fonts/font-provenance.json +426 -0
  67. package/public/oracle-splash/assets/fonts/oracle-font-00.woff2 +0 -0
  68. package/public/oracle-splash/assets/fonts/oracle-font-01.woff2 +0 -0
  69. package/public/oracle-splash/assets/fonts/oracle-font-02.woff2 +0 -0
  70. package/public/oracle-splash/assets/fonts/oracle-font-03.woff2 +0 -0
  71. package/public/oracle-splash/assets/fonts/oracle-font-04.woff2 +0 -0
  72. package/public/oracle-splash/assets/fonts/oracle-font-05.woff2 +0 -0
  73. package/public/oracle-splash/assets/fonts/oracle-font-06.woff2 +0 -0
  74. package/public/oracle-splash/assets/fonts/oracle-font-07.woff2 +0 -0
  75. package/public/oracle-splash/assets/fonts/oracle-font-08.woff2 +0 -0
  76. package/public/oracle-splash/assets/fonts/oracle-font-09.woff2 +0 -0
  77. package/public/oracle-splash/assets/fonts/oracle-font-10.woff2 +0 -0
  78. package/public/oracle-splash/assets/fonts/oracle-font-11.woff2 +0 -0
  79. package/public/oracle-splash/assets/fonts/oracle-font-12.woff2 +0 -0
  80. package/public/oracle-splash/assets/fonts/oracle-font-13.woff2 +0 -0
  81. package/public/oracle-splash/assets/fonts/oracle-font-14.woff2 +0 -0
  82. package/public/oracle-splash/assets/fonts/oracle-font-15.woff2 +0 -0
  83. package/public/oracle-splash/assets/fonts/oracle-font-16.woff2 +0 -0
  84. package/public/oracle-splash/assets/fonts/oracle-font-17.woff2 +0 -0
  85. package/public/oracle-splash/assets/fonts/oracle-font-18.woff2 +0 -0
  86. package/public/oracle-splash/assets/fonts/oracle-font-19.woff2 +0 -0
  87. package/public/oracle-splash/assets/fonts/oracle-font-20.woff2 +0 -0
  88. package/public/oracle-splash/assets/fonts/oracle-font-21.woff2 +0 -0
  89. package/public/oracle-splash/assets/fonts/oracle-font-22.woff2 +0 -0
  90. package/public/oracle-splash/assets/fonts/oracle-font-23.woff2 +0 -0
  91. package/public/oracle-splash/assets/fonts/oracle-font-24.woff2 +0 -0
  92. package/public/oracle-splash/assets/fonts/oracle-font-25.woff2 +0 -0
  93. package/public/oracle-splash/assets/fonts/oracle-font-26.woff2 +0 -0
  94. package/public/oracle-splash/assets/fonts/oracle-font-27.woff2 +0 -0
  95. package/public/oracle-splash/assets/fonts/oracle-fonts.css +504 -0
  96. package/public/oracle-splash/assets/transport-probe-sw.js +2 -0
  97. package/public/oracle-splash/docs/browser-and-web/index.html +6 -6
  98. package/public/oracle-splash/docs/connectors/index.html +5 -5
  99. package/public/oracle-splash/docs/docs.css +4 -4
  100. package/public/oracle-splash/docs/docs.js +119 -7
  101. package/public/oracle-splash/docs/getting-started/index.html +5 -5
  102. package/public/oracle-splash/docs/index.html +6 -6
  103. package/public/oracle-splash/docs/reference/index.html +5 -5
  104. package/public/oracle-splash/docs/security/index.html +5 -5
  105. package/public/oracle-splash/docs/using-oracle/index.html +5 -5
  106. package/public/oracle-splash/download/index.html +8 -10
  107. package/public/oracle-splash/downloads/index.html +3 -5
  108. package/public/oracle-splash/eval/archive/oracle-0.35.40.json +101 -0
  109. package/public/oracle-splash/eval/archive/oracle-0.35.41-blocked-attempt.json +672 -0
  110. package/public/oracle-splash/eval/index.html +104 -0
  111. package/public/oracle-splash/eval/releases/oracle-0.35.41.json +788 -0
  112. package/public/oracle-splash/index.html +16 -18
  113. package/public/oracle-splash/mesh-graph.svg +1 -1
  114. package/public/oracle-splash/pricing/index.html +6 -8
  115. package/public/oracle-splash/security/index.html +3 -5
  116. package/public/oracle-splash/what-it-does/index.html +4 -6
  117. package/public/oracle-splash/where-it-works/index.html +3 -5
  118. package/server.json +2 -2
@@ -1,6 +1,6 @@
1
- var Mn=Object.defineProperty;var K=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var Ln=(e,t)=>{for(var r in t)Mn(e,r,{get:t[r],enumerable:!0})};import we from"node:net";import Hn from"node:dns";function Ye(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=u=>{if(!u)return[];let c=u.split(":"),d=c.at(-1);if(d?.includes(".")){let m=d.split(".").map(Number);if(m.length!==4||m.some(p=>!Number.isInteger(p)||p<0||p>255))return null;c.splice(c.length-1,1,(m[0]<<8|m[1]).toString(16),(m[2]<<8|m[3]).toString(16))}return c.some(m=>!/^[0-9a-f]{1,4}$/.test(m))?null:c.map(m=>Number.parseInt(m,16))},[n,o]=t.split("::"),i=r(n),s=r(o);if(!i||!s)return null;let a=t.includes("::"),l=8-i.length-s.length;if(!a&&l!==0||a&&l<1)return null;let f=[...i,...Array(Math.max(0,l)).fill(0),...s];return f.length!==8?null:Uint8Array.from(f.flatMap(u=>[u>>8,u&255]))}function pt(e,t,r){let n=Math.floor(r/8),o=r%8;for(let s=0;s<n;s+=1)if(e[s]!==t[s])return!1;if(!o)return!0;let i=255<<8-o;return(e[n]&i)===(t[n]&i)}function mt(e){if(we.isIPv4(e)){let t=e.split(".").map(Number);return!(t[0]===0||t[0]===10||t[0]===127||t[0]>=224||t[0]===100&&t[1]>=64&&t[1]<=127||t[0]===169&&t[1]===254||t[0]===172&&t[1]>=16&&t[1]<=31||t[0]===192&&(t[1]===0||t[1]===2||t[1]===168)||t[0]===192&&t[1]===88&&t[2]===99||t[0]===198&&(t[1]===18||t[1]===19||t[1]===51)||t[0]===203&&t[1]===0&&t[2]===113)}if(we.isIPv6(e)){let t=Ye(e);if(!t)return!1;let r=Ye("::ffff:0:0");return pt(t,r,96)?mt([...t.slice(12)].join(".")):pt(t,Ye("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>pt(t,Ye(o),i)):!1}return!1}function Cn(e){let t;try{t=new URL(String(e))}catch{return{ok:!1,error:`not a valid URL: ${String(e).slice(0,120)}`}}if(t.protocol!=="http:"&&t.protocol!=="https:")return{ok:!1,error:`refused protocol ${t.protocol} (only http/https)`};let r=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(Fn.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=we.isIP(r);return n!==0&&!mt(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function ht(e,{lookupFn:t=Hn.promises.lookup}={}){let r=Cn(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:we.isIPv6(r.host)?6:4}]};let n;try{n=await t(r.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${r.host} did not resolve`}}return!Array.isArray(n)||n.length===0||n.some(o=>!mt(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function yt({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n;try{let c=await t();r=c.Agent,n=c.fetch}catch(c){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${c?.message||c}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let o=c=>String(c).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,s=c=>(Array.isArray(c)?c:[c]).map(d=>typeof d=="string"?{address:d}:d).filter(d=>d&&d.address).map(d=>({address:d.address,family:d.family||(we.isIPv6(d.address)?6:4)})),a=(c,d,m)=>{i.set(o(c),s(typeof d=="string"?[{address:d,family:m}]:d))},l=c=>{let d=o(c);if(we.isIP(d))return[{address:d,family:we.isIPv6(d)?6:4}];let m=i.get(d);if(!m||!m.length)throw new Error(`refused: unpinned host ${c} during pinned fetch`);return m},f=new r({connect:{lookup(c,d,m){let p;try{p=l(c)}catch(w){return m(w)}return d?.all?m(null,p):m(null,p[0].address,p[0].family)}}}),u=Un((c,d={})=>n(c,{...d,dispatcher:f}),a);return{dispatcher:f,fetch:u,pin:a,resolve:l,async close(){try{await f.destroy()}catch{}}}}function Un(e,t){if(typeof e!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof t!="function")throw new Error("markPinCapableFetch: pin must be a function");return e[wt]=Object.freeze({pin:t}),e}function gt(e){return typeof e=="function"&&typeof e[wt]?.pin=="function"}function sr(e,t,r){if(!gt(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[wt].pin(t,r)}var Fn,wt,ir=K(()=>{Fn=new Set(["localhost","metadata.google.internal","metadata.goog"]);wt=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as qn}from"node:crypto";import{types as le}from"node:util";function J(e){return de(`HTTP JSON body refused: ${e}`)}function Wn(e){return["isArgumentsObject","isArrayBuffer","isAnyArrayBuffer","isArrayBufferView","isBoxedPrimitive","isDataView","isDate","isExternal","isGeneratorObject","isKeyObject","isCryptoKey","isMap","isMapIterator","isModuleNamespaceObject","isNativeError","isPromise","isRegExp","isSet","isSetIterator","isTypedArray","isWeakMap","isWeakSet"].some(t=>typeof le[t]=="function"&&le[t](e))}function Zn(e){let t=[],r=0,n=0,o=0,i=0,s=new WeakSet,a=u=>{if(r+=Buffer.byteLength(u,"utf8"),r>ce.bytes)throw J("serialized byte limit exceeded");t.push(u)},l=u=>{if(Buffer.byteLength(u,"utf8")>ce.bytes)throw J("serialized byte limit exceeded");return JSON.stringify(u)},f=(u,c)=>{if(n+=1,n>ce.nodes)throw J("node limit exceeded");if(c>ce.depth)throw J("depth limit exceeded");if(u===null){a("null");return}if(typeof u=="string"){a(l(u));return}if(typeof u=="boolean"){a(u?"true":"false");return}if(typeof u=="number"){if(!Number.isFinite(u))throw J("non-finite number");a(Object.is(u,-0)?"0":String(u));return}if(typeof u!="object")throw J("unsupported non-JSON value");if(le.isProxy(u))throw J("proxy value");if(Wn(u))throw J("unsupported exotic object");if(s.has(u))throw J("cyclic value");s.add(u);try{if(Object.getOwnPropertySymbols(u).length>0)throw J("symbol-keyed fields are unsupported");if(Array.isArray(u)){let p=Object.getPrototypeOf(u),w=0;for(;p!==null;){if(le.isProxy(p))throw J("proxy array prototype");if(w+=1,w>ce.depth)throw J("array prototype depth limit exceeded");p=Object.getPrototypeOf(p)}if(u.length>ce.arrayLength)throw J("array length limit exceeded");for(let k=0;k<u.length;k+=1){let v=Object.getOwnPropertyDescriptor(u,String(k));if(!v||!Object.hasOwn(v,"value")||v.enumerable!==!0)throw J("array entries must be dense enumerable own data")}let x=0;for(let k in u){if(i+=1,i>ce.fields)throw J("enumeration limit exceeded");if(Object.hasOwn(u,k)&&(x+=1,x>u.length))throw J("named array fields are unsupported")}if(x!==u.length)throw J("array entries must be dense enumerable own data");a("[");for(let k=0;k<u.length;k+=1)k&&a(","),f(Object.getOwnPropertyDescriptor(u,String(k)).value,c+1);a("]");return}let d=Object.getPrototypeOf(u);if(d!==Object.prototype&&d!==null)throw J("non-plain object");let m=[];for(let p in u){if(i+=1,i>ce.fields)throw J("enumeration limit exceeded");if(!Object.hasOwn(u,p))continue;if(o+=1,o>ce.fields)throw J("field limit exceeded");let w=Object.getOwnPropertyDescriptor(u,p);if(!w||!Object.hasOwn(w,"value")||w.enumerable!==!0)throw J("object fields must be enumerable own data");m.push([p,w.value])}a("{");for(let p=0;p<m.length;p+=1)p&&a(","),a(l(m[p][0])),a(":"),f(m[p][1],c+1);a("}")}finally{s.delete(u)}};return f(e,0),t.join("")}function Xn(e){let t=Object.create(null);if(e==null)return t;if(typeof e!="object"&&typeof e!="function")throw new TypeError("HTTP headers must be an object");if(le.isProxy(e))throw new TypeError("HTTP headers must not be a proxy");if(Object.getOwnPropertySymbols(e).length>0)throw new TypeError("HTTP headers must not contain symbol fields");let r=new Set;for(let n of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(n))throw new TypeError("HTTP header names must be valid tokens");let o=n.toLowerCase();if(r.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");r.add(o);let i=Object.getOwnPropertyDescriptor(e,n);if(!i||!Object.hasOwn(i,"value"))throw new TypeError("HTTP headers must contain own data properties");let s=i.value;if(s==null||["object","function","symbol"].includes(typeof s))throw new TypeError("HTTP header values must be scalar");t[n]=String(s)}return t}function Qn(){return Object.assign(Object.create(null),{Accept:"application/json"})}function eo(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let r=new URL(String(e),String(t));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${r.protocol}`);return r.toString()}function to(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function We(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=ur.get(e);return t||(t=fr,fr+=1,ur.set(e,t)),`reference:${t}`}function dr(e){if(!e||typeof e!="object"||Array.isArray(e)||!Object.hasOwn(e,"jsonrpc")||!Object.hasOwn(e,"method")||e.jsonrpc!=="2.0")return!1;let t=typeof e.method=="string"?e.method:"";return t?ro.has(t)||/^get[A-Z0-9_]/u.test(t)||/^is[A-Z0-9_]/u.test(t)||/^eth_get[A-Z0-9_]/u.test(t):!1}function pr(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let r=t;if(typeof t=="string")try{r=JSON.parse(t)}catch{return!1}if(Array.isArray(r))return r.length>0&&r.every(dr);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return dr(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&no.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function oo(e,t,r,n={},o=null){let i=qn("sha256"),s=(l,f)=>{let u=String(f);i.update(String(Buffer.byteLength(l,"utf8"))).update(":").update(l),i.update("=").update(String(Buffer.byteLength(u,"utf8"))).update(":").update(u).update(`
2
- `)};s("method",e),s("url",t),Object.keys(r||{}).map((l,f)=>({name:l.toLowerCase(),order:f,value:String(r[l])})).sort((l,f)=>l.name.localeCompare(f.name)||l.order-f.order).forEach((l,f)=>{s(`header-name-${f}`,l.name),s(`header-value-${f}`,l.value)}),s("body",o??"-");for(let l of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])s(`context-${l}`,n[l]??"-");return i.digest("hex")}function so(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,cr):Math.min(250*2**e,cr)+Math.floor(Math.random()*100)}function de(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function Et(e,t,r){return de(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function ge(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function ao(e){return e?e.byteLength??e.length??0:0}async function co(e,t,{url:r,truncate:n=!1,onOversize:o}={}){if(t==null)return await e.text();let i=Number(e.headers?.get?.("content-length"));if(Number.isFinite(i)&&i>t&&(ge(e),!n))throw Et(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let c=await e.text(),d=Buffer.byteLength(c,"utf8");if(d>t){if(!n)throw Et(r,`body ${d} bytes`,t);return Buffer.from(c,"utf8").subarray(0,t).toString("utf8")}return c}let a=[],l=0,f=!1;try{for(;;){let{value:c,done:d}=await s.read();if(d)break;if(c&&(a.push(Buffer.from(c)),l+=ao(c),l>t)){f=!0;break}}}finally{if(f)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(f&&(typeof o=="function"&&o(),!n))throw Et(r,`streamed ${l} bytes`,t);let u=Buffer.concat(a);return(f?u.subarray(0,t):u).toString("utf8")}function lo(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function uo(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:l=!1,maxResponseBytes:f=null,sameOriginRedirectsOnly:u=!1,importUndici:c,validateResponse:d,signal:m,redirectPolicy:p="follow",maxRedirects:w=Ze}){let x=new AbortController,k=setTimeout(()=>x.abort(),i),v=m?lr?lr([m,x.signal]):m:x.signal,S=null,E=t,R=s?{lookupFn:s}:{};if(l&&!a&&!gt(E))throw de(`HTTP refused ${e}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let T=async(h,{status:M=null}={})=>{let U=await ht(h,R);if(!U.ok)throw de(M==null?`HTTP refused ${h}: ${U.error}`:`HTTP redirect to ${h} ${U.error}`,M==null?{}:{status:M});let Y=new URL(h).hostname;if(a){if(S&&(await S.close(),S=null),!S)try{S=await yt({requireUndici:!0,...c?{importUndici:c}:{}})}catch(O){throw de(M==null?`HTTP refused ${h}: ${O?.message||O}`:`HTTP redirect to ${h} refused: ${O?.message||O}`,M==null?{}:{status:M})}S.pin(Y,U.addresses),E=S.fetch}else sr(E,Y,U.addresses);return U};try{let h=String(e),M=Object.assign(Object.create(null),n||{});l&&await T(h);for(let U=0;U<=w;U+=1){let Y=Object.assign(Object.create(null),{method:r,headers:M,body:o,signal:v,redirect:"manual",dispatcher:void 0}),O=await E(h,Y);if((p==="error"||w===0)&&O.status>=300&&O.status<400)throw ge(O),de(`HTTP ${O.status} ${r} redirect refused`,{status:O.status,redirectRefused:!0});if(Yn.has(O.status)){let I=u===!0&&r==="POST"&&[307,308].includes(O.status)&&pr(r,o);if(r!=="GET"&&r!=="HEAD"&&!I){ge(O);let A=new Error(`HTTP ${O.status} ${r} ${h} redirected non-idempotent request`);throw A.status=O.status,A}if(U===w)throw ge(O),de(`HTTP ${O.status} ${r} redirect budget exhausted`,{status:O.status,redirectRefused:!0});let C=O.headers?.get?.("location"),L;try{L=eo(C,h)}catch(A){throw ge(O),A}let j=!to(L,h);if(ge(O),j&&r==="POST"){let A=new Error(`HTTP ${O.status} ${r} cross-origin redirect refused`);throw A.status=O.status,A}if(j&&u){let A=new Error(`HTTP ${O.status} ${r} cross-origin redirect refused`);throw A.status=O.status,A.retryable=!1,A}if(j&&(M=Qn(M)),l)await T(L,{status:O.status});else if(j){let A=await ht(L,R);if(!A.ok){let N=new Error(`HTTP redirect from ${h} ${A.error}`);throw N.status=O.status,N.retryable=!1,N}a&&A.addresses?.length&&(S||(S=await yt(c?{importUndici:c}:{})),S&&(S.pin(new URL(L).hostname,A.addresses),E=S.fetch))}h=L;continue}if(typeof d=="function")try{await d(O,{url:h})}catch(I){throw ge(O),de(I?.message||String(I))}let y=await co(O,f,{url:h,onOversize:()=>x.abort()}),$=lo(y);if(!O.ok){let I=new Error(`HTTP ${O.status} ${r} ${h}`);throw I.status=O.status,I.retryAfter=O.headers?.get?.("retry-after")??null,I.body=$??y.slice(0,300),I}return $??y}throw new Error(`HTTP redirect loop for ${e}`)}catch(h){if(x.signal.aborted&&!xt(m)){let M=h&&(typeof h=="object"||typeof h=="function")&&!le.isProxy(h)?h:null,U=M?Object.getOwnPropertyDescriptor(M,"oversize"):null;if(!(U&&Object.hasOwn(U,"value")&&U.value===!0))try{if(!M)throw new TypeError("unsafe rejection");Object.defineProperties(M,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let O=new Error("HTTP request timed out");throw Object.defineProperties(O,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),O}}throw h}finally{clearTimeout(k),S&&await S.close()}}async function mr(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&le.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let r=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let N of Object.getOwnPropertyNames(t)){let _=Object.getOwnPropertyDescriptor(t,N);if(!(N==="toJSON"&&_&&Object.hasOwn(_,"value")&&_.value===void 0)){if(!r.has(N))throw new TypeError("HTTP options contain unknown fields");if(!_||!_.enumerable||!Object.hasOwn(_,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=N=>{if(t==null||!Object.hasOwn(t,N))return;let _=Object.getOwnPropertyDescriptor(t,N);if(!_||!Object.hasOwn(_,"value"))throw new TypeError("HTTP options must contain own data properties");return _.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=n("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let i=n("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let s=n("retries");if(s!==void 0&&(!Number.isInteger(s)||s<0||s>10))throw new TypeError("HTTP retries must be a bounded integer");let a=n("redirectPolicy");if(a!==void 0&&a!=="follow"&&a!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let l=n("maxRedirects");if(l!==void 0&&(!Number.isInteger(l)||l<0||l>Ze))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${Ze}`);if(a==="error"&&l!==void 0&&l!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let f=a??"follow",u=f==="error"?0:l??Ze;for(let N of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let _=n(N);if(_!==void 0&&typeof _!="boolean")throw new TypeError(`HTTP ${N} must be boolean`)}let c=n("maxResponseBytes");if(c!==void 0&&(!Number.isInteger(c)||c<1||c>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let d=n("signal");if(d!==void 0){if(le.isProxy(d)||!(d instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{xt(d)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let N of["importUndici","lookupFn","validateResponse"]){let _=n(N);if(_!==void 0&&typeof _!="function")throw new TypeError(`HTTP ${N} must be a function`)}let m=n("fetchImpl"),p=m||globalThis.fetch;if(typeof p!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let w=i??12e3,x=(o||"GET").toUpperCase(),k=n("headers"),v=Xn(k),S=Object.assign(Object.create(null),v);Object.keys(S).some(N=>N.toLowerCase()==="accept")||(S.Accept="application/json");let E=n("body");E!=null&&typeof E!="string"&&(Object.keys(S).find(_=>_.toLowerCase()==="content-type")||(S["Content-Type"]="application/json"),E=Zn(E));let R=s??Bn,T=n("lookupFn"),h=!m,M=n("untrustedUrl")===!0,U=n("sameOriginRedirectsOnly")===!0,Y=n("importUndici"),O=n("validateResponse"),y=d,$=c??null,I=async()=>{let N;for(let _=0;_<=R;_++){y&&Vn.call(y);try{return await uo(e,{fetchImpl:p,method:x,headers:S,body:E,timeoutMs:w,lookupFn:T,realFetch:h,untrustedUrl:M,maxResponseBytes:$,sameOriginRedirectsOnly:U,importUndici:Y,validateResponse:O,signal:y,redirectPolicy:f,maxRedirects:u})}catch(G){N=G;let te=Ae=>{if(!G||typeof G!="object"&&typeof G!="function"||le.isProxy(G))return;let ye=Object.getOwnPropertyDescriptor(G,Ae);return ye&&Object.hasOwn(ye,"value")?ye.value:void 0},fe=te("status"),Pe=te("oracleTimeout")===!0||te("name")==="AbortError"||te("name")==="TimeoutError"||xt(y),Ve=new Set([408,425,429]),Ke=te("retryable")===!1?!1:fe!=null?Ve.has(fe)||Dn.has(fe)&&ar.has(x):!Pe&&ar.has(x);if(_===R||!Ke)throw G;let at=so(_,te("retryAfter"));y?await new Promise((Ae,ye)=>{let Ge=setTimeout(Ae,at);Kn.call(y,"abort",()=>{clearTimeout(Ge),ye(Gn(y)||new DOMException("Aborted","AbortError"))},{once:!0})}):await io(at)}}throw N};if(!(n("dedupe")!==!1&&!y&&pr(x,E)))return I();let L=oo(x,e,S,{untrustedUrl:M,maxResponseBytes:$,sameOriginRedirectsOnly:U,redirectPolicy:f,maxRedirects:u,timeoutMs:w,retries:R,fetchImpl:We(p),realFetch:h,lookupFn:We(T),importUndici:We(Y),validateResponse:We(O)},E),j=bt.get(L);if(j)return j;let A=I().finally(()=>bt.delete(L));return bt.set(L,A),A}var Dn,ar,Bn,cr,zn,Jn,Vn,Kn,lr,xt,Gn,Yn,Ze,Ni,ce,bt,ur,fr,ro,no,io,hr=K(()=>{ir();Dn=new Set([408,425,429,500,502,503,504]),ar=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Bn=2,cr=4e3,zn=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Jn=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Vn=AbortSignal.prototype.throwIfAborted,Kn=EventTarget.prototype.addEventListener,lr=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,xt=e=>e?zn.call(e):!1,Gn=e=>e?Jn.call(e):void 0,Yn=new Set([301,302,303,307,308]),Ze=3,Ni=64*1024,ce=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});bt=new Map,ur=new WeakMap,fr=1;ro=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),no=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);io=e=>new Promise(t=>setTimeout(t,e))});import{types as yr}from"node:util";function fo(e){if(!e||typeof e!="object"||yr.isProxy(e)||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Xe(e,t="provider response",r=0){if(r>64)throw new Error(`${t} exceeds the JSON nesting bound`);if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(Array.isArray(e)){if(yr.isProxy(e)||e.length>1e5)throw new Error(`${t} contains an invalid array`);let o=new Array(e.length);for(let i=0;i<e.length;i+=1){let s=Object.getOwnPropertyDescriptor(e,String(i));if(!s||!Object.hasOwn(s,"value"))throw new Error(`${t} arrays must contain dense own data`);o[i]=Xe(s.value,t,r+1)}return o}if(!fo(e))throw new Error(`${t} contains a non-JSON value`);let n=Object.create(null);for(let o of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,o);if(!i||!Object.hasOwn(i,"value"))throw new Error(`${t} objects must contain own data`);n[o]=Xe(i.value,t,r+1)}return n}var wr=K(()=>{});function ho({testnet:e,baseUrl:t}={}){if(t)return t.replace(/\/$/,"").endsWith("/info")?t:`${t.replace(/\/$/,"")}/info`;if(process.env.HL_INFO_URL)return process.env.HL_INFO_URL;if(process.env.HL_API_URL){let r=process.env.HL_API_URL.replace(/\/$/,"");return r.endsWith("/info")?r:`${r}/info`}return e||process.env.HL_TESTNET==="1"?mo:po}async function kt(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=ho(t);return Xe(await mr(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs,maxResponseBytes:t.maxResponseBytes,sameOriginRedirectsOnly:t.sameOriginRedirectsOnly}),"hyperliquid info response")}async function gr(e={}){return kt({type:"meta"},e)}async function br({coin:e,interval:t="1h",startTime:r,endTime:n},o={}){if(!e)throw new Error("hlCandleSnapshot requires coin");let i={type:"candleSnapshot",req:{coin:String(e),interval:t,startTime:r??Date.now()-24*3600*1e3,endTime:n??Date.now()}};return kt(i,o)}async function Er({coin:e,startTime:t,endTime:r},n={}){if(!e)throw new Error("hlFundingHistory requires coin");return kt({type:"fundingHistory",coin:String(e),startTime:t??Date.now()-24*3600*1e3,endTime:r??Date.now()},n)}var po,mo,St=K(()=>{hr();wr();po="https://api.hyperliquid.xyz/info",mo="https://api.hyperliquid-testnet.xyz/info"});import{createHash as yo}from"node:crypto";function oe(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function Te(e){return typeof e=="number"&&Number.isFinite(e)}function At(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)At(t);return Object.freeze(e)}for(let t of Object.keys(e))At(e[t]);return Object.freeze(e)}function be(e){if(Array.isArray(e))return e.map(be);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=be(e[r]);return t}return e}function Ot(e){return{netPnlUsd:e.metrics.netPnlUsd,netPnlPct:e.metrics.netPnlPct,maxDrawdownPct:e.metrics.maxDrawdownPct,winRate:e.metrics.winRate,profitFactor:e.metrics.profitFactor,tradeCount:e.metrics.tradeCount,sharpe:e.metrics.sharpe,turnoverUsd:e.metrics.turnoverUsd,exposurePct:e.metrics.exposurePct}}function xr(e){return{feesUsd:e.costs.feesUsd,builderFeesUsd:e.costs.builderFeesUsd,fundingUsd:e.costs.fundingUsd,slippageUsd:e.costs.slippageUsd}}function go(e){return(e.feesUsd||0)+(e.builderFeesUsd||0)+Math.max(0,e.fundingUsd||0)+(e.slippageUsd||0)}function bo(e){let t=0;for(let r of e.trades)r.grossPnlUsd>0&&(t+=r.grossPnlUsd);return t}function Eo(e,t,r){return!(!e||e.tradeCount<Math.max(1,Math.min(r,3))||!(e.netPnlUsd>0)||!(e.profitFactor>1)||!(e.maxDrawdownPct<=t.maxDailyLossPct))}function Sr(e){if(!oe(e))throw new TypeError("evidence artifact must be a plain object");if(!wo.includes(e.status))throw new TypeError("evidence artifact status is invalid");for(let t of["strategyHash","compilerHash","barsHash"])if(typeof e[t]!="string"||!/^[0-9a-f]{64}$/.test(e[t]))throw new TypeError(`evidence artifact ${t} must be a sha256 hash`);if(!oe(e.split))throw new TypeError("evidence artifact split required");if(!Array.isArray(e.flags))throw new TypeError("evidence artifact flags must be an array");if(!oe(e.walkForward)||!Array.isArray(e.walkForward.windows))throw new TypeError("evidence artifact walkForward windows required");if(e.status==="pass_live_eligible"&&(!oe(e.train)||!oe(e.holdout)))throw new TypeError("live-eligible evidence artifact requires train and holdout facts");return be({barsHash:e.barsHash,compilerHash:e.compilerHash,flags:e.flags.map(t=>be(t)),holdout:e.holdout??null,split:e.split,status:e.status,strategyHash:e.strategyHash,train:e.train??null,walkForward:{passRate:e.walkForward.passRate,windowsRun:e.walkForward.windowsRun??e.walkForward.windows.length,windows:e.walkForward.windows.map(t=>({index:t.index,trainStartIndex:t.trainStartIndex,trainEndIndex:t.trainEndIndex,passed:t.passed,reason:t.reason,evalStartIndex:t.evalStartIndex,evalEndIndex:t.evalEndIndex,metrics:t.metrics}))}})}function Or(e){return yo("sha256").update(JSON.stringify(Sr(e)),"utf8").digest("hex")}function re(e,t,r=0){if(!Number.isInteger(e)||e<r)throw new Error(`${t} must be an integer >= ${r}`);return e}function Pt(e,t){if(!oe(e)||!oe(e.metrics))throw new Error(`${t} metrics required`);let r=re(e.tradeCount,`${t}.tradeCount`);if(e.metrics.tradeCount!==r)throw new Error(`${t} tradeCount contradicts metrics.tradeCount`);for(let n of["netPnlUsd","profitFactor","maxDrawdownPct"])if(!Te(e.metrics[n]))throw new Error(`${t}.metrics.${n} must be finite`);if(e.metrics.maxDrawdownPct<0)throw new Error(`${t}.metrics.maxDrawdownPct must be >= 0`);return e.metrics}function xo(e,{maxDailyLossPct:t}={}){let r=e.split,n=re(r.trainStartIndex,"split.trainStartIndex"),o=re(r.trainEndIndex,"split.trainEndIndex"),i=re(r.trainBarCount,"split.trainBarCount",1),s=re(r.holdoutStartIndex,"split.holdoutStartIndex"),a=re(r.holdoutEndIndex,"split.holdoutEndIndex"),l=re(r.holdoutBarCount,"split.holdoutBarCount",1);if(n!==0||o-n+1!==i||s!==o+1||a-s+1!==l)throw new Error("evidence split must be contiguous, chronological, and count-consistent");if(!Te(r.trainFraction)||r.trainFraction<=0||r.trainFraction>=1)throw new Error("split.trainFraction must be in (0,1)");Pt(e.train,"train");let f=Pt(e.holdout,"holdout");if(f.tradeCount<1||f.netPnlUsd<=0||f.profitFactor<=1)throw new Error("live-eligible holdout metrics do not pass");if(Te(t)&&f.maxDrawdownPct>t)throw new Error("live-eligible holdout drawdown exceeds strategy risk");if(e.flags.length>0)throw new Error("live-eligible evidence cannot contain failure flags");let u=e.walkForward,c=u.windows;if(c.length<1||u.windowsRun!==c.length)throw new Error("live-eligible walk-forward windowsRun must match nonempty windows");let d=0,m=-1;for(let w=0;w<c.length;w++){let x=c[w];if(!oe(x)||x.index!==w||typeof x.passed!="boolean")throw new Error("walk-forward windows must be ordered and structurally valid");let k=re(x.trainStartIndex,`walkForward.windows[${w}].trainStartIndex`),v=re(x.trainEndIndex,`walkForward.windows[${w}].trainEndIndex`),S=re(x.evalStartIndex,`walkForward.windows[${w}].evalStartIndex`),E=re(x.evalEndIndex,`walkForward.windows[${w}].evalEndIndex`);if(k!==0||v>=S||S>E||S<=m)throw new Error("walk-forward windows must be chronological and disjoint");if(m=E,x.passed){if(d+=1,x.reason!=="pass")throw new Error("passed walk-forward window reason must be pass");let R=Pt({metrics:x.metrics,tradeCount:x.metrics?.tradeCount},`walkForward.windows[${w}]`);if(R.tradeCount<1||R.netPnlUsd<=0||R.profitFactor<=1)throw new Error("passed walk-forward window metrics do not pass");if(Te(t)&&R.maxDrawdownPct>t)throw new Error("passed walk-forward drawdown exceeds strategy risk")}else if(x.reason==="pass")throw new Error("failed walk-forward window cannot have pass reason")}let p=d/c.length;if(!Te(u.passRate)||Math.abs(u.passRate-p)>Number.EPSILON||p<.6)throw new Error("walk-forward passRate contradicts concrete windows or is below live threshold")}function Pr(e,t={}){if(typeof e?.id!="string"||!/^[0-9a-f]{64}$/.test(e.id))throw new Error("evidence.id must be a sha256 evidence artifact hash");let r=Sr(e),n=be({id:e.id,...r});if(JSON.stringify(be(e))!==JSON.stringify(n))throw new Error("evidence artifact contains fields unbound from its deterministic identity");let o=Or(e);if(e.id!==o)throw new Error("evidence.id does not match its deterministic artifact facts digest");return e.status==="pass_live_eligible"&&xo(e,t),e}function Tt({strategy:e,bars:t,backtestOptions:r={},trainFraction:n=.7,walkForwardWindows:o=3,minTrades:i=10}={}){let s=[];if(!oe(e))throw new TypeError("strategy must be a plain object");if(!Array.isArray(t))throw new TypeError("bars must be an array");if(!oe(r))throw new TypeError("backtestOptions must be a plain object");if(!Te(n)||n<=0||n>=1)throw new TypeError("trainFraction must be in (0,1)");if(!Number.isInteger(o)||o<1)throw new TypeError("walkForwardWindows must be a positive integer");if(!Number.isInteger(i)||i<0)throw new TypeError("minTrades must be an integer >= 0");let a=Z(e),l=$e(a),f=He(t),u=t.length,c=(j=[],A={})=>kr({status:"fail",strategy:a,sHash:l,barsHash:f,split:A.split||{trainStartIndex:0,trainEndIndex:-1,trainBarCount:0,holdoutStartIndex:0,holdoutEndIndex:-1,holdoutBarCount:0,trainFraction:n},train:A.train||null,holdout:A.holdout||null,walkForward:A.walkForward||{windows:[],passRate:0},flags:[...s,...j]});if(u<10)return c([{type:"insufficient_bars",message:"need at least 10 bars for evidence"}]);let d=Math.floor(u*n),m=d,p=u-m;if(d<5||p<3)return c([{type:"invalid_windowing",message:"train/holdout split too small",trainCount:d,holdoutCount:p}]);let w=t.slice(0,d),x=t.slice(m),k,v;try{k=pe(a,w,r),v=pe(a,x,r)}catch(j){return c([{type:"backtest_error",message:String(j.message||j)}])}let S={metrics:Ot(k),costs:xr(k),tradeCount:k.metrics.tradeCount},E={metrics:Ot(v),costs:xr(v),tradeCount:v.metrics.tradeCount},R={trainStartIndex:0,trainEndIndex:d-1,trainBarCount:d,holdoutStartIndex:m,holdoutEndIndex:u-1,holdoutBarCount:p,trainFraction:n},T=[],h=Math.floor(u/(o+1));if(h<3)s.push({type:"invalid_windowing",message:"walk-forward window size too small",wfSize:h});else for(let j=0;j<o;j++){let A=h*(j+1),N=A,_=Math.min(u,N+h);if(_-N<3||A<3){T.push({index:j,trainStartIndex:0,trainEndIndex:A-1,evalStartIndex:N,evalEndIndex:_-1,passed:!1,reason:"window_too_small",metrics:null});continue}let G=t.slice(N,_),te;try{te=pe(a,G,r)}catch{T.push({index:j,trainStartIndex:0,trainEndIndex:A-1,evalStartIndex:N,evalEndIndex:_-1,passed:!1,reason:"backtest_error",metrics:null});continue}let fe=Ot(te),Pe=Eo(fe,a.risk,i);T.push({index:j,trainStartIndex:0,trainEndIndex:A-1,evalStartIndex:N,evalEndIndex:_-1,passed:Pe,reason:Pe?"pass":"fail_metrics",metrics:fe})}let M=T.filter(j=>j.passed).length,U=T.length===0?0:M/T.length,Y={windows:T,passRate:U,windowsRun:T.length};E.metrics.tradeCount===0&&S.metrics.tradeCount===0&&s.push({type:"no_trades",message:"no trades in train or holdout"}),E.metrics.tradeCount===0&&s.push({type:"absent_oos_trades",message:"holdout produced no trades"}),E.metrics.netPnlUsd<0&&s.push({type:"holdout_loss",message:"holdout netPnlUsd is negative"}),S.metrics.netPnlUsd>0&&E.metrics.netPnlUsd<0&&S.metrics.netPnlUsd>Math.abs(E.metrics.netPnlUsd)*.25?s.push({type:"overfit",message:"profitable train with losing holdout (OOS collapse)"}):S.metrics.netPnlUsd>0&&E.metrics.netPnlUsd>0&&E.metrics.netPnlUsd<S.metrics.netPnlUsd*.1&&S.metrics.tradeCount>=i&&s.push({type:"severe_oos_collapse",message:"holdout pnl collapsed vs train"});let O=go(E.costs),y=bo(v);y>0&&O>y&&s.push({type:"costs_exceed_gross",message:"holdout costs exceed gross gains"});let $=s.some(j=>["insufficient_bars","invalid_windowing","absent_oos_trades","holdout_loss","no_trades","severe_oos_collapse","backtest_error"].includes(j.type)),I=s.some(j=>j.type==="overfit"),C="fail";return E.metrics.tradeCount>=i&&E.metrics.netPnlUsd>0&&E.metrics.profitFactor>1&&E.metrics.maxDrawdownPct<=a.risk.maxDailyLossPct&&U>=.6&&!(y>0&&O>y)&&!I&&!s.some(j=>j.type==="severe_oos_collapse"||j.type==="invalid_windowing")?C="pass_live_eligible":!$&&E.metrics.tradeCount>0&&S.metrics.tradeCount>0&&Number.isFinite(E.metrics.netPnlUsd)?(C="pass_paper_only",E.metrics.tradeCount<i&&s.push({type:"undersampled",message:"holdout trades below minTrades"})):I&&E.metrics.tradeCount>0&&S.metrics.netPnlUsd>0?C="fail":E.metrics.tradeCount>0&&S.metrics.tradeCount>0&&!$?C="pass_paper_only":C="fail",E.metrics.netPnlUsd<0&&(C=C==="pass_live_eligible"?"fail":C==="pass_paper_only"?"pass_paper_only":"fail",C="fail"),kr({status:C,strategy:a,sHash:l,barsHash:f,split:R,train:S,holdout:E,walkForward:Y,flags:s})}function kr({status:e,strategy:t,sHash:r,barsHash:n,split:o,train:i,holdout:s,walkForward:a,flags:l}){let f={status:e,strategyHash:r,compilerHash:xe,barsHash:n,split:o,train:i,holdout:s,walkForward:a,flags:l};return f.id=Or(f),At(be(JSON.parse(JSON.stringify(f))))}var wo,$t=K(()=>{ke();Ee();Qe();wo=Object.freeze(["fail","pass_paper_only","pass_live_eligible"])});import{createHash as ko,createHmac as So,timingSafeEqual as Vi}from"node:crypto";function _t(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(_t).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${_t(e[r])}`).join(",")}}`}function Ar(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Tr(e=process.env){return Ar(process.env)||Ar(e)}function To(e){let{prepareHash:t,prepareMac:r,note:n,...o}=e||{};return o}function $o(e){let t=To(e);return ko("sha256").update(_t(t)).digest("hex")}function _o(e,t=Tr()){return t?So("sha256",t).update(String(e)).digest("hex"):""}function $r(e,{provider:t,kind:r,env:n=process.env,nowMs:o=Date.now(),expiresAtMs:i}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let s=Object.prototype.hasOwnProperty.call(e,"oraclePrepared");if(s&&typeof e.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let a={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:s?e.oraclePrepared:!0};if(!a.provider)throw new Error("stampPrepared: provider required");if(!a.kind)throw new Error("stampPrepared: kind required");let l=Number(o),f=i==null?l+Po:Number(i),u=f-l;if(!Number.isSafeInteger(l)||!Number.isSafeInteger(f)||u<=0||u>Ao)throw new Error("stampPrepared: bounded preparedAt/expiresAt required");let d={...a,preparedAt:l,expiresAt:f,prepareVersion:Oo},m=$o(d),p=Tr(n),w=p?_o(m,p):void 0,x={...d,prepareHash:m};return w&&(x.prepareMac=w),x}var Oo,Po,Ao,_r=K(()=>{Oo=2,Po=300*1e3,Ao=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});function Fe(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function vo(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function vt(e,t="value"){if(Array.isArray(e)){e.forEach((r,n)=>vt(r,`${t}[${n}]`));return}if(Fe(e))for(let[r,n]of Object.entries(e)){let o=vo(r);if(Io.some(i=>o.includes(i)))throw new Error(`handoff: forbidden secret-like field at ${t}.${r}`);vt(n,`${t}.${r}`)}}function It(e){return typeof e=="number"&&Number.isFinite(e)&&e>0}function Ir({strategy:e,evidence:t,shadow:r,caps:n,nowMs:o=Date.now(),env:i=process.env}={}){if(vt({strategy:e,evidence:t,shadow:r,caps:n},"handoff"),!Fe(e))throw new Error("handoff: strategy required");if(!Fe(t))throw new Error("handoff: evidence required");if(!Fe(r))throw new Error("handoff: shadow required");if(!Fe(n))throw new Error("handoff: caps required");if(typeof r.id!="string"||!r.id.trim())throw new Error("handoff: shadow.id required");if(typeof r.stateHash!="string"||!/^[0-9a-f]{64}$/.test(r.stateHash))throw new Error("handoff: shadow.stateHash must be a sha256 hash");if(r.status!=="running")throw new Error("handoff: shadow.status must be running");if(!Number.isInteger(r.cursor)||r.cursor<=0)throw new Error("handoff: shadow.cursor must be a positive integer");if(!Number.isInteger(r.updatedAt)||r.updatedAt<=0||r.updatedAt>o)throw new Error("handoff: shadow.updatedAt must be a positive integer <= nowMs");let s=Z(e,{nowMs:o}),a=X(s);if(Pr(t,{maxDailyLossPct:s.risk.maxDailyLossPct}),t.status!=="pass_live_eligible")throw new Error("handoff: evidence.status must be pass_live_eligible");if(t.strategyHash!==a.strategyHash)throw new Error("handoff: evidence.strategyHash mismatch");if(t.compilerHash!==a.compilerHash)throw new Error("handoff: evidence.compilerHash mismatch");let l=["perStrategyNotionalUsd","maxLeverage","dailyLossCapUsd","chainAllowlist","assetAllowlist","expiresAt","killSwitchRequired"];for(let d of l)if(!(d in n)||n[d]==null)throw new Error(`handoff: caps.${d} required`);if(!It(n.perStrategyNotionalUsd))throw new Error("handoff: caps.perStrategyNotionalUsd must be positive");if(n.perStrategyNotionalUsd>a.strategy.risk.maxNotionalUsd)throw new Error("handoff: caps.perStrategyNotionalUsd exceeds strategy.risk.maxNotionalUsd");if(!It(n.maxLeverage))throw new Error("handoff: caps.maxLeverage must be positive");if(n.maxLeverage>a.strategy.risk.maxLeverage)throw new Error("handoff: caps.maxLeverage exceeds strategy.risk.maxLeverage");if(!It(n.dailyLossCapUsd))throw new Error("handoff: caps.dailyLossCapUsd must be positive");let f=a.strategy.risk.maxNotionalUsd*(a.strategy.risk.maxDailyLossPct/100);if(n.dailyLossCapUsd>f)throw new Error("handoff: caps.dailyLossCapUsd exceeds strategy daily loss ceiling");if(!Array.isArray(n.chainAllowlist)||n.chainAllowlist.length===0)throw new Error("handoff: caps.chainAllowlist must be a non-empty array");if(!n.chainAllowlist.every(d=>d==="hyperliquid"))throw new Error("handoff: caps.chainAllowlist must include only hyperliquid");if(!n.chainAllowlist.includes("hyperliquid"))throw new Error("handoff: caps.chainAllowlist must include hyperliquid");if(!Array.isArray(n.assetAllowlist)||n.assetAllowlist.length===0)throw new Error("handoff: caps.assetAllowlist must be a non-empty array");if(n.assetAllowlist.length!==1||n.assetAllowlist[0]!==a.strategy.market.coin)throw new Error("handoff: caps.assetAllowlist must contain only the strategy market coin");if(!Number.isInteger(n.expiresAt)||!(n.expiresAt>o))throw new Error("handoff: caps.expiresAt must be an integer > nowMs");if(n.expiresAt>a.strategy.risk.expiresAt)throw new Error("handoff: caps.expiresAt exceeds strategy.risk.expiresAt");if(n.killSwitchRequired!==!0)throw new Error("handoff: caps.killSwitchRequired must be exactly true");let u={perStrategyNotionalUsd:n.perStrategyNotionalUsd,maxLeverage:n.maxLeverage,dailyLossCapUsd:n.dailyLossCapUsd,chainAllowlist:[...n.chainAllowlist],assetAllowlist:[...n.assetAllowlist],expiresAt:n.expiresAt,killSwitchRequired:!0},c={strategyHash:a.strategyHash,compilerHash:a.compilerHash,evidence:JSON.parse(JSON.stringify(t)),shadow:{id:r.id,stateHash:r.stateHash,status:r.status,cursor:r.cursor,updatedAt:r.updatedAt},compiled:{strategyHash:a.strategyHash,compilerHash:a.compilerHash,compilerVersion:Ce,venue:"hyperliquid",market:{coin:a.strategy.market.coin,kind:"perp",interval:a.strategy.market.interval},risk:{...a.strategy.risk},strategy:JSON.parse(JSON.stringify(a.strategy))},arming:{liveBroadcast:!1,requiresExplicitUserArm:!0,caps:u},requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,executionReady:!1};return $r(c,{provider:"hl-strategy",kind:"strategy-live-handoff",env:i})}var Io,vr=K(()=>{ke();$t();Ee();_r();Io=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});function _e(e,t){let r=Number(e);if(!Number.isFinite(r))throw new TypeError(`${t} must be finite`);return r}function Ie(e,t){if(!Number.isSafeInteger(e)||e<0)throw new TypeError(`${t} must be a non-negative safe integer`);return e}function Ue(e){if(Array.isArray(e))for(let t of e)Ue(t);else if(e&&typeof e=="object")for(let t of Object.values(e))Ue(t);return Object.freeze(e)}function No(e){let t=jo[e];if(!t)throw new TypeError(`unsupported strategy interval: ${e}`);return t}function Ro(e,{endTime:t=Number.MAX_SAFE_INTEGER}={}){if(!Array.isArray(e))throw new TypeError("Hyperliquid candles must be an array");Ie(t,"endTime");let r=new Map;for(let n=0;n<e.length;n++){let o=e[n];if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError(`candles[${n}] must be an object`);let i=Ie(Number(o.t),`candles[${n}].t`);if(Ie(Number(o.T),`candles[${n}].T`)>t)continue;let a={t:i,o:_e(o.o,`candles[${n}].o`),h:_e(o.h,`candles[${n}].h`),l:_e(o.l,`candles[${n}].l`),c:_e(o.c,`candles[${n}].c`),v:_e(o.v,`candles[${n}].v`)};if(a.h<Math.max(a.o,a.c,a.l))throw new TypeError(`candles[${n}].h is below another price`);if(a.l>Math.min(a.o,a.c,a.h))throw new TypeError(`candles[${n}].l is above another price`);if(a.v<0)throw new TypeError(`candles[${n}].v must be non-negative`);let l=r.get(i);if(l&&JSON.stringify(l)!==JSON.stringify(a))throw new TypeError(`conflicting duplicate candle at timestamp ${i}`);l||r.set(i,a)}return Ue([...r.values()].sort((n,o)=>n.t-o.t))}function Mo(e,t){if(!Array.isArray(e))throw new TypeError("Hyperliquid funding history must be an array");let r=new Map;for(let n=0;n<e.length;n++){let o=e[n];if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError(`funding[${n}] must be an object`);let i=Ie(Number(o.time),`funding[${n}].time`);i>t||r.set(i,{time:i,fundingRate:_e(o.fundingRate,`funding[${n}].fundingRate`)})}return[...r.values()].sort((n,o)=>n.time-o.time)}async function Lo({coin:e,startTime:t,endTime:r},n){let o=[],i=Math.max(0,t-288e5),s=!1;for(let a=0;a<16&&i<=r;a++){let l=await Er({coin:e,startTime:i,endTime:r},n);if(!Array.isArray(l))throw new TypeError("Hyperliquid funding history must be an array");o.push(...l);let f=i;for(let u of l){let c=Number(u?.time);Number.isSafeInteger(c)&&c>f&&(f=c)}if(l.length<500||f>=r){s=!0;break}if(f<=i)throw new Error("Hyperliquid funding history pagination did not advance");i=f+1}if(!s)throw new Error("strategy history exceeds the bounded funding history limit");return Mo(o,r)}function Ho(e,t,r){let n=0,o=null;return e.map(i=>{let s=i.t+r,a=0;for(;n<t.length&&t[n].time<s;){let l=t[n];o=l.fundingRate,l.time>=i.t&&(a+=l.fundingRate),n+=1}return o==null?{...i,fundingPaymentRate:a}:{...i,fundingRate:o,fundingPaymentRate:a}})}async function jr(e,t={}){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("strategy history input must be an object");let r=String(e.coin||"").trim().toUpperCase();if(!/^[A-Z0-9][A-Z0-9._-]{0,11}$/.test(r))throw new TypeError("coin must be an uppercase Hyperliquid asset id");let n=String(e.interval||"15m"),o=No(n);if(e.endTime==null)throw new TypeError("endTime is required for deterministic history");let i=Ie(e.endTime,"endTime"),s=e.count==null?1500:e.count;if(!Number.isInteger(s)||s<20||s>5e3)throw new TypeError("count must be an integer from 20 to 5000");let a=e.startTime==null?Math.max(0,i-s*o):Ie(e.startTime,"startTime");if(a>=i)throw new TypeError("startTime must be before endTime");let[l,f]=await Promise.all([br({coin:r,interval:n,startTime:a,endTime:i},t),Lo({coin:r,startTime:a,endTime:i},t)]),u=Ro(l,{endTime:i}),c=Ue(Ho(u,f,o));return Ue({coin:r,interval:n,range:{startTime:a,endTime:i},bars:c})}var jo,Nr=K(()=>{St();jo=Object.freeze({"1m":6e4,"3m":18e4,"5m":3e5,"15m":9e5,"30m":18e5,"1h":36e5,"2h":72e5,"4h":144e5,"8h":288e5,"12h":432e5,"1d":864e5})});function Uo(e){let t=[];if(!e||typeof e!="object"||Array.isArray(e))return{ok:!1,errors:[{path:"market",message:"must be a plain object"}],market:null};for(let r of Object.keys(e))Co.has(r)||t.push({path:`market.${r}`,message:"unknown field is not allowed"});return(typeof e.coin!="string"||e.coin.length===0||e.coin.length>32)&&t.push({path:"market.coin",message:"must be a non-empty string max 32"}),(typeof e.interval!="string"||!Fo.has(e.interval))&&t.push({path:"market.interval",message:"must be a supported interval"}),t.length?{ok:!1,errors:t,market:null}:{ok:!0,errors:[],market:{coin:e.coin,interval:e.interval}}}async function qo(e={}){let t=await gr(e);if(!t||!Array.isArray(t.universe))throw new TypeError("Hyperliquid market metadata must contain universe");return Object.freeze(t.universe.map((r,n)=>{if(!r||typeof r.name!="string"||!r.name)throw new TypeError(`Hyperliquid market metadata universe[${n}].name is invalid`);return r.name}))}var Fo,Co,Rr,Mr=K(()=>{St();vr();Nr();Fo=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),Co=new Set(["coin","interval"]);Rr=Object.freeze({id:"hyperliquid",validateMarket:Uo,fetchBars:jr,listMarkets:qo,prepareIntent(e){return Ir(e)}})});function Bo(e){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("strategy venue adapter must be an object");if(typeof e.id!="string"||!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(e.id))throw new TypeError("strategy venue adapter id is malformed");for(let t of Do.slice(1))if(typeof e[t]!="function")throw new TypeError(`strategy venue adapter ${e.id} requires ${t}()`);for(let t of["fetchBars","listMarkets"])if(e[t]!=null&&typeof e[t]!="function")throw new TypeError(`strategy venue adapter ${e.id} ${t} must be a function`);return e}function jt(e){return typeof e!="string"?null:zo.get(e)??null}function Nt(e){let t=jt(e);if(!t)throw new Error(`unknown strategy venue: ${String(e)}`);return t}var Do,Lr,zo,ia,Rt=K(()=>{Mr();Do=Object.freeze(["id","validateMarket","prepareIntent"]);Lr=[Rr].map(Bo),zo=new Map(Lr.map(e=>[e.id,e])),ia=Object.freeze([...Lr])});import{createHash as Jo}from"node:crypto";function ee(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function z(e){return typeof e=="number"&&Number.isFinite(e)}function zr(e){return Number.isInteger(e)&&e>0}function Ct(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Ct(t);return Object.freeze(e)}for(let t of Object.keys(e))Ct(e[t]);return Object.freeze(e)}function Ut(e){if(Array.isArray(e))return e.map(Ut);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=Ut(e[r]);return t}return e}function g(e,t,r){e.push({path:t,message:r})}function me(e,t,r,n){for(let o of Object.keys(e))t.has(o)||g(n,r?`${r}.${o}`:o,"unknown field is not allowed")}function Gr(e,t,r,n){if(!z(e)||!z(t)||!z(r)||!z(n)||n<=0||e<t||e>r)return!1;let o=(e-t)/n;if(!Number.isFinite(o))return!1;let i=Math.round(o);return Math.abs(o-i)<=1e-9}function Ft(e,t,r,n){if(ee(e)){if(me(e,new Set(["param"]),t,n),typeof e.param!="string"||!e.param)return g(n,`${t}.param`,"must be a parameter name string"),null;if(!Object.prototype.hasOwnProperty.call(r,e.param))return g(n,`${t}.param`,`unknown parameter "${e.param}"`),null;let o=r[e.param];return!ee(o)||![o.value,o.min,o.max,o.step].every(zr)?(g(n,`${t}.param`,"referenced period parameter value min max and step must be positive integers"),null):{param:e.param}}return zr(e)?e:(g(n,t,"must be a positive integer or {param}"),null)}function Jr(e,t,r,n){return ee(e)?(me(e,new Set(["param"]),t,n),typeof e.param!="string"||!e.param?(g(n,`${t}.param`,"must be a parameter name string"),null):Object.prototype.hasOwnProperty.call(r,e.param)?{param:e.param}:(g(n,`${t}.param`,`unknown parameter "${e.param}"`),null)):z(e)?e:(g(n,t,"must be a finite number or {param}"),null)}function et(e){switch(e.type){case"input":case"constant":return[];case"indicator":return e.input?[e.input]:[];case"compare":case"cross":return[e.left,e.right].filter(Boolean);case"logic":return Array.isArray(e.inputs)?[...e.inputs]:[];default:return[]}}function es(e){let t=new Map,r=n=>{let o=t.get(n)||0;if(o===1)return!0;if(o===2)return!1;t.set(n,1);let i=e.get(n);if(i){for(let s of et(i))if(e.has(s)&&r(s))return!0}return t.set(n,2),!1};for(let n of e.keys())if(r(n))return!0;return!1}function ts(e,t){if(!ee(e))return g(t,"parameters","must be a plain object"),null;let r=Object.keys(e);if(r.length>qr)return g(t,"parameters",`too many parameters (max ${qr})`),null;let n={};for(let o of r){if(!Vr.test(o)){g(t,`parameters.${o}`,"parameter name is malformed");continue}let i=e[o],s=`parameters.${o}`;if(!ee(i)){g(t,s,"must be a plain object");continue}me(i,Fr,s,t);for(let c of Fr)c in i||g(t,`${s}.${c}`,"required field is missing");let{value:a,min:l,max:f,step:u}=i;z(l)||g(t,`${s}.min`,"must be a finite number"),z(f)||g(t,`${s}.max`,"must be a finite number"),(!z(u)||u<=0)&&g(t,`${s}.step`,"must be a positive finite number"),z(a)||g(t,`${s}.value`,"must be a finite number"),z(l)&&z(f)&&l>f&&g(t,`${s}.min`,"min must be <= max"),z(a)&&z(l)&&z(f)&&z(u)&&u>0&&(Gr(a,l,f,u)||g(t,`${s}.value`,"value must lie on the declared min/max/step grid")),n[o]={value:a,min:l,max:f,step:u}}return n}function rs(e,t,r,n){let o=`nodes.${t}`;if(!ee(e))return g(n,o,"must be a plain object"),null;if(typeof e.type!="string"||!Ur[e.type])return g(n,`${o}.type`,"unknown or missing node type"),me(e,Qo,o,n),null;switch(me(e,Ur[e.type],o,n),(typeof e.id!="string"||!Kr.test(e.id))&&g(n,`${o}.id`,"must be a 1-64 char id starting with alphanumeric"),e.type){case"input":return(typeof e.field!="string"||!Vo.has(e.field))&&g(n,`${o}.field`,"must be one of open|high|low|close|volume|fundingRate|openInterest|premium|oiDelta|bookImbalance"),{id:e.id,type:"input",field:e.field};case"constant":{let i=Jr(e.value,`${o}.value`,r,n);return{id:e.id,type:"constant",value:i}}case"indicator":{(typeof e.indicator!="string"||!Ko.has(e.indicator))&&g(n,`${o}.indicator`,"must be one of sma|ema|rsi|macd|bollinger|atr");let i=e.indicator,s={id:e.id,type:"indicator",indicator:i};if(i==="atr"){"input"in e&&(typeof e.input!="string"||!e.input?g(n,`${o}.input`,"must be a node id string when provided"):s.input=e.input);let a=Ft(e.period,`${o}.period`,r,n);a!=null&&(s.period=a)}else typeof e.input!="string"||!e.input?g(n,`${o}.input`,"must be a node id string"):s.input=e.input;if((i==="sma"||i==="ema"||i==="rsi"||i==="bollinger"||i==="atr")&&("period"in e,i!=="macd"))if(!("period"in e))g(n,`${o}.period`,"required field is missing");else{let a=Ft(e.period,`${o}.period`,r,n);a!=null&&(s.period=a)}if(i==="macd"){for(let a of["fastPeriod","slowPeriod","signalPeriod"])if(!(a in e))g(n,`${o}.${a}`,"required field is missing");else{let l=Ft(e[a],`${o}.${a}`,r,n);l!=null&&(s[a]=l)}"output"in e?Zo.has(e.output)?s.output=e.output:g(n,`${o}.output`,"must be line|signal|histogram"):g(n,`${o}.output`,"required field is missing"),"period"in e&&g(n,`${o}.period`,"forbidden for macd"),"stdDev"in e&&g(n,`${o}.stdDev`,"forbidden for macd")}else if(i==="bollinger"){if(!("stdDev"in e))g(n,`${o}.stdDev`,"required field is missing");else{let a=Jr(e.stdDev,`${o}.stdDev`,r,n);a!=null&&(typeof a=="number"&&a<=0?g(n,`${o}.stdDev`,"must be > 0"):s.stdDev=a)}"output"in e?Xo.has(e.output)?s.output=e.output:g(n,`${o}.output`,"must be upper|middle|lower"):g(n,`${o}.output`,"required field is missing");for(let a of["fastPeriod","slowPeriod","signalPeriod"])a in e&&g(n,`${o}.${a}`,`forbidden for ${i}`)}else{"output"in e&&g(n,`${o}.output`,`forbidden for ${i}`),"stdDev"in e&&i!=="bollinger"&&g(n,`${o}.stdDev`,`forbidden for ${i}`);for(let a of["fastPeriod","slowPeriod","signalPeriod"])a in e&&g(n,`${o}.${a}`,`forbidden for ${i}`)}return s}case"compare":return(typeof e.op!="string"||!Go.has(e.op))&&g(n,`${o}.op`,"must be gt|gte|lt|lte|eq"),(typeof e.left!="string"||!e.left)&&g(n,`${o}.left`,"must be a node id"),(typeof e.right!="string"||!e.right)&&g(n,`${o}.right`,"must be a node id"),{id:e.id,type:"compare",op:e.op,left:e.left,right:e.right};case"logic":{if((typeof e.op!="string"||!Yo.has(e.op))&&g(n,`${o}.op`,"must be and|or|not"),!Array.isArray(e.inputs))return g(n,`${o}.inputs`,"must be an array of node ids"),{id:e.id,type:"logic",op:e.op,inputs:[]};let i=[];for(let s=0;s<e.inputs.length;s++){let a=e.inputs[s];typeof a!="string"||!a?g(n,`${o}.inputs.${s}`,"must be a node id"):i.push(a)}return e.op==="not"?i.length!==1&&g(n,`${o}.inputs`,"not requires exactly one input"):(e.op==="and"||e.op==="or")&&i.length<2&&g(n,`${o}.inputs`,`${e.op} requires at least two inputs`),{id:e.id,type:"logic",op:e.op,inputs:i}}case"cross":return(typeof e.direction!="string"||!Wo.has(e.direction))&&g(n,`${o}.direction`,"must be above|below"),(typeof e.left!="string"||!e.left)&&g(n,`${o}.left`,"must be a node id"),(typeof e.right!="string"||!e.right)&&g(n,`${o}.right`,"must be a node id"),{id:e.id,type:"cross",direction:e.direction,left:e.left,right:e.right};default:return null}}function ns(e,t,r){if(!ee(e))return g(t,"risk","must be a plain object"),null;me(e,Cr,"risk",t);for(let d of Cr)(!(d in e)||e[d]==null)&&g(t,`risk.${d}`,"required field is missing");let n={},o=e.maxLeverage;!z(o)||o<=0||o>50?g(t,"risk.maxLeverage","must be a number > 0 and <= 50"):n.maxLeverage=o;let i=e.maxNotionalUsd;!z(i)||i<=0?g(t,"risk.maxNotionalUsd","must be a number > 0"):n.maxNotionalUsd=i;let s=e.positionSizePct;!z(s)||s<=0||s>100?g(t,"risk.positionSizePct","must be a number > 0 and <= 100"):n.positionSizePct=s;let a=e.stopLossPct;!z(a)||a<=0||a>100?g(t,"risk.stopLossPct","must be a number > 0 and <= 100"):n.stopLossPct=a;let l=e.takeProfitPct;!z(l)||l<=0||l>1e3?g(t,"risk.takeProfitPct","must be a number > 0 and <= 1000"):n.takeProfitPct=l;let f=e.cooldownBars;!Number.isInteger(f)||f<0||f>1e5?g(t,"risk.cooldownBars","must be an integer >= 0 and <= 100000"):n.cooldownBars=f;let u=e.maxDailyLossPct;!z(u)||u<=0||u>100?g(t,"risk.maxDailyLossPct","must be a number > 0 and <= 100"):n.maxDailyLossPct=u;let c=e.expiresAt;return!Number.isInteger(c)||c<=0?g(t,"risk.expiresAt","must be an integer epoch milliseconds > 0"):(r.nowMs!==void 0&&(Number.isInteger(r.nowMs)?c<=r.nowMs&&g(t,"risk.expiresAt","must be strictly greater than nowMs"):g(t,"nowMs","must be an integer epoch milliseconds")),n.expiresAt=c),n}function qt(e,t={}){let r=[];if(!ee(e))return g(r,"","strategy must be a plain object"),{ok:!1,errors:r,strategy:null};me(e,Hr,"",r);for(let c of Hr)(!(c in e)||e[c]==null)&&g(r,c,"required field is missing");e.version!==Mt&&g(r,"version",`must be ${Mt}`),(typeof e.id!="string"||!Vr.test(e.id))&&g(r,"id","must match /^[a-z0-9][a-z0-9._-]{0,63}$/"),(typeof e.name!="string"||e.name.length===0||e.name.length>Br)&&g(r,"name",`must be a non-empty string max ${Br}`);let n=jt(e.venue);n||g(r,"venue",`unknown strategy venue "${String(e.venue)}"`);let o=null;if(!n)ee(e.market)||g(r,"market","must be a plain object");else{let c=n.validateMarket(e.market);if(!c||typeof c.ok!="boolean"||!Array.isArray(c.errors))g(r,"market",`venue ${n.id} returned an invalid market validation result`);else if(c.ok)o=c.market;else for(let d of c.errors)g(r,d.path,d.message)}let i=ts(e.parameters,r),s=null,a=new Map;if(!Array.isArray(e.nodes))g(r,"nodes","must be an array");else if(e.nodes.length>Dr)g(r,"nodes",`too many nodes (max ${Dr})`);else{s=[];for(let c=0;c<e.nodes.length;c++){let d=rs(e.nodes[c],c,i||{},r);d&&(typeof d.id=="string"&&Kr.test(d.id)&&(a.has(d.id)?g(r,`nodes.${c}.id`,`duplicate node id "${d.id}"`):a.set(d.id,d)),s.push(d))}for(let c=0;c<s.length;c++){let d=s[c],m=`nodes.${c}`;for(let p of et(d))a.has(p)||g(r,m,`unknown node ref "${p}"`);if(d.type==="indicator"||d.type==="compare"||d.type==="cross")for(let p of et(d)){let w=a.get(p);w&&Lt.has(w.type)&&g(r,m,`node ref "${p}" must be numeric`)}if(d.type==="logic")for(let p of et(d)){let w=a.get(p);w&&!Lt.has(w.type)&&g(r,m,`node ref "${p}" must be boolean`)}}es(a)&&g(r,"nodes","graph contains a cycle")}let l=null;if(!ee(e.rules))g(r,"rules","must be a plain object");else{me(e.rules,Ht,"rules",r);for(let c of Ht)c in e.rules||g(r,`rules.${c}`,"required field is missing");l={};for(let c of Ht){let d=e.rules[c];if(d===null){l[c]=null;continue}if(typeof d!="string"||!d){g(r,`rules.${c}`,"must be a node id or null"),l[c]=d;continue}if(!a.has(d)){g(r,`rules.${c}`,`unknown node ref "${d}"`),l[c]=d;continue}let m=a.get(d);Lt.has(m.type)||g(r,`rules.${c}`,`rule must reference a boolean node, not ${m.type}`),l[c]=d}}let f=ns(e.risk,r,t);if(r.length)return{ok:!1,errors:r,strategy:null};let u=Ct({version:Mt,id:e.id,name:e.name,venue:n.id,market:o,parameters:i,nodes:s,rules:l,risk:f});return{ok:!0,errors:[],strategy:u}}function Z(e,t={}){let r=qt(e,t);if(!r.ok)throw new ve(r.errors);return r.strategy}function os(e){let t=Z(e);return JSON.stringify(Ut(t))}function $e(e){let t=os(e);return Jo("sha256").update(t,"utf8").digest("hex")}function qe(e,t){if(!ee(e))throw new ve([{path:"",message:"strategy must be a plain object"}]);if(!ee(t))throw new ve([{path:"overrides",message:"must be a plain object"}]);let r=Z(e),n={};for(let[i,s]of Object.entries(r.parameters))n[i]={value:s.value,min:s.min,max:s.max,step:s.step};let o=[];for(let[i,s]of Object.entries(t)){if(!Object.prototype.hasOwnProperty.call(n,i)){g(o,i,`unknown parameter "${i}"`);continue}let a=n[i];if(!z(s)){g(o,i,"override must be a finite number");continue}if(!Gr(s,a.min,a.max,a.step)){g(o,i,"override must lie on the declared min/max/step grid");continue}n[i]={...a,value:s}}if(o.length)throw new ve(o);return Z({version:r.version,id:r.id,name:r.name,venue:r.venue,market:{coin:r.market.coin,interval:r.market.interval},parameters:n,nodes:r.nodes.map(i=>{let s={...i};return Array.isArray(i.inputs)&&(s.inputs=[...i.inputs]),s}),rules:{...r.rules},risk:{...r.risk}})}var Mt,Vr,Kr,Vo,Ko,Go,Yo,Wo,Zo,Xo,Lt,Hr,Fr,Ht,Cr,Qo,Ur,qr,Dr,Br,ve,Ee=K(()=>{Rt();Mt=1,Vr=/^[a-z0-9][a-z0-9._-]{0,63}$/,Kr=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/,Vo=new Set(["open","high","low","close","volume","fundingRate","openInterest","premium","oiDelta","bookImbalance"]),Ko=new Set(["sma","ema","rsi","macd","bollinger","atr"]),Go=new Set(["gt","gte","lt","lte","eq"]),Yo=new Set(["and","or","not"]),Wo=new Set(["above","below"]),Zo=new Set(["line","signal","histogram"]),Xo=new Set(["upper","middle","lower"]),Lt=new Set(["compare","logic","cross"]),Hr=new Set(["version","id","name","venue","market","parameters","nodes","rules","risk"]),Fr=new Set(["value","min","max","step"]),Ht=new Set(["entryLong","entryShort","exitLong","exitShort"]),Cr=new Set(["maxLeverage","maxNotionalUsd","positionSizePct","stopLossPct","takeProfitPct","cooldownBars","maxDailyLossPct","expiresAt"]),Qo=new Set(["id","type"]),Ur={input:new Set(["id","type","field"]),constant:new Set(["id","type","value"]),indicator:new Set(["id","type","indicator","input","period","fastPeriod","slowPeriod","signalPeriod","stdDev","output"]),compare:new Set(["id","type","op","left","right"]),logic:new Set(["id","type","op","inputs"]),cross:new Set(["id","type","direction","left","right"])},qr=16,Dr=128,Br=100,ve=class extends Error{constructor(t){let r=t.map(n=>`${n.path}: ${n.message}`);super(`invalid strategy (${t.length} error${t.length===1?"":"s"}): ${r.join("; ")}`),this.name="StrategyValidationError",this.errors=t}}});function De(e){if(!Array.isArray(e))throw new TypeError("values must be an array");for(let t=0;t<e.length;t++){let r=e[t];if(typeof r!="number"||!Number.isFinite(r))throw new TypeError(`values[${t}] must be a finite number`)}}function he(e){if(!Number.isInteger(e)||e<=0)throw new TypeError("period must be a positive integer")}function ss(e){if(!Array.isArray(e))throw new TypeError("bars must be an array");for(let t=0;t<e.length;t++){let r=e[t];if(r==null||typeof r!="object")throw new TypeError(`bars[${t}] must be an object`);for(let n of["o","h","l","c"]){let o=r[n];if(typeof o!="number"||!Number.isFinite(o))throw new TypeError(`bars[${t}].${n} must be a finite number`)}if(r.h<r.l)throw new TypeError(`bars[${t}] high must be >= low`)}}function Wr(e,t){De(e),he(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=0;for(let o=0;o<e.length;o++)n+=e[o],o>=t&&(n-=e[o-t]),o>=t-1&&(r[o]=n/t);return r}function tt(e,t){De(e),he(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=0;for(let s=0;s<t;s++)n+=e[s];let o=n/t;r[t-1]=o;let i=2/(t+1);for(let s=t;s<e.length;s++)o=i*e[s]+(1-i)*o,r[s]=o;return r}function Zr(e,t){De(e),he(t);let r=new Array(e.length).fill(null);if(e.length<=t)return r;let n=0,o=0;for(let a=1;a<=t;a++){let l=e[a]-e[a-1];l>=0?n+=l:o-=l}let i=n/t,s=o/t;r[t]=Yr(i,s);for(let a=t+1;a<e.length;a++){let l=e[a]-e[a-1],f=l>0?l:0,u=l<0?-l:0;i=(i*(t-1)+f)/t,s=(s*(t-1)+u)/t,r[a]=Yr(i,s)}return r}function Yr(e,t){return e===0&&t===0?50:t===0?100:e===0?0:100-100/(1+e/t)}function Xr(e,t={}){De(e);let r=t.fastPeriod,n=t.slowPeriod,o=t.signalPeriod;if(he(r),he(n),he(o),r>=n)throw new TypeError("fastPeriod must be < slowPeriod");let i=tt(e,r),s=tt(e,n),a=new Array(e.length).fill(null);for(let c=0;c<e.length;c++)i[c]!=null&&s[c]!=null&&(a[c]=i[c]-s[c]);let l=new Array(e.length).fill(null),f=new Array(e.length).fill(null),u=[];for(let c=0;c<a.length;c++)a[c]!=null&&u.push(c);if(u.length>=o){let c=0;for(let w=0;w<o;w++)c+=a[u[w]];let d=c/o,m=u[o-1];l[m]=d,f[m]=a[m]-d;let p=2/(o+1);for(let w=o;w<u.length;w++){let x=u[w];d=p*a[x]+(1-p)*d,l[x]=d,f[x]=a[x]-d}}return{line:a,signal:l,histogram:f}}function Qr(e,t={}){De(e);let r=t.period,n=t.stdDev;if(he(r),typeof n!="number"||!Number.isFinite(n)||n<=0)throw new TypeError("stdDev must be a finite number > 0");let o=new Array(e.length).fill(null),i=new Array(e.length).fill(null),s=new Array(e.length).fill(null);if(e.length<r)return{upper:i,middle:o,lower:s};let a=0,l=0;for(let f=0;f<e.length;f++){let u=e[f];if(a+=u,l+=u*u,f>=r){let c=e[f-r];a-=c,l-=c*c}if(f>=r-1){let c=a/r,d=l/r-c*c;d<0&&d>-1e-12&&(d=0);let m=Math.sqrt(d);o[f]=c,i[f]=c+n*m,s[f]=c-n*m}}return{upper:i,middle:o,lower:s}}function en(e,t){ss(e),he(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=new Array(e.length);for(let s=0;s<e.length;s++){let a=e[s];if(s===0)n[s]=a.h-a.l;else{let l=e[s-1].c;n[s]=Math.max(a.h-a.l,Math.abs(a.h-l),Math.abs(a.l-l))}}let o=0;for(let s=0;s<t;s++)o+=n[s];let i=o/t;r[t-1]=i;for(let s=t;s<e.length;s++)i=(i*(t-1)+n[s])/t,r[s]=i;return r}var tn=K(()=>{});import{createHash as is}from"node:crypto";var Dt,as,cs,ls,rn,nn=K(()=>{Dt=3,as="7477966facc4ef928a94e6221c8fd238eef4fcbeec46b96ae1b89178e13c2d5f",cs="68f5b412a9975f04024cf9b9b6209b4bccedd52f176e95f34f786b3f53479c6a",ls="967fd45ecddd0d59ac0f662fe92ea813c32620ba751f249b4ace6cb6b809fb5e",rn=is("sha256").update(JSON.stringify({version:Dt,compilerSourceHash:as,indicatorsSourceHash:cs,schemaSourceHash:ls})).digest("hex")});function Q(e){return typeof e=="number"&&Number.isFinite(e)}function ds(e){let t=new Map(e.map(a=>[a.id,a])),r=a=>{switch(a.type){case"indicator":return a.input?[a.input]:[];case"compare":case"cross":return[a.left,a.right];case"logic":return[...a.inputs];default:return[]}},n=new Map,o=new Map;for(let a of e)n.set(a.id,0),o.set(a.id,[]);for(let a of e)for(let l of r(a))t.has(l)&&(o.get(l).push(a.id),n.set(a.id,n.get(a.id)+1));let i=[];for(let[a,l]of n)l===0&&i.push(a);let s=[];for(;i.length;){let a=i.shift();s.push(a);for(let l of o.get(a))n.set(l,n.get(l)-1),n.get(l)===0&&i.push(l)}if(s.length!==e.length)throw new Error("strategy graph is cyclic");return s}function je(e,t){return e!=null&&typeof e=="object"&&"param"in e?t[e.param].value:e}function ps(e,t,r){if(!Array.isArray(e)||e.length===0)throw new TypeError("bars must be a non-empty array");if(!Number.isInteger(t)||t<0||t>=e.length)throw new RangeError("index out of range");let n=null;for(let o=0;o<=t;o++){let i=e[o];if(i==null||typeof i!="object"||Array.isArray(i))throw new TypeError(`bars[${o}] must be an object`);let{t:s,o:a,h:l,l:f,c:u,v:c}=i;if(!Q(s)&&(typeof s=="number"&&Number.isFinite(s)),!Number.isFinite(s))throw new TypeError(`bars[${o}].t must be finite`);for(let[d,m]of[["o",a],["h",l],["l",f],["c",u],["v",c]])if(!Q(m))throw new TypeError(`bars[${o}].${d} must be a finite number`);for(let[d,m]of[["o",a],["h",l],["l",f],["c",u]])if(!(m>0))throw new TypeError(`bars[${o}].${d} price must be positive`);if(c<0)throw new TypeError(`bars[${o}].v volume must be non-negative`);if(l<Math.max(a,u,f))throw new TypeError(`bars[${o}] high must be >= max(open, close, low)`);if(f>Math.min(a,u,l))throw new TypeError(`bars[${o}] low must be <= min(open, close, high)`);if(n!=null){if(!(s>n))throw new TypeError("bars t must be strictly increasing");if(s-n!==fs[r])throw new TypeError(`bars t must match ${r} cadence`)}if(n=s,"fundingRate"in i&&i.fundingRate!=null&&!Q(i.fundingRate))throw new TypeError(`bars[${o}].fundingRate must be finite when present`);if("openInterest"in i&&i.openInterest!=null){if(!Q(i.openInterest))throw new TypeError(`bars[${o}].openInterest must be finite when present`);if(i.openInterest<0)throw new TypeError(`bars[${o}].openInterest must be non-negative`)}for(let d of["premium","oiDelta"])if(d in i&&i[d]!=null&&!Q(i[d]))throw new TypeError(`bars[${o}].${d} must be finite when present`);if("bookImbalance"in i&&i.bookImbalance!=null){if(!Q(i.bookImbalance))throw new TypeError(`bars[${o}].bookImbalance must be finite when present`);if(i.bookImbalance<-1||i.bookImbalance>1)throw new TypeError(`bars[${o}].bookImbalance must be within [-1, 1]`)}}}function Se(e,t,r,n,o,i){if(i.has(e))return i.get(e);let s=t.get(e),a;switch(s.type){case"input":{let l=us[s.field];a=new Array(o+1);for(let f=0;f<=o;f++){let u=n[f][l];a[f]=u===void 0?null:u}break}case"constant":{let l=je(s.value,r);a=new Array(o+1).fill(l);break}case"indicator":{let l=s.period!=null?je(s.period,r):void 0;if(s.indicator==="atr"){let c=[];for(let d=0;d<=o;d++){let m=n[d];c.push({o:m.o,h:m.h,l:m.l,c:m.c})}a=en(c,l);break}let u=Se(s.input,t,r,n,o,i).map((c,d)=>{if(c==null||!Q(c))throw new TypeError(`indicator input ${s.input} has non-finite value at ${d}`);return c});if(s.indicator==="sma")a=Wr(u,l);else if(s.indicator==="ema")a=tt(u,l);else if(s.indicator==="rsi")a=Zr(u,l);else if(s.indicator==="macd")a=Xr(u,{fastPeriod:je(s.fastPeriod,r),slowPeriod:je(s.slowPeriod,r),signalPeriod:je(s.signalPeriod,r)})[s.output];else if(s.indicator==="bollinger")a=Qr(u,{period:l,stdDev:je(s.stdDev,r)})[s.output];else throw new Error(`unsupported indicator ${s.indicator}`);break}case"compare":{let l=Se(s.left,t,r,n,o,i),f=Se(s.right,t,r,n,o,i);a=new Array(o+1);for(let u=0;u<=o;u++){let c=l[u],d=f[u];if(c==null||d==null||!Q(c)||!Q(d)){a[u]=!1;continue}switch(s.op){case"gt":a[u]=c>d;break;case"gte":a[u]=c>=d;break;case"lt":a[u]=c<d;break;case"lte":a[u]=c<=d;break;case"eq":a[u]=c===d;break;default:a[u]=!1}}break}case"logic":{let l=s.inputs.map(f=>Se(f,t,r,n,o,i));a=new Array(o+1);for(let f=0;f<=o;f++)if(s.op==="not"){let u=l[0][f];a[f]=u===!0?!1:u===!1}else if(s.op==="and"){let u=!0;for(let c of l)if(c[f]!==!0){u=!1;break}a[f]=u}else if(s.op==="or"){let u=!1;for(let c of l)if(c[f]===!0){u=!0;break}a[f]=u}else a[f]=!1;break}case"cross":{let l=Se(s.left,t,r,n,o,i),f=Se(s.right,t,r,n,o,i);a=new Array(o+1),a[0]=!1;for(let u=1;u<=o;u++){let c=l[u-1],d=f[u-1],m=l[u],p=f[u];if(c==null||d==null||m==null||p==null||!Q(c)||!Q(d)||!Q(m)||!Q(p)){a[u]=!1;continue}s.direction==="above"?a[u]=c<=d&&m>p:a[u]=c>=d&&m<p}break}default:throw new Error(`unknown node type ${s.type}`)}return i.set(e,a),a}function X(e,t={}){let r=Z(e);t&&Object.keys(t).length&&(r=qe(r,t));let n=new Map(r.nodes.map(m=>[m.id,m])),o=Object.freeze(ds(r.nodes)),i=r.parameters,s=new Set(r.nodes.filter(m=>m.type==="input").map(m=>m.field));if(r.nodes.some(m=>m.type==="indicator"&&m.indicator==="atr"))for(let m of["open","high","low","close"])s.add(m);let a=Object.freeze([...s].sort()),l=$e(r);function f(m,p){let w={};for(let k of o){let v=m.get(k);w[k]=v[p]}let x=k=>k!=null&&w[k]===!0;return{values:w,signals:{entryLong:x(r.rules.entryLong),entryShort:x(r.rules.entryShort),exitLong:x(r.rules.exitLong),exitShort:x(r.rules.exitShort)}}}function u(m,p){ps(m,p,r.market.interval);let w=new Map;for(let x of o)Se(x,n,i,m,p,w);return w}function c(m,p){return f(u(m,p),p)}function d(m){if(!Array.isArray(m)||m.length===0)throw new TypeError("bars must be a non-empty array");let p=m.length-1,w=u(m,p);return Object.freeze(m.map((x,k)=>Object.freeze(f(w,k))))}return Object.freeze({strategy:r,strategyHash:l,compilerVersion:Ce,compilerHash:xe,requiredSeries:a,nodeOrder:o,evaluate:c,evaluateAll:d})}var Ce,xe,us,fs,ke=K(()=>{Ee();tn();nn();Ce=Dt,xe=rn,us=Object.freeze({open:"o",high:"h",low:"l",close:"c",volume:"v",fundingRate:"fundingRate",openInterest:"openInterest",premium:"premium",oiDelta:"oiDelta",bookImbalance:"bookImbalance"}),fs=Object.freeze({"1m":6e4,"3m":18e4,"5m":3e5,"15m":9e5,"30m":18e5,"1h":36e5,"2h":72e5,"4h":144e5,"8h":288e5,"12h":432e5,"1d":864e5})});import{createHash as ms}from"node:crypto";function ys(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function se(e){return typeof e=="number"&&Number.isFinite(e)}function Bt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Bt(t);return Object.freeze(e)}for(let t of Object.keys(e))Bt(e[t]);return Object.freeze(e)}function rt(e){if(Array.isArray(e))return e.map(rt);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=rt(e[r]);return t}return e}function zt(e,t="result"){if(typeof e=="number"){if(!Number.isFinite(e))throw new Error(`non-finite backtest result at ${t}`);return}if(!(e==null||typeof e!="object")){if(Array.isArray(e)){e.forEach((r,n)=>zt(r,`${t}[${n}]`));return}for(let[r,n]of Object.entries(e))zt(n,`${t}.${r}`)}}function sn(e){if(!Array.isArray(e)||e.length===0)throw new TypeError("bars must be a non-empty array");let t=null;for(let r=0;r<e.length;r++){let n=e[r];if(n==null||typeof n!="object"||Array.isArray(n))throw new TypeError(`bars[${r}] must be an object`);let{t:o,o:i,h:s,l:a,c:l,v:f}=n;if(!se(o))throw new TypeError(`bars[${r}].t must be finite`);for(let[u,c]of[["o",i],["h",s],["l",a],["c",l],["v",f]])if(!se(c))throw new TypeError(`bars[${r}].${u} must be a finite number`);for(let[u,c]of[["o",i],["h",s],["l",a],["c",l]])if(!(c>0))throw new TypeError(`bars[${r}].${u} price must be positive`);if(f<0)throw new TypeError(`bars[${r}].v volume must be non-negative`);if(s<Math.max(i,l,a))throw new TypeError(`bars[${r}] high must be >= max(open, close, low)`);if(a>Math.min(i,l,s))throw new TypeError(`bars[${r}] low must be <= min(open, close, high)`);if(t!=null&&!(o>t))throw new TypeError("bars t must be strictly increasing");if(t=o,"fundingRate"in n&&n.fundingRate!=null&&!se(n.fundingRate))throw new TypeError(`bars[${r}].fundingRate must be finite when present`);if("fundingPaymentRate"in n&&n.fundingPaymentRate!=null&&!se(n.fundingPaymentRate))throw new TypeError(`bars[${r}].fundingPaymentRate must be finite when present`);if("openInterest"in n&&n.openInterest!=null&&!se(n.openInterest))throw new TypeError(`bars[${r}].openInterest must be finite when present`)}}function He(e){if(!Array.isArray(e))throw new TypeError("bars must be an array");return e.length>0&&sn(e),ms("sha256").update(JSON.stringify(rt(e)),"utf8").digest("hex")}function ws(e){if(e==null&&(e={}),!ys(e))throw new TypeError("options must be a plain object");let t={...hs},r=new Set(["initialEquityUsd","takerFeeBps","builderFeeBps","slippageBps","latencyBars","maxVolumeParticipationPct","nowMs"]);for(let n of Object.keys(e))if(!r.has(n))throw new TypeError(`unknown option "${n}"`);if("initialEquityUsd"in e){if(!se(e.initialEquityUsd)||e.initialEquityUsd<=0)throw new TypeError("initialEquityUsd must be a positive finite number");t.initialEquityUsd=e.initialEquityUsd}for(let n of["takerFeeBps","builderFeeBps","slippageBps"])if(n in e){let o=e[n];if(!se(o)||o<0)throw new TypeError(`${n} must be a finite number >= 0`);if(n==="slippageBps"?o>=1e4:o>1e4)throw new TypeError(`${n} exceeds its safe basis-point bound`);t[n]=o}if("latencyBars"in e){let n=e.latencyBars;if(!Number.isInteger(n)||n<1)throw new TypeError("latencyBars must be an integer >= 1");t.latencyBars=n}if("maxVolumeParticipationPct"in e){let n=e.maxVolumeParticipationPct;if(!se(n)||n<=0||n>100)throw new TypeError("maxVolumeParticipationPct must be in (0,100]");t.maxVolumeParticipationPct=n}if("nowMs"in e){if(!Number.isInteger(e.nowMs))throw new TypeError("nowMs must be an integer epoch milliseconds");t.nowMs=e.nowMs}return t}function nt(e){return e/1e4}function gs(e,t,r){let n=nt(r);return t==="long"?e*(1+n):e*(1-n)}function bs(e,t,r){let n=nt(r);return t==="long"?e*(1-n):e*(1+n)}function on(e,t,r){let n=Math.abs(e)*nt(t),o=Math.abs(e)*nt(r);return{taker:n,builder:o,total:n+o}}function Es(e,t){let r=e*(t.positionSizePct/100)*t.maxLeverage;return Math.min(r,t.maxNotionalUsd)}function xs(e,t,r){let n=r/100;return t==="long"?e*(1-n):e*(1+n)}function ks(e,t,r){let n=r/100;return t==="long"?e*(1+n):e*(1-n)}function Ss(e,t,r,n){if(!(r>0))return t==="long"?0:Number.POSITIVE_INFINITY;let o=Math.min(.99,1/(2*r)+n/1e4);return t==="long"?e*(1-1/r)/(1-o):e*(1+1/r)/(1+o)}function Os(e,t,r){return t==="long"?e.l<=r:e.h>=r}function Ps(e,t,r){return t==="long"?e.h>=r:e.l<=r}function As(e,t,r){return t==="long"?e.l<=r:e.h>=r}function Be(e,t){for(let r of e.requiredSeries)if(Ts.includes(r)&&!t.every(n=>se(n?.[r])))throw new Error(`strategy required series is absent: ${r}`)}function $s(e){if(e.length<3)return 0;let t=[];for(let s=1;s<e.length;s++){let a=e[s-1].equity,l=e[s].equity;a>0&&t.push((l-a)/a)}if(t.length<2)return 0;let r=0;for(let s of t)r+=s;let n=r/t.length,o=0;for(let s of t)o+=(s-n)**2;let i=Math.sqrt(o/(t.length-1));return i>0?n/i:0}function _s(e){let t=-1/0,r=0;for(let n of e){let o=n.equity;if(o>t&&(t=o),t>0){let i=(t-o)/t*100;i>r&&(r=i)}}return r}function pe(e,t,r={}){let n=ws(r);sn(t);let o=He(t);n.nowMs!==void 0&&Z(e,{nowMs:n.nowMs});let i=X(e);if(Be(i,t),n.nowMs!==void 0&&i.strategy.risk.expiresAt<=n.nowMs)throw new Error("strategy is expired: risk.expiresAt must be strictly greater than nowMs");let s=i.strategy.risk,a=i.evaluateAll(t),l=n.latencyBars,f=n.slippageBps,u=n.takerFeeBps,c=n.builderFeeBps,d=n.initialEquityUsd,m=0,p=0,w=0,x=0,k=0,v=[],S=[],E=[],R=[],T=[],h=null,M=0,U=null,Y=d,O=!1,y=0,$=0,I=[],C=new Array(t.length).fill(0);function L(b){I.push(b)}function j(b){let H=t[b].v*(n.maxVolumeParticipationPct/100);return Math.max(0,H-C[b])}function A(b){if(!h)return d;let H=h.side==="long"?(b-h.entryPrice)*h.qty:(h.entryPrice-b)*h.qty;return d+H}function N(b,H,P){let D=P.o,F=Es(d,s);if(!(F>0)||!(D>0))return;let B=gs(D,H,f),q=F/B,V=j(b),Me=B*V;if(q>V){E.push({kind:"entry",barIndex:b,time:P.t,side:H,requestedNotionalUsd:F,maxFillNotionalUsd:Me,reason:"volume_participation"});return}C[b]+=q;let ne=Math.abs(B-D)*q,ae=on(F,u,c);d-=ae.total,m+=ae.taker,p+=ae.builder,x+=ne,k+=F,h={lifecycleEpoch:++$,side:H,entryBarIndex:b,entryReferencePrice:D,entryPrice:B,qty:q,notionalUsd:F,stop:xs(B,H,s.stopLossPct),take:ks(B,H,s.takeProfitPct),liq:Ss(B,H,s.maxLeverage,u+c),entryFees:ae.taker,entryBuilderFees:ae.builder,entrySlippageUsd:ne,fundingAccrued:0}}function _(b,H,P,D){if(!h)return!1;let F=h.side,B=H,q=B;P!=="liquidation"&&D&&(q=bs(B,F,f));let V=h.qty,Me=V*q;if(P!=="liquidation"){let or=j(b),Rn=q*or;if(V>or)return E.push({kind:"exit",barIndex:b,time:t[b].t,side:F,requestedNotionalUsd:Me,maxFillNotionalUsd:Rn,reason:"volume_participation",triggerReason:P}),!1;C[b]+=V}let ne=on(Me,u,c),ae=P==="liquidation"?0:Math.abs(q-B)*V,Le,dt;F==="long"?(Le=(B-h.entryReferencePrice)*V,dt=(q-h.entryPrice)*V):(Le=(h.entryReferencePrice-B)*V,dt=(h.entryPrice-q)*V),d+=dt,d-=ne.total,m+=ne.taker,p+=ne.builder,x+=ae,k+=Me;let Nn={side:F,entryBarIndex:h.entryBarIndex,entryTime:t[h.entryBarIndex].t,entryPrice:h.entryPrice,exitBarIndex:b,exitTime:t[b].t,exitPrice:q,exitReason:P,qty:V,notionalUsd:h.notionalUsd,grossPnlUsd:Le,feesUsd:h.entryFees+ne.taker,builderFeesUsd:h.entryBuilderFees+ne.builder,fundingUsd:h.fundingAccrued,slippageUsd:h.entrySlippageUsd+ae,netPnlUsd:Le-(h.entryFees+ne.taker+h.entryBuilderFees+ne.builder)-h.fundingAccrued-(h.entrySlippageUsd+ae)};return v.push(Nn),P==="liquidation"&&S.push({barIndex:b,time:t[b].t,side:F,price:q,tradeIndex:v.length-1}),h=null,$+=1,y=b+1+(s.cooldownBars||0),!0}function G(b,H,P,D){let F=b+1;if(F>=t.length)return;I.some(q=>q.kind==="exit"&&q.side===H&&q.fillBar===F&&q.epoch===D)||L({kind:"exit",side:H,signalBar:b,fillBar:F,reason:P,epoch:D})}function te(b){let H=I.filter(P=>P.fillBar===b);for(let P=I.length-1;P>=0;P--)I[P].fillBar===b&&I.splice(P,1);H.sort((P,D)=>{let F=B=>B.kind==="exit"?0:1;return F(P)-F(D)});for(let P of H)if(P.kind==="exit"){if(!h||h.side!==P.side||h.lifecycleEpoch!==P.epoch)continue;let D=P.reason||"rule";_(b,t[b].o,D,!0)||G(b,P.side,D,P.epoch)}else if(P.kind==="entry"){if(h||P.epoch!==$||b<y)continue;N(b,P.side,t[b])}}function fe(b){if(!h)return;let H=t[b],P=H.fundingPaymentRate;if(P==null||!se(P)||P===0)return;let D=Math.abs(h.qty*H.c),F=P*D;h.side==="long"?(d-=F,h.fundingAccrued+=F,w+=F):(d+=F,h.fundingAccrued-=F,w-=F)}function Pe(b){if(!h)return;let H=t[b].o;(h.side==="long"?H<=h.liq:H>=h.liq)&&_(b,H,"liquidation",!1)}function Ve(b){if(!h)return;let H=t[b],P=h.side,D=As(H,P,h.liq),F=Os(H,P,h.stop),B=Ps(H,P,h.take),q=V=>P==="long"?Math.min(V,H.o):Math.max(V,H.o);if(D){_(b,q(h.liq),"liquidation",!1);return}if(F&&B){_(b,q(h.stop),"stop_loss",!0)||G(b,P,"stop_loss",h.lifecycleEpoch);return}if(F){_(b,q(h.stop),"stop_loss",!0)||G(b,P,"stop_loss",h.lifecycleEpoch);return}B&&(_(b,h.take,"take_profit",!0)||G(b,P,"take_profit",h.lifecycleEpoch))}for(let b=0;b<t.length;b++){let H=Math.floor(t[b].t/864e5);H!==U&&(U=H,Y=A(t[b].o),O=!1),Pe(b),te(b),Ve(b),fe(b),!O&&A(t[b].c)<=Y*(1-s.maxDailyLossPct/100)&&(O=!0,R.push({type:"daily_loss_limit",barIndex:b,time:t[b].t,message:"daily loss limit reached; new entries blocked for UTC day"}));let P=a[b].signals,D=b+l;if(h)(h.side==="long"&&P.exitLong===!0||h.side==="short"&&P.exitShort===!0)&&D<t.length&&(I.some(V=>V.kind==="exit"&&V.side===h.side&&V.fillBar===D&&V.epoch===h.lifecycleEpoch)||L({kind:"exit",side:h.side,signalBar:b,fillBar:D,reason:"rule",epoch:h.lifecycleEpoch}));else{let B=P.entryLong===!0,q=P.entryShort===!0;B&&q?R.push({type:"conflicting_entry_signals",barIndex:b,time:t[b].t,message:"conflicting entry signals; no position opened"}):!O&&(B||q)&&D<t.length&&b>=y&&L({kind:"entry",side:B?"long":"short",signalBar:b,fillBar:D,epoch:$})}let F=d;h&&(M+=1,F=A(t[b].c)),T.push({barIndex:b,time:t[b].t,equity:F,positionSide:h?h.side:null})}let Ke=null;if(h){let b=t.length-1;if(_(b,t[b].c,"end_of_data",!0))T[b]={barIndex:b,time:t[b].t,equity:d,positionSide:null};else{let P=A(t[b].c);Ke={side:h.side,entryBarIndex:h.entryBarIndex,entryTime:t[h.entryBarIndex].t,entryPrice:h.entryPrice,qty:h.qty,notionalUsd:h.notionalUsd,markPrice:t[b].c,markedEquityUsd:P},R.push({type:"open_position_at_end",barIndex:b,time:t[b].t,message:"end-of-data exit missed; position remains open and marked"})}}let Ae=(h?A(t[t.length-1].c):d)-n.initialEquityUsd,ye=Ae/n.initialEquityUsd*100,Ge=0,ct=0,lt=0;for(let b of v)b.netPnlUsd>0?(Ge+=1,ct+=b.netPnlUsd):b.netPnlUsd<0&&(lt+=-b.netPnlUsd);let ut=v.length,In=ut===0?0:Ge/ut,ft=0;lt>0?ft=ct/lt:ct>0&&(ft=1e12);let vn={netPnlUsd:Ae,netPnlPct:ye,maxDrawdownPct:_s(T),winRate:In,profitFactor:ft,tradeCount:ut,sharpe:$s(T),turnoverUsd:k,exposurePct:M/t.length*100},jn={initialEquityUsd:n.initialEquityUsd,takerFeeBps:n.takerFeeBps,builderFeeBps:n.builderFeeBps,slippageBps:n.slippageBps,latencyBars:n.latencyBars,maxVolumeParticipationPct:n.maxVolumeParticipationPct},nr={barsHash:o,strategyHash:i.strategyHash,compilerHash:xe,compilerVersion:Ce,config:jn,trades:v,equityCurve:T,metrics:vn,costs:{feesUsd:m,builderFeesUsd:p,fundingUsd:w,slippageUsd:x},liquidations:S,missedFills:E,openPositionAtEnd:Ke,flags:R};return zt(nr),Bt(rt(nr))}var hs,Ts,Qe=K(()=>{ke();Ee();hs=Object.freeze({initialEquityUsd:1e4,takerFeeBps:3.5,builderFeeBps:2,slippageBps:2,latencyBars:1,maxVolumeParticipationPct:100});Ts=Object.freeze(["fundingRate","openInterest","premium","oiDelta","bookImbalance"])});import{createHash as Is}from"node:crypto";function Fs(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function Jt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Jt(t);return Object.freeze(e)}for(let t of Object.keys(e))Jt(e[t]);return Object.freeze(e)}function Cs(e){return String(e).trim().replace(/\s+/g," ")}function Us(e){let t=e.match(/\b(long|short)\b/i);return t?t[1].toLowerCase():null}function qs(e){for(let r of js)if(new RegExp(`\\b${r}\\b`,"i").test(e))return r;let t=e.match(/\b([A-Z][A-Z0-9]{1,11})\b/);return t?t[1]:null}function Ds(e){let t=e.match(/\bon\s+(1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/i);if(!t)return"15m";let r=t[1].toLowerCase();return vs.has(r)?r:null}function Bs(e){let t={...Rs},r=e.match(/stop\s*loss\s*(\d+(?:\.\d+)?)\s*%?/i);r&&(t.stopLossPct=Number(r[1]));let n=e.match(/take\s*profit\s*(\d+(?:\.\d+)?)\s*%?/i);n&&(t.takeProfitPct=Number(n[1]));let o=e.match(/leverage\s*(\d+(?:\.\d+)?)/i);o&&(t.maxLeverage=Number(o[1]));let i=e.match(/position\s*size\s*(\d+(?:\.\d+)?)\s*%?/i);i&&(t.positionSizePct=Number(i[1]));let s=e.match(/max\s*notional\s*(?:usd\s*)?\$?\s*(\d+(?:\.\d+)?)/i);return s&&(t.maxNotionalUsd=Number(s[1])),t}function zs(e){return[/\bon\s+(?:1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/gi,/\bstop\s*loss\s*\d+(?:\.\d+)?\s*%?/gi,/\btake\s*profit\s*\d+(?:\.\d+)?\s*%?/gi,/\bleverage\s*\d+(?:\.\d+)?/gi,/\bposition\s*size\s*\d+(?:\.\d+)?\s*%?/gi,/\bmax\s*notional\s*(?:usd\s*)?\$?\s*\d+(?:\.\d+)?/gi].some(r=>(e.match(r)??[]).length>1)}function Js(e){let t=Is("sha256").update(e,"utf8").digest("hex").slice(0,10),r=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40),o=`${r.length?r:"draft"}-${t}`.replace(/[^a-z0-9._-]/g,"").slice(0,64);return/^[a-z0-9]/.test(o)?o:`d${o}`.slice(0,64)}function Vs(e){let t=e.match(/\bema\s*(\d+)\s*cross(?:es)?\s*(above|below)\s*ema\s*(\d+)\b/i);if(!t)return null;let r=Number(t[1]),n=t[2].toLowerCase(),o=Number(t[3]);if(!(r>0)||!(o>0)||r===o)return null;let i=/\b(exit\s+on\s+reverse|reverse\s+exit)\b/i.test(e);return{kind:"ema_cross",fast:r,slow:o,direction:n,reverse:i}}function Ks(e){let t=e.match(/\brsi\s*(\d+)\s*(above|below)\s*(-?\d+(?:\.\d+)?)/i);if(!t)return null;let r=Number(t[3]);return!Number.isFinite(r)||r<=0||r>=100?null:{kind:"rsi",period:Number(t[1]),op:t[2].toLowerCase(),threshold:r}}function Gs(e){let t=e.match(/\bfunding\s*rate\s*(above|below)\s*(-?\d+(?:\.\d+)?)(%?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return t[3]==="%"&&(r=r/100),{kind:"funding",op:t[1].toLowerCase(),threshold:r}}function Ys(e){let t=e.match(/\bopen\s*interest\s*(above|below)\s*(-?\d+(?:\.\d+)?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return!Number.isFinite(r)||r<0?null:{kind:"open_interest",op:t[1].toLowerCase(),threshold:r}}function Ws(e){let t=e.match(/\bpremium\s*(above|below)\s*(-?\d+(?:\.\d+)?)(%?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return Number.isFinite(r)?(t[3]==="%"&&(r=r/100),{kind:"premium",op:t[1].toLowerCase(),threshold:r}):null}function Zs(e){let t=e.match(/\boi\s*delta\s*(above|below)\s*(-?\d+(?:\.\d+)?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return Number.isFinite(r)?{kind:"oi_delta",op:t[1].toLowerCase(),threshold:r}:null}function Xs(e){let t=e.match(/\bbook\s*imbalance\s*(above|below)\s*(-?\d+(?:\.\d+)?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return!Number.isFinite(r)||r<-1||r>1?null:{kind:"book_imbalance",op:t[1].toLowerCase(),threshold:r}}function Qs(e,t){let r=e.replace(/^(long|short)\s+[A-Z][A-Z0-9]{1,11}\s+when\s+/i,"");if(r===e)return!1;t.kind==="ema_cross"?r=r.replace(/^ema\s*\d+\s*cross(?:es)?\s*(?:above|below)\s*ema\s*\d+\b/i,""):t.kind==="rsi"?r=r.replace(/^rsi\s*\d+\s*(?:above|below)\s*\d+(?:\.\d+)?\b/i,""):t.kind==="open_interest"?r=r.replace(/^open\s*interest\s*(?:above|below)\s*-?\d+(?:\.\d+)?(?=\s|,|$)/i,""):t.kind==="premium"?r=r.replace(/^premium\s*(?:above|below)\s*-?\d+(?:\.\d+)?%?(?=\s|,|$)/i,""):t.kind==="oi_delta"?r=r.replace(/^oi\s*delta\s*(?:above|below)\s*-?\d+(?:\.\d+)?(?=\s|,|$)/i,""):t.kind==="book_imbalance"?r=r.replace(/^book\s*imbalance\s*(?:above|below)\s*-?\d+(?:\.\d+)?(?=\s|,|$)/i,""):r=r.replace(/^funding\s*rate\s*(?:above|below)\s*-?\d+(?:\.\d+)?%?(?=\s|,|$)/i,"");let n=[/(?:,\s*)?\bon\s+(?:1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/gi,/(?:,\s*)?\bstop\s*loss\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\btake\s*profit\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\bleverage\s*\d+(?:\.\d+)?/gi,/(?:,\s*)?\bposition\s*size\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\bmax\s*notional\s*(?:usd\s*)?\$?\s*\d+(?:\.\d+)?/gi];t.kind==="ema_cross"&&n.push(/(?:,\s*)?\b(?:exit\s+on\s+reverse|reverse\s+exit)\b/gi);for(let o of n)r=r.replace(o,"");return r.replace(/[\s,;]+/g,"")===""}function an(e){let t=Math.max(2,Math.floor(e/2));return{value:e,min:Math.max(2,e-t),max:Math.min(500,e+t),step:1}}function ei({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let l=[{id:"c",type:"input",field:"close"},{id:"emaLeft",type:"indicator",indicator:"ema",input:"c",period:{param:"ema_left_period"}},{id:"emaRight",type:"indicator",indicator:"ema",input:"c",period:{param:"ema_right_period"}},{id:"cross",type:"cross",direction:a.direction,left:"emaLeft",right:"emaRight"}],f={entryLong:null,entryShort:null,exitLong:null,exitShort:null};if(e==="long"?f.entryLong="cross":f.entryShort="cross",a.reverse){let u=a.direction==="above"?"below":"above";l.push({id:"crossRev",type:"cross",direction:u,left:"emaLeft",right:"emaRight"}),e==="long"?f.exitLong="crossRev":f.exitShort="crossRev"}return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{ema_left_period:an(a.fast),ema_right_period:an(a.slow)},nodes:l,rules:f,risk:{...n,expiresAt:o}}}function ti({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let l=[{id:"c",type:"input",field:"close"},{id:"rsi",type:"indicator",indicator:"rsi",input:"c",period:a.period},{id:"thr",type:"constant",value:a.threshold},{id:"sig",type:"compare",op:a.op==="above"?"gt":"lt",left:"rsi",right:"thr"}];return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{},nodes:l,rules:{entryLong:e==="long"?"sig":null,entryShort:e==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:o}}}function ri({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let l=[{id:"fr",type:"input",field:"fundingRate"},{id:"thr",type:"constant",value:a.threshold},{id:"sig",type:"compare",op:a.op==="above"?"gt":"lt",left:"fr",right:"thr"}];return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{},nodes:l,rules:{entryLong:e==="long"?"sig":null,entryShort:e==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:o}}}function ni({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let l=[{id:"oi",type:"input",field:"openInterest"},{id:"thr",type:"constant",value:a.threshold},{id:"sig",type:"compare",op:a.op==="above"?"gt":"lt",left:"oi",right:"thr"}];return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{},nodes:l,rules:{entryLong:e==="long"?"sig":null,entryShort:e==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:o}}}function si({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let f=[{id:"sig_input",type:"input",field:oi[a.kind]},{id:"thr",type:"constant",value:a.threshold},{id:"sig",type:"compare",op:a.op==="above"?"gt":"lt",left:"sig_input",right:"thr"}];return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{},nodes:f,rules:{entryLong:e==="long"?"sig":null,entryShort:e==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:o}}}function cn(e,t={}){if(typeof e!="string")throw new W("prompt must be a string");if(e.length>1e3)throw new W("prompt length must be <= 1000");if(!Fs(t))throw new W("options must be a plain object");if(!Number.isInteger(t.nowMs))throw new W("options.nowMs is required integer epoch ms");let r=t.nowMs,n=Hs;if("expiresInMs"in t){if(!Number.isInteger(t.expiresInMs))throw new W("expiresInMs must be an integer");if(n=t.expiresInMs,n<Ms||n>Ls)throw new W("expiresInMs must be between 1h and 30d")}if(Ns.test(e))throw new W(`prompt appears to contain secrets and is rejected. ${Ne}`);let o=Cs(e);if(!o)throw new W(`empty prompt. ${Ne}`);if(zs(o))throw new W(`duplicate interval or risk clause. ${Ne}`);let i=Us(o),s=qs(o),a=Ds(o);if(!i||!s||!a)throw new W(`could not parse side/coin/interval. ${Ne}`);let l=Bs(o);if(!(l.maxLeverage>0)||l.maxLeverage>50)throw new W("leverage out of range");if(!(l.positionSizePct>0)||l.positionSizePct>100)throw new W("position size out of range");let f=r+n,u=Js(o),c=`Draft ${s} ${i}`.slice(0,100),d=Vs(o),m=Ks(o),p=Gs(o),w=Ys(o),x=Ws(o),k=Zs(o),v=Xs(o),S=[d,m,p,w,x,k,v].filter(Boolean);if(S.length!==1)throw new W(`unsupported or ambiguous prompt. ${Ne}`);if(!Qs(o,S[0]))throw new W(`unsupported or ambiguous prompt. ${Ne}`);let E,R=S[0],T={side:i,coin:s,interval:a,risk:l,expiresAt:f,id:u,name:c,spec:R};R.kind==="ema_cross"?E=ei(T):R.kind==="rsi"?E=ti(T):R.kind==="open_interest"?E=ni(T):R.kind==="funding"?E=ri(T):E=si(T);let h=qt(E,{nowMs:r});if(!h.ok)throw new W(`draft failed validation: ${h.errors.map(M=>M.message).join("; ")}`);return Jt(Z(E,{nowMs:r}))}var W,vs,js,Ns,Ne,Rs,Ms,Ls,Hs,oi,ln=K(()=>{Ee();W=class extends Error{constructor(t){super(t),this.name="StrategyDraftError"}},vs=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),js=new Set(["BTC","ETH","SOL","HYPE"]),Ns=/\b(mnemonic|private\s*key|privkey|seed\s*phrase|seed\b|api[_-]?key|secret\s*key|wallet\s*key|passphrase)\b/i,Ne="Supported grammar: (1) EMA cross: <long|short> <COIN> when EMA <n> crosses <above|below> EMA <m> [on <interval>] [, exit on reverse] [, risk knobs]; (2) RSI: <long|short> <COIN> when RSI <n> <above|below> <threshold> [on <interval>] [, risk knobs]; (3) funding: <long|short> <COIN> when funding rate <above|below> <decimal|percent%> [on <interval>] [, risk knobs]; (4) open interest: <long|short> <COIN> when open interest <above|below> <non-negative number> [on <interval>] [, risk knobs]; (5) premium: <long|short> <COIN> when premium <above|below> <decimal|percent%> [on <interval>] [, risk knobs]; (6) oi delta: <long|short> <COIN> when oi delta <above|below> <number> [on <interval>] [, risk knobs]; (7) book imbalance: <long|short> <COIN> when book imbalance <above|below> <-1..1> [on <interval>] [, risk knobs]. Risk knobs: stop loss %, take profit %, leverage, position size %, max notional USD. Coins: BTC ETH SOL HYPE or uppercase token <=12 chars. Intervals: 1m 3m 5m 15m 30m 1h 2h 4h 8h 12h 1d.",Rs=Object.freeze({maxLeverage:1,maxNotionalUsd:100,positionSizePct:5,stopLossPct:2,takeProfitPct:4,cooldownBars:1,maxDailyLossPct:3}),Ms=36e5,Ls=30*864e5,Hs=864e5;oi=Object.freeze({funding:"fundingRate",open_interest:"openInterest",premium:"premium",oi_delta:"oiDelta",book_imbalance:"bookImbalance"})});import{createHash as ii}from"node:crypto";function dn(e){let t=String(e).toLowerCase();return t==="holdout"||t==="test"||t==="oos"||t.includes("holdout")||t.includes("oos")?!0:t==="testbars"||t.endsWith("testbars")||t.startsWith("test")||t.endsWith("test")?!t.includes("backtest"):!1}function pn(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function Kt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Kt(t);return Object.freeze(e)}for(let t of Object.keys(e))Kt(e[t]);return Object.freeze(e)}function ze(e){if(Array.isArray(e))return e.map(ze);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=ze(e[r]);return t}return e}function ot(e){return JSON.stringify(ze(e))}function ai(e){let{min:t,max:r,step:n}=e;if(!(n>0)||t>r)return[];let o=[],i=Math.floor((r-t)/n+1e-9);for(let a=0;a<=i;a++){let l=t+a*n;if(l>r+1e-9)break;let f=Math.abs(l-Math.round(l))<1e-9?Math.round(l):Number(l.toPrecision(12));f<t-1e-9||f>r+1e-9||o.push(f)}if(o.length===0)return[];let s=o[o.length-1];if(Math.abs(s-r)>1e-9){let a=(r-t)/n;Math.abs(a-Math.round(a))<=1e-9&&o.push(r)}return o}function ci(e,t){if(e.length===0)return[];let r=[{}];for(let n of e){let o=t[n],i=[];for(let s of r)for(let a of o)i.push({...s,[n]:a});r=i}return r.sort((n,o)=>{let i=ot(n),s=ot(o);return i<s?-1:i>s?1:0}),r}function Vt(e,t,r,n,o){let i=0;if(e==="maxDrawdownPct"){if(i=t.maxDrawdownPct-n.maxDrawdownPct,i!==0)return i<0}else if(i=t[e]-n[e],i!==0)return i>0;let s=ot(r),a=ot(o);return s<a}function mn(e,t,r={}){if(!pn(r))throw new TypeError("options must be a plain object");for(let E of Object.keys(r))if(dn(E))throw new TypeError(`options must not include holdout/test/oos key "${E}"`);let n=new Set(["maxTrials","objective","backtestOptions"]);for(let E of Object.keys(r))if(!n.has(E))throw new TypeError(`unknown option "${E}"`);let o=64;if("maxTrials"in r){let E=r.maxTrials;if(!Number.isInteger(E)||E<1||E>un)throw new TypeError(`maxTrials must be an integer 1..${un}`);o=E}let i=r.objective??"netPnlUsd";if(!fn.has(i))throw new TypeError(`objective must be one of ${[...fn].join("|")}`);let s=r.backtestOptions??{};if(!pn(s))throw new TypeError("backtestOptions must be a plain object");for(let E of Object.keys(s))if(dn(E))throw new TypeError(`backtestOptions must not include holdout/test/oos key "${E}"`);let a=Z(e),l=Object.keys(a.parameters).sort();if(l.length===0)throw new Error("optimizeStrategy requires at least one declared parameter");let f={},u=1;for(let E of l){let R=ai(a.parameters[E]);if(R.length===0)throw new Error(`parameter "${E}" produces an empty grid`);f[E]=R,u*=R.length}let c=ci(l,f);if(c.length===0)throw new Error("parameter grid is empty");let d=c.slice(0,o),m=[],p=null,w=null;for(let E of d){let R=qe(a,E),T=pe(R,t,s);w==null&&(w=T.config);let h={netPnlUsd:T.metrics.netPnlUsd,netPnlPct:T.metrics.netPnlPct,maxDrawdownPct:T.metrics.maxDrawdownPct,winRate:T.metrics.winRate,profitFactor:T.metrics.profitFactor,tradeCount:T.metrics.tradeCount,sharpe:T.metrics.sharpe,turnoverUsd:T.metrics.turnoverUsd},M={parameters:{...E},metrics:h};m.push(M),(!p||Vt(i,h,E,p.metrics,p.parameters))&&(p=M)}m.sort((E,R)=>Vt(i,E.metrics,E.parameters,R.metrics,R.parameters)?-1:Vt(i,R.metrics,R.parameters,E.metrics,E.parameters)?1:0);let x={...p.parameters},k=qe(a,x),v={strategyHash:$e(a),compilerHash:xe,trainBarsHash:He(t),backtestConfig:w,objective:i,maxTrials:o,trialsRun:m.length,candidates:m,bestParameters:x,bestStrategy:k},S={id:ii("sha256").update(JSON.stringify(ze(v)),"utf8").digest("hex"),...v};return Kt(ze(JSON.parse(JSON.stringify(S))))}var un,fn,hn=K(()=>{ke();Ee();Qe();un=256,fn=new Set(["netPnlUsd","profitFactor","sharpe","maxDrawdownPct"])});import ue from"node:fs";import st from"node:path";function it(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function ie(e){return e==null?e:JSON.parse(JSON.stringify(e))}function ui(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function Re(e,t="record"){if(Array.isArray(e)){e.forEach((r,n)=>Re(r,`${t}[${n}]`));return}if(it(e))for(let[r,n]of Object.entries(e)){let o=ui(r);if(li.some(i=>o.includes(i)))throw new Error(`shadow-store: forbidden secret-like field at ${t}.${r}`);Re(n,`${t}.${r}`)}}function fi(e){if(typeof e!="string"||!e||!st.isAbsolute(e))throw new Error("shadow-store: path must be an absolute path")}function yn(e){let t;try{t=ue.lstatSync(e)}catch(n){if(n&&n.code==="ENOENT")return;throw n}if(t.isSymbolicLink())throw new Error("shadow-store: store path must not be a symlink");if(!t.isFile())throw new Error("shadow-store: store path must be a regular file");if(t.mode&511&18)throw new Error("shadow-store: store file must not be group or world writable")}function di(){return{version:Yt,runners:[]}}function wn(e,t){let r;try{r=JSON.parse(e)}catch{throw new Error("shadow-store: malformed JSON")}if(!it(r))throw new Error("shadow-store: malformed JSON root");if(r.version!==Yt)throw new Error(`shadow-store: unsupported version ${r.version}`);if(!Array.isArray(r.runners))throw new Error("shadow-store: runners must be an array");return Re(r,st.basename(t)),{version:Yt,runners:r.runners.map(n=>ie(n))}}function gn(e,t){Re(t,"store");let r=st.dirname(e);ue.mkdirSync(r,{recursive:!0,mode:448});let n=st.join(r,`.shadow-store.${process.pid}.${Date.now()}.tmp`),o=`${JSON.stringify(t)}
3
- `;try{ue.writeFileSync(n,o,{mode:384,flag:"wx"}),ue.renameSync(n,e);try{ue.chmodSync(e,384)}catch{}}catch(i){try{ue.unlinkSync(n)}catch{}throw i}}function bn(e={}){let t=e.path;if(fi(t),yn(t),ue.existsSync(t)?wn(ue.readFileSync(t,"utf8"),t):gn(t,di()),Gt.has(t))return Gt.get(t);let r=!1,n=[];function o(){if(r)return;let p=n.shift();if(p){r=!0;try{let w=p.fn();r=!1,p.resolve(w),o()}catch(w){r=!1,p.reject(w),o()}}}function i(p){if(!r&&n.length===0){r=!0;try{return p()}finally{r=!1,queueMicrotask(o)}}return new Promise((w,x)=>{n.push({fn:p,resolve:w,reject:x}),queueMicrotask(o)})}function s(){return yn(t),wn(ue.readFileSync(t,"utf8"),t)}function a(p){gn(t,p)}function l(p){if(!it(p)||typeof p.id!="string"||!p.id)throw new Error("shadow-store: create requires record with string id");Re(p,"record");let w=s();if(w.runners.some(k=>k.id===p.id))throw new Error(`shadow-store: runner id already exists: ${p.id}`);let x=ie(p);return w.runners.push(x),a(w),ie(x)}function f(p){let w=s().runners.find(x=>x.id===p);return w?ie(w):null}function u(){return s().runners.map(p=>ie(p))}function c(p,w){if(typeof w!="function")throw new Error("shadow-store: updater must be a function");let x=s(),k=x.runners.findIndex(E=>E.id===p);if(k<0)throw new Error(`shadow-store: runner not found: ${p}`);let v=ie(x.runners[k]),S=w(v);if(!it(S)||S.id!==p)throw new Error("shadow-store: updater must return record with same id");return Re(S,"record"),x.runners[k]=ie(S),a(x),ie(x.runners[k])}function d(p){let w=s(),x=w.runners.findIndex(v=>v.id===p);if(x<0)throw new Error(`shadow-store: runner not found: ${p}`);let k=ie(w.runners[x]);return k.status!=="stopped"&&(k.status="stopped",w.runners[x]=k,a(w)),ie(w.runners[x])}let m={create(p){return i(()=>l(p))},get(p){return f(p)},list(){return u()},update(p,w){return i(()=>c(p,w))},stop(p){return i(()=>d(p))}};return Gt.set(t,m),m}var Yt,li,Gt,En=K(()=>{Yt=1,li=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"];Gt=new Map});import{createHash as Xt}from"node:crypto";function Wt(e){return e==null?e:JSON.parse(JSON.stringify(e))}function Zt(e){return Array.isArray(e)?e.map(Zt):e&&typeof e=="object"?Object.fromEntries(Object.keys(e).sort().map(t=>[t,Zt(e[t])])):e}function kn(e){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("shadow-runner: record must be an object");return Xt("sha256").update(JSON.stringify(Zt(e))).digest("hex")}function pi(e,t,r,n,o){return Xt("sha256").update(`${e}|${t}|${r}|${n}|${o}`).digest("hex")}function mi(e,t,r,n){return Xt("sha256").update(`shadow|${e}|${t}|${r}|${n??""}`).digest("hex")}function hi(e){return e==="entryLong"||e==="exitShort"?"buy":e==="entryShort"||e==="exitLong"?"sell":e}function xn(e){return e==="entryLong"||e==="entryShort"}function Qt({storePath:e,clock:t=Date.now}={}){if(typeof e!="string"||!e)throw new Error("shadow-runner: storePath required");let r=bn({path:e});function n({strategy:l,evidenceId:f=null}={}){let u=X(l),c=f==null?null:String(f),d=r.list().filter(k=>k.status==="running"&&k.strategyHash===u.strategyHash&&k.compilerHash===u.compilerHash&&k.evidenceId===c).sort((k,v)=>k.createdAt-v.createdAt||k.id.localeCompare(v.id))[0];if(d)return Wt(d);let m=t(),p=mi(m,u.strategyHash,u.compilerHash,c),w=r.get(p);if(w)return Wt(w);let x={id:p,strategy:Wt(u.strategy),strategyHash:u.strategyHash,compilerHash:u.compilerHash,evidenceId:c,status:"running",cursor:null,intendedOrders:[],fills:[],missedFills:[],markouts:[],createdAt:m,updatedAt:m,position:null,cooldownBarsRemaining:0,cooldownStartT:null,lastProcessedBarIndex:-1};return r.create(x)}function o(l){return r.get(l)}function i(){return r.list()}function s(l){return r.stop(l)}function a(l,f,{markoutHorizons:u=[1,4,12]}={}){if(!Array.isArray(f))throw new TypeError("shadow-runner: bars must be an array");return r.update(l,c=>{if(c.status!=="running")throw new Error("shadow-runner: runner is stopped");if(f.length===0)return c;let m=X(c.strategy).evaluateAll(f),p=new Map;for(let y=0;y<f.length;y++)p.set(f[y].t,y);let w=c.cursor,x=[];for(let y=0;y<f.length;y++){let $=f[y].t;(w==null||$>w)&&x.push(y)}if(x.length===0)return c;let k=new Map(c.intendedOrders.map(y=>[y.id,y])),v=new Set(c.fills.map(y=>y.orderId)),S=new Map(c.missedFills.map(y=>[y.orderId,y])),E=(y,$)=>`${y}|${$}`,R=new Map(c.markouts.map(y=>[E(y.orderId,y.horizon),y])),T=c.position?{...c.position}:null,h=Number.isInteger(c.cooldownBarsRemaining)?Math.max(0,c.cooldownBarsRemaining):0,M=Number.isFinite(c.cooldownStartT)?c.cooldownStartT:null;function U({action:y,signalBarT:$,signalIndex:I}){let C=hi(y),L=pi(c.id,c.strategyHash,$,C,y);if(k.has(L))return k.get(L);let j=I+1,A=j<f.length,N={id:L,action:y,type:y,side:C,signalBarT:$,fillBarT:A?f[j].t:null,status:A?"open":"missed"};return k.set(L,N),c.intendedOrders.push(N),N}function Y(y,$,I){if(v.has(y.id))return;let C={orderId:y.id,action:xn(y.action)?"entry":"exit",side:y.side,price:$.o,barT:$.t,signalBarT:y.signalBarT,barIndex:I};if(c.fills.push(C),v.add(y.id),y.status="filled",y.fillBarT=$.t,S.has(y.id)&&(S.delete(y.id),c.missedFills=c.missedFills.filter(L=>L.orderId!==y.id)),xn(y.action)){T={side:y.action==="entryLong"?"long":"short",entryOrderId:y.id,entryBarT:$.t,entryPrice:$.o,entryBarIndex:I};for(let L of u){let j=E(y.id,L);if(R.has(j))continue;let A={orderId:y.id,horizon:L,entryBarT:$.t,entryPrice:$.o,side:T.side,status:"pending",close:null,barT:null};R.set(j,A),c.markouts.push(A)}}else T=null,h=Number(c.strategy?.risk?.cooldownBars)||0,M=$.t}function O(y){if(v.has(y.id)||S.has(y.id))return;let $={orderId:y.id,action:y.action,side:y.side,signalBarT:y.signalBarT,status:"missed"};S.set(y.id,$),c.missedFills.push($),y.status="missed"}for(let y of c.intendedOrders){if(y.status==="filled"||v.has(y.id))continue;let $=p.get(y.signalBarT);if($==null)continue;let I=$+1;I<f.length&&(w==null||f[I].t>w)&&Y(y,f[I],I)}for(let y of x){let $=f[y],I=m[y].signals,C=T,L=A=>{if(T||h>0&&(M==null||$.t>=M))return;let _=U({action:A,signalBarT:$.t,signalIndex:y}),G=y+1;G<f.length?Y(_,f[G],G):O(_)},j=A=>{if(!T||T.side==="long"&&A!=="exitLong"||T.side==="short"&&A!=="exitShort")return;let N=U({action:A,signalBarT:$.t,signalIndex:y}),_=y+1;_<f.length?Y(N,f[_],_):O(N)};C?(I.exitLong&&j("exitLong"),I.exitShort&&j("exitShort")):I.entryLong&&I.entryShort||(I.entryLong&&L("entryLong"),I.entryShort&&L("entryShort")),h>0&&M!=null&&$.t>=M&&(h-=1,h===0&&(M=null)),c.cursor=$.t,c.lastProcessedBarIndex=y}for(let y of c.markouts){if(y.status!=="pending")continue;let $=c.fills.find(L=>L.orderId===y.orderId&&L.action==="entry");if(!$)continue;let I=p.get($.barT);if(I==null)continue;let C=I+y.horizon;if(C<f.length){y.close=f[C].c,y.barT=f[C].t,y.status="filled";let L=y.entryPrice;y.markout=y.side==="long"?(y.close-L)/L:(L-y.close)/L}}return c.position=T,c.cooldownBarsRemaining=h,c.cooldownStartT=M,c.updatedAt=t(),c})}return{start:n,step:a,list:i,get:o,stop:s}}var Sn=K(()=>{ke();En()});var An={};Ln(An,{runStrategyOperation:()=>Si});import yi from"node:os";import wi from"node:path";function Je(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function bi(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function tr(e){if(Array.isArray(e)){for(let t of e)tr(t);return}if(Je(e))for(let[t,r]of Object.entries(e)){if(gi.some(n=>bi(t).includes(n)))throw new Error(`strategy service: secret-like field "${t}" is forbidden`);tr(r)}}function Ei(e){if(!Je(e))throw new TypeError("strategy input must be a plain object");return tr(e),e}function xi(e,t={}){if(t.nowMs!==void 0){if(!Number.isInteger(t.nowMs))throw new TypeError("nowMs must be an integer epoch milliseconds");return t.nowMs}let r=Date.now();if(e.nowMs===void 0||e.nowMs===null)return r;if(!Number.isInteger(e.nowMs))throw new TypeError("nowMs must be an integer epoch milliseconds");if(Math.abs(e.nowMs-r)>12e4)throw new Error("nowMs outside allowed wall-clock skew (120s); omit nowMs to use server time");return e.nowMs}async function er(e,t,r,n){if(Array.isArray(t.bars))return t.bars;let o=Nt(e.venue),i=r.fetchBars??o.fetchBars;if(typeof i!="function")throw new Error(`strategy venue ${o.id} does not support history`);r.signal?.throwIfAborted?.();let s=await i({coin:e.market.coin,interval:e.market.interval,count:t.count??1500,endTime:t.endTime??n},{signal:r.signal});r.signal?.throwIfAborted?.();let a=Array.isArray(s)?s:s?.bars;if(!Array.isArray(a))throw new Error("strategy history provider returned no bars");return a}function rr(e,t){let r=e.backtestOptions??{};if(!Je(r))throw new TypeError("backtestOptions must be a plain object");return{...r,nowMs:t}}function On(e,t,r,n,o={}){let i=e.evidenceOptions??{};if(!Je(i))throw new TypeError("evidenceOptions must be a plain object");return{...i,...o,strategy:t,bars:r,backtestOptions:rr(e,n)}}function Pn(){return wi.join(yi.homedir(),".oracle","strategy-shadow.json")}function ki(e,t){return{perStrategyNotionalUsd:e.risk.maxNotionalUsd,maxLeverage:e.risk.maxLeverage,dailyLossCapUsd:e.risk.maxNotionalUsd*(e.risk.maxDailyLossPct/100),chainAllowlist:[e.venue],assetAllowlist:[e.market.coin],expiresAt:Math.min(e.risk.expiresAt,t+864e5),killSwitchRequired:!0}}async function Si(e,t={},r={}){r.signal?.throwIfAborted?.();let n=Ei(t),o=xi(n,r);if(e==="draft")return{strategy:cn(n.prompt,{nowMs:o})};if(e==="validate"){let i=X(n.strategy);if(i.strategy.risk.expiresAt<=o)throw new Error("strategy is expired");return{valid:!0,strategy:i.strategy,strategyHash:i.strategyHash,compilerHash:i.compilerHash,compilerVersion:i.compilerVersion,requiredSeries:i.requiredSeries}}if(e==="backtest"||e==="evidence"){let i=X(n.strategy),s=await er(i.strategy,n,r,o);Be(i,s);let a=Tt(On(n,i.strategy,s,o));return e==="evidence"?a:{backtest:pe(i.strategy,s,rr(n,o)),evidence:a}}if(e==="optimize"){let i=X(n.strategy),s=await er(i.strategy,n,r,o);Be(i,s);let a=n.trainFraction,l=n.evidenceOptions?.trainFraction;if(a!=null&&l!=null&&a!==l)throw new TypeError("conflicting trainFraction controls are forbidden");let f=a??l??.7;if(typeof f!="number"||f<=0||f>=1)throw new TypeError("trainFraction must be in (0,1)");let u=s.slice(0,Math.floor(s.length*f)),c=n.options??{};if(!Je(c))throw new TypeError("options must be a plain object");let d=mn(i.strategy,u,{...c,...n.maxTrials==null?{}:{maxTrials:n.maxTrials},backtestOptions:rr(n,o)}),m=d.bestStrategy;return{strategy:m,optimization:d,evidence:Tt(On(n,m,s,o,{trainFraction:f}))}}if(e==="shadow"){let i=Qt({storePath:r.storePath??Pn(),clock:()=>o}),s=n.action;if(s==="start")return await i.start({strategy:n.strategy,evidenceId:n.evidenceId??n.evidence?.id??null});if(s==="list")return await i.list();if(s==="get")return await i.get(n.id);if(s==="stop")return await i.stop(n.id);if(s==="step"){let a=await i.get(n.id);if(!a)throw new Error(`shadow runner not found: ${n.id}`);let l=await er(a.strategy,n,r,o);return Be(X(a.strategy),l),await i.step(n.id,l,n.stepOptions??{})}throw new Error(`unknown shadow action: ${s}`)}if(e==="prepare"){let i=X(n.strategy),s=Nt(i.strategy.venue);if(typeof n.shadowId!="string"||!n.shadowId)throw new Error("strategy prepare requires a matching shadow runner id");let l=await Qt({storePath:r.storePath??Pn(),clock:()=>o}).get(n.shadowId);if(!l)throw new Error("strategy prepare shadow runner not found");if(l.status!=="running")throw new Error("strategy prepare requires an active shadow runner");if(!Number.isFinite(l.cursor))throw new Error("strategy prepare requires a stepped shadow runner");if(l.strategyHash!==i.strategyHash||l.compilerHash!==i.compilerHash)throw new Error("strategy prepare shadow runner does not match strategy artifacts");if(l.evidenceId!==n.evidence?.id)throw new Error("strategy prepare shadow runner does not match evidence artifact");let f=n.caps??ki(i.strategy,o);return s.prepareIntent({strategy:i.strategy,evidence:n.evidence,shadow:{id:l.id,stateHash:kn(l),status:l.status,cursor:l.cursor,updatedAt:l.updatedAt},caps:f,nowMs:o,env:r.env??process.env})}throw new Error(`unknown strategy operation: ${e}`)}var gi,Tn=K(()=>{Qe();ke();$t();ln();hn();Sn();Rt();gi=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});import $n from"node:fs";function Oi(e){let t={},r=[];for(let n=0;n<e.length;n++){let o=e[n];if(!o.startsWith("--")){r.push(o);continue}let i=o.slice(2),s=e[n+1];s!=null&&!s.startsWith("--")?(t[i]=s,n++):t[i]=!0}return{flags:t,positional:r}}function Oe(e,t){if(!e)throw new Error(`${t} path required`);let r=e==="-"?$n.readFileSync(0,"utf8"):$n.readFileSync(e,"utf8");try{return JSON.parse(r)}catch{throw new Error(`${t} must contain valid JSON`)}}function _n(e,t){if(e==null)return;let r=Number(e);if(!Number.isFinite(r))throw new Error(`${t} must be a finite number`);return r}var Pi=`oracle strategy <draft|validate|backtest|optimize|evidence|shadow|prepare> [args]
1
+ var Ln=Object.defineProperty;var G=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var Hn=(e,t)=>{for(var r in t)Ln(e,r,{get:t[r],enumerable:!0})};import ge from"node:net";import Fn from"node:dns";function Ze(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=u=>{if(!u)return[];let c=u.split(":"),d=c.at(-1);if(d?.includes(".")){let m=d.split(".").map(Number);if(m.length!==4||m.some(p=>!Number.isInteger(p)||p<0||p>255))return null;c.splice(c.length-1,1,(m[0]<<8|m[1]).toString(16),(m[2]<<8|m[3]).toString(16))}return c.some(m=>!/^[0-9a-f]{1,4}$/.test(m))?null:c.map(m=>Number.parseInt(m,16))},[n,o]=t.split("::"),i=r(n),s=r(o);if(!i||!s)return null;let a=t.includes("::"),l=8-i.length-s.length;if(!a&&l!==0||a&&l<1)return null;let f=[...i,...Array(Math.max(0,l)).fill(0),...s];return f.length!==8?null:Uint8Array.from(f.flatMap(u=>[u>>8,u&255]))}function mt(e,t,r){let n=Math.floor(r/8),o=r%8;for(let s=0;s<n;s+=1)if(e[s]!==t[s])return!1;if(!o)return!0;let i=255<<8-o;return(e[n]&i)===(t[n]&i)}function ht(e){if(ge.isIPv4(e)){let t=e.split(".").map(Number);return!(t[0]===0||t[0]===10||t[0]===127||t[0]>=224||t[0]===100&&t[1]>=64&&t[1]<=127||t[0]===169&&t[1]===254||t[0]===172&&t[1]>=16&&t[1]<=31||t[0]===192&&(t[1]===0||t[1]===2||t[1]===168)||t[0]===192&&t[1]===88&&t[2]===99||t[0]===198&&(t[1]===18||t[1]===19||t[1]===51)||t[0]===203&&t[1]===0&&t[2]===113)}if(ge.isIPv6(e)){let t=Ze(e);if(!t)return!1;let r=Ze("::ffff:0:0");return mt(t,r,96)?ht([...t.slice(12)].join(".")):mt(t,Ze("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>mt(t,Ze(o),i)):!1}return!1}function Un(e){let t;try{t=new URL(String(e))}catch{return{ok:!1,error:`not a valid URL: ${String(e).slice(0,120)}`}}if(t.protocol!=="http:"&&t.protocol!=="https:")return{ok:!1,error:`refused protocol ${t.protocol} (only http/https)`};let r=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(Cn.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=ge.isIP(r);return n!==0&&!ht(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function yt(e,{lookupFn:t=Fn.promises.lookup}={}){let r=Un(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:ge.isIPv6(r.host)?6:4}]};let n;try{n=await t(r.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${r.host} did not resolve`}}return!Array.isArray(n)||n.length===0||n.some(o=>!ht(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function wt({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n;try{let c=await t();r=c.Agent,n=c.fetch}catch(c){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${c?.message||c}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let o=c=>String(c).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,s=c=>(Array.isArray(c)?c:[c]).map(d=>typeof d=="string"?{address:d}:d).filter(d=>d&&d.address).map(d=>({address:d.address,family:d.family||(ge.isIPv6(d.address)?6:4)})),a=(c,d,m)=>{i.set(o(c),s(typeof d=="string"?[{address:d,family:m}]:d))},l=c=>{let d=o(c);if(ge.isIP(d))return[{address:d,family:ge.isIPv6(d)?6:4}];let m=i.get(d);if(!m||!m.length)throw new Error(`refused: unpinned host ${c} during pinned fetch`);return m},f=new r({connect:{lookup(c,d,m){let p;try{p=l(c)}catch(w){return m(w)}return d?.all?m(null,p):m(null,p[0].address,p[0].family)}}}),u=qn((c,d={})=>n(c,{...d,dispatcher:f}),a);return{dispatcher:f,fetch:u,pin:a,resolve:l,async close(){try{await f.destroy()}catch{}}}}function qn(e,t){if(typeof e!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof t!="function")throw new Error("markPinCapableFetch: pin must be a function");return e[gt]=Object.freeze({pin:t}),e}function bt(e){return typeof e=="function"&&typeof e[gt]?.pin=="function"}function sr(e,t,r){if(!bt(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[gt].pin(t,r)}var Cn,gt,ir=G(()=>{Cn=new Set(["localhost","metadata.google.internal","metadata.goog"]);gt=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as Dn}from"node:crypto";import{types as ue}from"node:util";function J(e){return pe(`HTTP JSON body refused: ${e}`)}function Zn(e){return["isArgumentsObject","isArrayBuffer","isAnyArrayBuffer","isArrayBufferView","isBoxedPrimitive","isDataView","isDate","isExternal","isGeneratorObject","isKeyObject","isCryptoKey","isMap","isMapIterator","isModuleNamespaceObject","isNativeError","isPromise","isRegExp","isSet","isSetIterator","isTypedArray","isWeakMap","isWeakSet"].some(t=>typeof ue[t]=="function"&&ue[t](e))}function Xn(e){let t=[],r=0,n=0,o=0,i=0,s=new WeakSet,a=u=>{if(r+=Buffer.byteLength(u,"utf8"),r>le.bytes)throw J("serialized byte limit exceeded");t.push(u)},l=u=>{if(Buffer.byteLength(u,"utf8")>le.bytes)throw J("serialized byte limit exceeded");return JSON.stringify(u)},f=(u,c)=>{if(n+=1,n>le.nodes)throw J("node limit exceeded");if(c>le.depth)throw J("depth limit exceeded");if(u===null){a("null");return}if(typeof u=="string"){a(l(u));return}if(typeof u=="boolean"){a(u?"true":"false");return}if(typeof u=="number"){if(!Number.isFinite(u))throw J("non-finite number");a(Object.is(u,-0)?"0":String(u));return}if(typeof u!="object")throw J("unsupported non-JSON value");if(ue.isProxy(u))throw J("proxy value");if(Zn(u))throw J("unsupported exotic object");if(s.has(u))throw J("cyclic value");s.add(u);try{if(Object.getOwnPropertySymbols(u).length>0)throw J("symbol-keyed fields are unsupported");if(Array.isArray(u)){let p=Object.getPrototypeOf(u),w=0;for(;p!==null;){if(ue.isProxy(p))throw J("proxy array prototype");if(w+=1,w>le.depth)throw J("array prototype depth limit exceeded");p=Object.getPrototypeOf(p)}if(u.length>le.arrayLength)throw J("array length limit exceeded");for(let k=0;k<u.length;k+=1){let v=Object.getOwnPropertyDescriptor(u,String(k));if(!v||!Object.hasOwn(v,"value")||v.enumerable!==!0)throw J("array entries must be dense enumerable own data")}let g=0;for(let k in u){if(i+=1,i>le.fields)throw J("enumeration limit exceeded");if(Object.hasOwn(u,k)&&(g+=1,g>u.length))throw J("named array fields are unsupported")}if(g!==u.length)throw J("array entries must be dense enumerable own data");a("[");for(let k=0;k<u.length;k+=1)k&&a(","),f(Object.getOwnPropertyDescriptor(u,String(k)).value,c+1);a("]");return}let d=Object.getPrototypeOf(u);if(d!==Object.prototype&&d!==null)throw J("non-plain object");let m=[];for(let p in u){if(i+=1,i>le.fields)throw J("enumeration limit exceeded");if(!Object.hasOwn(u,p))continue;if(o+=1,o>le.fields)throw J("field limit exceeded");let w=Object.getOwnPropertyDescriptor(u,p);if(!w||!Object.hasOwn(w,"value")||w.enumerable!==!0)throw J("object fields must be enumerable own data");m.push([p,w.value])}a("{");for(let p=0;p<m.length;p+=1)p&&a(","),a(l(m[p][0])),a(":"),f(m[p][1],c+1);a("}")}finally{s.delete(u)}};return f(e,0),t.join("")}function Qn(e){let t=Object.create(null);if(e==null)return t;if(typeof e!="object"&&typeof e!="function")throw new TypeError("HTTP headers must be an object");if(ue.isProxy(e))throw new TypeError("HTTP headers must not be a proxy");if(Object.getOwnPropertySymbols(e).length>0)throw new TypeError("HTTP headers must not contain symbol fields");let r=new Set;for(let n of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(n))throw new TypeError("HTTP header names must be valid tokens");let o=n.toLowerCase();if(r.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");r.add(o);let i=Object.getOwnPropertyDescriptor(e,n);if(!i||!Object.hasOwn(i,"value"))throw new TypeError("HTTP headers must contain own data properties");let s=i.value;if(s==null||["object","function","symbol"].includes(typeof s))throw new TypeError("HTTP header values must be scalar");t[n]=String(s)}return t}function eo(){return Object.assign(Object.create(null),{Accept:"application/json"})}function to(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let r=new URL(String(e),String(t));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${r.protocol}`);return r.toString()}function ro(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Xe(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=fr.get(e);return t||(t=dr,dr+=1,fr.set(e,t)),`reference:${t}`}function pr(e){if(!e||typeof e!="object"||Array.isArray(e)||!Object.hasOwn(e,"jsonrpc")||!Object.hasOwn(e,"method")||e.jsonrpc!=="2.0")return!1;let t=typeof e.method=="string"?e.method:"";return t?no.has(t)||/^get[A-Z0-9_]/u.test(t)||/^is[A-Z0-9_]/u.test(t)||/^eth_get[A-Z0-9_]/u.test(t):!1}function mr(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let r=t;if(typeof t=="string")try{r=JSON.parse(t)}catch{return!1}if(Array.isArray(r))return r.length>0&&r.every(pr);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return pr(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&oo.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function so(e,t,r,n={},o=null){let i=Dn("sha256"),s=(l,f)=>{let u=String(f);i.update(String(Buffer.byteLength(l,"utf8"))).update(":").update(l),i.update("=").update(String(Buffer.byteLength(u,"utf8"))).update(":").update(u).update(`
2
+ `)};s("method",e),s("url",t),Object.keys(r||{}).map((l,f)=>({name:l.toLowerCase(),order:f,value:String(r[l])})).sort((l,f)=>l.name.localeCompare(f.name)||l.order-f.order).forEach((l,f)=>{s(`header-name-${f}`,l.name),s(`header-value-${f}`,l.value)}),s("body",o??"-");for(let l of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])s(`context-${l}`,n[l]??"-");return i.digest("hex")}function io(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,cr):Math.min(250*2**e,cr)+Math.floor(Math.random()*100)}function pe(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function xt(e,t,r){return pe(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function be(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function co(e){return e?e.byteLength??e.length??0:0}async function lo(e,t,{url:r,truncate:n=!1,onOversize:o}={}){if(t==null)return await e.text();let i=Number(e.headers?.get?.("content-length"));if(Number.isFinite(i)&&i>t&&(be(e),!n))throw xt(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let c=await e.text(),d=Buffer.byteLength(c,"utf8");if(d>t){if(!n)throw xt(r,`body ${d} bytes`,t);return Buffer.from(c,"utf8").subarray(0,t).toString("utf8")}return c}let a=[],l=0,f=!1;try{for(;;){let{value:c,done:d}=await s.read();if(d)break;if(c&&(a.push(Buffer.from(c)),l+=co(c),l>t)){f=!0;break}}}finally{if(f)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(f&&(typeof o=="function"&&o(),!n))throw xt(r,`streamed ${l} bytes`,t);let u=Buffer.concat(a);return(f?u.subarray(0,t):u).toString("utf8")}function uo(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function fo(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:l=!1,maxResponseBytes:f=null,sameOriginRedirectsOnly:u=!1,importUndici:c,validateResponse:d,signal:m,redirectPolicy:p="follow",maxRedirects:w=Qe}){let g=null,k=t,v=s?{lookupFn:s}:{};if(l&&!a&&!bt(k))throw pe(`HTTP refused ${e}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let T=new AbortController,x=setTimeout(()=>T.abort(),i),R=m?ur?ur([m,T.signal]):m:T.signal,A=async(h,{status:M=null}={})=>{let U=await yt(h,v);if(!U.ok)throw pe(M==null?`HTTP refused ${h}: ${U.error}`:`HTTP redirect to ${h} ${U.error}`,M==null?{}:{status:M});let Y=new URL(h).hostname;if(a){if(g&&(await g.close(),g=null),!g)try{g=await wt({requireUndici:!0,...c?{importUndici:c}:{}})}catch(S){throw pe(M==null?`HTTP refused ${h}: ${S?.message||S}`:`HTTP redirect to ${h} refused: ${S?.message||S}`,M==null?{}:{status:M})}g.pin(Y,U.addresses),k=g.fetch}else sr(k,Y,U.addresses);return U};try{let h=String(e),M=Object.assign(Object.create(null),n||{});l&&await A(h);for(let U=0;U<=w;U+=1){let Y=Object.assign(Object.create(null),{method:r,headers:M,body:o,signal:R,redirect:"manual",dispatcher:void 0}),S=await k(h,Y);if((p==="error"||w===0)&&S.status>=300&&S.status<400)throw be(S),pe(`HTTP ${S.status} ${r} redirect refused`,{status:S.status,redirectRefused:!0});if(Wn.has(S.status)){let I=u===!0&&r==="POST"&&[307,308].includes(S.status)&&mr(r,o);if(r!=="GET"&&r!=="HEAD"&&!I){be(S);let P=new Error(`HTTP ${S.status} ${r} ${h} redirected non-idempotent request`);throw P.status=S.status,P}if(U===w)throw be(S),pe(`HTTP ${S.status} ${r} redirect budget exhausted`,{status:S.status,redirectRefused:!0});let C=S.headers?.get?.("location"),L;try{L=to(C,h)}catch(P){throw be(S),P}let j=!ro(L,h);if(be(S),j&&r==="POST"){let P=new Error(`HTTP ${S.status} ${r} cross-origin redirect refused`);throw P.status=S.status,P}if(j&&u){let P=new Error(`HTTP ${S.status} ${r} cross-origin redirect refused`);throw P.status=S.status,P.retryable=!1,P}if(j&&(M=eo(M)),l)await A(L,{status:S.status});else if(j){let P=await yt(L,v);if(!P.ok){let N=new Error(`HTTP redirect from ${h} ${P.error}`);throw N.status=S.status,N.retryable=!1,N}a&&P.addresses?.length&&(g||(g=await wt(c?{importUndici:c}:{})),g&&(g.pin(new URL(L).hostname,P.addresses),k=g.fetch))}h=L;continue}if(typeof d=="function")try{await d(S,{url:h})}catch(I){throw be(S),pe(I?.message||String(I))}let y=await lo(S,f,{url:h,onOversize:()=>T.abort()}),$=uo(y);if(!S.ok){let I=new Error(`HTTP ${S.status} ${r} ${h}`);throw I.status=S.status,I.retryAfter=S.headers?.get?.("retry-after")??null,I.body=$??y.slice(0,300),I}return $??y}throw new Error(`HTTP redirect loop for ${e}`)}catch(h){if(T.signal.aborted&&!Ce(m)){let M=h&&(typeof h=="object"||typeof h=="function")&&!ue.isProxy(h)?h:null,U=M?Object.getOwnPropertyDescriptor(M,"oversize"):null;if(!(U&&Object.hasOwn(U,"value")&&U.value===!0))try{if(!M)throw new TypeError("unsafe rejection");Object.defineProperties(M,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let S=new Error("HTTP request timed out");throw Object.defineProperties(S,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),S}}throw h}finally{clearTimeout(x),g&&await g.close()}}async function hr(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&ue.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let r=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let N of Object.getOwnPropertyNames(t)){let _=Object.getOwnPropertyDescriptor(t,N);if(!(N==="toJSON"&&_&&Object.hasOwn(_,"value")&&_.value===void 0)){if(!r.has(N))throw new TypeError("HTTP options contain unknown fields");if(!_||!_.enumerable||!Object.hasOwn(_,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=N=>{if(t==null||!Object.hasOwn(t,N))return;let _=Object.getOwnPropertyDescriptor(t,N);if(!_||!Object.hasOwn(_,"value"))throw new TypeError("HTTP options must contain own data properties");return _.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=n("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let i=n("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let s=n("retries");if(s!==void 0&&(!Number.isInteger(s)||s<0||s>10))throw new TypeError("HTTP retries must be a bounded integer");let a=n("redirectPolicy");if(a!==void 0&&a!=="follow"&&a!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let l=n("maxRedirects");if(l!==void 0&&(!Number.isInteger(l)||l<0||l>Qe))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${Qe}`);if(a==="error"&&l!==void 0&&l!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let f=a??"follow",u=f==="error"?0:l??Qe;for(let N of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let _=n(N);if(_!==void 0&&typeof _!="boolean")throw new TypeError(`HTTP ${N} must be boolean`)}let c=n("maxResponseBytes");if(c!==void 0&&(!Number.isInteger(c)||c<1||c>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let d=n("signal");if(d!==void 0){if(ue.isProxy(d)||!(d instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{Ce(d)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let N of["importUndici","lookupFn","validateResponse"]){let _=n(N);if(_!==void 0&&typeof _!="function")throw new TypeError(`HTTP ${N} must be a function`)}let m=n("fetchImpl"),p=m||globalThis.fetch;if(typeof p!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let w=i??12e3,g=(o||"GET").toUpperCase(),k=n("headers"),v=Qn(k),T=Object.assign(Object.create(null),v);Object.keys(T).some(N=>N.toLowerCase()==="accept")||(T.Accept="application/json");let x=n("body");x!=null&&typeof x!="string"&&(Object.keys(T).find(_=>_.toLowerCase()==="content-type")||(T["Content-Type"]="application/json"),x=Xn(x));let R=s??zn,A=n("lookupFn"),h=!m,M=n("untrustedUrl")===!0,U=n("sameOriginRedirectsOnly")===!0,Y=n("importUndici"),S=n("validateResponse"),y=d,$=c??null,I=async()=>{let N;for(let _=0;_<=R;_++){y&&Gn.call(y);try{return await fo(e,{fetchImpl:p,method:g,headers:T,body:x,timeoutMs:w,lookupFn:A,realFetch:h,untrustedUrl:M,maxResponseBytes:$,sameOriginRedirectsOnly:U,importUndici:Y,validateResponse:S,signal:y,redirectPolicy:f,maxRedirects:u})}catch(K){N=K;let te=Ae=>{if(!K||typeof K!="object"&&typeof K!="function"||ue.isProxy(K))return;let we=Object.getOwnPropertyDescriptor(K,Ae);return we&&Object.hasOwn(we,"value")?we.value:void 0},de=te("status"),Te=te("oracleTimeout")===!0||te("name")==="AbortError"||te("name")==="TimeoutError"||Ce(y),Ye=new Set([408,425,429]),We=te("retryable")===!1?!1:de!=null?Ye.has(de)||Bn.has(de)&&ar.has(g):!Te&&ar.has(g);if(_===R||!We)throw K;let lt=io(_,te("retryAfter"));y?await new Promise((Ae,we)=>{let Le,ae=()=>{clearTimeout(Le),lr.call(y,"abort",ae),we(Yn(y)||new DOMException("Aborted","AbortError"))};if(Ce(y)){ae();return}Le=setTimeout(()=>{lr.call(y,"abort",ae),Ae()},lt),Kn.call(y,"abort",ae,{once:!0}),Ce(y)&&ae()}):await ao(lt)}}throw N};if(!(n("dedupe")!==!1&&!y&&mr(g,x)))return I();let L=so(g,e,T,{untrustedUrl:M,maxResponseBytes:$,sameOriginRedirectsOnly:U,redirectPolicy:f,maxRedirects:u,timeoutMs:w,retries:R,fetchImpl:Xe(p),realFetch:h,lookupFn:Xe(A),importUndici:Xe(Y),validateResponse:Xe(S)},x),j=Et.get(L);if(j)return j;let P=I().finally(()=>Et.delete(L));return Et.set(L,P),P}var Bn,ar,zn,cr,Jn,Vn,Gn,Kn,lr,ur,Ce,Yn,Wn,Qe,Ri,le,Et,fr,dr,no,oo,ao,yr=G(()=>{ir();Bn=new Set([408,425,429,500,502,503,504]),ar=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),zn=2,cr=4e3,Jn=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Vn=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Gn=AbortSignal.prototype.throwIfAborted,Kn=EventTarget.prototype.addEventListener,lr=EventTarget.prototype.removeEventListener,ur=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,Ce=e=>e?Jn.call(e):!1,Yn=e=>e?Vn.call(e):void 0,Wn=new Set([301,302,303,307,308]),Qe=3,Ri=64*1024,le=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});Et=new Map,fr=new WeakMap,dr=1;no=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),oo=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);ao=e=>new Promise(t=>setTimeout(t,e))});import{types as wr}from"node:util";function po(e){if(!e||typeof e!="object"||wr.isProxy(e)||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function et(e,t="provider response",r=0){if(r>64)throw new Error(`${t} exceeds the JSON nesting bound`);if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(Array.isArray(e)){if(wr.isProxy(e)||e.length>1e5)throw new Error(`${t} contains an invalid array`);let o=new Array(e.length);for(let i=0;i<e.length;i+=1){let s=Object.getOwnPropertyDescriptor(e,String(i));if(!s||!Object.hasOwn(s,"value"))throw new Error(`${t} arrays must contain dense own data`);o[i]=et(s.value,t,r+1)}return o}if(!po(e))throw new Error(`${t} contains a non-JSON value`);let n=Object.create(null);for(let o of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,o);if(!i||!Object.hasOwn(i,"value"))throw new Error(`${t} objects must contain own data`);n[o]=et(i.value,t,r+1)}return n}var gr=G(()=>{});function yo({testnet:e,baseUrl:t}={}){if(t)return t.replace(/\/$/,"").endsWith("/info")?t:`${t.replace(/\/$/,"")}/info`;if(process.env.HL_INFO_URL)return process.env.HL_INFO_URL;if(process.env.HL_API_URL){let r=process.env.HL_API_URL.replace(/\/$/,"");return r.endsWith("/info")?r:`${r}/info`}return e||process.env.HL_TESTNET==="1"?ho:mo}async function kt(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=yo(t);return et(await hr(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs,maxResponseBytes:t.maxResponseBytes,sameOriginRedirectsOnly:t.sameOriginRedirectsOnly}),"hyperliquid info response")}async function br(e={}){return kt({type:"meta"},e)}async function Er({coin:e,interval:t="1h",startTime:r,endTime:n},o={}){if(!e)throw new Error("hlCandleSnapshot requires coin");let i={type:"candleSnapshot",req:{coin:String(e),interval:t,startTime:r??Date.now()-24*3600*1e3,endTime:n??Date.now()}};return kt(i,o)}async function xr({coin:e,startTime:t,endTime:r},n={}){if(!e)throw new Error("hlFundingHistory requires coin");return kt({type:"fundingHistory",coin:String(e),startTime:t??Date.now()-24*3600*1e3,endTime:r??Date.now()},n)}var mo,ho,St=G(()=>{yr();gr();mo="https://api.hyperliquid.xyz/info",ho="https://api.hyperliquid-testnet.xyz/info"});import{createHash as wo}from"node:crypto";function oe(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function $e(e){return typeof e=="number"&&Number.isFinite(e)}function Tt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Tt(t);return Object.freeze(e)}for(let t of Object.keys(e))Tt(e[t]);return Object.freeze(e)}function Ee(e){if(Array.isArray(e))return e.map(Ee);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=Ee(e[r]);return t}return e}function Ot(e){return{netPnlUsd:e.metrics.netPnlUsd,netPnlPct:e.metrics.netPnlPct,maxDrawdownPct:e.metrics.maxDrawdownPct,winRate:e.metrics.winRate,profitFactor:e.metrics.profitFactor,tradeCount:e.metrics.tradeCount,sharpe:e.metrics.sharpe,turnoverUsd:e.metrics.turnoverUsd,exposurePct:e.metrics.exposurePct}}function kr(e){return{feesUsd:e.costs.feesUsd,builderFeesUsd:e.costs.builderFeesUsd,fundingUsd:e.costs.fundingUsd,slippageUsd:e.costs.slippageUsd}}function bo(e){return(e.feesUsd||0)+(e.builderFeesUsd||0)+Math.max(0,e.fundingUsd||0)+(e.slippageUsd||0)}function Eo(e){let t=0;for(let r of e.trades)r.grossPnlUsd>0&&(t+=r.grossPnlUsd);return t}function xo(e,t,r){return!(!e||e.tradeCount<Math.max(1,Math.min(r,3))||!(e.netPnlUsd>0)||!(e.profitFactor>1)||!(e.maxDrawdownPct<=t.maxDailyLossPct))}function Or(e){if(!oe(e))throw new TypeError("evidence artifact must be a plain object");if(!go.includes(e.status))throw new TypeError("evidence artifact status is invalid");for(let t of["strategyHash","compilerHash","barsHash"])if(typeof e[t]!="string"||!/^[0-9a-f]{64}$/.test(e[t]))throw new TypeError(`evidence artifact ${t} must be a sha256 hash`);if(!oe(e.split))throw new TypeError("evidence artifact split required");if(!Array.isArray(e.flags))throw new TypeError("evidence artifact flags must be an array");if(!oe(e.walkForward)||!Array.isArray(e.walkForward.windows))throw new TypeError("evidence artifact walkForward windows required");if(e.status==="pass_live_eligible"&&(!oe(e.train)||!oe(e.holdout)))throw new TypeError("live-eligible evidence artifact requires train and holdout facts");return Ee({barsHash:e.barsHash,compilerHash:e.compilerHash,flags:e.flags.map(t=>Ee(t)),holdout:e.holdout??null,split:e.split,status:e.status,strategyHash:e.strategyHash,train:e.train??null,walkForward:{passRate:e.walkForward.passRate,windowsRun:e.walkForward.windowsRun??e.walkForward.windows.length,windows:e.walkForward.windows.map(t=>({index:t.index,trainStartIndex:t.trainStartIndex,trainEndIndex:t.trainEndIndex,passed:t.passed,reason:t.reason,evalStartIndex:t.evalStartIndex,evalEndIndex:t.evalEndIndex,metrics:t.metrics}))}})}function Pr(e){return wo("sha256").update(JSON.stringify(Or(e)),"utf8").digest("hex")}function re(e,t,r=0){if(!Number.isInteger(e)||e<r)throw new Error(`${t} must be an integer >= ${r}`);return e}function Pt(e,t){if(!oe(e)||!oe(e.metrics))throw new Error(`${t} metrics required`);let r=re(e.tradeCount,`${t}.tradeCount`);if(e.metrics.tradeCount!==r)throw new Error(`${t} tradeCount contradicts metrics.tradeCount`);for(let n of["netPnlUsd","profitFactor","maxDrawdownPct"])if(!$e(e.metrics[n]))throw new Error(`${t}.metrics.${n} must be finite`);if(e.metrics.maxDrawdownPct<0)throw new Error(`${t}.metrics.maxDrawdownPct must be >= 0`);return e.metrics}function ko(e,{maxDailyLossPct:t}={}){let r=e.split,n=re(r.trainStartIndex,"split.trainStartIndex"),o=re(r.trainEndIndex,"split.trainEndIndex"),i=re(r.trainBarCount,"split.trainBarCount",1),s=re(r.holdoutStartIndex,"split.holdoutStartIndex"),a=re(r.holdoutEndIndex,"split.holdoutEndIndex"),l=re(r.holdoutBarCount,"split.holdoutBarCount",1);if(n!==0||o-n+1!==i||s!==o+1||a-s+1!==l)throw new Error("evidence split must be contiguous, chronological, and count-consistent");if(!$e(r.trainFraction)||r.trainFraction<=0||r.trainFraction>=1)throw new Error("split.trainFraction must be in (0,1)");Pt(e.train,"train");let f=Pt(e.holdout,"holdout");if(f.tradeCount<1||f.netPnlUsd<=0||f.profitFactor<=1)throw new Error("live-eligible holdout metrics do not pass");if($e(t)&&f.maxDrawdownPct>t)throw new Error("live-eligible holdout drawdown exceeds strategy risk");if(e.flags.length>0)throw new Error("live-eligible evidence cannot contain failure flags");let u=e.walkForward,c=u.windows;if(c.length<1||u.windowsRun!==c.length)throw new Error("live-eligible walk-forward windowsRun must match nonempty windows");let d=0,m=-1;for(let w=0;w<c.length;w++){let g=c[w];if(!oe(g)||g.index!==w||typeof g.passed!="boolean")throw new Error("walk-forward windows must be ordered and structurally valid");let k=re(g.trainStartIndex,`walkForward.windows[${w}].trainStartIndex`),v=re(g.trainEndIndex,`walkForward.windows[${w}].trainEndIndex`),T=re(g.evalStartIndex,`walkForward.windows[${w}].evalStartIndex`),x=re(g.evalEndIndex,`walkForward.windows[${w}].evalEndIndex`);if(k!==0||v>=T||T>x||T<=m)throw new Error("walk-forward windows must be chronological and disjoint");if(m=x,g.passed){if(d+=1,g.reason!=="pass")throw new Error("passed walk-forward window reason must be pass");let R=Pt({metrics:g.metrics,tradeCount:g.metrics?.tradeCount},`walkForward.windows[${w}]`);if(R.tradeCount<1||R.netPnlUsd<=0||R.profitFactor<=1)throw new Error("passed walk-forward window metrics do not pass");if($e(t)&&R.maxDrawdownPct>t)throw new Error("passed walk-forward drawdown exceeds strategy risk")}else if(g.reason==="pass")throw new Error("failed walk-forward window cannot have pass reason")}let p=d/c.length;if(!$e(u.passRate)||Math.abs(u.passRate-p)>Number.EPSILON||p<.6)throw new Error("walk-forward passRate contradicts concrete windows or is below live threshold")}function Tr(e,t={}){if(typeof e?.id!="string"||!/^[0-9a-f]{64}$/.test(e.id))throw new Error("evidence.id must be a sha256 evidence artifact hash");let r=Or(e),n=Ee({id:e.id,...r});if(JSON.stringify(Ee(e))!==JSON.stringify(n))throw new Error("evidence artifact contains fields unbound from its deterministic identity");let o=Pr(e);if(e.id!==o)throw new Error("evidence.id does not match its deterministic artifact facts digest");return e.status==="pass_live_eligible"&&ko(e,t),e}function At({strategy:e,bars:t,backtestOptions:r={},trainFraction:n=.7,walkForwardWindows:o=3,minTrades:i=10}={}){let s=[];if(!oe(e))throw new TypeError("strategy must be a plain object");if(!Array.isArray(t))throw new TypeError("bars must be an array");if(!oe(r))throw new TypeError("backtestOptions must be a plain object");if(!$e(n)||n<=0||n>=1)throw new TypeError("trainFraction must be in (0,1)");if(!Number.isInteger(o)||o<1)throw new TypeError("walkForwardWindows must be a positive integer");if(!Number.isInteger(i)||i<0)throw new TypeError("minTrades must be an integer >= 0");let a=Z(e),l=_e(a),f=Ue(t),u=t.length,c=(j=[],P={})=>Sr({status:"fail",strategy:a,sHash:l,barsHash:f,split:P.split||{trainStartIndex:0,trainEndIndex:-1,trainBarCount:0,holdoutStartIndex:0,holdoutEndIndex:-1,holdoutBarCount:0,trainFraction:n},train:P.train||null,holdout:P.holdout||null,walkForward:P.walkForward||{windows:[],passRate:0},flags:[...s,...j]});if(u<10)return c([{type:"insufficient_bars",message:"need at least 10 bars for evidence"}]);let d=Math.floor(u*n),m=d,p=u-m;if(d<5||p<3)return c([{type:"invalid_windowing",message:"train/holdout split too small",trainCount:d,holdoutCount:p}]);let w=t.slice(0,d),g=t.slice(m),k,v;try{k=me(a,w,r),v=me(a,g,r)}catch(j){return c([{type:"backtest_error",message:String(j.message||j)}])}let T={metrics:Ot(k),costs:kr(k),tradeCount:k.metrics.tradeCount},x={metrics:Ot(v),costs:kr(v),tradeCount:v.metrics.tradeCount},R={trainStartIndex:0,trainEndIndex:d-1,trainBarCount:d,holdoutStartIndex:m,holdoutEndIndex:u-1,holdoutBarCount:p,trainFraction:n},A=[],h=Math.floor(u/(o+1));if(h<3)s.push({type:"invalid_windowing",message:"walk-forward window size too small",wfSize:h});else for(let j=0;j<o;j++){let P=h*(j+1),N=P,_=Math.min(u,N+h);if(_-N<3||P<3){A.push({index:j,trainStartIndex:0,trainEndIndex:P-1,evalStartIndex:N,evalEndIndex:_-1,passed:!1,reason:"window_too_small",metrics:null});continue}let K=t.slice(N,_),te;try{te=me(a,K,r)}catch{A.push({index:j,trainStartIndex:0,trainEndIndex:P-1,evalStartIndex:N,evalEndIndex:_-1,passed:!1,reason:"backtest_error",metrics:null});continue}let de=Ot(te),Te=xo(de,a.risk,i);A.push({index:j,trainStartIndex:0,trainEndIndex:P-1,evalStartIndex:N,evalEndIndex:_-1,passed:Te,reason:Te?"pass":"fail_metrics",metrics:de})}let M=A.filter(j=>j.passed).length,U=A.length===0?0:M/A.length,Y={windows:A,passRate:U,windowsRun:A.length};x.metrics.tradeCount===0&&T.metrics.tradeCount===0&&s.push({type:"no_trades",message:"no trades in train or holdout"}),x.metrics.tradeCount===0&&s.push({type:"absent_oos_trades",message:"holdout produced no trades"}),x.metrics.netPnlUsd<0&&s.push({type:"holdout_loss",message:"holdout netPnlUsd is negative"}),T.metrics.netPnlUsd>0&&x.metrics.netPnlUsd<0&&T.metrics.netPnlUsd>Math.abs(x.metrics.netPnlUsd)*.25?s.push({type:"overfit",message:"profitable train with losing holdout (OOS collapse)"}):T.metrics.netPnlUsd>0&&x.metrics.netPnlUsd>0&&x.metrics.netPnlUsd<T.metrics.netPnlUsd*.1&&T.metrics.tradeCount>=i&&s.push({type:"severe_oos_collapse",message:"holdout pnl collapsed vs train"});let S=bo(x.costs),y=Eo(v);y>0&&S>y&&s.push({type:"costs_exceed_gross",message:"holdout costs exceed gross gains"});let $=s.some(j=>["insufficient_bars","invalid_windowing","absent_oos_trades","holdout_loss","no_trades","severe_oos_collapse","backtest_error"].includes(j.type)),I=s.some(j=>j.type==="overfit"),C="fail";return x.metrics.tradeCount>=i&&x.metrics.netPnlUsd>0&&x.metrics.profitFactor>1&&x.metrics.maxDrawdownPct<=a.risk.maxDailyLossPct&&U>=.6&&!(y>0&&S>y)&&!I&&!s.some(j=>j.type==="severe_oos_collapse"||j.type==="invalid_windowing")?C="pass_live_eligible":!$&&x.metrics.tradeCount>0&&T.metrics.tradeCount>0&&Number.isFinite(x.metrics.netPnlUsd)?(C="pass_paper_only",x.metrics.tradeCount<i&&s.push({type:"undersampled",message:"holdout trades below minTrades"})):I&&x.metrics.tradeCount>0&&T.metrics.netPnlUsd>0?C="fail":x.metrics.tradeCount>0&&T.metrics.tradeCount>0&&!$?C="pass_paper_only":C="fail",x.metrics.netPnlUsd<0&&(C=C==="pass_live_eligible"?"fail":C==="pass_paper_only"?"pass_paper_only":"fail",C="fail"),Sr({status:C,strategy:a,sHash:l,barsHash:f,split:R,train:T,holdout:x,walkForward:Y,flags:s})}function Sr({status:e,strategy:t,sHash:r,barsHash:n,split:o,train:i,holdout:s,walkForward:a,flags:l}){let f={status:e,strategyHash:r,compilerHash:ke,barsHash:n,split:o,train:i,holdout:s,walkForward:a,flags:l};return f.id=Pr(f),Tt(Ee(JSON.parse(JSON.stringify(f))))}var go,$t=G(()=>{Se();xe();tt();go=Object.freeze(["fail","pass_paper_only","pass_live_eligible"])});import{createHash as So,createHmac as Oo,timingSafeEqual as Gi}from"node:crypto";function _t(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(_t).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${_t(e[r])}`).join(",")}}`}function Ar(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function $r(e=process.env){return Ar(process.env)||Ar(e)}function $o(e){let{prepareHash:t,prepareMac:r,note:n,...o}=e||{};return o}function _o(e){let t=$o(e);return So("sha256").update(_t(t)).digest("hex")}function Io(e,t=$r()){return t?Oo("sha256",t).update(String(e)).digest("hex"):""}function _r(e,{provider:t,kind:r,env:n=process.env,nowMs:o=Date.now(),expiresAtMs:i}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let s=Object.prototype.hasOwnProperty.call(e,"oraclePrepared");if(s&&typeof e.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let a={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:s?e.oraclePrepared:!0};if(!a.provider)throw new Error("stampPrepared: provider required");if(!a.kind)throw new Error("stampPrepared: kind required");let l=Number(o),f=i==null?l+To:Number(i),u=f-l;if(!Number.isSafeInteger(l)||!Number.isSafeInteger(f)||u<=0||u>Ao)throw new Error("stampPrepared: bounded preparedAt/expiresAt required");let d={...a,preparedAt:l,expiresAt:f,prepareVersion:Po},m=_o(d),p=$r(n),w=p?Io(m,p):void 0,g={...d,prepareHash:m};return w&&(g.prepareMac=w),g}var Po,To,Ao,Ir=G(()=>{Po=2,To=300*1e3,Ao=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});function qe(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function jo(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function vt(e,t="value"){if(Array.isArray(e)){e.forEach((r,n)=>vt(r,`${t}[${n}]`));return}if(qe(e))for(let[r,n]of Object.entries(e)){let o=jo(r);if(vo.some(i=>o.includes(i)))throw new Error(`handoff: forbidden secret-like field at ${t}.${r}`);vt(n,`${t}.${r}`)}}function It(e){return typeof e=="number"&&Number.isFinite(e)&&e>0}function vr({strategy:e,evidence:t,shadow:r,caps:n,nowMs:o=Date.now(),env:i=process.env}={}){if(vt({strategy:e,evidence:t,shadow:r,caps:n},"handoff"),!qe(e))throw new Error("handoff: strategy required");if(!qe(t))throw new Error("handoff: evidence required");if(!qe(r))throw new Error("handoff: shadow required");if(!qe(n))throw new Error("handoff: caps required");if(typeof r.id!="string"||!r.id.trim())throw new Error("handoff: shadow.id required");if(typeof r.stateHash!="string"||!/^[0-9a-f]{64}$/.test(r.stateHash))throw new Error("handoff: shadow.stateHash must be a sha256 hash");if(r.status!=="running")throw new Error("handoff: shadow.status must be running");if(!Number.isInteger(r.cursor)||r.cursor<=0)throw new Error("handoff: shadow.cursor must be a positive integer");if(!Number.isInteger(r.updatedAt)||r.updatedAt<=0||r.updatedAt>o)throw new Error("handoff: shadow.updatedAt must be a positive integer <= nowMs");let s=Z(e,{nowMs:o}),a=X(s);if(Tr(t,{maxDailyLossPct:s.risk.maxDailyLossPct}),t.status!=="pass_live_eligible")throw new Error("handoff: evidence.status must be pass_live_eligible");if(t.strategyHash!==a.strategyHash)throw new Error("handoff: evidence.strategyHash mismatch");if(t.compilerHash!==a.compilerHash)throw new Error("handoff: evidence.compilerHash mismatch");let l=["perStrategyNotionalUsd","maxLeverage","dailyLossCapUsd","chainAllowlist","assetAllowlist","expiresAt","killSwitchRequired"];for(let d of l)if(!(d in n)||n[d]==null)throw new Error(`handoff: caps.${d} required`);if(!It(n.perStrategyNotionalUsd))throw new Error("handoff: caps.perStrategyNotionalUsd must be positive");if(n.perStrategyNotionalUsd>a.strategy.risk.maxNotionalUsd)throw new Error("handoff: caps.perStrategyNotionalUsd exceeds strategy.risk.maxNotionalUsd");if(!It(n.maxLeverage))throw new Error("handoff: caps.maxLeverage must be positive");if(n.maxLeverage>a.strategy.risk.maxLeverage)throw new Error("handoff: caps.maxLeverage exceeds strategy.risk.maxLeverage");if(!It(n.dailyLossCapUsd))throw new Error("handoff: caps.dailyLossCapUsd must be positive");let f=a.strategy.risk.maxNotionalUsd*(a.strategy.risk.maxDailyLossPct/100);if(n.dailyLossCapUsd>f)throw new Error("handoff: caps.dailyLossCapUsd exceeds strategy daily loss ceiling");if(!Array.isArray(n.chainAllowlist)||n.chainAllowlist.length===0)throw new Error("handoff: caps.chainAllowlist must be a non-empty array");if(!n.chainAllowlist.every(d=>d==="hyperliquid"))throw new Error("handoff: caps.chainAllowlist must include only hyperliquid");if(!n.chainAllowlist.includes("hyperliquid"))throw new Error("handoff: caps.chainAllowlist must include hyperliquid");if(!Array.isArray(n.assetAllowlist)||n.assetAllowlist.length===0)throw new Error("handoff: caps.assetAllowlist must be a non-empty array");if(n.assetAllowlist.length!==1||n.assetAllowlist[0]!==a.strategy.market.coin)throw new Error("handoff: caps.assetAllowlist must contain only the strategy market coin");if(!Number.isInteger(n.expiresAt)||!(n.expiresAt>o))throw new Error("handoff: caps.expiresAt must be an integer > nowMs");if(n.expiresAt>a.strategy.risk.expiresAt)throw new Error("handoff: caps.expiresAt exceeds strategy.risk.expiresAt");if(n.killSwitchRequired!==!0)throw new Error("handoff: caps.killSwitchRequired must be exactly true");let u={perStrategyNotionalUsd:n.perStrategyNotionalUsd,maxLeverage:n.maxLeverage,dailyLossCapUsd:n.dailyLossCapUsd,chainAllowlist:[...n.chainAllowlist],assetAllowlist:[...n.assetAllowlist],expiresAt:n.expiresAt,killSwitchRequired:!0},c={strategyHash:a.strategyHash,compilerHash:a.compilerHash,evidence:JSON.parse(JSON.stringify(t)),shadow:{id:r.id,stateHash:r.stateHash,status:r.status,cursor:r.cursor,updatedAt:r.updatedAt},compiled:{strategyHash:a.strategyHash,compilerHash:a.compilerHash,compilerVersion:De,venue:"hyperliquid",market:{coin:a.strategy.market.coin,kind:"perp",interval:a.strategy.market.interval},risk:{...a.strategy.risk},strategy:JSON.parse(JSON.stringify(a.strategy))},arming:{liveBroadcast:!1,requiresExplicitUserArm:!0,caps:u},requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,executionReady:!1};return _r(c,{provider:"hl-strategy",kind:"strategy-live-handoff",env:i})}var vo,jr=G(()=>{Se();$t();xe();Ir();vo=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});function Ie(e,t){let r=Number(e);if(!Number.isFinite(r))throw new TypeError(`${t} must be finite`);return r}function ve(e,t){if(!Number.isSafeInteger(e)||e<0)throw new TypeError(`${t} must be a non-negative safe integer`);return e}function Be(e){if(Array.isArray(e))for(let t of e)Be(t);else if(e&&typeof e=="object")for(let t of Object.values(e))Be(t);return Object.freeze(e)}function Ro(e){let t=No[e];if(!t)throw new TypeError(`unsupported strategy interval: ${e}`);return t}function Mo(e,{endTime:t=Number.MAX_SAFE_INTEGER}={}){if(!Array.isArray(e))throw new TypeError("Hyperliquid candles must be an array");ve(t,"endTime");let r=new Map;for(let n=0;n<e.length;n++){let o=e[n];if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError(`candles[${n}] must be an object`);let i=ve(Number(o.t),`candles[${n}].t`);if(ve(Number(o.T),`candles[${n}].T`)>t)continue;let a={t:i,o:Ie(o.o,`candles[${n}].o`),h:Ie(o.h,`candles[${n}].h`),l:Ie(o.l,`candles[${n}].l`),c:Ie(o.c,`candles[${n}].c`),v:Ie(o.v,`candles[${n}].v`)};if(a.h<Math.max(a.o,a.c,a.l))throw new TypeError(`candles[${n}].h is below another price`);if(a.l>Math.min(a.o,a.c,a.h))throw new TypeError(`candles[${n}].l is above another price`);if(a.v<0)throw new TypeError(`candles[${n}].v must be non-negative`);let l=r.get(i);if(l&&JSON.stringify(l)!==JSON.stringify(a))throw new TypeError(`conflicting duplicate candle at timestamp ${i}`);l||r.set(i,a)}return Be([...r.values()].sort((n,o)=>n.t-o.t))}function Lo(e,t){if(!Array.isArray(e))throw new TypeError("Hyperliquid funding history must be an array");let r=new Map;for(let n=0;n<e.length;n++){let o=e[n];if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError(`funding[${n}] must be an object`);let i=ve(Number(o.time),`funding[${n}].time`);i>t||r.set(i,{time:i,fundingRate:Ie(o.fundingRate,`funding[${n}].fundingRate`)})}return[...r.values()].sort((n,o)=>n.time-o.time)}async function Ho({coin:e,startTime:t,endTime:r},n){let o=[],i=Math.max(0,t-288e5),s=!1;for(let a=0;a<16&&i<=r;a++){let l=await xr({coin:e,startTime:i,endTime:r},n);if(!Array.isArray(l))throw new TypeError("Hyperliquid funding history must be an array");o.push(...l);let f=i;for(let u of l){let c=Number(u?.time);Number.isSafeInteger(c)&&c>f&&(f=c)}if(l.length<500||f>=r){s=!0;break}if(f<=i)throw new Error("Hyperliquid funding history pagination did not advance");i=f+1}if(!s)throw new Error("strategy history exceeds the bounded funding history limit");return Lo(o,r)}function Fo(e,t,r){let n=0,o=null;return e.map(i=>{let s=i.t+r,a=0;for(;n<t.length&&t[n].time<s;){let l=t[n];o=l.fundingRate,l.time>=i.t&&(a+=l.fundingRate),n+=1}return o==null?{...i,fundingPaymentRate:a}:{...i,fundingRate:o,fundingPaymentRate:a}})}async function Nr(e,t={}){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("strategy history input must be an object");let r=String(e.coin||"").trim().toUpperCase();if(!/^[A-Z0-9][A-Z0-9._-]{0,11}$/.test(r))throw new TypeError("coin must be an uppercase Hyperliquid asset id");let n=String(e.interval||"15m"),o=Ro(n);if(e.endTime==null)throw new TypeError("endTime is required for deterministic history");let i=ve(e.endTime,"endTime"),s=e.count==null?1500:e.count;if(!Number.isInteger(s)||s<20||s>5e3)throw new TypeError("count must be an integer from 20 to 5000");let a=e.startTime==null?Math.max(0,i-s*o):ve(e.startTime,"startTime");if(a>=i)throw new TypeError("startTime must be before endTime");let[l,f]=await Promise.all([Er({coin:r,interval:n,startTime:a,endTime:i},t),Ho({coin:r,startTime:a,endTime:i},t)]),u=Mo(l,{endTime:i}),c=Be(Fo(u,f,o));return Be({coin:r,interval:n,range:{startTime:a,endTime:i},bars:c})}var No,Rr=G(()=>{St();No=Object.freeze({"1m":6e4,"3m":18e4,"5m":3e5,"15m":9e5,"30m":18e5,"1h":36e5,"2h":72e5,"4h":144e5,"8h":288e5,"12h":432e5,"1d":864e5})});function qo(e){let t=[];if(!e||typeof e!="object"||Array.isArray(e))return{ok:!1,errors:[{path:"market",message:"must be a plain object"}],market:null};for(let r of Object.keys(e))Uo.has(r)||t.push({path:`market.${r}`,message:"unknown field is not allowed"});return(typeof e.coin!="string"||e.coin.length===0||e.coin.length>32)&&t.push({path:"market.coin",message:"must be a non-empty string max 32"}),(typeof e.interval!="string"||!Co.has(e.interval))&&t.push({path:"market.interval",message:"must be a supported interval"}),t.length?{ok:!1,errors:t,market:null}:{ok:!0,errors:[],market:{coin:e.coin,interval:e.interval}}}async function Do(e={}){let t=await br(e);if(!t||!Array.isArray(t.universe))throw new TypeError("Hyperliquid market metadata must contain universe");return Object.freeze(t.universe.map((r,n)=>{if(!r||typeof r.name!="string"||!r.name)throw new TypeError(`Hyperliquid market metadata universe[${n}].name is invalid`);return r.name}))}var Co,Uo,Mr,Lr=G(()=>{St();jr();Rr();Co=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),Uo=new Set(["coin","interval"]);Mr=Object.freeze({id:"hyperliquid",validateMarket:qo,fetchBars:Nr,listMarkets:Do,prepareIntent(e){return vr(e)}})});function zo(e){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("strategy venue adapter must be an object");if(typeof e.id!="string"||!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(e.id))throw new TypeError("strategy venue adapter id is malformed");for(let t of Bo.slice(1))if(typeof e[t]!="function")throw new TypeError(`strategy venue adapter ${e.id} requires ${t}()`);for(let t of["fetchBars","listMarkets"])if(e[t]!=null&&typeof e[t]!="function")throw new TypeError(`strategy venue adapter ${e.id} ${t} must be a function`);return e}function jt(e){return typeof e!="string"?null:Jo.get(e)??null}function Nt(e){let t=jt(e);if(!t)throw new Error(`unknown strategy venue: ${String(e)}`);return t}var Bo,Hr,Jo,aa,Rt=G(()=>{Lr();Bo=Object.freeze(["id","validateMarket","prepareIntent"]);Hr=[Mr].map(zo),Jo=new Map(Hr.map(e=>[e.id,e])),aa=Object.freeze([...Hr])});import{createHash as Vo}from"node:crypto";function ee(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function z(e){return typeof e=="number"&&Number.isFinite(e)}function Jr(e){return Number.isInteger(e)&&e>0}function Ct(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Ct(t);return Object.freeze(e)}for(let t of Object.keys(e))Ct(e[t]);return Object.freeze(e)}function Ut(e){if(Array.isArray(e))return e.map(Ut);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=Ut(e[r]);return t}return e}function b(e,t,r){e.push({path:t,message:r})}function he(e,t,r,n){for(let o of Object.keys(e))t.has(o)||b(n,r?`${r}.${o}`:o,"unknown field is not allowed")}function Yr(e,t,r,n){if(!z(e)||!z(t)||!z(r)||!z(n)||n<=0||e<t||e>r)return!1;let o=(e-t)/n;if(!Number.isFinite(o))return!1;let i=Math.round(o);return Math.abs(o-i)<=1e-9}function Ft(e,t,r,n){if(ee(e)){if(he(e,new Set(["param"]),t,n),typeof e.param!="string"||!e.param)return b(n,`${t}.param`,"must be a parameter name string"),null;if(!Object.prototype.hasOwnProperty.call(r,e.param))return b(n,`${t}.param`,`unknown parameter "${e.param}"`),null;let o=r[e.param];return!ee(o)||![o.value,o.min,o.max,o.step].every(Jr)?(b(n,`${t}.param`,"referenced period parameter value min max and step must be positive integers"),null):{param:e.param}}return Jr(e)?e:(b(n,t,"must be a positive integer or {param}"),null)}function Vr(e,t,r,n){return ee(e)?(he(e,new Set(["param"]),t,n),typeof e.param!="string"||!e.param?(b(n,`${t}.param`,"must be a parameter name string"),null):Object.prototype.hasOwnProperty.call(r,e.param)?{param:e.param}:(b(n,`${t}.param`,`unknown parameter "${e.param}"`),null)):z(e)?e:(b(n,t,"must be a finite number or {param}"),null)}function rt(e){switch(e.type){case"input":case"constant":return[];case"indicator":return e.input?[e.input]:[];case"compare":case"cross":return[e.left,e.right].filter(Boolean);case"logic":return Array.isArray(e.inputs)?[...e.inputs]:[];default:return[]}}function ts(e){let t=new Map,r=n=>{let o=t.get(n)||0;if(o===1)return!0;if(o===2)return!1;t.set(n,1);let i=e.get(n);if(i){for(let s of rt(i))if(e.has(s)&&r(s))return!0}return t.set(n,2),!1};for(let n of e.keys())if(r(n))return!0;return!1}function rs(e,t){if(!ee(e))return b(t,"parameters","must be a plain object"),null;let r=Object.keys(e);if(r.length>Dr)return b(t,"parameters",`too many parameters (max ${Dr})`),null;let n={};for(let o of r){if(!Gr.test(o)){b(t,`parameters.${o}`,"parameter name is malformed");continue}let i=e[o],s=`parameters.${o}`;if(!ee(i)){b(t,s,"must be a plain object");continue}he(i,Cr,s,t);for(let c of Cr)c in i||b(t,`${s}.${c}`,"required field is missing");let{value:a,min:l,max:f,step:u}=i;z(l)||b(t,`${s}.min`,"must be a finite number"),z(f)||b(t,`${s}.max`,"must be a finite number"),(!z(u)||u<=0)&&b(t,`${s}.step`,"must be a positive finite number"),z(a)||b(t,`${s}.value`,"must be a finite number"),z(l)&&z(f)&&l>f&&b(t,`${s}.min`,"min must be <= max"),z(a)&&z(l)&&z(f)&&z(u)&&u>0&&(Yr(a,l,f,u)||b(t,`${s}.value`,"value must lie on the declared min/max/step grid")),n[o]={value:a,min:l,max:f,step:u}}return n}function ns(e,t,r,n){let o=`nodes.${t}`;if(!ee(e))return b(n,o,"must be a plain object"),null;if(typeof e.type!="string"||!qr[e.type])return b(n,`${o}.type`,"unknown or missing node type"),he(e,es,o,n),null;switch(he(e,qr[e.type],o,n),(typeof e.id!="string"||!Kr.test(e.id))&&b(n,`${o}.id`,"must be a 1-64 char id starting with alphanumeric"),e.type){case"input":return(typeof e.field!="string"||!Go.has(e.field))&&b(n,`${o}.field`,"must be one of open|high|low|close|volume|fundingRate|openInterest|premium|oiDelta|bookImbalance"),{id:e.id,type:"input",field:e.field};case"constant":{let i=Vr(e.value,`${o}.value`,r,n);return{id:e.id,type:"constant",value:i}}case"indicator":{(typeof e.indicator!="string"||!Ko.has(e.indicator))&&b(n,`${o}.indicator`,"must be one of sma|ema|rsi|macd|bollinger|atr");let i=e.indicator,s={id:e.id,type:"indicator",indicator:i};if(i==="atr"){"input"in e&&(typeof e.input!="string"||!e.input?b(n,`${o}.input`,"must be a node id string when provided"):s.input=e.input);let a=Ft(e.period,`${o}.period`,r,n);a!=null&&(s.period=a)}else typeof e.input!="string"||!e.input?b(n,`${o}.input`,"must be a node id string"):s.input=e.input;if((i==="sma"||i==="ema"||i==="rsi"||i==="bollinger"||i==="atr")&&("period"in e,i!=="macd"))if(!("period"in e))b(n,`${o}.period`,"required field is missing");else{let a=Ft(e.period,`${o}.period`,r,n);a!=null&&(s.period=a)}if(i==="macd"){for(let a of["fastPeriod","slowPeriod","signalPeriod"])if(!(a in e))b(n,`${o}.${a}`,"required field is missing");else{let l=Ft(e[a],`${o}.${a}`,r,n);l!=null&&(s[a]=l)}"output"in e?Xo.has(e.output)?s.output=e.output:b(n,`${o}.output`,"must be line|signal|histogram"):b(n,`${o}.output`,"required field is missing"),"period"in e&&b(n,`${o}.period`,"forbidden for macd"),"stdDev"in e&&b(n,`${o}.stdDev`,"forbidden for macd")}else if(i==="bollinger"){if(!("stdDev"in e))b(n,`${o}.stdDev`,"required field is missing");else{let a=Vr(e.stdDev,`${o}.stdDev`,r,n);a!=null&&(typeof a=="number"&&a<=0?b(n,`${o}.stdDev`,"must be > 0"):s.stdDev=a)}"output"in e?Qo.has(e.output)?s.output=e.output:b(n,`${o}.output`,"must be upper|middle|lower"):b(n,`${o}.output`,"required field is missing");for(let a of["fastPeriod","slowPeriod","signalPeriod"])a in e&&b(n,`${o}.${a}`,`forbidden for ${i}`)}else{"output"in e&&b(n,`${o}.output`,`forbidden for ${i}`),"stdDev"in e&&i!=="bollinger"&&b(n,`${o}.stdDev`,`forbidden for ${i}`);for(let a of["fastPeriod","slowPeriod","signalPeriod"])a in e&&b(n,`${o}.${a}`,`forbidden for ${i}`)}return s}case"compare":return(typeof e.op!="string"||!Yo.has(e.op))&&b(n,`${o}.op`,"must be gt|gte|lt|lte|eq"),(typeof e.left!="string"||!e.left)&&b(n,`${o}.left`,"must be a node id"),(typeof e.right!="string"||!e.right)&&b(n,`${o}.right`,"must be a node id"),{id:e.id,type:"compare",op:e.op,left:e.left,right:e.right};case"logic":{if((typeof e.op!="string"||!Wo.has(e.op))&&b(n,`${o}.op`,"must be and|or|not"),!Array.isArray(e.inputs))return b(n,`${o}.inputs`,"must be an array of node ids"),{id:e.id,type:"logic",op:e.op,inputs:[]};let i=[];for(let s=0;s<e.inputs.length;s++){let a=e.inputs[s];typeof a!="string"||!a?b(n,`${o}.inputs.${s}`,"must be a node id"):i.push(a)}return e.op==="not"?i.length!==1&&b(n,`${o}.inputs`,"not requires exactly one input"):(e.op==="and"||e.op==="or")&&i.length<2&&b(n,`${o}.inputs`,`${e.op} requires at least two inputs`),{id:e.id,type:"logic",op:e.op,inputs:i}}case"cross":return(typeof e.direction!="string"||!Zo.has(e.direction))&&b(n,`${o}.direction`,"must be above|below"),(typeof e.left!="string"||!e.left)&&b(n,`${o}.left`,"must be a node id"),(typeof e.right!="string"||!e.right)&&b(n,`${o}.right`,"must be a node id"),{id:e.id,type:"cross",direction:e.direction,left:e.left,right:e.right};default:return null}}function os(e,t,r){if(!ee(e))return b(t,"risk","must be a plain object"),null;he(e,Ur,"risk",t);for(let d of Ur)(!(d in e)||e[d]==null)&&b(t,`risk.${d}`,"required field is missing");let n={},o=e.maxLeverage;!z(o)||o<=0||o>50?b(t,"risk.maxLeverage","must be a number > 0 and <= 50"):n.maxLeverage=o;let i=e.maxNotionalUsd;!z(i)||i<=0?b(t,"risk.maxNotionalUsd","must be a number > 0"):n.maxNotionalUsd=i;let s=e.positionSizePct;!z(s)||s<=0||s>100?b(t,"risk.positionSizePct","must be a number > 0 and <= 100"):n.positionSizePct=s;let a=e.stopLossPct;!z(a)||a<=0||a>100?b(t,"risk.stopLossPct","must be a number > 0 and <= 100"):n.stopLossPct=a;let l=e.takeProfitPct;!z(l)||l<=0||l>1e3?b(t,"risk.takeProfitPct","must be a number > 0 and <= 1000"):n.takeProfitPct=l;let f=e.cooldownBars;!Number.isInteger(f)||f<0||f>1e5?b(t,"risk.cooldownBars","must be an integer >= 0 and <= 100000"):n.cooldownBars=f;let u=e.maxDailyLossPct;!z(u)||u<=0||u>100?b(t,"risk.maxDailyLossPct","must be a number > 0 and <= 100"):n.maxDailyLossPct=u;let c=e.expiresAt;return!Number.isInteger(c)||c<=0?b(t,"risk.expiresAt","must be an integer epoch milliseconds > 0"):(r.nowMs!==void 0&&(Number.isInteger(r.nowMs)?c<=r.nowMs&&b(t,"risk.expiresAt","must be strictly greater than nowMs"):b(t,"nowMs","must be an integer epoch milliseconds")),n.expiresAt=c),n}function qt(e,t={}){let r=[];if(!ee(e))return b(r,"","strategy must be a plain object"),{ok:!1,errors:r,strategy:null};he(e,Fr,"",r);for(let c of Fr)(!(c in e)||e[c]==null)&&b(r,c,"required field is missing");e.version!==Mt&&b(r,"version",`must be ${Mt}`),(typeof e.id!="string"||!Gr.test(e.id))&&b(r,"id","must match /^[a-z0-9][a-z0-9._-]{0,63}$/"),(typeof e.name!="string"||e.name.length===0||e.name.length>zr)&&b(r,"name",`must be a non-empty string max ${zr}`);let n=jt(e.venue);n||b(r,"venue",`unknown strategy venue "${String(e.venue)}"`);let o=null;if(!n)ee(e.market)||b(r,"market","must be a plain object");else{let c=n.validateMarket(e.market);if(!c||typeof c.ok!="boolean"||!Array.isArray(c.errors))b(r,"market",`venue ${n.id} returned an invalid market validation result`);else if(c.ok)o=c.market;else for(let d of c.errors)b(r,d.path,d.message)}let i=rs(e.parameters,r),s=null,a=new Map;if(!Array.isArray(e.nodes))b(r,"nodes","must be an array");else if(e.nodes.length>Br)b(r,"nodes",`too many nodes (max ${Br})`);else{s=[];for(let c=0;c<e.nodes.length;c++){let d=ns(e.nodes[c],c,i||{},r);d&&(typeof d.id=="string"&&Kr.test(d.id)&&(a.has(d.id)?b(r,`nodes.${c}.id`,`duplicate node id "${d.id}"`):a.set(d.id,d)),s.push(d))}for(let c=0;c<s.length;c++){let d=s[c],m=`nodes.${c}`;for(let p of rt(d))a.has(p)||b(r,m,`unknown node ref "${p}"`);if(d.type==="indicator"||d.type==="compare"||d.type==="cross")for(let p of rt(d)){let w=a.get(p);w&&Lt.has(w.type)&&b(r,m,`node ref "${p}" must be numeric`)}if(d.type==="logic")for(let p of rt(d)){let w=a.get(p);w&&!Lt.has(w.type)&&b(r,m,`node ref "${p}" must be boolean`)}}ts(a)&&b(r,"nodes","graph contains a cycle")}let l=null;if(!ee(e.rules))b(r,"rules","must be a plain object");else{he(e.rules,Ht,"rules",r);for(let c of Ht)c in e.rules||b(r,`rules.${c}`,"required field is missing");l={};for(let c of Ht){let d=e.rules[c];if(d===null){l[c]=null;continue}if(typeof d!="string"||!d){b(r,`rules.${c}`,"must be a node id or null"),l[c]=d;continue}if(!a.has(d)){b(r,`rules.${c}`,`unknown node ref "${d}"`),l[c]=d;continue}let m=a.get(d);Lt.has(m.type)||b(r,`rules.${c}`,`rule must reference a boolean node, not ${m.type}`),l[c]=d}}let f=os(e.risk,r,t);if(r.length)return{ok:!1,errors:r,strategy:null};let u=Ct({version:Mt,id:e.id,name:e.name,venue:n.id,market:o,parameters:i,nodes:s,rules:l,risk:f});return{ok:!0,errors:[],strategy:u}}function Z(e,t={}){let r=qt(e,t);if(!r.ok)throw new je(r.errors);return r.strategy}function ss(e){let t=Z(e);return JSON.stringify(Ut(t))}function _e(e){let t=ss(e);return Vo("sha256").update(t,"utf8").digest("hex")}function ze(e,t){if(!ee(e))throw new je([{path:"",message:"strategy must be a plain object"}]);if(!ee(t))throw new je([{path:"overrides",message:"must be a plain object"}]);let r=Z(e),n={};for(let[i,s]of Object.entries(r.parameters))n[i]={value:s.value,min:s.min,max:s.max,step:s.step};let o=[];for(let[i,s]of Object.entries(t)){if(!Object.prototype.hasOwnProperty.call(n,i)){b(o,i,`unknown parameter "${i}"`);continue}let a=n[i];if(!z(s)){b(o,i,"override must be a finite number");continue}if(!Yr(s,a.min,a.max,a.step)){b(o,i,"override must lie on the declared min/max/step grid");continue}n[i]={...a,value:s}}if(o.length)throw new je(o);return Z({version:r.version,id:r.id,name:r.name,venue:r.venue,market:{coin:r.market.coin,interval:r.market.interval},parameters:n,nodes:r.nodes.map(i=>{let s={...i};return Array.isArray(i.inputs)&&(s.inputs=[...i.inputs]),s}),rules:{...r.rules},risk:{...r.risk}})}var Mt,Gr,Kr,Go,Ko,Yo,Wo,Zo,Xo,Qo,Lt,Fr,Cr,Ht,Ur,es,qr,Dr,Br,zr,je,xe=G(()=>{Rt();Mt=1,Gr=/^[a-z0-9][a-z0-9._-]{0,63}$/,Kr=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/,Go=new Set(["open","high","low","close","volume","fundingRate","openInterest","premium","oiDelta","bookImbalance"]),Ko=new Set(["sma","ema","rsi","macd","bollinger","atr"]),Yo=new Set(["gt","gte","lt","lte","eq"]),Wo=new Set(["and","or","not"]),Zo=new Set(["above","below"]),Xo=new Set(["line","signal","histogram"]),Qo=new Set(["upper","middle","lower"]),Lt=new Set(["compare","logic","cross"]),Fr=new Set(["version","id","name","venue","market","parameters","nodes","rules","risk"]),Cr=new Set(["value","min","max","step"]),Ht=new Set(["entryLong","entryShort","exitLong","exitShort"]),Ur=new Set(["maxLeverage","maxNotionalUsd","positionSizePct","stopLossPct","takeProfitPct","cooldownBars","maxDailyLossPct","expiresAt"]),es=new Set(["id","type"]),qr={input:new Set(["id","type","field"]),constant:new Set(["id","type","value"]),indicator:new Set(["id","type","indicator","input","period","fastPeriod","slowPeriod","signalPeriod","stdDev","output"]),compare:new Set(["id","type","op","left","right"]),logic:new Set(["id","type","op","inputs"]),cross:new Set(["id","type","direction","left","right"])},Dr=16,Br=128,zr=100,je=class extends Error{constructor(t){let r=t.map(n=>`${n.path}: ${n.message}`);super(`invalid strategy (${t.length} error${t.length===1?"":"s"}): ${r.join("; ")}`),this.name="StrategyValidationError",this.errors=t}}});function Je(e){if(!Array.isArray(e))throw new TypeError("values must be an array");for(let t=0;t<e.length;t++){let r=e[t];if(typeof r!="number"||!Number.isFinite(r))throw new TypeError(`values[${t}] must be a finite number`)}}function ye(e){if(!Number.isInteger(e)||e<=0)throw new TypeError("period must be a positive integer")}function is(e){if(!Array.isArray(e))throw new TypeError("bars must be an array");for(let t=0;t<e.length;t++){let r=e[t];if(r==null||typeof r!="object")throw new TypeError(`bars[${t}] must be an object`);for(let n of["o","h","l","c"]){let o=r[n];if(typeof o!="number"||!Number.isFinite(o))throw new TypeError(`bars[${t}].${n} must be a finite number`)}if(r.h<r.l)throw new TypeError(`bars[${t}] high must be >= low`)}}function Zr(e,t){Je(e),ye(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=0;for(let o=0;o<e.length;o++)n+=e[o],o>=t&&(n-=e[o-t]),o>=t-1&&(r[o]=n/t);return r}function nt(e,t){Je(e),ye(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=0;for(let s=0;s<t;s++)n+=e[s];let o=n/t;r[t-1]=o;let i=2/(t+1);for(let s=t;s<e.length;s++)o=i*e[s]+(1-i)*o,r[s]=o;return r}function Xr(e,t){Je(e),ye(t);let r=new Array(e.length).fill(null);if(e.length<=t)return r;let n=0,o=0;for(let a=1;a<=t;a++){let l=e[a]-e[a-1];l>=0?n+=l:o-=l}let i=n/t,s=o/t;r[t]=Wr(i,s);for(let a=t+1;a<e.length;a++){let l=e[a]-e[a-1],f=l>0?l:0,u=l<0?-l:0;i=(i*(t-1)+f)/t,s=(s*(t-1)+u)/t,r[a]=Wr(i,s)}return r}function Wr(e,t){return e===0&&t===0?50:t===0?100:e===0?0:100-100/(1+e/t)}function Qr(e,t={}){Je(e);let r=t.fastPeriod,n=t.slowPeriod,o=t.signalPeriod;if(ye(r),ye(n),ye(o),r>=n)throw new TypeError("fastPeriod must be < slowPeriod");let i=nt(e,r),s=nt(e,n),a=new Array(e.length).fill(null);for(let c=0;c<e.length;c++)i[c]!=null&&s[c]!=null&&(a[c]=i[c]-s[c]);let l=new Array(e.length).fill(null),f=new Array(e.length).fill(null),u=[];for(let c=0;c<a.length;c++)a[c]!=null&&u.push(c);if(u.length>=o){let c=0;for(let w=0;w<o;w++)c+=a[u[w]];let d=c/o,m=u[o-1];l[m]=d,f[m]=a[m]-d;let p=2/(o+1);for(let w=o;w<u.length;w++){let g=u[w];d=p*a[g]+(1-p)*d,l[g]=d,f[g]=a[g]-d}}return{line:a,signal:l,histogram:f}}function en(e,t={}){Je(e);let r=t.period,n=t.stdDev;if(ye(r),typeof n!="number"||!Number.isFinite(n)||n<=0)throw new TypeError("stdDev must be a finite number > 0");let o=new Array(e.length).fill(null),i=new Array(e.length).fill(null),s=new Array(e.length).fill(null);if(e.length<r)return{upper:i,middle:o,lower:s};let a=0,l=0;for(let f=0;f<e.length;f++){let u=e[f];if(a+=u,l+=u*u,f>=r){let c=e[f-r];a-=c,l-=c*c}if(f>=r-1){let c=a/r,d=l/r-c*c;d<0&&d>-1e-12&&(d=0);let m=Math.sqrt(d);o[f]=c,i[f]=c+n*m,s[f]=c-n*m}}return{upper:i,middle:o,lower:s}}function tn(e,t){is(e),ye(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=new Array(e.length);for(let s=0;s<e.length;s++){let a=e[s];if(s===0)n[s]=a.h-a.l;else{let l=e[s-1].c;n[s]=Math.max(a.h-a.l,Math.abs(a.h-l),Math.abs(a.l-l))}}let o=0;for(let s=0;s<t;s++)o+=n[s];let i=o/t;r[t-1]=i;for(let s=t;s<e.length;s++)i=(i*(t-1)+n[s])/t,r[s]=i;return r}var rn=G(()=>{});import{createHash as as}from"node:crypto";var Dt,cs,ls,us,nn,on=G(()=>{Dt=3,cs="7477966facc4ef928a94e6221c8fd238eef4fcbeec46b96ae1b89178e13c2d5f",ls="68f5b412a9975f04024cf9b9b6209b4bccedd52f176e95f34f786b3f53479c6a",us="967fd45ecddd0d59ac0f662fe92ea813c32620ba751f249b4ace6cb6b809fb5e",nn=as("sha256").update(JSON.stringify({version:Dt,compilerSourceHash:cs,indicatorsSourceHash:ls,schemaSourceHash:us})).digest("hex")});function Q(e){return typeof e=="number"&&Number.isFinite(e)}function ps(e){let t=new Map(e.map(a=>[a.id,a])),r=a=>{switch(a.type){case"indicator":return a.input?[a.input]:[];case"compare":case"cross":return[a.left,a.right];case"logic":return[...a.inputs];default:return[]}},n=new Map,o=new Map;for(let a of e)n.set(a.id,0),o.set(a.id,[]);for(let a of e)for(let l of r(a))t.has(l)&&(o.get(l).push(a.id),n.set(a.id,n.get(a.id)+1));let i=[];for(let[a,l]of n)l===0&&i.push(a);let s=[];for(;i.length;){let a=i.shift();s.push(a);for(let l of o.get(a))n.set(l,n.get(l)-1),n.get(l)===0&&i.push(l)}if(s.length!==e.length)throw new Error("strategy graph is cyclic");return s}function Ne(e,t){return e!=null&&typeof e=="object"&&"param"in e?t[e.param].value:e}function ms(e,t,r){if(!Array.isArray(e)||e.length===0)throw new TypeError("bars must be a non-empty array");if(!Number.isInteger(t)||t<0||t>=e.length)throw new RangeError("index out of range");let n=null;for(let o=0;o<=t;o++){let i=e[o];if(i==null||typeof i!="object"||Array.isArray(i))throw new TypeError(`bars[${o}] must be an object`);let{t:s,o:a,h:l,l:f,c:u,v:c}=i;if(!Q(s)&&(typeof s=="number"&&Number.isFinite(s)),!Number.isFinite(s))throw new TypeError(`bars[${o}].t must be finite`);for(let[d,m]of[["o",a],["h",l],["l",f],["c",u],["v",c]])if(!Q(m))throw new TypeError(`bars[${o}].${d} must be a finite number`);for(let[d,m]of[["o",a],["h",l],["l",f],["c",u]])if(!(m>0))throw new TypeError(`bars[${o}].${d} price must be positive`);if(c<0)throw new TypeError(`bars[${o}].v volume must be non-negative`);if(l<Math.max(a,u,f))throw new TypeError(`bars[${o}] high must be >= max(open, close, low)`);if(f>Math.min(a,u,l))throw new TypeError(`bars[${o}] low must be <= min(open, close, high)`);if(n!=null){if(!(s>n))throw new TypeError("bars t must be strictly increasing");if(s-n!==ds[r])throw new TypeError(`bars t must match ${r} cadence`)}if(n=s,"fundingRate"in i&&i.fundingRate!=null&&!Q(i.fundingRate))throw new TypeError(`bars[${o}].fundingRate must be finite when present`);if("openInterest"in i&&i.openInterest!=null){if(!Q(i.openInterest))throw new TypeError(`bars[${o}].openInterest must be finite when present`);if(i.openInterest<0)throw new TypeError(`bars[${o}].openInterest must be non-negative`)}for(let d of["premium","oiDelta"])if(d in i&&i[d]!=null&&!Q(i[d]))throw new TypeError(`bars[${o}].${d} must be finite when present`);if("bookImbalance"in i&&i.bookImbalance!=null){if(!Q(i.bookImbalance))throw new TypeError(`bars[${o}].bookImbalance must be finite when present`);if(i.bookImbalance<-1||i.bookImbalance>1)throw new TypeError(`bars[${o}].bookImbalance must be within [-1, 1]`)}}}function Oe(e,t,r,n,o,i){if(i.has(e))return i.get(e);let s=t.get(e),a;switch(s.type){case"input":{let l=fs[s.field];a=new Array(o+1);for(let f=0;f<=o;f++){let u=n[f][l];a[f]=u===void 0?null:u}break}case"constant":{let l=Ne(s.value,r);a=new Array(o+1).fill(l);break}case"indicator":{let l=s.period!=null?Ne(s.period,r):void 0;if(s.indicator==="atr"){let c=[];for(let d=0;d<=o;d++){let m=n[d];c.push({o:m.o,h:m.h,l:m.l,c:m.c})}a=tn(c,l);break}let u=Oe(s.input,t,r,n,o,i).map((c,d)=>{if(c==null||!Q(c))throw new TypeError(`indicator input ${s.input} has non-finite value at ${d}`);return c});if(s.indicator==="sma")a=Zr(u,l);else if(s.indicator==="ema")a=nt(u,l);else if(s.indicator==="rsi")a=Xr(u,l);else if(s.indicator==="macd")a=Qr(u,{fastPeriod:Ne(s.fastPeriod,r),slowPeriod:Ne(s.slowPeriod,r),signalPeriod:Ne(s.signalPeriod,r)})[s.output];else if(s.indicator==="bollinger")a=en(u,{period:l,stdDev:Ne(s.stdDev,r)})[s.output];else throw new Error(`unsupported indicator ${s.indicator}`);break}case"compare":{let l=Oe(s.left,t,r,n,o,i),f=Oe(s.right,t,r,n,o,i);a=new Array(o+1);for(let u=0;u<=o;u++){let c=l[u],d=f[u];if(c==null||d==null||!Q(c)||!Q(d)){a[u]=!1;continue}switch(s.op){case"gt":a[u]=c>d;break;case"gte":a[u]=c>=d;break;case"lt":a[u]=c<d;break;case"lte":a[u]=c<=d;break;case"eq":a[u]=c===d;break;default:a[u]=!1}}break}case"logic":{let l=s.inputs.map(f=>Oe(f,t,r,n,o,i));a=new Array(o+1);for(let f=0;f<=o;f++)if(s.op==="not"){let u=l[0][f];a[f]=u===!0?!1:u===!1}else if(s.op==="and"){let u=!0;for(let c of l)if(c[f]!==!0){u=!1;break}a[f]=u}else if(s.op==="or"){let u=!1;for(let c of l)if(c[f]===!0){u=!0;break}a[f]=u}else a[f]=!1;break}case"cross":{let l=Oe(s.left,t,r,n,o,i),f=Oe(s.right,t,r,n,o,i);a=new Array(o+1),a[0]=!1;for(let u=1;u<=o;u++){let c=l[u-1],d=f[u-1],m=l[u],p=f[u];if(c==null||d==null||m==null||p==null||!Q(c)||!Q(d)||!Q(m)||!Q(p)){a[u]=!1;continue}s.direction==="above"?a[u]=c<=d&&m>p:a[u]=c>=d&&m<p}break}default:throw new Error(`unknown node type ${s.type}`)}return i.set(e,a),a}function X(e,t={}){let r=Z(e);t&&Object.keys(t).length&&(r=ze(r,t));let n=new Map(r.nodes.map(m=>[m.id,m])),o=Object.freeze(ps(r.nodes)),i=r.parameters,s=new Set(r.nodes.filter(m=>m.type==="input").map(m=>m.field));if(r.nodes.some(m=>m.type==="indicator"&&m.indicator==="atr"))for(let m of["open","high","low","close"])s.add(m);let a=Object.freeze([...s].sort()),l=_e(r);function f(m,p){let w={};for(let k of o){let v=m.get(k);w[k]=v[p]}let g=k=>k!=null&&w[k]===!0;return{values:w,signals:{entryLong:g(r.rules.entryLong),entryShort:g(r.rules.entryShort),exitLong:g(r.rules.exitLong),exitShort:g(r.rules.exitShort)}}}function u(m,p){ms(m,p,r.market.interval);let w=new Map;for(let g of o)Oe(g,n,i,m,p,w);return w}function c(m,p){return f(u(m,p),p)}function d(m){if(!Array.isArray(m)||m.length===0)throw new TypeError("bars must be a non-empty array");let p=m.length-1,w=u(m,p);return Object.freeze(m.map((g,k)=>Object.freeze(f(w,k))))}return Object.freeze({strategy:r,strategyHash:l,compilerVersion:De,compilerHash:ke,requiredSeries:a,nodeOrder:o,evaluate:c,evaluateAll:d})}var De,ke,fs,ds,Se=G(()=>{xe();rn();on();De=Dt,ke=nn,fs=Object.freeze({open:"o",high:"h",low:"l",close:"c",volume:"v",fundingRate:"fundingRate",openInterest:"openInterest",premium:"premium",oiDelta:"oiDelta",bookImbalance:"bookImbalance"}),ds=Object.freeze({"1m":6e4,"3m":18e4,"5m":3e5,"15m":9e5,"30m":18e5,"1h":36e5,"2h":72e5,"4h":144e5,"8h":288e5,"12h":432e5,"1d":864e5})});import{createHash as hs}from"node:crypto";function ws(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function se(e){return typeof e=="number"&&Number.isFinite(e)}function Bt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Bt(t);return Object.freeze(e)}for(let t of Object.keys(e))Bt(e[t]);return Object.freeze(e)}function ot(e){if(Array.isArray(e))return e.map(ot);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=ot(e[r]);return t}return e}function zt(e,t="result"){if(typeof e=="number"){if(!Number.isFinite(e))throw new Error(`non-finite backtest result at ${t}`);return}if(!(e==null||typeof e!="object")){if(Array.isArray(e)){e.forEach((r,n)=>zt(r,`${t}[${n}]`));return}for(let[r,n]of Object.entries(e))zt(n,`${t}.${r}`)}}function an(e){if(!Array.isArray(e)||e.length===0)throw new TypeError("bars must be a non-empty array");let t=null;for(let r=0;r<e.length;r++){let n=e[r];if(n==null||typeof n!="object"||Array.isArray(n))throw new TypeError(`bars[${r}] must be an object`);let{t:o,o:i,h:s,l:a,c:l,v:f}=n;if(!se(o))throw new TypeError(`bars[${r}].t must be finite`);for(let[u,c]of[["o",i],["h",s],["l",a],["c",l],["v",f]])if(!se(c))throw new TypeError(`bars[${r}].${u} must be a finite number`);for(let[u,c]of[["o",i],["h",s],["l",a],["c",l]])if(!(c>0))throw new TypeError(`bars[${r}].${u} price must be positive`);if(f<0)throw new TypeError(`bars[${r}].v volume must be non-negative`);if(s<Math.max(i,l,a))throw new TypeError(`bars[${r}] high must be >= max(open, close, low)`);if(a>Math.min(i,l,s))throw new TypeError(`bars[${r}] low must be <= min(open, close, high)`);if(t!=null&&!(o>t))throw new TypeError("bars t must be strictly increasing");if(t=o,"fundingRate"in n&&n.fundingRate!=null&&!se(n.fundingRate))throw new TypeError(`bars[${r}].fundingRate must be finite when present`);if("fundingPaymentRate"in n&&n.fundingPaymentRate!=null&&!se(n.fundingPaymentRate))throw new TypeError(`bars[${r}].fundingPaymentRate must be finite when present`);if("openInterest"in n&&n.openInterest!=null&&!se(n.openInterest))throw new TypeError(`bars[${r}].openInterest must be finite when present`)}}function Ue(e){if(!Array.isArray(e))throw new TypeError("bars must be an array");return e.length>0&&an(e),hs("sha256").update(JSON.stringify(ot(e)),"utf8").digest("hex")}function gs(e){if(e==null&&(e={}),!ws(e))throw new TypeError("options must be a plain object");let t={...ys},r=new Set(["initialEquityUsd","takerFeeBps","builderFeeBps","slippageBps","latencyBars","maxVolumeParticipationPct","nowMs"]);for(let n of Object.keys(e))if(!r.has(n))throw new TypeError(`unknown option "${n}"`);if("initialEquityUsd"in e){if(!se(e.initialEquityUsd)||e.initialEquityUsd<=0)throw new TypeError("initialEquityUsd must be a positive finite number");t.initialEquityUsd=e.initialEquityUsd}for(let n of["takerFeeBps","builderFeeBps","slippageBps"])if(n in e){let o=e[n];if(!se(o)||o<0)throw new TypeError(`${n} must be a finite number >= 0`);if(n==="slippageBps"?o>=1e4:o>1e4)throw new TypeError(`${n} exceeds its safe basis-point bound`);t[n]=o}if("latencyBars"in e){let n=e.latencyBars;if(!Number.isInteger(n)||n<1)throw new TypeError("latencyBars must be an integer >= 1");t.latencyBars=n}if("maxVolumeParticipationPct"in e){let n=e.maxVolumeParticipationPct;if(!se(n)||n<=0||n>100)throw new TypeError("maxVolumeParticipationPct must be in (0,100]");t.maxVolumeParticipationPct=n}if("nowMs"in e){if(!Number.isInteger(e.nowMs))throw new TypeError("nowMs must be an integer epoch milliseconds");t.nowMs=e.nowMs}return t}function st(e){return e/1e4}function bs(e,t,r){let n=st(r);return t==="long"?e*(1+n):e*(1-n)}function Es(e,t,r){let n=st(r);return t==="long"?e*(1-n):e*(1+n)}function sn(e,t,r){let n=Math.abs(e)*st(t),o=Math.abs(e)*st(r);return{taker:n,builder:o,total:n+o}}function xs(e,t){let r=e*(t.positionSizePct/100)*t.maxLeverage;return Math.min(r,t.maxNotionalUsd)}function ks(e,t,r){let n=r/100;return t==="long"?e*(1-n):e*(1+n)}function Ss(e,t,r){let n=r/100;return t==="long"?e*(1+n):e*(1-n)}function Os(e,t,r,n){if(!(r>0))return t==="long"?0:Number.POSITIVE_INFINITY;let o=Math.min(.99,1/(2*r)+n/1e4);return t==="long"?e*(1-1/r)/(1-o):e*(1+1/r)/(1+o)}function Ps(e,t,r){return t==="long"?e.l<=r:e.h>=r}function Ts(e,t,r){return t==="long"?e.h>=r:e.l<=r}function As(e,t,r){return t==="long"?e.l<=r:e.h>=r}function Ve(e,t){for(let r of e.requiredSeries)if($s.includes(r)&&!t.every(n=>se(n?.[r])))throw new Error(`strategy required series is absent: ${r}`)}function _s(e){if(e.length<3)return 0;let t=[];for(let s=1;s<e.length;s++){let a=e[s-1].equity,l=e[s].equity;a>0&&t.push((l-a)/a)}if(t.length<2)return 0;let r=0;for(let s of t)r+=s;let n=r/t.length,o=0;for(let s of t)o+=(s-n)**2;let i=Math.sqrt(o/(t.length-1));return i>0?n/i:0}function Is(e){let t=-1/0,r=0;for(let n of e){let o=n.equity;if(o>t&&(t=o),t>0){let i=(t-o)/t*100;i>r&&(r=i)}}return r}function me(e,t,r={}){let n=gs(r);an(t);let o=Ue(t);n.nowMs!==void 0&&Z(e,{nowMs:n.nowMs});let i=X(e);if(Ve(i,t),n.nowMs!==void 0&&i.strategy.risk.expiresAt<=n.nowMs)throw new Error("strategy is expired: risk.expiresAt must be strictly greater than nowMs");let s=i.strategy.risk,a=i.evaluateAll(t),l=n.latencyBars,f=n.slippageBps,u=n.takerFeeBps,c=n.builderFeeBps,d=n.initialEquityUsd,m=0,p=0,w=0,g=0,k=0,v=[],T=[],x=[],R=[],A=[],h=null,M=0,U=null,Y=d,S=!1,y=0,$=0,I=[],C=new Array(t.length).fill(0);function L(E){I.push(E)}function j(E){let H=t[E].v*(n.maxVolumeParticipationPct/100);return Math.max(0,H-C[E])}function P(E){if(!h)return d;let H=h.side==="long"?(E-h.entryPrice)*h.qty:(h.entryPrice-E)*h.qty;return d+H}function N(E,H,O){let D=O.o,F=xs(d,s);if(!(F>0)||!(D>0))return;let B=bs(D,H,f),q=F/B,V=j(E),He=B*V;if(q>V){x.push({kind:"entry",barIndex:E,time:O.t,side:H,requestedNotionalUsd:F,maxFillNotionalUsd:He,reason:"volume_participation"});return}C[E]+=q;let ne=Math.abs(B-D)*q,ce=sn(F,u,c);d-=ce.total,m+=ce.taker,p+=ce.builder,g+=ne,k+=F,h={lifecycleEpoch:++$,side:H,entryBarIndex:E,entryReferencePrice:D,entryPrice:B,qty:q,notionalUsd:F,stop:ks(B,H,s.stopLossPct),take:Ss(B,H,s.takeProfitPct),liq:Os(B,H,s.maxLeverage,u+c),entryFees:ce.taker,entryBuilderFees:ce.builder,entrySlippageUsd:ne,fundingAccrued:0}}function _(E,H,O,D){if(!h)return!1;let F=h.side,B=H,q=B;O!=="liquidation"&&D&&(q=Es(B,F,f));let V=h.qty,He=V*q;if(O!=="liquidation"){let or=j(E),Mn=q*or;if(V>or)return x.push({kind:"exit",barIndex:E,time:t[E].t,side:F,requestedNotionalUsd:He,maxFillNotionalUsd:Mn,reason:"volume_participation",triggerReason:O}),!1;C[E]+=V}let ne=sn(He,u,c),ce=O==="liquidation"?0:Math.abs(q-B)*V,Fe,pt;F==="long"?(Fe=(B-h.entryReferencePrice)*V,pt=(q-h.entryPrice)*V):(Fe=(h.entryReferencePrice-B)*V,pt=(h.entryPrice-q)*V),d+=pt,d-=ne.total,m+=ne.taker,p+=ne.builder,g+=ce,k+=He;let Rn={side:F,entryBarIndex:h.entryBarIndex,entryTime:t[h.entryBarIndex].t,entryPrice:h.entryPrice,exitBarIndex:E,exitTime:t[E].t,exitPrice:q,exitReason:O,qty:V,notionalUsd:h.notionalUsd,grossPnlUsd:Fe,feesUsd:h.entryFees+ne.taker,builderFeesUsd:h.entryBuilderFees+ne.builder,fundingUsd:h.fundingAccrued,slippageUsd:h.entrySlippageUsd+ce,netPnlUsd:Fe-(h.entryFees+ne.taker+h.entryBuilderFees+ne.builder)-h.fundingAccrued-(h.entrySlippageUsd+ce)};return v.push(Rn),O==="liquidation"&&T.push({barIndex:E,time:t[E].t,side:F,price:q,tradeIndex:v.length-1}),h=null,$+=1,y=E+1+(s.cooldownBars||0),!0}function K(E,H,O,D){let F=E+1;if(F>=t.length)return;I.some(q=>q.kind==="exit"&&q.side===H&&q.fillBar===F&&q.epoch===D)||L({kind:"exit",side:H,signalBar:E,fillBar:F,reason:O,epoch:D})}function te(E){let H=I.filter(O=>O.fillBar===E);for(let O=I.length-1;O>=0;O--)I[O].fillBar===E&&I.splice(O,1);H.sort((O,D)=>{let F=B=>B.kind==="exit"?0:1;return F(O)-F(D)});for(let O of H)if(O.kind==="exit"){if(!h||h.side!==O.side||h.lifecycleEpoch!==O.epoch)continue;let D=O.reason||"rule";_(E,t[E].o,D,!0)||K(E,O.side,D,O.epoch)}else if(O.kind==="entry"){if(h||O.epoch!==$||E<y)continue;N(E,O.side,t[E])}}function de(E){if(!h)return;let H=t[E],O=H.fundingPaymentRate;if(O==null||!se(O)||O===0)return;let D=Math.abs(h.qty*H.c),F=O*D;h.side==="long"?(d-=F,h.fundingAccrued+=F,w+=F):(d+=F,h.fundingAccrued-=F,w-=F)}function Te(E){if(!h)return;let H=t[E].o;(h.side==="long"?H<=h.liq:H>=h.liq)&&_(E,H,"liquidation",!1)}function Ye(E){if(!h)return;let H=t[E],O=h.side,D=As(H,O,h.liq),F=Ps(H,O,h.stop),B=Ts(H,O,h.take),q=V=>O==="long"?Math.min(V,H.o):Math.max(V,H.o);if(D){_(E,q(h.liq),"liquidation",!1);return}if(F&&B){_(E,q(h.stop),"stop_loss",!0)||K(E,O,"stop_loss",h.lifecycleEpoch);return}if(F){_(E,q(h.stop),"stop_loss",!0)||K(E,O,"stop_loss",h.lifecycleEpoch);return}B&&(_(E,h.take,"take_profit",!0)||K(E,O,"take_profit",h.lifecycleEpoch))}for(let E=0;E<t.length;E++){let H=Math.floor(t[E].t/864e5);H!==U&&(U=H,Y=P(t[E].o),S=!1),Te(E),te(E),Ye(E),de(E),!S&&P(t[E].c)<=Y*(1-s.maxDailyLossPct/100)&&(S=!0,R.push({type:"daily_loss_limit",barIndex:E,time:t[E].t,message:"daily loss limit reached; new entries blocked for UTC day"}));let O=a[E].signals,D=E+l;if(h)(h.side==="long"&&O.exitLong===!0||h.side==="short"&&O.exitShort===!0)&&D<t.length&&(I.some(V=>V.kind==="exit"&&V.side===h.side&&V.fillBar===D&&V.epoch===h.lifecycleEpoch)||L({kind:"exit",side:h.side,signalBar:E,fillBar:D,reason:"rule",epoch:h.lifecycleEpoch}));else{let B=O.entryLong===!0,q=O.entryShort===!0;B&&q?R.push({type:"conflicting_entry_signals",barIndex:E,time:t[E].t,message:"conflicting entry signals; no position opened"}):!S&&(B||q)&&D<t.length&&E>=y&&L({kind:"entry",side:B?"long":"short",signalBar:E,fillBar:D,epoch:$})}let F=d;h&&(M+=1,F=P(t[E].c)),A.push({barIndex:E,time:t[E].t,equity:F,positionSide:h?h.side:null})}let We=null;if(h){let E=t.length-1;if(_(E,t[E].c,"end_of_data",!0))A[E]={barIndex:E,time:t[E].t,equity:d,positionSide:null};else{let O=P(t[E].c);We={side:h.side,entryBarIndex:h.entryBarIndex,entryTime:t[h.entryBarIndex].t,entryPrice:h.entryPrice,qty:h.qty,notionalUsd:h.notionalUsd,markPrice:t[E].c,markedEquityUsd:O},R.push({type:"open_position_at_end",barIndex:E,time:t[E].t,message:"end-of-data exit missed; position remains open and marked"})}}let Ae=(h?P(t[t.length-1].c):d)-n.initialEquityUsd,we=Ae/n.initialEquityUsd*100,Le=0,ae=0,ut=0;for(let E of v)E.netPnlUsd>0?(Le+=1,ae+=E.netPnlUsd):E.netPnlUsd<0&&(ut+=-E.netPnlUsd);let ft=v.length,vn=ft===0?0:Le/ft,dt=0;ut>0?dt=ae/ut:ae>0&&(dt=1e12);let jn={netPnlUsd:Ae,netPnlPct:we,maxDrawdownPct:Is(A),winRate:vn,profitFactor:dt,tradeCount:ft,sharpe:_s(A),turnoverUsd:k,exposurePct:M/t.length*100},Nn={initialEquityUsd:n.initialEquityUsd,takerFeeBps:n.takerFeeBps,builderFeeBps:n.builderFeeBps,slippageBps:n.slippageBps,latencyBars:n.latencyBars,maxVolumeParticipationPct:n.maxVolumeParticipationPct},nr={barsHash:o,strategyHash:i.strategyHash,compilerHash:ke,compilerVersion:De,config:Nn,trades:v,equityCurve:A,metrics:jn,costs:{feesUsd:m,builderFeesUsd:p,fundingUsd:w,slippageUsd:g},liquidations:T,missedFills:x,openPositionAtEnd:We,flags:R};return zt(nr),Bt(ot(nr))}var ys,$s,tt=G(()=>{Se();xe();ys=Object.freeze({initialEquityUsd:1e4,takerFeeBps:3.5,builderFeeBps:2,slippageBps:2,latencyBars:1,maxVolumeParticipationPct:100});$s=Object.freeze(["fundingRate","openInterest","premium","oiDelta","bookImbalance"])});import{createHash as vs}from"node:crypto";function Cs(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function Jt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Jt(t);return Object.freeze(e)}for(let t of Object.keys(e))Jt(e[t]);return Object.freeze(e)}function Us(e){return String(e).trim().replace(/\s+/g," ")}function qs(e){let t=e.match(/\b(long|short)\b/i);return t?t[1].toLowerCase():null}function Ds(e){for(let r of Ns)if(new RegExp(`\\b${r}\\b`,"i").test(e))return r;let t=e.match(/\b([A-Z][A-Z0-9]{1,11})\b/);return t?t[1]:null}function Bs(e){let t=e.match(/\bon\s+(1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/i);if(!t)return"15m";let r=t[1].toLowerCase();return js.has(r)?r:null}function zs(e){let t={...Ms},r=e.match(/stop\s*loss\s*(\d+(?:\.\d+)?)\s*%?/i);r&&(t.stopLossPct=Number(r[1]));let n=e.match(/take\s*profit\s*(\d+(?:\.\d+)?)\s*%?/i);n&&(t.takeProfitPct=Number(n[1]));let o=e.match(/leverage\s*(\d+(?:\.\d+)?)/i);o&&(t.maxLeverage=Number(o[1]));let i=e.match(/position\s*size\s*(\d+(?:\.\d+)?)\s*%?/i);i&&(t.positionSizePct=Number(i[1]));let s=e.match(/max\s*notional\s*(?:usd\s*)?\$?\s*(\d+(?:\.\d+)?)/i);return s&&(t.maxNotionalUsd=Number(s[1])),t}function Js(e){return[/\bon\s+(?:1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/gi,/\bstop\s*loss\s*\d+(?:\.\d+)?\s*%?/gi,/\btake\s*profit\s*\d+(?:\.\d+)?\s*%?/gi,/\bleverage\s*\d+(?:\.\d+)?/gi,/\bposition\s*size\s*\d+(?:\.\d+)?\s*%?/gi,/\bmax\s*notional\s*(?:usd\s*)?\$?\s*\d+(?:\.\d+)?/gi].some(r=>(e.match(r)??[]).length>1)}function Vs(e){let t=vs("sha256").update(e,"utf8").digest("hex").slice(0,10),r=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40),o=`${r.length?r:"draft"}-${t}`.replace(/[^a-z0-9._-]/g,"").slice(0,64);return/^[a-z0-9]/.test(o)?o:`d${o}`.slice(0,64)}function Gs(e){let t=e.match(/\bema\s*(\d+)\s*cross(?:es)?\s*(above|below)\s*ema\s*(\d+)\b/i);if(!t)return null;let r=Number(t[1]),n=t[2].toLowerCase(),o=Number(t[3]);if(!(r>0)||!(o>0)||r===o)return null;let i=/\b(exit\s+on\s+reverse|reverse\s+exit)\b/i.test(e);return{kind:"ema_cross",fast:r,slow:o,direction:n,reverse:i}}function Ks(e){let t=e.match(/\brsi\s*(\d+)\s*(above|below)\s*(-?\d+(?:\.\d+)?)/i);if(!t)return null;let r=Number(t[3]);return!Number.isFinite(r)||r<=0||r>=100?null:{kind:"rsi",period:Number(t[1]),op:t[2].toLowerCase(),threshold:r}}function Ys(e){let t=e.match(/\bfunding\s*rate\s*(above|below)\s*(-?\d+(?:\.\d+)?)(%?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return t[3]==="%"&&(r=r/100),{kind:"funding",op:t[1].toLowerCase(),threshold:r}}function Ws(e){let t=e.match(/\bopen\s*interest\s*(above|below)\s*(-?\d+(?:\.\d+)?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return!Number.isFinite(r)||r<0?null:{kind:"open_interest",op:t[1].toLowerCase(),threshold:r}}function Zs(e){let t=e.match(/\bpremium\s*(above|below)\s*(-?\d+(?:\.\d+)?)(%?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return Number.isFinite(r)?(t[3]==="%"&&(r=r/100),{kind:"premium",op:t[1].toLowerCase(),threshold:r}):null}function Xs(e){let t=e.match(/\boi\s*delta\s*(above|below)\s*(-?\d+(?:\.\d+)?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return Number.isFinite(r)?{kind:"oi_delta",op:t[1].toLowerCase(),threshold:r}:null}function Qs(e){let t=e.match(/\bbook\s*imbalance\s*(above|below)\s*(-?\d+(?:\.\d+)?)(?=\s|,|$)/i);if(!t)return null;let r=Number(t[2]);return!Number.isFinite(r)||r<-1||r>1?null:{kind:"book_imbalance",op:t[1].toLowerCase(),threshold:r}}function ei(e,t){let r=e.replace(/^(long|short)\s+[A-Z][A-Z0-9]{1,11}\s+when\s+/i,"");if(r===e)return!1;t.kind==="ema_cross"?r=r.replace(/^ema\s*\d+\s*cross(?:es)?\s*(?:above|below)\s*ema\s*\d+\b/i,""):t.kind==="rsi"?r=r.replace(/^rsi\s*\d+\s*(?:above|below)\s*\d+(?:\.\d+)?\b/i,""):t.kind==="open_interest"?r=r.replace(/^open\s*interest\s*(?:above|below)\s*-?\d+(?:\.\d+)?(?=\s|,|$)/i,""):t.kind==="premium"?r=r.replace(/^premium\s*(?:above|below)\s*-?\d+(?:\.\d+)?%?(?=\s|,|$)/i,""):t.kind==="oi_delta"?r=r.replace(/^oi\s*delta\s*(?:above|below)\s*-?\d+(?:\.\d+)?(?=\s|,|$)/i,""):t.kind==="book_imbalance"?r=r.replace(/^book\s*imbalance\s*(?:above|below)\s*-?\d+(?:\.\d+)?(?=\s|,|$)/i,""):r=r.replace(/^funding\s*rate\s*(?:above|below)\s*-?\d+(?:\.\d+)?%?(?=\s|,|$)/i,"");let n=[/(?:,\s*)?\bon\s+(?:1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/gi,/(?:,\s*)?\bstop\s*loss\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\btake\s*profit\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\bleverage\s*\d+(?:\.\d+)?/gi,/(?:,\s*)?\bposition\s*size\s*\d+(?:\.\d+)?\s*%?/gi,/(?:,\s*)?\bmax\s*notional\s*(?:usd\s*)?\$?\s*\d+(?:\.\d+)?/gi];t.kind==="ema_cross"&&n.push(/(?:,\s*)?\b(?:exit\s+on\s+reverse|reverse\s+exit)\b/gi);for(let o of n)r=r.replace(o,"");return r.replace(/[\s,;]+/g,"")===""}function cn(e){let t=Math.max(2,Math.floor(e/2));return{value:e,min:Math.max(2,e-t),max:Math.min(500,e+t),step:1}}function ti({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let l=[{id:"c",type:"input",field:"close"},{id:"emaLeft",type:"indicator",indicator:"ema",input:"c",period:{param:"ema_left_period"}},{id:"emaRight",type:"indicator",indicator:"ema",input:"c",period:{param:"ema_right_period"}},{id:"cross",type:"cross",direction:a.direction,left:"emaLeft",right:"emaRight"}],f={entryLong:null,entryShort:null,exitLong:null,exitShort:null};if(e==="long"?f.entryLong="cross":f.entryShort="cross",a.reverse){let u=a.direction==="above"?"below":"above";l.push({id:"crossRev",type:"cross",direction:u,left:"emaLeft",right:"emaRight"}),e==="long"?f.exitLong="crossRev":f.exitShort="crossRev"}return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{ema_left_period:cn(a.fast),ema_right_period:cn(a.slow)},nodes:l,rules:f,risk:{...n,expiresAt:o}}}function ri({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let l=[{id:"c",type:"input",field:"close"},{id:"rsi",type:"indicator",indicator:"rsi",input:"c",period:a.period},{id:"thr",type:"constant",value:a.threshold},{id:"sig",type:"compare",op:a.op==="above"?"gt":"lt",left:"rsi",right:"thr"}];return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{},nodes:l,rules:{entryLong:e==="long"?"sig":null,entryShort:e==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:o}}}function ni({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let l=[{id:"fr",type:"input",field:"fundingRate"},{id:"thr",type:"constant",value:a.threshold},{id:"sig",type:"compare",op:a.op==="above"?"gt":"lt",left:"fr",right:"thr"}];return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{},nodes:l,rules:{entryLong:e==="long"?"sig":null,entryShort:e==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:o}}}function oi({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let l=[{id:"oi",type:"input",field:"openInterest"},{id:"thr",type:"constant",value:a.threshold},{id:"sig",type:"compare",op:a.op==="above"?"gt":"lt",left:"oi",right:"thr"}];return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{},nodes:l,rules:{entryLong:e==="long"?"sig":null,entryShort:e==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:o}}}function ii({side:e,coin:t,interval:r,risk:n,expiresAt:o,id:i,name:s,spec:a}){let f=[{id:"sig_input",type:"input",field:si[a.kind]},{id:"thr",type:"constant",value:a.threshold},{id:"sig",type:"compare",op:a.op==="above"?"gt":"lt",left:"sig_input",right:"thr"}];return{version:1,id:i,name:s,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{},nodes:f,rules:{entryLong:e==="long"?"sig":null,entryShort:e==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:o}}}function ln(e,t={}){if(typeof e!="string")throw new W("prompt must be a string");if(e.length>1e3)throw new W("prompt length must be <= 1000");if(!Cs(t))throw new W("options must be a plain object");if(!Number.isInteger(t.nowMs))throw new W("options.nowMs is required integer epoch ms");let r=t.nowMs,n=Fs;if("expiresInMs"in t){if(!Number.isInteger(t.expiresInMs))throw new W("expiresInMs must be an integer");if(n=t.expiresInMs,n<Ls||n>Hs)throw new W("expiresInMs must be between 1h and 30d")}if(Rs.test(e))throw new W(`prompt appears to contain secrets and is rejected. ${Re}`);let o=Us(e);if(!o)throw new W(`empty prompt. ${Re}`);if(Js(o))throw new W(`duplicate interval or risk clause. ${Re}`);let i=qs(o),s=Ds(o),a=Bs(o);if(!i||!s||!a)throw new W(`could not parse side/coin/interval. ${Re}`);let l=zs(o);if(!(l.maxLeverage>0)||l.maxLeverage>50)throw new W("leverage out of range");if(!(l.positionSizePct>0)||l.positionSizePct>100)throw new W("position size out of range");let f=r+n,u=Vs(o),c=`Draft ${s} ${i}`.slice(0,100),d=Gs(o),m=Ks(o),p=Ys(o),w=Ws(o),g=Zs(o),k=Xs(o),v=Qs(o),T=[d,m,p,w,g,k,v].filter(Boolean);if(T.length!==1)throw new W(`unsupported or ambiguous prompt. ${Re}`);if(!ei(o,T[0]))throw new W(`unsupported or ambiguous prompt. ${Re}`);let x,R=T[0],A={side:i,coin:s,interval:a,risk:l,expiresAt:f,id:u,name:c,spec:R};R.kind==="ema_cross"?x=ti(A):R.kind==="rsi"?x=ri(A):R.kind==="open_interest"?x=oi(A):R.kind==="funding"?x=ni(A):x=ii(A);let h=qt(x,{nowMs:r});if(!h.ok)throw new W(`draft failed validation: ${h.errors.map(M=>M.message).join("; ")}`);return Jt(Z(x,{nowMs:r}))}var W,js,Ns,Rs,Re,Ms,Ls,Hs,Fs,si,un=G(()=>{xe();W=class extends Error{constructor(t){super(t),this.name="StrategyDraftError"}},js=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),Ns=new Set(["BTC","ETH","SOL","HYPE"]),Rs=/\b(mnemonic|private\s*key|privkey|seed\s*phrase|seed\b|api[_-]?key|secret\s*key|wallet\s*key|passphrase)\b/i,Re="Supported grammar: (1) EMA cross: <long|short> <COIN> when EMA <n> crosses <above|below> EMA <m> [on <interval>] [, exit on reverse] [, risk knobs]; (2) RSI: <long|short> <COIN> when RSI <n> <above|below> <threshold> [on <interval>] [, risk knobs]; (3) funding: <long|short> <COIN> when funding rate <above|below> <decimal|percent%> [on <interval>] [, risk knobs]; (4) open interest: <long|short> <COIN> when open interest <above|below> <non-negative number> [on <interval>] [, risk knobs]; (5) premium: <long|short> <COIN> when premium <above|below> <decimal|percent%> [on <interval>] [, risk knobs]; (6) oi delta: <long|short> <COIN> when oi delta <above|below> <number> [on <interval>] [, risk knobs]; (7) book imbalance: <long|short> <COIN> when book imbalance <above|below> <-1..1> [on <interval>] [, risk knobs]. Risk knobs: stop loss %, take profit %, leverage, position size %, max notional USD. Coins: BTC ETH SOL HYPE or uppercase token <=12 chars. Intervals: 1m 3m 5m 15m 30m 1h 2h 4h 8h 12h 1d.",Ms=Object.freeze({maxLeverage:1,maxNotionalUsd:100,positionSizePct:5,stopLossPct:2,takeProfitPct:4,cooldownBars:1,maxDailyLossPct:3}),Ls=36e5,Hs=30*864e5,Fs=864e5;si=Object.freeze({funding:"fundingRate",open_interest:"openInterest",premium:"premium",oi_delta:"oiDelta",book_imbalance:"bookImbalance"})});import{createHash as ai}from"node:crypto";function pn(e){let t=String(e).toLowerCase();return t==="holdout"||t==="test"||t==="oos"||t.includes("holdout")||t.includes("oos")?!0:t==="testbars"||t.endsWith("testbars")||t.startsWith("test")||t.endsWith("test")?!t.includes("backtest"):!1}function mn(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function Gt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)Gt(t);return Object.freeze(e)}for(let t of Object.keys(e))Gt(e[t]);return Object.freeze(e)}function Ge(e){if(Array.isArray(e))return e.map(Ge);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=Ge(e[r]);return t}return e}function it(e){return JSON.stringify(Ge(e))}function ci(e){let{min:t,max:r,step:n}=e;if(!(n>0)||t>r)return[];let o=[],i=Math.floor((r-t)/n+1e-9);for(let a=0;a<=i;a++){let l=t+a*n;if(l>r+1e-9)break;let f=Math.abs(l-Math.round(l))<1e-9?Math.round(l):Number(l.toPrecision(12));f<t-1e-9||f>r+1e-9||o.push(f)}if(o.length===0)return[];let s=o[o.length-1];if(Math.abs(s-r)>1e-9){let a=(r-t)/n;Math.abs(a-Math.round(a))<=1e-9&&o.push(r)}return o}function li(e,t){if(e.length===0)return[];let r=[{}];for(let n of e){let o=t[n],i=[];for(let s of r)for(let a of o)i.push({...s,[n]:a});r=i}return r.sort((n,o)=>{let i=it(n),s=it(o);return i<s?-1:i>s?1:0}),r}function Vt(e,t,r,n,o){let i=0;if(e==="maxDrawdownPct"){if(i=t.maxDrawdownPct-n.maxDrawdownPct,i!==0)return i<0}else if(i=t[e]-n[e],i!==0)return i>0;let s=it(r),a=it(o);return s<a}function hn(e,t,r={}){if(!mn(r))throw new TypeError("options must be a plain object");for(let x of Object.keys(r))if(pn(x))throw new TypeError(`options must not include holdout/test/oos key "${x}"`);let n=new Set(["maxTrials","objective","backtestOptions"]);for(let x of Object.keys(r))if(!n.has(x))throw new TypeError(`unknown option "${x}"`);let o=64;if("maxTrials"in r){let x=r.maxTrials;if(!Number.isInteger(x)||x<1||x>fn)throw new TypeError(`maxTrials must be an integer 1..${fn}`);o=x}let i=r.objective??"netPnlUsd";if(!dn.has(i))throw new TypeError(`objective must be one of ${[...dn].join("|")}`);let s=r.backtestOptions??{};if(!mn(s))throw new TypeError("backtestOptions must be a plain object");for(let x of Object.keys(s))if(pn(x))throw new TypeError(`backtestOptions must not include holdout/test/oos key "${x}"`);let a=Z(e),l=Object.keys(a.parameters).sort();if(l.length===0)throw new Error("optimizeStrategy requires at least one declared parameter");let f={},u=1;for(let x of l){let R=ci(a.parameters[x]);if(R.length===0)throw new Error(`parameter "${x}" produces an empty grid`);f[x]=R,u*=R.length}let c=li(l,f);if(c.length===0)throw new Error("parameter grid is empty");let d=c.slice(0,o),m=[],p=null,w=null;for(let x of d){let R=ze(a,x),A=me(R,t,s);w==null&&(w=A.config);let h={netPnlUsd:A.metrics.netPnlUsd,netPnlPct:A.metrics.netPnlPct,maxDrawdownPct:A.metrics.maxDrawdownPct,winRate:A.metrics.winRate,profitFactor:A.metrics.profitFactor,tradeCount:A.metrics.tradeCount,sharpe:A.metrics.sharpe,turnoverUsd:A.metrics.turnoverUsd},M={parameters:{...x},metrics:h};m.push(M),(!p||Vt(i,h,x,p.metrics,p.parameters))&&(p=M)}m.sort((x,R)=>Vt(i,x.metrics,x.parameters,R.metrics,R.parameters)?-1:Vt(i,R.metrics,R.parameters,x.metrics,x.parameters)?1:0);let g={...p.parameters},k=ze(a,g),v={strategyHash:_e(a),compilerHash:ke,trainBarsHash:Ue(t),backtestConfig:w,objective:i,maxTrials:o,trialsRun:m.length,candidates:m,bestParameters:g,bestStrategy:k},T={id:ai("sha256").update(JSON.stringify(Ge(v)),"utf8").digest("hex"),...v};return Gt(Ge(JSON.parse(JSON.stringify(T))))}var fn,dn,yn=G(()=>{Se();xe();tt();fn=256,dn=new Set(["netPnlUsd","profitFactor","sharpe","maxDrawdownPct"])});import fe from"node:fs";import at from"node:path";function ct(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function ie(e){return e==null?e:JSON.parse(JSON.stringify(e))}function fi(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function Me(e,t="record"){if(Array.isArray(e)){e.forEach((r,n)=>Me(r,`${t}[${n}]`));return}if(ct(e))for(let[r,n]of Object.entries(e)){let o=fi(r);if(ui.some(i=>o.includes(i)))throw new Error(`shadow-store: forbidden secret-like field at ${t}.${r}`);Me(n,`${t}.${r}`)}}function di(e){if(typeof e!="string"||!e||!at.isAbsolute(e))throw new Error("shadow-store: path must be an absolute path")}function wn(e){let t;try{t=fe.lstatSync(e)}catch(n){if(n&&n.code==="ENOENT")return;throw n}if(t.isSymbolicLink())throw new Error("shadow-store: store path must not be a symlink");if(!t.isFile())throw new Error("shadow-store: store path must be a regular file");if(t.mode&511&18)throw new Error("shadow-store: store file must not be group or world writable")}function pi(){return{version:Yt,runners:[]}}function gn(e,t){let r;try{r=JSON.parse(e)}catch{throw new Error("shadow-store: malformed JSON")}if(!ct(r))throw new Error("shadow-store: malformed JSON root");if(r.version!==Yt)throw new Error(`shadow-store: unsupported version ${r.version}`);if(!Array.isArray(r.runners))throw new Error("shadow-store: runners must be an array");return Me(r,at.basename(t)),{version:Yt,runners:r.runners.map(n=>ie(n))}}function bn(e,t){Me(t,"store");let r=at.dirname(e);fe.mkdirSync(r,{recursive:!0,mode:448});let n=at.join(r,`.shadow-store.${process.pid}.${Date.now()}.tmp`),o=`${JSON.stringify(t)}
3
+ `;try{fe.writeFileSync(n,o,{mode:384,flag:"wx"}),fe.renameSync(n,e);try{fe.chmodSync(e,384)}catch{}}catch(i){try{fe.unlinkSync(n)}catch{}throw i}}function En(e={}){let t=e.path;if(di(t),wn(t),fe.existsSync(t)?gn(fe.readFileSync(t,"utf8"),t):bn(t,pi()),Kt.has(t))return Kt.get(t);let r=!1,n=[];function o(){if(r)return;let p=n.shift();if(p){r=!0;try{let w=p.fn();r=!1,p.resolve(w),o()}catch(w){r=!1,p.reject(w),o()}}}function i(p){if(!r&&n.length===0){r=!0;try{return p()}finally{r=!1,queueMicrotask(o)}}return new Promise((w,g)=>{n.push({fn:p,resolve:w,reject:g}),queueMicrotask(o)})}function s(){return wn(t),gn(fe.readFileSync(t,"utf8"),t)}function a(p){bn(t,p)}function l(p){if(!ct(p)||typeof p.id!="string"||!p.id)throw new Error("shadow-store: create requires record with string id");Me(p,"record");let w=s();if(w.runners.some(k=>k.id===p.id))throw new Error(`shadow-store: runner id already exists: ${p.id}`);let g=ie(p);return w.runners.push(g),a(w),ie(g)}function f(p){let w=s().runners.find(g=>g.id===p);return w?ie(w):null}function u(){return s().runners.map(p=>ie(p))}function c(p,w){if(typeof w!="function")throw new Error("shadow-store: updater must be a function");let g=s(),k=g.runners.findIndex(x=>x.id===p);if(k<0)throw new Error(`shadow-store: runner not found: ${p}`);let v=ie(g.runners[k]),T=w(v);if(!ct(T)||T.id!==p)throw new Error("shadow-store: updater must return record with same id");return Me(T,"record"),g.runners[k]=ie(T),a(g),ie(g.runners[k])}function d(p){let w=s(),g=w.runners.findIndex(v=>v.id===p);if(g<0)throw new Error(`shadow-store: runner not found: ${p}`);let k=ie(w.runners[g]);return k.status!=="stopped"&&(k.status="stopped",w.runners[g]=k,a(w)),ie(w.runners[g])}let m={create(p){return i(()=>l(p))},get(p){return f(p)},list(){return u()},update(p,w){return i(()=>c(p,w))},stop(p){return i(()=>d(p))}};return Kt.set(t,m),m}var Yt,ui,Kt,xn=G(()=>{Yt=1,ui=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"];Kt=new Map});import{createHash as Xt}from"node:crypto";function Wt(e){return e==null?e:JSON.parse(JSON.stringify(e))}function Zt(e){return Array.isArray(e)?e.map(Zt):e&&typeof e=="object"?Object.fromEntries(Object.keys(e).sort().map(t=>[t,Zt(e[t])])):e}function Sn(e){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("shadow-runner: record must be an object");return Xt("sha256").update(JSON.stringify(Zt(e))).digest("hex")}function mi(e,t,r,n,o){return Xt("sha256").update(`${e}|${t}|${r}|${n}|${o}`).digest("hex")}function hi(e,t,r,n){return Xt("sha256").update(`shadow|${e}|${t}|${r}|${n??""}`).digest("hex")}function yi(e){return e==="entryLong"||e==="exitShort"?"buy":e==="entryShort"||e==="exitLong"?"sell":e}function kn(e){return e==="entryLong"||e==="entryShort"}function Qt({storePath:e,clock:t=Date.now}={}){if(typeof e!="string"||!e)throw new Error("shadow-runner: storePath required");let r=En({path:e});function n({strategy:l,evidenceId:f=null}={}){let u=X(l),c=f==null?null:String(f),d=r.list().filter(k=>k.status==="running"&&k.strategyHash===u.strategyHash&&k.compilerHash===u.compilerHash&&k.evidenceId===c).sort((k,v)=>k.createdAt-v.createdAt||k.id.localeCompare(v.id))[0];if(d)return Wt(d);let m=t(),p=hi(m,u.strategyHash,u.compilerHash,c),w=r.get(p);if(w)return Wt(w);let g={id:p,strategy:Wt(u.strategy),strategyHash:u.strategyHash,compilerHash:u.compilerHash,evidenceId:c,status:"running",cursor:null,intendedOrders:[],fills:[],missedFills:[],markouts:[],createdAt:m,updatedAt:m,position:null,cooldownBarsRemaining:0,cooldownStartT:null,lastProcessedBarIndex:-1};return r.create(g)}function o(l){return r.get(l)}function i(){return r.list()}function s(l){return r.stop(l)}function a(l,f,{markoutHorizons:u=[1,4,12]}={}){if(!Array.isArray(f))throw new TypeError("shadow-runner: bars must be an array");return r.update(l,c=>{if(c.status!=="running")throw new Error("shadow-runner: runner is stopped");if(f.length===0)return c;let m=X(c.strategy).evaluateAll(f),p=new Map;for(let y=0;y<f.length;y++)p.set(f[y].t,y);let w=c.cursor,g=[];for(let y=0;y<f.length;y++){let $=f[y].t;(w==null||$>w)&&g.push(y)}if(g.length===0)return c;let k=new Map(c.intendedOrders.map(y=>[y.id,y])),v=new Set(c.fills.map(y=>y.orderId)),T=new Map(c.missedFills.map(y=>[y.orderId,y])),x=(y,$)=>`${y}|${$}`,R=new Map(c.markouts.map(y=>[x(y.orderId,y.horizon),y])),A=c.position?{...c.position}:null,h=Number.isInteger(c.cooldownBarsRemaining)?Math.max(0,c.cooldownBarsRemaining):0,M=Number.isFinite(c.cooldownStartT)?c.cooldownStartT:null;function U({action:y,signalBarT:$,signalIndex:I}){let C=yi(y),L=mi(c.id,c.strategyHash,$,C,y);if(k.has(L))return k.get(L);let j=I+1,P=j<f.length,N={id:L,action:y,type:y,side:C,signalBarT:$,fillBarT:P?f[j].t:null,status:P?"open":"missed"};return k.set(L,N),c.intendedOrders.push(N),N}function Y(y,$,I){if(v.has(y.id))return;let C={orderId:y.id,action:kn(y.action)?"entry":"exit",side:y.side,price:$.o,barT:$.t,signalBarT:y.signalBarT,barIndex:I};if(c.fills.push(C),v.add(y.id),y.status="filled",y.fillBarT=$.t,T.has(y.id)&&(T.delete(y.id),c.missedFills=c.missedFills.filter(L=>L.orderId!==y.id)),kn(y.action)){A={side:y.action==="entryLong"?"long":"short",entryOrderId:y.id,entryBarT:$.t,entryPrice:$.o,entryBarIndex:I};for(let L of u){let j=x(y.id,L);if(R.has(j))continue;let P={orderId:y.id,horizon:L,entryBarT:$.t,entryPrice:$.o,side:A.side,status:"pending",close:null,barT:null};R.set(j,P),c.markouts.push(P)}}else A=null,h=Number(c.strategy?.risk?.cooldownBars)||0,M=$.t}function S(y){if(v.has(y.id)||T.has(y.id))return;let $={orderId:y.id,action:y.action,side:y.side,signalBarT:y.signalBarT,status:"missed"};T.set(y.id,$),c.missedFills.push($),y.status="missed"}for(let y of c.intendedOrders){if(y.status==="filled"||v.has(y.id))continue;let $=p.get(y.signalBarT);if($==null)continue;let I=$+1;I<f.length&&(w==null||f[I].t>w)&&Y(y,f[I],I)}for(let y of g){let $=f[y],I=m[y].signals,C=A,L=P=>{if(A||h>0&&(M==null||$.t>=M))return;let _=U({action:P,signalBarT:$.t,signalIndex:y}),K=y+1;K<f.length?Y(_,f[K],K):S(_)},j=P=>{if(!A||A.side==="long"&&P!=="exitLong"||A.side==="short"&&P!=="exitShort")return;let N=U({action:P,signalBarT:$.t,signalIndex:y}),_=y+1;_<f.length?Y(N,f[_],_):S(N)};C?(I.exitLong&&j("exitLong"),I.exitShort&&j("exitShort")):I.entryLong&&I.entryShort||(I.entryLong&&L("entryLong"),I.entryShort&&L("entryShort")),h>0&&M!=null&&$.t>=M&&(h-=1,h===0&&(M=null)),c.cursor=$.t,c.lastProcessedBarIndex=y}for(let y of c.markouts){if(y.status!=="pending")continue;let $=c.fills.find(L=>L.orderId===y.orderId&&L.action==="entry");if(!$)continue;let I=p.get($.barT);if(I==null)continue;let C=I+y.horizon;if(C<f.length){y.close=f[C].c,y.barT=f[C].t,y.status="filled";let L=y.entryPrice;y.markout=y.side==="long"?(y.close-L)/L:(L-y.close)/L}}return c.position=A,c.cooldownBarsRemaining=h,c.cooldownStartT=M,c.updatedAt=t(),c})}return{start:n,step:a,list:i,get:o,stop:s}}var On=G(()=>{Se();xn()});var An={};Hn(An,{runStrategyOperation:()=>Oi});import wi from"node:os";import gi from"node:path";function Ke(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function Ei(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function tr(e){if(Array.isArray(e)){for(let t of e)tr(t);return}if(Ke(e))for(let[t,r]of Object.entries(e)){if(bi.some(n=>Ei(t).includes(n)))throw new Error(`strategy service: secret-like field "${t}" is forbidden`);tr(r)}}function xi(e){if(!Ke(e))throw new TypeError("strategy input must be a plain object");return tr(e),e}function ki(e,t={}){if(t.nowMs!==void 0){if(!Number.isInteger(t.nowMs))throw new TypeError("nowMs must be an integer epoch milliseconds");return t.nowMs}let r=Date.now();if(e.nowMs===void 0||e.nowMs===null)return r;if(!Number.isInteger(e.nowMs))throw new TypeError("nowMs must be an integer epoch milliseconds");if(Math.abs(e.nowMs-r)>12e4)throw new Error("nowMs outside allowed wall-clock skew (120s); omit nowMs to use server time");return e.nowMs}async function er(e,t,r,n){if(Array.isArray(t.bars))return t.bars;let o=Nt(e.venue),i=r.fetchBars??o.fetchBars;if(typeof i!="function")throw new Error(`strategy venue ${o.id} does not support history`);r.signal?.throwIfAborted?.();let s=await i({coin:e.market.coin,interval:e.market.interval,count:t.count??1500,endTime:t.endTime??n},{signal:r.signal});r.signal?.throwIfAborted?.();let a=Array.isArray(s)?s:s?.bars;if(!Array.isArray(a))throw new Error("strategy history provider returned no bars");return a}function rr(e,t){let r=e.backtestOptions??{};if(!Ke(r))throw new TypeError("backtestOptions must be a plain object");return{...r,nowMs:t}}function Pn(e,t,r,n,o={}){let i=e.evidenceOptions??{};if(!Ke(i))throw new TypeError("evidenceOptions must be a plain object");return{...i,...o,strategy:t,bars:r,backtestOptions:rr(e,n)}}function Tn(){return gi.join(wi.homedir(),".oracle","strategy-shadow.json")}function Si(e,t){return{perStrategyNotionalUsd:e.risk.maxNotionalUsd,maxLeverage:e.risk.maxLeverage,dailyLossCapUsd:e.risk.maxNotionalUsd*(e.risk.maxDailyLossPct/100),chainAllowlist:[e.venue],assetAllowlist:[e.market.coin],expiresAt:Math.min(e.risk.expiresAt,t+864e5),killSwitchRequired:!0}}async function Oi(e,t={},r={}){r.signal?.throwIfAborted?.();let n=xi(t),o=ki(n,r);if(e==="draft")return{strategy:ln(n.prompt,{nowMs:o})};if(e==="validate"){let i=X(n.strategy);if(i.strategy.risk.expiresAt<=o)throw new Error("strategy is expired");return{valid:!0,strategy:i.strategy,strategyHash:i.strategyHash,compilerHash:i.compilerHash,compilerVersion:i.compilerVersion,requiredSeries:i.requiredSeries}}if(e==="backtest"||e==="evidence"){let i=X(n.strategy),s=await er(i.strategy,n,r,o);Ve(i,s);let a=At(Pn(n,i.strategy,s,o));return e==="evidence"?a:{backtest:me(i.strategy,s,rr(n,o)),evidence:a}}if(e==="optimize"){let i=X(n.strategy),s=await er(i.strategy,n,r,o);Ve(i,s);let a=n.trainFraction,l=n.evidenceOptions?.trainFraction;if(a!=null&&l!=null&&a!==l)throw new TypeError("conflicting trainFraction controls are forbidden");let f=a??l??.7;if(typeof f!="number"||f<=0||f>=1)throw new TypeError("trainFraction must be in (0,1)");let u=s.slice(0,Math.floor(s.length*f)),c=n.options??{};if(!Ke(c))throw new TypeError("options must be a plain object");let d=hn(i.strategy,u,{...c,...n.maxTrials==null?{}:{maxTrials:n.maxTrials},backtestOptions:rr(n,o)}),m=d.bestStrategy;return{strategy:m,optimization:d,evidence:At(Pn(n,m,s,o,{trainFraction:f}))}}if(e==="shadow"){let i=Qt({storePath:r.storePath??Tn(),clock:()=>o}),s=n.action;if(s==="start")return await i.start({strategy:n.strategy,evidenceId:n.evidenceId??n.evidence?.id??null});if(s==="list")return await i.list();if(s==="get")return await i.get(n.id);if(s==="stop")return await i.stop(n.id);if(s==="step"){let a=await i.get(n.id);if(!a)throw new Error(`shadow runner not found: ${n.id}`);let l=await er(a.strategy,n,r,o);return Ve(X(a.strategy),l),await i.step(n.id,l,n.stepOptions??{})}throw new Error(`unknown shadow action: ${s}`)}if(e==="prepare"){let i=X(n.strategy),s=Nt(i.strategy.venue);if(typeof n.shadowId!="string"||!n.shadowId)throw new Error("strategy prepare requires a matching shadow runner id");let l=await Qt({storePath:r.storePath??Tn(),clock:()=>o}).get(n.shadowId);if(!l)throw new Error("strategy prepare shadow runner not found");if(l.status!=="running")throw new Error("strategy prepare requires an active shadow runner");if(!Number.isFinite(l.cursor))throw new Error("strategy prepare requires a stepped shadow runner");if(l.strategyHash!==i.strategyHash||l.compilerHash!==i.compilerHash)throw new Error("strategy prepare shadow runner does not match strategy artifacts");if(l.evidenceId!==n.evidence?.id)throw new Error("strategy prepare shadow runner does not match evidence artifact");let f=n.caps??Si(i.strategy,o);return s.prepareIntent({strategy:i.strategy,evidence:n.evidence,shadow:{id:l.id,stateHash:Sn(l),status:l.status,cursor:l.cursor,updatedAt:l.updatedAt},caps:f,nowMs:o,env:r.env??process.env})}throw new Error(`unknown strategy operation: ${e}`)}var bi,$n=G(()=>{tt();Se();$t();un();yn();On();Rt();bi=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});import _n from"node:fs";function Pi(e){let t={},r=[];for(let n=0;n<e.length;n++){let o=e[n];if(!o.startsWith("--")){r.push(o);continue}let i=o.slice(2),s=e[n+1];s!=null&&!s.startsWith("--")?(t[i]=s,n++):t[i]=!0}return{flags:t,positional:r}}function Pe(e,t){if(!e)throw new Error(`${t} path required`);let r=e==="-"?_n.readFileSync(0,"utf8"):_n.readFileSync(e,"utf8");try{return JSON.parse(r)}catch{throw new Error(`${t} must contain valid JSON`)}}function In(e,t){if(e==null)return;let r=Number(e);if(!Number.isFinite(r))throw new Error(`${t} must be a finite number`);return r}var Ti=`oracle strategy <draft|validate|backtest|optimize|evidence|shadow|prepare> [args]
4
4
 
5
5
  oracle strategy draft "Long BTC when the 20 EMA crosses above the 50 EMA"
6
6
  oracle strategy validate strategy.json
@@ -14,5 +14,5 @@ var Mn=Object.defineProperty;var K=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(
14
14
  oracle strategy prepare strategy.json --evidence evidence.json --shadow-id <id> [--caps caps.json]
15
15
 
16
16
  Strategy simulation and shadowing are local and deterministic. Prepare returns an integrity-bound artifact, HMAC-authenticated when local attestation is configured. Sign and broadcast through an approved execution path.
17
- `,Ka={name:"strategy",summary:"deterministic Hyperliquid strategy lab, evidence, shadow, prepare-only handoff",group:"read",usage:"oracle strategy <draft|validate|backtest|optimize|evidence|shadow|prepare> [args]",async run(e){let{flags:t,positional:r}=Oi(e.argv);if(t.help||r.length===0)return process.stdout.write(Pi),0;let[n,...o]=r,{runStrategyOperation:i}=await Promise.resolve().then(()=>(Tn(),An)),s={nowMs:Date.now(),count:_n(t.count,"count")};if(n==="draft")s.prompt=o.join(" ").trim();else if(["validate","backtest","optimize","evidence"].includes(n))s.strategy=Oe(o[0],"strategy"),t.bars&&(s.bars=Oe(t.bars,"bars")),s.maxTrials=_n(t["max-trials"],"max-trials");else if(n==="shadow"){let l=o[0];if(!l)throw new Error("shadow action required");s.action=l,l==="start"&&(s.strategy=Oe(o[1],"strategy")),l==="step"&&(s.id=o[1],t.bars&&(s.bars=Oe(t.bars,"bars"))),l==="stop"&&(s.id=o[1])}else if(n==="prepare")s.strategy=Oe(o[0],"strategy"),s.evidence=Oe(t.evidence,"evidence"),s.shadowId=t["shadow-id"],t.caps&&(s.caps=Oe(t.caps,"caps"));else throw new Error(`unknown strategy operation: ${n}`);let a=await i(n,s);return process.stdout.write(`${JSON.stringify(a,null,2)}
17
+ `,Ka={name:"strategy",summary:"deterministic Hyperliquid strategy lab, evidence, shadow, prepare-only handoff",group:"read",usage:"oracle strategy <draft|validate|backtest|optimize|evidence|shadow|prepare> [args]",async run(e){let{flags:t,positional:r}=Pi(e.argv);if(t.help||r.length===0)return process.stdout.write(Ti),0;let[n,...o]=r,{runStrategyOperation:i}=await Promise.resolve().then(()=>($n(),An)),s={nowMs:Date.now(),count:In(t.count,"count")};if(n==="draft")s.prompt=o.join(" ").trim();else if(["validate","backtest","optimize","evidence"].includes(n))s.strategy=Pe(o[0],"strategy"),t.bars&&(s.bars=Pe(t.bars,"bars")),s.maxTrials=In(t["max-trials"],"max-trials");else if(n==="shadow"){let l=o[0];if(!l)throw new Error("shadow action required");s.action=l,l==="start"&&(s.strategy=Pe(o[1],"strategy")),l==="step"&&(s.id=o[1],t.bars&&(s.bars=Pe(t.bars,"bars"))),l==="stop"&&(s.id=o[1])}else if(n==="prepare")s.strategy=Pe(o[0],"strategy"),s.evidence=Pe(t.evidence,"evidence"),s.shadowId=t["shadow-id"],t.caps&&(s.caps=Pe(t.caps,"caps"));else throw new Error(`unknown strategy operation: ${n}`);let a=await i(n,s);return process.stdout.write(`${JSON.stringify(a,null,2)}
18
18
  `),0}};export{Ka as default};