@oracle-agent/oracle 0.22.12 → 0.22.14

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.
@@ -1,6 +1,6 @@
1
- var ln=Object.defineProperty;var B=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var un=(t,e)=>{for(var r in e)ln(t,r,{get:e[r],enumerable:!0})};import{createHash as fn}from"node:crypto";function hn(t){let e=String(t||"").toLowerCase();return Be.includes(e)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(e)}function yn(t){let e={};for(let[r,n]of Object.entries(t||{}))hn(r)||(e[r]=n);return e}function wn(t,e){if(!t)throw new Error(`HTTP redirect from ${e} missing Location`);let r=new URL(String(t),String(e));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${e} used unsupported protocol ${r.protocol}`);return r.toString()}function gn(t,e){return new URL(String(t)).origin===new URL(String(e)).origin}function bn(t,e,r){let n={};for(let[l,u]of Object.entries(r||{}))n[l.toLowerCase()]=u;let s=Object.keys(n).filter(l=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(l)),o=[...new Set([...Be,...s])].sort().map(l=>`${l}=${n[l]??""}`).join(`
2
- `),i=fn("sha256").update(o).digest("hex").slice(0,32);return`${t} ${e} ${i}`}function En(t,e){let r=Number(e);return Number.isFinite(r)&&r>0?Math.min(r*1e3,qe):Math.min(250*2**t,qe)+Math.floor(Math.random()*100)}async function kn(t,{fetchImpl:e,method:r,headers:n,body:s,timeoutMs:a}){let o=new AbortController,i=setTimeout(()=>o.abort(),a);try{let l=String(t),u={...n||{}};for(let f=0;f<=Ce;f+=1){let c=await e(l,{method:r,headers:u,body:s,signal:o.signal,redirect:"manual"}),d=await c.text(),m=null;if(d)try{m=JSON.parse(d)}catch{m=null}if(mn.has(c.status)){if(r!=="GET"&&r!=="HEAD"){let h=new Error(`HTTP ${c.status} ${r} ${l} redirected non-idempotent request`);throw h.status=c.status,h.body=m??d.slice(0,300),h}if(f===Ce)throw new Error(`HTTP redirect loop for ${t}`);let p=wn(c.headers?.get?.("location"),l);gn(p,l)||(u=yn(u)),l=p;continue}if(!c.ok){let p=new Error(`HTTP ${c.status} ${r} ${l}`);throw p.status=c.status,p.retryAfter=c.headers?.get?.("retry-after")??null,p.body=m??d.slice(0,300),p}return m??d}throw new Error(`HTTP redirect loop for ${t}`)}finally{clearTimeout(i)}}async function ze(t,e={}){let r=e.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=e.timeoutMs??12e3,s=(e.method||"GET").toUpperCase(),a={Accept:"application/json",...e.headers||{}},o=e.body;o!=null&&typeof o!="string"&&(a["Content-Type"]=a["Content-Type"]||"application/json",o=JSON.stringify(o));let i=Number.isInteger(e.retries)?Math.max(e.retries,0):pn,l=async()=>{let m;for(let p=0;p<=i;p++)try{return await kn(t,{fetchImpl:r,method:s,headers:a,body:o,timeoutMs:n})}catch(h){m=h;let E=h?.status,S=h?.name==="AbortError",P=new Set([408,425,429]),T=E!=null?P.has(E)||dn.has(E)&&Ue.has(s):!S&&Ue.has(s);if(p===i||!T)throw h;await xn(En(p,h?.retryAfter))}throw m};if(!(e.dedupe!==!1&&s==="GET"&&o==null))return l();let f=bn(s,t,a),c=Wt.get(f);if(c)return c;let d=l().finally(()=>Wt.delete(f));return Wt.set(f,d),d}var dn,Ue,pn,qe,Be,mn,Ce,Wt,xn,De=B(()=>{dn=new Set([408,425,429,500,502,503,504]),Ue=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),pn=2,qe=4e3,Be=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],mn=new Set([301,302,303,307,308]),Ce=3;Wt=new Map;xn=t=>new Promise(e=>setTimeout(e,t))});function Pn({testnet:t,baseUrl:e}={}){if(e)return e.replace(/\/$/,"").endsWith("/info")?e:`${e.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 t||process.env.HL_TESTNET==="1"?An:Sn}async function Zt(t,e={}){if(!t||!t.type)throw new Error("hlInfo requires body.type");let r=Pn(e);return ze(r,{method:"POST",body:t,fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs})}async function Ve(t={}){return Zt({type:"meta"},t)}async function Je({coin:t,interval:e="1h",startTime:r,endTime:n},s={}){if(!t)throw new Error("hlCandleSnapshot requires coin");let a={type:"candleSnapshot",req:{coin:String(t),interval:e,startTime:r??Date.now()-24*3600*1e3,endTime:n??Date.now()}};return Zt(a,s)}async function Ke({coin:t,startTime:e,endTime:r},n={}){if(!t)throw new Error("hlFundingHistory requires coin");return Zt({type:"fundingHistory",coin:String(t),startTime:e??Date.now()-24*3600*1e3,endTime:r??Date.now()},n)}var Sn,An,Qt=B(()=>{De();Sn="https://api.hyperliquid.xyz/info",An="https://api.hyperliquid-testnet.xyz/info"});import{createHash as $n}from"node:crypto";function tt(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function yt(t){return typeof t=="number"&&Number.isFinite(t)}function re(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)re(e);return Object.freeze(t)}for(let e of Object.keys(t))re(t[e]);return Object.freeze(t)}function ut(t){if(Array.isArray(t))return t.map(ut);if(t!=null&&typeof t=="object"){let e={};for(let r of Object.keys(t).sort())e[r]=ut(t[r]);return e}return t}function te(t){return{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,exposurePct:t.metrics.exposurePct}}function Ye(t){return{feesUsd:t.costs.feesUsd,builderFeesUsd:t.costs.builderFeesUsd,fundingUsd:t.costs.fundingUsd,slippageUsd:t.costs.slippageUsd}}function _n(t){return(t.feesUsd||0)+(t.builderFeesUsd||0)+Math.max(0,t.fundingUsd||0)+(t.slippageUsd||0)}function In(t){let e=0;for(let r of t.trades)r.grossPnlUsd>0&&(e+=r.grossPnlUsd);return e}function On(t,e,r){return!(!t||t.tradeCount<Math.max(1,Math.min(r,3))||!(t.netPnlUsd>0)||!(t.profitFactor>1)||!(t.maxDrawdownPct<=e.maxDailyLossPct))}function Xe(t){if(!tt(t))throw new TypeError("evidence artifact must be a plain object");if(!Tn.includes(t.status))throw new TypeError("evidence artifact status is invalid");for(let e of["strategyHash","compilerHash","barsHash"])if(typeof t[e]!="string"||!/^[0-9a-f]{64}$/.test(t[e]))throw new TypeError(`evidence artifact ${e} must be a sha256 hash`);if(!tt(t.split))throw new TypeError("evidence artifact split required");if(!Array.isArray(t.flags))throw new TypeError("evidence artifact flags must be an array");if(!tt(t.walkForward)||!Array.isArray(t.walkForward.windows))throw new TypeError("evidence artifact walkForward windows required");if(t.status==="pass_live_eligible"&&(!tt(t.train)||!tt(t.holdout)))throw new TypeError("live-eligible evidence artifact requires train and holdout facts");return ut({barsHash:t.barsHash,compilerHash:t.compilerHash,flags:t.flags.map(e=>ut(e)),holdout:t.holdout??null,split:t.split,status:t.status,strategyHash:t.strategyHash,train:t.train??null,walkForward:{passRate:t.walkForward.passRate,windowsRun:t.walkForward.windowsRun??t.walkForward.windows.length,windows:t.walkForward.windows.map(e=>({index:e.index,trainStartIndex:e.trainStartIndex,trainEndIndex:e.trainEndIndex,passed:e.passed,reason:e.reason,evalStartIndex:e.evalStartIndex,evalEndIndex:e.evalEndIndex,metrics:e.metrics}))}})}function We(t){return $n("sha256").update(JSON.stringify(Xe(t)),"utf8").digest("hex")}function G(t,e,r=0){if(!Number.isInteger(t)||t<r)throw new Error(`${e} must be an integer >= ${r}`);return t}function ee(t,e){if(!tt(t)||!tt(t.metrics))throw new Error(`${e} metrics required`);let r=G(t.tradeCount,`${e}.tradeCount`);if(t.metrics.tradeCount!==r)throw new Error(`${e} tradeCount contradicts metrics.tradeCount`);for(let n of["netPnlUsd","profitFactor","maxDrawdownPct"])if(!yt(t.metrics[n]))throw new Error(`${e}.metrics.${n} must be finite`);if(t.metrics.maxDrawdownPct<0)throw new Error(`${e}.metrics.maxDrawdownPct must be >= 0`);return t.metrics}function vn(t,{maxDailyLossPct:e}={}){let r=t.split,n=G(r.trainStartIndex,"split.trainStartIndex"),s=G(r.trainEndIndex,"split.trainEndIndex"),a=G(r.trainBarCount,"split.trainBarCount",1),o=G(r.holdoutStartIndex,"split.holdoutStartIndex"),i=G(r.holdoutEndIndex,"split.holdoutEndIndex"),l=G(r.holdoutBarCount,"split.holdoutBarCount",1);if(n!==0||s-n+1!==a||o!==s+1||i-o+1!==l)throw new Error("evidence split must be contiguous, chronological, and count-consistent");if(!yt(r.trainFraction)||r.trainFraction<=0||r.trainFraction>=1)throw new Error("split.trainFraction must be in (0,1)");ee(t.train,"train");let u=ee(t.holdout,"holdout");if(u.tradeCount<1||u.netPnlUsd<=0||u.profitFactor<=1)throw new Error("live-eligible holdout metrics do not pass");if(yt(e)&&u.maxDrawdownPct>e)throw new Error("live-eligible holdout drawdown exceeds strategy risk");if(t.flags.length>0)throw new Error("live-eligible evidence cannot contain failure flags");let f=t.walkForward,c=f.windows;if(c.length<1||f.windowsRun!==c.length)throw new Error("live-eligible walk-forward windowsRun must match nonempty windows");let d=0,m=-1;for(let h=0;h<c.length;h++){let E=c[h];if(!tt(E)||E.index!==h||typeof E.passed!="boolean")throw new Error("walk-forward windows must be ordered and structurally valid");let S=G(E.trainStartIndex,`walkForward.windows[${h}].trainStartIndex`),P=G(E.trainEndIndex,`walkForward.windows[${h}].trainEndIndex`),T=G(E.evalStartIndex,`walkForward.windows[${h}].evalStartIndex`),x=G(E.evalEndIndex,`walkForward.windows[${h}].evalEndIndex`);if(S!==0||P>=T||T>x||T<=m)throw new Error("walk-forward windows must be chronological and disjoint");if(m=x,E.passed){if(d+=1,E.reason!=="pass")throw new Error("passed walk-forward window reason must be pass");let R=ee({metrics:E.metrics,tradeCount:E.metrics?.tradeCount},`walkForward.windows[${h}]`);if(R.tradeCount<1||R.netPnlUsd<=0||R.profitFactor<=1)throw new Error("passed walk-forward window metrics do not pass");if(yt(e)&&R.maxDrawdownPct>e)throw new Error("passed walk-forward drawdown exceeds strategy risk")}else if(E.reason==="pass")throw new Error("failed walk-forward window cannot have pass reason")}let p=d/c.length;if(!yt(f.passRate)||Math.abs(f.passRate-p)>Number.EPSILON||p<.6)throw new Error("walk-forward passRate contradicts concrete windows or is below live threshold")}function Ze(t,e={}){if(typeof t?.id!="string"||!/^[0-9a-f]{64}$/.test(t.id))throw new Error("evidence.id must be a sha256 evidence artifact hash");let r=Xe(t),n=ut({id:t.id,...r});if(JSON.stringify(ut(t))!==JSON.stringify(n))throw new Error("evidence artifact contains fields unbound from its deterministic identity");let s=We(t);if(t.id!==s)throw new Error("evidence.id does not match its deterministic artifact facts digest");return t.status==="pass_live_eligible"&&vn(t,e),t}function ne({strategy:t,bars:e,backtestOptions:r={},trainFraction:n=.7,walkForwardWindows:s=3,minTrades:a=10}={}){let o=[];if(!tt(t))throw new TypeError("strategy must be a plain object");if(!Array.isArray(e))throw new TypeError("bars must be an array");if(!tt(r))throw new TypeError("backtestOptions must be a plain object");if(!yt(n)||n<=0||n>=1)throw new TypeError("trainFraction must be in (0,1)");if(!Number.isInteger(s)||s<1)throw new TypeError("walkForwardWindows must be a positive integer");if(!Number.isInteger(a)||a<0)throw new TypeError("minTrades must be an integer >= 0");let i=J(t),l=wt(i),u=$t(e),f=e.length,c=(I=[],N={})=>Ge({status:"fail",strategy:i,sHash:l,barsHash:u,split:N.split||{trainStartIndex:0,trainEndIndex:-1,trainBarCount:0,holdoutStartIndex:0,holdoutEndIndex:-1,holdoutBarCount:0,trainFraction:n},train:N.train||null,holdout:N.holdout||null,walkForward:N.walkForward||{windows:[],passRate:0},flags:[...o,...I]});if(f<10)return c([{type:"insufficient_bars",message:"need at least 10 bars for evidence"}]);let d=Math.floor(f*n),m=d,p=f-m;if(d<5||p<3)return c([{type:"invalid_windowing",message:"train/holdout split too small",trainCount:d,holdoutCount:p}]);let h=e.slice(0,d),E=e.slice(m),S,P;try{S=at(i,h,r),P=at(i,E,r)}catch(I){return c([{type:"backtest_error",message:String(I.message||I)}])}let T={metrics:te(S),costs:Ye(S),tradeCount:S.metrics.tradeCount},x={metrics:te(P),costs:Ye(P),tradeCount:P.metrics.tradeCount},R={trainStartIndex:0,trainEndIndex:d-1,trainBarCount:d,holdoutStartIndex:m,holdoutEndIndex:f-1,holdoutBarCount:p,trainFraction:n},_=[],g=Math.floor(f/(s+1));if(g<3)o.push({type:"invalid_windowing",message:"walk-forward window size too small",wfSize:g});else for(let I=0;I<s;I++){let N=g*(I+1),z=N,q=Math.min(f,z+g);if(q-z<3||N<3){_.push({index:I,trainStartIndex:0,trainEndIndex:N-1,evalStartIndex:z,evalEndIndex:q-1,passed:!1,reason:"window_too_small",metrics:null});continue}let Z=e.slice(z,q),jt;try{jt=at(i,Z,r)}catch{_.push({index:I,trainStartIndex:0,trainEndIndex:N-1,evalStartIndex:z,evalEndIndex:q-1,passed:!1,reason:"backtest_error",metrics:null});continue}let Ft=te(jt),Lt=On(Ft,i.risk,a);_.push({index:I,trainStartIndex:0,trainEndIndex:N-1,evalStartIndex:z,evalEndIndex:q-1,passed:Lt,reason:Lt?"pass":"fail_metrics",metrics:Ft})}let V=_.filter(I=>I.passed).length,ot=_.length===0?0:V/_.length,it={windows:_,passRate:ot,windowsRun:_.length};x.metrics.tradeCount===0&&T.metrics.tradeCount===0&&o.push({type:"no_trades",message:"no trades in train or holdout"}),x.metrics.tradeCount===0&&o.push({type:"absent_oos_trades",message:"holdout produced no trades"}),x.metrics.netPnlUsd<0&&o.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?o.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>=a&&o.push({type:"severe_oos_collapse",message:"holdout pnl collapsed vs train"});let W=_n(x.costs),y=In(P);y>0&&W>y&&o.push({type:"costs_exceed_gross",message:"holdout costs exceed gross gains"});let A=o.some(I=>["insufficient_bars","invalid_windowing","absent_oos_trades","holdout_loss","no_trades","severe_oos_collapse","backtest_error"].includes(I.type)),v=o.some(I=>I.type==="overfit"),j="fail";return x.metrics.tradeCount>=a&&x.metrics.netPnlUsd>0&&x.metrics.profitFactor>1&&x.metrics.maxDrawdownPct<=i.risk.maxDailyLossPct&&ot>=.6&&!(y>0&&W>y)&&!v&&!o.some(I=>I.type==="severe_oos_collapse"||I.type==="invalid_windowing")?j="pass_live_eligible":!A&&x.metrics.tradeCount>0&&T.metrics.tradeCount>0&&Number.isFinite(x.metrics.netPnlUsd)?(j="pass_paper_only",x.metrics.tradeCount<a&&o.push({type:"undersampled",message:"holdout trades below minTrades"})):v&&x.metrics.tradeCount>0&&T.metrics.netPnlUsd>0?j="fail":x.metrics.tradeCount>0&&T.metrics.tradeCount>0&&!A?j="pass_paper_only":j="fail",x.metrics.netPnlUsd<0&&(j=j==="pass_live_eligible"?"fail":j==="pass_paper_only"?"pass_paper_only":"fail",j="fail"),Ge({status:j,strategy:i,sHash:l,barsHash:u,split:R,train:T,holdout:x,walkForward:it,flags:o})}function Ge({status:t,strategy:e,sHash:r,barsHash:n,split:s,train:a,holdout:o,walkForward:i,flags:l}){let u={status:t,strategyHash:r,compilerHash:dt,barsHash:n,split:s,train:a,holdout:o,walkForward:i,flags:l};return u.id=We(u),re(ut(JSON.parse(JSON.stringify(u))))}var Tn,se=B(()=>{pt();ft();Ht();Tn=Object.freeze(["fail","pass_paper_only","pass_live_eligible"])});import{createHash as Nn,createHmac as Mn,timingSafeEqual as qo}from"node:crypto";function oe(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?`[${t.map(oe).join(",")}]`:`{${Object.keys(t).sort().map(r=>`${JSON.stringify(r)}:${oe(t[r])}`).join(",")}}`}function Qe(t){let e=String(t?.ORACLE_STAMP_HMAC_SECRET||"").trim();return e.length>=16?e:""}function tr(t=process.env){return Qe(process.env)||Qe(t)}function Fn(t){let{oraclePrepared:e,prepareHash:r,prepareMac:n,note:s,...a}=t||{};return a}function Ln(t){let e=Fn(t);return Nn("sha256").update(oe(e)).digest("hex")}function Hn(t,e=tr()){return e?Mn("sha256",e).update(String(t)).digest("hex"):""}function er(t,{provider:e,kind:r,env:n=process.env}={}){if(!t||typeof t!="object")throw new Error("stampPrepared: payload object required");let s={...t,provider:t.provider||e,kind:t.kind||r,requiresUserSignature:t.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!s.provider)throw new Error("stampPrepared: provider required");if(!s.kind)throw new Error("stampPrepared: kind required");let a=Date.now(),o=a+jn,l={...s,preparedAt:a,expiresAt:o,prepareVersion:Rn},u=Ln(l),f=tr(n),c=f?Hn(u,f):void 0,d={...l,oraclePrepared:!0,prepareHash:u};return c&&(d.prepareMac=c),d}var Rn,jn,Co,rr=B(()=>{Rn=2,jn=300*1e3,Co=(()=>{let t=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(t)&&t>0?t:1800*1e3})()});function Tt(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function qn(t){return String(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function ae(t,e="value"){if(Array.isArray(t)){t.forEach((r,n)=>ae(r,`${e}[${n}]`));return}if(Tt(t))for(let[r,n]of Object.entries(t)){let s=qn(r);if(Un.some(a=>s.includes(a)))throw new Error(`handoff: forbidden secret-like field at ${e}.${r}`);ae(n,`${e}.${r}`)}}function ie(t){return typeof t=="number"&&Number.isFinite(t)&&t>0}function nr({strategy:t,evidence:e,shadow:r,caps:n,nowMs:s=Date.now(),env:a=process.env}={}){if(ae({strategy:t,evidence:e,shadow:r,caps:n},"handoff"),!Tt(t))throw new Error("handoff: strategy required");if(!Tt(e))throw new Error("handoff: evidence required");if(!Tt(r))throw new Error("handoff: shadow required");if(!Tt(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>s)throw new Error("handoff: shadow.updatedAt must be a positive integer <= nowMs");let o=J(t,{nowMs:s}),i=K(o);if(Ze(e,{maxDailyLossPct:o.risk.maxDailyLossPct}),e.status!=="pass_live_eligible")throw new Error("handoff: evidence.status must be pass_live_eligible");if(e.strategyHash!==i.strategyHash)throw new Error("handoff: evidence.strategyHash mismatch");if(e.compilerHash!==i.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(!ie(n.perStrategyNotionalUsd))throw new Error("handoff: caps.perStrategyNotionalUsd must be positive");if(n.perStrategyNotionalUsd>i.strategy.risk.maxNotionalUsd)throw new Error("handoff: caps.perStrategyNotionalUsd exceeds strategy.risk.maxNotionalUsd");if(!ie(n.maxLeverage))throw new Error("handoff: caps.maxLeverage must be positive");if(n.maxLeverage>i.strategy.risk.maxLeverage)throw new Error("handoff: caps.maxLeverage exceeds strategy.risk.maxLeverage");if(!ie(n.dailyLossCapUsd))throw new Error("handoff: caps.dailyLossCapUsd must be positive");let u=i.strategy.risk.maxNotionalUsd*(i.strategy.risk.maxDailyLossPct/100);if(n.dailyLossCapUsd>u)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]!==i.strategy.market.coin)throw new Error("handoff: caps.assetAllowlist must contain only the strategy market coin");if(!Number.isInteger(n.expiresAt)||!(n.expiresAt>s))throw new Error("handoff: caps.expiresAt must be an integer > nowMs");if(n.expiresAt>i.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 f={perStrategyNotionalUsd:n.perStrategyNotionalUsd,maxLeverage:n.maxLeverage,dailyLossCapUsd:n.dailyLossCapUsd,chainAllowlist:[...n.chainAllowlist],assetAllowlist:[...n.assetAllowlist],expiresAt:n.expiresAt,killSwitchRequired:!0},c={strategyHash:i.strategyHash,compilerHash:i.compilerHash,evidence:JSON.parse(JSON.stringify(e)),shadow:{id:r.id,stateHash:r.stateHash,status:r.status,cursor:r.cursor,updatedAt:r.updatedAt},compiled:{strategyHash:i.strategyHash,compilerHash:i.compilerHash,compilerVersion:_t,venue:"hyperliquid",market:{coin:i.strategy.market.coin,kind:"perp",interval:i.strategy.market.interval},risk:{...i.strategy.risk},strategy:JSON.parse(JSON.stringify(i.strategy))},arming:{liveBroadcast:!1,requiresExplicitUserArm:!0,caps:f},requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,executionReady:!1};return er(c,{provider:"hl-strategy",kind:"strategy-live-handoff",env:a})}var Un,sr=B(()=>{pt();se();ft();rr();Un=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});function gt(t,e){let r=Number(t);if(!Number.isFinite(r))throw new TypeError(`${e} must be finite`);return r}function bt(t,e){if(!Number.isSafeInteger(t)||t<0)throw new TypeError(`${e} must be a non-negative safe integer`);return t}function It(t){if(Array.isArray(t))for(let e of t)It(e);else if(t&&typeof t=="object")for(let e of Object.values(t))It(e);return Object.freeze(t)}function Bn(t){let e=Cn[t];if(!e)throw new TypeError(`unsupported strategy interval: ${t}`);return e}function zn(t,{endTime:e=Number.MAX_SAFE_INTEGER}={}){if(!Array.isArray(t))throw new TypeError("Hyperliquid candles must be an array");bt(e,"endTime");let r=new Map;for(let n=0;n<t.length;n++){let s=t[n];if(!s||typeof s!="object"||Array.isArray(s))throw new TypeError(`candles[${n}] must be an object`);let a=bt(Number(s.t),`candles[${n}].t`);if(bt(Number(s.T),`candles[${n}].T`)>e)continue;let i={t:a,o:gt(s.o,`candles[${n}].o`),h:gt(s.h,`candles[${n}].h`),l:gt(s.l,`candles[${n}].l`),c:gt(s.c,`candles[${n}].c`),v:gt(s.v,`candles[${n}].v`)};if(i.h<Math.max(i.o,i.c,i.l))throw new TypeError(`candles[${n}].h is below another price`);if(i.l>Math.min(i.o,i.c,i.h))throw new TypeError(`candles[${n}].l is above another price`);if(i.v<0)throw new TypeError(`candles[${n}].v must be non-negative`);let l=r.get(a);if(l&&JSON.stringify(l)!==JSON.stringify(i))throw new TypeError(`conflicting duplicate candle at timestamp ${a}`);l||r.set(a,i)}return It([...r.values()].sort((n,s)=>n.t-s.t))}function Dn(t,e){if(!Array.isArray(t))throw new TypeError("Hyperliquid funding history must be an array");let r=new Map;for(let n=0;n<t.length;n++){let s=t[n];if(!s||typeof s!="object"||Array.isArray(s))throw new TypeError(`funding[${n}] must be an object`);let a=bt(Number(s.time),`funding[${n}].time`);a>e||r.set(a,{time:a,fundingRate:gt(s.fundingRate,`funding[${n}].fundingRate`)})}return[...r.values()].sort((n,s)=>n.time-s.time)}async function Vn({coin:t,startTime:e,endTime:r},n){let s=[],a=Math.max(0,e-288e5),o=!1;for(let i=0;i<16&&a<=r;i++){let l=await Ke({coin:t,startTime:a,endTime:r},n);if(!Array.isArray(l))throw new TypeError("Hyperliquid funding history must be an array");s.push(...l);let u=a;for(let f of l){let c=Number(f?.time);Number.isSafeInteger(c)&&c>u&&(u=c)}if(l.length<500||u>=r){o=!0;break}if(u<=a)throw new Error("Hyperliquid funding history pagination did not advance");a=u+1}if(!o)throw new Error("strategy history exceeds the bounded funding history limit");return Dn(s,r)}function Jn(t,e,r){let n=0,s=null;return t.map(a=>{let o=a.t+r,i=0;for(;n<e.length&&e[n].time<o;){let l=e[n];s=l.fundingRate,l.time>=a.t&&(i+=l.fundingRate),n+=1}return s==null?{...a,fundingPaymentRate:i}:{...a,fundingRate:s,fundingPaymentRate:i}})}async function or(t,e={}){if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("strategy history input must be an object");let r=String(t.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(t.interval||"15m"),s=Bn(n);if(t.endTime==null)throw new TypeError("endTime is required for deterministic history");let a=bt(t.endTime,"endTime"),o=t.count==null?1500:t.count;if(!Number.isInteger(o)||o<20||o>5e3)throw new TypeError("count must be an integer from 20 to 5000");let i=t.startTime==null?Math.max(0,a-o*s):bt(t.startTime,"startTime");if(i>=a)throw new TypeError("startTime must be before endTime");let[l,u]=await Promise.all([Je({coin:r,interval:n,startTime:i,endTime:a},e),Vn({coin:r,startTime:i,endTime:a},e)]),f=zn(l,{endTime:a}),c=It(Jn(f,u,s));return It({coin:r,interval:n,range:{startTime:i,endTime:a},bars:c})}var Cn,ir=B(()=>{Qt();Cn=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 Gn(t){let e=[];if(!t||typeof t!="object"||Array.isArray(t))return{ok:!1,errors:[{path:"market",message:"must be a plain object"}],market:null};for(let r of Object.keys(t))Yn.has(r)||e.push({path:`market.${r}`,message:"unknown field is not allowed"});return(typeof t.coin!="string"||t.coin.length===0||t.coin.length>32)&&e.push({path:"market.coin",message:"must be a non-empty string max 32"}),(typeof t.interval!="string"||!Kn.has(t.interval))&&e.push({path:"market.interval",message:"must be a supported interval"}),e.length?{ok:!1,errors:e,market:null}:{ok:!0,errors:[],market:{coin:t.coin,interval:t.interval}}}async function Xn(t={}){let e=await Ve(t);if(!e||!Array.isArray(e.universe))throw new TypeError("Hyperliquid market metadata must contain universe");return Object.freeze(e.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 Kn,Yn,ar,cr=B(()=>{Qt();sr();ir();Kn=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),Yn=new Set(["coin","interval"]);ar=Object.freeze({id:"hyperliquid",validateMarket:Gn,fetchBars:or,listMarkets:Xn,prepareIntent(t){return nr(t)}})});function Zn(t){if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("strategy venue adapter must be an object");if(typeof t.id!="string"||!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t.id))throw new TypeError("strategy venue adapter id is malformed");for(let e of Wn.slice(1))if(typeof t[e]!="function")throw new TypeError(`strategy venue adapter ${t.id} requires ${e}()`);for(let e of["fetchBars","listMarkets"])if(t[e]!=null&&typeof t[e]!="function")throw new TypeError(`strategy venue adapter ${t.id} ${e} must be a function`);return t}function ce(t){return typeof t!="string"?null:Qn.get(t)??null}function le(t){let e=ce(t);if(!e)throw new Error(`unknown strategy venue: ${String(t)}`);return e}var Wn,lr,Qn,ei,ue=B(()=>{cr();Wn=Object.freeze(["id","validateMarket","prepareIntent"]);lr=[ar].map(Zn),Qn=new Map(lr.map(t=>[t.id,t])),ei=Object.freeze([...lr])});import{createHash as ts}from"node:crypto";function Y(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function U(t){return typeof t=="number"&&Number.isFinite(t)}function wr(t){return Number.isInteger(t)&&t>0}function he(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)he(e);return Object.freeze(t)}for(let e of Object.keys(t))he(t[e]);return Object.freeze(t)}function ye(t){if(Array.isArray(t))return t.map(ye);if(t!=null&&typeof t=="object"){let e={};for(let r of Object.keys(t).sort())e[r]=ye(t[r]);return e}return t}function w(t,e,r){t.push({path:e,message:r})}function ct(t,e,r,n){for(let s of Object.keys(t))e.has(s)||w(n,r?`${r}.${s}`:s,"unknown field is not allowed")}function xr(t,e,r,n){if(!U(t)||!U(e)||!U(r)||!U(n)||n<=0||t<e||t>r)return!1;let s=(t-e)/n;if(!Number.isFinite(s))return!1;let a=Math.round(s);return Math.abs(s-a)<=1e-9}function me(t,e,r,n){if(Y(t)){if(ct(t,new Set(["param"]),e,n),typeof t.param!="string"||!t.param)return w(n,`${e}.param`,"must be a parameter name string"),null;if(!Object.prototype.hasOwnProperty.call(r,t.param))return w(n,`${e}.param`,`unknown parameter "${t.param}"`),null;let s=r[t.param];return!Y(s)||![s.value,s.min,s.max,s.step].every(wr)?(w(n,`${e}.param`,"referenced period parameter value min max and step must be positive integers"),null):{param:t.param}}return wr(t)?t:(w(n,e,"must be a positive integer or {param}"),null)}function gr(t,e,r,n){return Y(t)?(ct(t,new Set(["param"]),e,n),typeof t.param!="string"||!t.param?(w(n,`${e}.param`,"must be a parameter name string"),null):Object.prototype.hasOwnProperty.call(r,t.param)?{param:t.param}:(w(n,`${e}.param`,`unknown parameter "${t.param}"`),null)):U(t)?t:(w(n,e,"must be a finite number or {param}"),null)}function Ut(t){switch(t.type){case"input":case"constant":return[];case"indicator":return t.input?[t.input]:[];case"compare":case"cross":return[t.left,t.right].filter(Boolean);case"logic":return Array.isArray(t.inputs)?[...t.inputs]:[];default:return[]}}function ls(t){let e=new Map,r=n=>{let s=e.get(n)||0;if(s===1)return!0;if(s===2)return!1;e.set(n,1);let a=t.get(n);if(a){for(let o of Ut(a))if(t.has(o)&&r(o))return!0}return e.set(n,2),!1};for(let n of t.keys())if(r(n))return!0;return!1}function us(t,e){if(!Y(t))return w(e,"parameters","must be a plain object"),null;let r=Object.keys(t);if(r.length>mr)return w(e,"parameters",`too many parameters (max ${mr})`),null;let n={};for(let s of r){if(!br.test(s)){w(e,`parameters.${s}`,"parameter name is malformed");continue}let a=t[s],o=`parameters.${s}`;if(!Y(a)){w(e,o,"must be a plain object");continue}ct(a,fr,o,e);for(let c of fr)c in a||w(e,`${o}.${c}`,"required field is missing");let{value:i,min:l,max:u,step:f}=a;U(l)||w(e,`${o}.min`,"must be a finite number"),U(u)||w(e,`${o}.max`,"must be a finite number"),(!U(f)||f<=0)&&w(e,`${o}.step`,"must be a positive finite number"),U(i)||w(e,`${o}.value`,"must be a finite number"),U(l)&&U(u)&&l>u&&w(e,`${o}.min`,"min must be <= max"),U(i)&&U(l)&&U(u)&&U(f)&&f>0&&(xr(i,l,u,f)||w(e,`${o}.value`,"value must lie on the declared min/max/step grid")),n[s]={value:i,min:l,max:u,step:f}}return n}function fs(t,e,r,n){let s=`nodes.${e}`;if(!Y(t))return w(n,s,"must be a plain object"),null;if(typeof t.type!="string"||!pr[t.type])return w(n,`${s}.type`,"unknown or missing node type"),ct(t,cs,s,n),null;switch(ct(t,pr[t.type],s,n),(typeof t.id!="string"||!Er.test(t.id))&&w(n,`${s}.id`,"must be a 1-64 char id starting with alphanumeric"),t.type){case"input":return(typeof t.field!="string"||!es.has(t.field))&&w(n,`${s}.field`,"must be one of open|high|low|close|volume|fundingRate|openInterest"),{id:t.id,type:"input",field:t.field};case"constant":{let a=gr(t.value,`${s}.value`,r,n);return{id:t.id,type:"constant",value:a}}case"indicator":{(typeof t.indicator!="string"||!rs.has(t.indicator))&&w(n,`${s}.indicator`,"must be one of sma|ema|rsi|macd|bollinger|atr");let a=t.indicator,o={id:t.id,type:"indicator",indicator:a};if(a==="atr"){"input"in t&&(typeof t.input!="string"||!t.input?w(n,`${s}.input`,"must be a node id string when provided"):o.input=t.input);let i=me(t.period,`${s}.period`,r,n);i!=null&&(o.period=i)}else typeof t.input!="string"||!t.input?w(n,`${s}.input`,"must be a node id string"):o.input=t.input;if((a==="sma"||a==="ema"||a==="rsi"||a==="bollinger"||a==="atr")&&("period"in t,a!=="macd"))if(!("period"in t))w(n,`${s}.period`,"required field is missing");else{let i=me(t.period,`${s}.period`,r,n);i!=null&&(o.period=i)}if(a==="macd"){for(let i of["fastPeriod","slowPeriod","signalPeriod"])if(!(i in t))w(n,`${s}.${i}`,"required field is missing");else{let l=me(t[i],`${s}.${i}`,r,n);l!=null&&(o[i]=l)}"output"in t?is.has(t.output)?o.output=t.output:w(n,`${s}.output`,"must be line|signal|histogram"):w(n,`${s}.output`,"required field is missing"),"period"in t&&w(n,`${s}.period`,"forbidden for macd"),"stdDev"in t&&w(n,`${s}.stdDev`,"forbidden for macd")}else if(a==="bollinger"){if(!("stdDev"in t))w(n,`${s}.stdDev`,"required field is missing");else{let i=gr(t.stdDev,`${s}.stdDev`,r,n);i!=null&&(typeof i=="number"&&i<=0?w(n,`${s}.stdDev`,"must be > 0"):o.stdDev=i)}"output"in t?as.has(t.output)?o.output=t.output:w(n,`${s}.output`,"must be upper|middle|lower"):w(n,`${s}.output`,"required field is missing");for(let i of["fastPeriod","slowPeriod","signalPeriod"])i in t&&w(n,`${s}.${i}`,`forbidden for ${a}`)}else{"output"in t&&w(n,`${s}.output`,`forbidden for ${a}`),"stdDev"in t&&a!=="bollinger"&&w(n,`${s}.stdDev`,`forbidden for ${a}`);for(let i of["fastPeriod","slowPeriod","signalPeriod"])i in t&&w(n,`${s}.${i}`,`forbidden for ${a}`)}return o}case"compare":return(typeof t.op!="string"||!ns.has(t.op))&&w(n,`${s}.op`,"must be gt|gte|lt|lte|eq"),(typeof t.left!="string"||!t.left)&&w(n,`${s}.left`,"must be a node id"),(typeof t.right!="string"||!t.right)&&w(n,`${s}.right`,"must be a node id"),{id:t.id,type:"compare",op:t.op,left:t.left,right:t.right};case"logic":{if((typeof t.op!="string"||!ss.has(t.op))&&w(n,`${s}.op`,"must be and|or|not"),!Array.isArray(t.inputs))return w(n,`${s}.inputs`,"must be an array of node ids"),{id:t.id,type:"logic",op:t.op,inputs:[]};let a=[];for(let o=0;o<t.inputs.length;o++){let i=t.inputs[o];typeof i!="string"||!i?w(n,`${s}.inputs.${o}`,"must be a node id"):a.push(i)}return t.op==="not"?a.length!==1&&w(n,`${s}.inputs`,"not requires exactly one input"):(t.op==="and"||t.op==="or")&&a.length<2&&w(n,`${s}.inputs`,`${t.op} requires at least two inputs`),{id:t.id,type:"logic",op:t.op,inputs:a}}case"cross":return(typeof t.direction!="string"||!os.has(t.direction))&&w(n,`${s}.direction`,"must be above|below"),(typeof t.left!="string"||!t.left)&&w(n,`${s}.left`,"must be a node id"),(typeof t.right!="string"||!t.right)&&w(n,`${s}.right`,"must be a node id"),{id:t.id,type:"cross",direction:t.direction,left:t.left,right:t.right};default:return null}}function ds(t,e,r){if(!Y(t))return w(e,"risk","must be a plain object"),null;ct(t,dr,"risk",e);for(let d of dr)(!(d in t)||t[d]==null)&&w(e,`risk.${d}`,"required field is missing");let n={},s=t.maxLeverage;!U(s)||s<=0||s>50?w(e,"risk.maxLeverage","must be a number > 0 and <= 50"):n.maxLeverage=s;let a=t.maxNotionalUsd;!U(a)||a<=0?w(e,"risk.maxNotionalUsd","must be a number > 0"):n.maxNotionalUsd=a;let o=t.positionSizePct;!U(o)||o<=0||o>100?w(e,"risk.positionSizePct","must be a number > 0 and <= 100"):n.positionSizePct=o;let i=t.stopLossPct;!U(i)||i<=0||i>100?w(e,"risk.stopLossPct","must be a number > 0 and <= 100"):n.stopLossPct=i;let l=t.takeProfitPct;!U(l)||l<=0||l>1e3?w(e,"risk.takeProfitPct","must be a number > 0 and <= 1000"):n.takeProfitPct=l;let u=t.cooldownBars;!Number.isInteger(u)||u<0||u>1e5?w(e,"risk.cooldownBars","must be an integer >= 0 and <= 100000"):n.cooldownBars=u;let f=t.maxDailyLossPct;!U(f)||f<=0||f>100?w(e,"risk.maxDailyLossPct","must be a number > 0 and <= 100"):n.maxDailyLossPct=f;let c=t.expiresAt;return!Number.isInteger(c)||c<=0?w(e,"risk.expiresAt","must be an integer epoch milliseconds > 0"):(r.nowMs!==void 0&&(Number.isInteger(r.nowMs)?c<=r.nowMs&&w(e,"risk.expiresAt","must be strictly greater than nowMs"):w(e,"nowMs","must be an integer epoch milliseconds")),n.expiresAt=c),n}function we(t,e={}){let r=[];if(!Y(t))return w(r,"","strategy must be a plain object"),{ok:!1,errors:r,strategy:null};ct(t,ur,"",r);for(let c of ur)(!(c in t)||t[c]==null)&&w(r,c,"required field is missing");t.version!==fe&&w(r,"version",`must be ${fe}`),(typeof t.id!="string"||!br.test(t.id))&&w(r,"id","must match /^[a-z0-9][a-z0-9._-]{0,63}$/"),(typeof t.name!="string"||t.name.length===0||t.name.length>yr)&&w(r,"name",`must be a non-empty string max ${yr}`);let n=ce(t.venue);n||w(r,"venue",`unknown strategy venue "${String(t.venue)}"`);let s=null;if(!n)Y(t.market)||w(r,"market","must be a plain object");else{let c=n.validateMarket(t.market);if(!c||typeof c.ok!="boolean"||!Array.isArray(c.errors))w(r,"market",`venue ${n.id} returned an invalid market validation result`);else if(c.ok)s=c.market;else for(let d of c.errors)w(r,d.path,d.message)}let a=us(t.parameters,r),o=null,i=new Map;if(!Array.isArray(t.nodes))w(r,"nodes","must be an array");else if(t.nodes.length>hr)w(r,"nodes",`too many nodes (max ${hr})`);else{o=[];for(let c=0;c<t.nodes.length;c++){let d=fs(t.nodes[c],c,a||{},r);d&&(typeof d.id=="string"&&Er.test(d.id)&&(i.has(d.id)?w(r,`nodes.${c}.id`,`duplicate node id "${d.id}"`):i.set(d.id,d)),o.push(d))}for(let c=0;c<o.length;c++){let d=o[c],m=`nodes.${c}`;for(let p of Ut(d))i.has(p)||w(r,m,`unknown node ref "${p}"`);if(d.type==="indicator"||d.type==="compare"||d.type==="cross")for(let p of Ut(d)){let h=i.get(p);h&&de.has(h.type)&&w(r,m,`node ref "${p}" must be numeric`)}if(d.type==="logic")for(let p of Ut(d)){let h=i.get(p);h&&!de.has(h.type)&&w(r,m,`node ref "${p}" must be boolean`)}}ls(i)&&w(r,"nodes","graph contains a cycle")}let l=null;if(!Y(t.rules))w(r,"rules","must be a plain object");else{ct(t.rules,pe,"rules",r);for(let c of pe)c in t.rules||w(r,`rules.${c}`,"required field is missing");l={};for(let c of pe){let d=t.rules[c];if(d===null){l[c]=null;continue}if(typeof d!="string"||!d){w(r,`rules.${c}`,"must be a node id or null"),l[c]=d;continue}if(!i.has(d)){w(r,`rules.${c}`,`unknown node ref "${d}"`),l[c]=d;continue}let m=i.get(d);de.has(m.type)||w(r,`rules.${c}`,`rule must reference a boolean node, not ${m.type}`),l[c]=d}}let u=ds(t.risk,r,e);if(r.length)return{ok:!1,errors:r,strategy:null};let f=he({version:fe,id:t.id,name:t.name,venue:n.id,market:s,parameters:a,nodes:o,rules:l,risk:u});return{ok:!0,errors:[],strategy:f}}function J(t,e={}){let r=we(t,e);if(!r.ok)throw new Et(r.errors);return r.strategy}function ps(t){let e=J(t);return JSON.stringify(ye(e))}function wt(t){let e=ps(t);return ts("sha256").update(e,"utf8").digest("hex")}function Ot(t,e){if(!Y(t))throw new Et([{path:"",message:"strategy must be a plain object"}]);if(!Y(e))throw new Et([{path:"overrides",message:"must be a plain object"}]);let r=J(t),n={};for(let[a,o]of Object.entries(r.parameters))n[a]={value:o.value,min:o.min,max:o.max,step:o.step};let s=[];for(let[a,o]of Object.entries(e)){if(!Object.prototype.hasOwnProperty.call(n,a)){w(s,a,`unknown parameter "${a}"`);continue}let i=n[a];if(!U(o)){w(s,a,"override must be a finite number");continue}if(!xr(o,i.min,i.max,i.step)){w(s,a,"override must lie on the declared min/max/step grid");continue}n[a]={...i,value:o}}if(s.length)throw new Et(s);return J({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(a=>{let o={...a};return Array.isArray(a.inputs)&&(o.inputs=[...a.inputs]),o}),rules:{...r.rules},risk:{...r.risk}})}var fe,br,Er,es,rs,ns,ss,os,is,as,de,ur,fr,pe,dr,cs,pr,mr,hr,yr,Et,ft=B(()=>{ue();fe=1,br=/^[a-z0-9][a-z0-9._-]{0,63}$/,Er=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/,es=new Set(["open","high","low","close","volume","fundingRate","openInterest"]),rs=new Set(["sma","ema","rsi","macd","bollinger","atr"]),ns=new Set(["gt","gte","lt","lte","eq"]),ss=new Set(["and","or","not"]),os=new Set(["above","below"]),is=new Set(["line","signal","histogram"]),as=new Set(["upper","middle","lower"]),de=new Set(["compare","logic","cross"]),ur=new Set(["version","id","name","venue","market","parameters","nodes","rules","risk"]),fr=new Set(["value","min","max","step"]),pe=new Set(["entryLong","entryShort","exitLong","exitShort"]),dr=new Set(["maxLeverage","maxNotionalUsd","positionSizePct","stopLossPct","takeProfitPct","cooldownBars","maxDailyLossPct","expiresAt"]),cs=new Set(["id","type"]),pr={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"])},mr=16,hr=128,yr=100,Et=class extends Error{constructor(e){let r=e.map(n=>`${n.path}: ${n.message}`);super(`invalid strategy (${e.length} error${e.length===1?"":"s"}): ${r.join("; ")}`),this.name="StrategyValidationError",this.errors=e}}});function vt(t){if(!Array.isArray(t))throw new TypeError("values must be an array");for(let e=0;e<t.length;e++){let r=t[e];if(typeof r!="number"||!Number.isFinite(r))throw new TypeError(`values[${e}] must be a finite number`)}}function lt(t){if(!Number.isInteger(t)||t<=0)throw new TypeError("period must be a positive integer")}function ms(t){if(!Array.isArray(t))throw new TypeError("bars must be an array");for(let e=0;e<t.length;e++){let r=t[e];if(r==null||typeof r!="object")throw new TypeError(`bars[${e}] must be an object`);for(let n of["o","h","l","c"]){let s=r[n];if(typeof s!="number"||!Number.isFinite(s))throw new TypeError(`bars[${e}].${n} must be a finite number`)}if(r.h<r.l)throw new TypeError(`bars[${e}] high must be >= low`)}}function Sr(t,e){vt(t),lt(e);let r=new Array(t.length).fill(null);if(t.length<e)return r;let n=0;for(let s=0;s<t.length;s++)n+=t[s],s>=e&&(n-=t[s-e]),s>=e-1&&(r[s]=n/e);return r}function qt(t,e){vt(t),lt(e);let r=new Array(t.length).fill(null);if(t.length<e)return r;let n=0;for(let o=0;o<e;o++)n+=t[o];let s=n/e;r[e-1]=s;let a=2/(e+1);for(let o=e;o<t.length;o++)s=a*t[o]+(1-a)*s,r[o]=s;return r}function Ar(t,e){vt(t),lt(e);let r=new Array(t.length).fill(null);if(t.length<=e)return r;let n=0,s=0;for(let i=1;i<=e;i++){let l=t[i]-t[i-1];l>=0?n+=l:s-=l}let a=n/e,o=s/e;r[e]=kr(a,o);for(let i=e+1;i<t.length;i++){let l=t[i]-t[i-1],u=l>0?l:0,f=l<0?-l:0;a=(a*(e-1)+u)/e,o=(o*(e-1)+f)/e,r[i]=kr(a,o)}return r}function kr(t,e){return t===0&&e===0?50:e===0?100:t===0?0:100-100/(1+t/e)}function Pr(t,e={}){vt(t);let r=e.fastPeriod,n=e.slowPeriod,s=e.signalPeriod;if(lt(r),lt(n),lt(s),r>=n)throw new TypeError("fastPeriod must be < slowPeriod");let a=qt(t,r),o=qt(t,n),i=new Array(t.length).fill(null);for(let c=0;c<t.length;c++)a[c]!=null&&o[c]!=null&&(i[c]=a[c]-o[c]);let l=new Array(t.length).fill(null),u=new Array(t.length).fill(null),f=[];for(let c=0;c<i.length;c++)i[c]!=null&&f.push(c);if(f.length>=s){let c=0;for(let h=0;h<s;h++)c+=i[f[h]];let d=c/s,m=f[s-1];l[m]=d,u[m]=i[m]-d;let p=2/(s+1);for(let h=s;h<f.length;h++){let E=f[h];d=p*i[E]+(1-p)*d,l[E]=d,u[E]=i[E]-d}}return{line:i,signal:l,histogram:u}}function $r(t,e={}){vt(t);let r=e.period,n=e.stdDev;if(lt(r),typeof n!="number"||!Number.isFinite(n)||n<=0)throw new TypeError("stdDev must be a finite number > 0");let s=new Array(t.length).fill(null),a=new Array(t.length).fill(null),o=new Array(t.length).fill(null);if(t.length<r)return{upper:a,middle:s,lower:o};let i=0,l=0;for(let u=0;u<t.length;u++){let f=t[u];if(i+=f,l+=f*f,u>=r){let c=t[u-r];i-=c,l-=c*c}if(u>=r-1){let c=i/r,d=l/r-c*c;d<0&&d>-1e-12&&(d=0);let m=Math.sqrt(d);s[u]=c,a[u]=c+n*m,o[u]=c-n*m}}return{upper:a,middle:s,lower:o}}function Tr(t,e){ms(t),lt(e);let r=new Array(t.length).fill(null);if(t.length<e)return r;let n=new Array(t.length);for(let o=0;o<t.length;o++){let i=t[o];if(o===0)n[o]=i.h-i.l;else{let l=t[o-1].c;n[o]=Math.max(i.h-i.l,Math.abs(i.h-l),Math.abs(i.l-l))}}let s=0;for(let o=0;o<e;o++)s+=n[o];let a=s/e;r[e-1]=a;for(let o=e;o<t.length;o++)a=(a*(e-1)+n[o])/e,r[o]=a;return r}var _r=B(()=>{});import{createHash as hs}from"node:crypto";var ge,ys,ws,gs,Ir,Or=B(()=>{ge=2,ys="93f9c998260e73756c13871dc1a84dd6cdb26ec6113bd1941f023519939db440",ws="68f5b412a9975f04024cf9b9b6209b4bccedd52f176e95f34f786b3f53479c6a",gs="f197a38ff1c0f4ebe13326db8cbb8167ea3dd5d62e6033fe97c2fee8d23d96b5",Ir=hs("sha256").update(JSON.stringify({version:ge,compilerSourceHash:ys,indicatorsSourceHash:ws,schemaSourceHash:gs})).digest("hex")});function X(t){return typeof t=="number"&&Number.isFinite(t)}function xs(t){let e=new Map(t.map(i=>[i.id,i])),r=i=>{switch(i.type){case"indicator":return i.input?[i.input]:[];case"compare":case"cross":return[i.left,i.right];case"logic":return[...i.inputs];default:return[]}},n=new Map,s=new Map;for(let i of t)n.set(i.id,0),s.set(i.id,[]);for(let i of t)for(let l of r(i))e.has(l)&&(s.get(l).push(i.id),n.set(i.id,n.get(i.id)+1));let a=[];for(let[i,l]of n)l===0&&a.push(i);let o=[];for(;a.length;){let i=a.shift();o.push(i);for(let l of s.get(i))n.set(l,n.get(l)-1),n.get(l)===0&&a.push(l)}if(o.length!==t.length)throw new Error("strategy graph is cyclic");return o}function xt(t,e){return t!=null&&typeof t=="object"&&"param"in t?e[t.param].value:t}function ks(t,e,r){if(!Array.isArray(t)||t.length===0)throw new TypeError("bars must be a non-empty array");if(!Number.isInteger(e)||e<0||e>=t.length)throw new RangeError("index out of range");let n=null;for(let s=0;s<=e;s++){let a=t[s];if(a==null||typeof a!="object"||Array.isArray(a))throw new TypeError(`bars[${s}] must be an object`);let{t:o,o:i,h:l,l:u,c:f,v:c}=a;if(!X(o)&&(typeof o=="number"&&Number.isFinite(o)),!Number.isFinite(o))throw new TypeError(`bars[${s}].t must be finite`);for(let[d,m]of[["o",i],["h",l],["l",u],["c",f],["v",c]])if(!X(m))throw new TypeError(`bars[${s}].${d} must be a finite number`);for(let[d,m]of[["o",i],["h",l],["l",u],["c",f]])if(!(m>0))throw new TypeError(`bars[${s}].${d} price must be positive`);if(c<0)throw new TypeError(`bars[${s}].v volume must be non-negative`);if(l<Math.max(i,f,u))throw new TypeError(`bars[${s}] high must be >= max(open, close, low)`);if(u>Math.min(i,f,l))throw new TypeError(`bars[${s}] low must be <= min(open, close, high)`);if(n!=null){if(!(o>n))throw new TypeError("bars t must be strictly increasing");if(o-n!==Es[r])throw new TypeError(`bars t must match ${r} cadence`)}if(n=o,"fundingRate"in a&&a.fundingRate!=null&&!X(a.fundingRate))throw new TypeError(`bars[${s}].fundingRate must be finite when present`);if("openInterest"in a&&a.openInterest!=null){if(!X(a.openInterest))throw new TypeError(`bars[${s}].openInterest must be finite when present`);if(a.openInterest<0)throw new TypeError(`bars[${s}].openInterest must be non-negative`)}}}function mt(t,e,r,n,s,a){if(a.has(t))return a.get(t);let o=e.get(t),i;switch(o.type){case"input":{let l=bs[o.field];i=new Array(s+1);for(let u=0;u<=s;u++){let f=n[u][l];i[u]=f===void 0?null:f}break}case"constant":{let l=xt(o.value,r);i=new Array(s+1).fill(l);break}case"indicator":{let l=o.period!=null?xt(o.period,r):void 0;if(o.indicator==="atr"){let c=[];for(let d=0;d<=s;d++){let m=n[d];c.push({o:m.o,h:m.h,l:m.l,c:m.c})}i=Tr(c,l);break}let f=mt(o.input,e,r,n,s,a).map((c,d)=>{if(c==null||!X(c))throw new TypeError(`indicator input ${o.input} has non-finite value at ${d}`);return c});if(o.indicator==="sma")i=Sr(f,l);else if(o.indicator==="ema")i=qt(f,l);else if(o.indicator==="rsi")i=Ar(f,l);else if(o.indicator==="macd")i=Pr(f,{fastPeriod:xt(o.fastPeriod,r),slowPeriod:xt(o.slowPeriod,r),signalPeriod:xt(o.signalPeriod,r)})[o.output];else if(o.indicator==="bollinger")i=$r(f,{period:l,stdDev:xt(o.stdDev,r)})[o.output];else throw new Error(`unsupported indicator ${o.indicator}`);break}case"compare":{let l=mt(o.left,e,r,n,s,a),u=mt(o.right,e,r,n,s,a);i=new Array(s+1);for(let f=0;f<=s;f++){let c=l[f],d=u[f];if(c==null||d==null||!X(c)||!X(d)){i[f]=!1;continue}switch(o.op){case"gt":i[f]=c>d;break;case"gte":i[f]=c>=d;break;case"lt":i[f]=c<d;break;case"lte":i[f]=c<=d;break;case"eq":i[f]=c===d;break;default:i[f]=!1}}break}case"logic":{let l=o.inputs.map(u=>mt(u,e,r,n,s,a));i=new Array(s+1);for(let u=0;u<=s;u++)if(o.op==="not"){let f=l[0][u];i[u]=f===!0?!1:f===!1}else if(o.op==="and"){let f=!0;for(let c of l)if(c[u]!==!0){f=!1;break}i[u]=f}else if(o.op==="or"){let f=!1;for(let c of l)if(c[u]===!0){f=!0;break}i[u]=f}else i[u]=!1;break}case"cross":{let l=mt(o.left,e,r,n,s,a),u=mt(o.right,e,r,n,s,a);i=new Array(s+1),i[0]=!1;for(let f=1;f<=s;f++){let c=l[f-1],d=u[f-1],m=l[f],p=u[f];if(c==null||d==null||m==null||p==null||!X(c)||!X(d)||!X(m)||!X(p)){i[f]=!1;continue}o.direction==="above"?i[f]=c<=d&&m>p:i[f]=c>=d&&m<p}break}default:throw new Error(`unknown node type ${o.type}`)}return a.set(t,i),i}function K(t,e={}){let r=J(t);e&&Object.keys(e).length&&(r=Ot(r,e));let n=new Map(r.nodes.map(m=>[m.id,m])),s=Object.freeze(xs(r.nodes)),a=r.parameters,o=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"])o.add(m);let i=Object.freeze([...o].sort()),l=wt(r);function u(m,p){let h={};for(let S of s){let P=m.get(S);h[S]=P[p]}let E=S=>S!=null&&h[S]===!0;return{values:h,signals:{entryLong:E(r.rules.entryLong),entryShort:E(r.rules.entryShort),exitLong:E(r.rules.exitLong),exitShort:E(r.rules.exitShort)}}}function f(m,p){ks(m,p,r.market.interval);let h=new Map;for(let E of s)mt(E,n,a,m,p,h);return h}function c(m,p){return u(f(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,h=f(m,p);return Object.freeze(m.map((E,S)=>Object.freeze(u(h,S))))}return Object.freeze({strategy:r,strategyHash:l,compilerVersion:_t,compilerHash:dt,requiredSeries:i,nodeOrder:s,evaluate:c,evaluateAll:d})}var _t,dt,bs,Es,pt=B(()=>{ft();_r();Or();_t=ge,dt=Ir,bs=Object.freeze({open:"o",high:"h",low:"l",close:"c",volume:"v",fundingRate:"fundingRate",openInterest:"openInterest"}),Es=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 Ss}from"node:crypto";function Ps(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function et(t){return typeof t=="number"&&Number.isFinite(t)}function be(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)be(e);return Object.freeze(t)}for(let e of Object.keys(t))be(t[e]);return Object.freeze(t)}function Ct(t){if(Array.isArray(t))return t.map(Ct);if(t!=null&&typeof t=="object"){let e={};for(let r of Object.keys(t).sort())e[r]=Ct(t[r]);return e}return t}function Ee(t,e="result"){if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`non-finite backtest result at ${e}`);return}if(!(t==null||typeof t!="object")){if(Array.isArray(t)){t.forEach((r,n)=>Ee(r,`${e}[${n}]`));return}for(let[r,n]of Object.entries(t))Ee(n,`${e}.${r}`)}}function Nr(t){if(!Array.isArray(t)||t.length===0)throw new TypeError("bars must be a non-empty array");let e=null;for(let r=0;r<t.length;r++){let n=t[r];if(n==null||typeof n!="object"||Array.isArray(n))throw new TypeError(`bars[${r}] must be an object`);let{t:s,o:a,h:o,l:i,c:l,v:u}=n;if(!et(s))throw new TypeError(`bars[${r}].t must be finite`);for(let[f,c]of[["o",a],["h",o],["l",i],["c",l],["v",u]])if(!et(c))throw new TypeError(`bars[${r}].${f} must be a finite number`);for(let[f,c]of[["o",a],["h",o],["l",i],["c",l]])if(!(c>0))throw new TypeError(`bars[${r}].${f} price must be positive`);if(u<0)throw new TypeError(`bars[${r}].v volume must be non-negative`);if(o<Math.max(a,l,i))throw new TypeError(`bars[${r}] high must be >= max(open, close, low)`);if(i>Math.min(a,l,o))throw new TypeError(`bars[${r}] low must be <= min(open, close, high)`);if(e!=null&&!(s>e))throw new TypeError("bars t must be strictly increasing");if(e=s,"fundingRate"in n&&n.fundingRate!=null&&!et(n.fundingRate))throw new TypeError(`bars[${r}].fundingRate must be finite when present`);if("fundingPaymentRate"in n&&n.fundingPaymentRate!=null&&!et(n.fundingPaymentRate))throw new TypeError(`bars[${r}].fundingPaymentRate must be finite when present`);if("openInterest"in n&&n.openInterest!=null&&!et(n.openInterest))throw new TypeError(`bars[${r}].openInterest must be finite when present`)}}function $t(t){if(!Array.isArray(t))throw new TypeError("bars must be an array");return t.length>0&&Nr(t),Ss("sha256").update(JSON.stringify(Ct(t)),"utf8").digest("hex")}function $s(t){if(t==null&&(t={}),!Ps(t))throw new TypeError("options must be a plain object");let e={...As},r=new Set(["initialEquityUsd","takerFeeBps","builderFeeBps","slippageBps","latencyBars","maxVolumeParticipationPct","nowMs"]);for(let n of Object.keys(t))if(!r.has(n))throw new TypeError(`unknown option "${n}"`);if("initialEquityUsd"in t){if(!et(t.initialEquityUsd)||t.initialEquityUsd<=0)throw new TypeError("initialEquityUsd must be a positive finite number");e.initialEquityUsd=t.initialEquityUsd}for(let n of["takerFeeBps","builderFeeBps","slippageBps"])if(n in t){let s=t[n];if(!et(s)||s<0)throw new TypeError(`${n} must be a finite number >= 0`);if(n==="slippageBps"?s>=1e4:s>1e4)throw new TypeError(`${n} exceeds its safe basis-point bound`);e[n]=s}if("latencyBars"in t){let n=t.latencyBars;if(!Number.isInteger(n)||n<1)throw new TypeError("latencyBars must be an integer >= 1");e.latencyBars=n}if("maxVolumeParticipationPct"in t){let n=t.maxVolumeParticipationPct;if(!et(n)||n<=0||n>100)throw new TypeError("maxVolumeParticipationPct must be in (0,100]");e.maxVolumeParticipationPct=n}if("nowMs"in t){if(!Number.isInteger(t.nowMs))throw new TypeError("nowMs must be an integer epoch milliseconds");e.nowMs=t.nowMs}return e}function Bt(t){return t/1e4}function Ts(t,e,r){let n=Bt(r);return e==="long"?t*(1+n):t*(1-n)}function _s(t,e,r){let n=Bt(r);return e==="long"?t*(1-n):t*(1+n)}function vr(t,e,r){let n=Math.abs(t)*Bt(e),s=Math.abs(t)*Bt(r);return{taker:n,builder:s,total:n+s}}function Is(t,e){let r=t*(e.positionSizePct/100)*e.maxLeverage;return Math.min(r,e.maxNotionalUsd)}function Os(t,e,r){let n=r/100;return e==="long"?t*(1-n):t*(1+n)}function vs(t,e,r){let n=r/100;return e==="long"?t*(1+n):t*(1-n)}function Ns(t,e,r,n){if(!(r>0))return e==="long"?0:Number.POSITIVE_INFINITY;let s=Math.min(.99,1/(2*r)+n/1e4);return e==="long"?t*(1-1/r)/(1-s):t*(1+1/r)/(1+s)}function Ms(t,e,r){return e==="long"?t.l<=r:t.h>=r}function Rs(t,e,r){return e==="long"?t.h>=r:t.l<=r}function js(t,e,r){return e==="long"?t.l<=r:t.h>=r}function Nt(t,e){for(let r of t.requiredSeries)if(["fundingRate","openInterest"].includes(r)&&!e.every(n=>et(n?.[r])))throw new Error(`strategy required series is absent: ${r}`)}function Fs(t){if(t.length<3)return 0;let e=[];for(let o=1;o<t.length;o++){let i=t[o-1].equity,l=t[o].equity;i>0&&e.push((l-i)/i)}if(e.length<2)return 0;let r=0;for(let o of e)r+=o;let n=r/e.length,s=0;for(let o of e)s+=(o-n)**2;let a=Math.sqrt(s/(e.length-1));return a>0?n/a:0}function Ls(t){let e=-1/0,r=0;for(let n of t){let s=n.equity;if(s>e&&(e=s),e>0){let a=(e-s)/e*100;a>r&&(r=a)}}return r}function at(t,e,r={}){let n=$s(r);Nr(e);let s=$t(e);n.nowMs!==void 0&&J(t,{nowMs:n.nowMs});let a=K(t);if(Nt(a,e),n.nowMs!==void 0&&a.strategy.risk.expiresAt<=n.nowMs)throw new Error("strategy is expired: risk.expiresAt must be strictly greater than nowMs");let o=a.strategy.risk,i=a.evaluateAll(e),l=n.latencyBars,u=n.slippageBps,f=n.takerFeeBps,c=n.builderFeeBps,d=n.initialEquityUsd,m=0,p=0,h=0,E=0,S=0,P=[],T=[],x=[],R=[],_=[],g=null,V=0,ot=null,it=d,W=!1,y=0,A=0,v=[],j=new Array(e.length).fill(0);function F(b){v.push(b)}function I(b){let $=e[b].v*(n.maxVolumeParticipationPct/100);return Math.max(0,$-j[b])}function N(b){if(!g)return d;let $=g.side==="long"?(b-g.entryPrice)*g.qty:(g.entryPrice-b)*g.qty;return d+$}function z(b,$,k){let L=k.o,O=Is(d,o);if(!(O>0)||!(L>0))return;let H=Ts(L,$,u),M=O/H,C=I(b),At=H*C;if(M>C){x.push({kind:"entry",barIndex:b,time:k.t,side:$,requestedNotionalUsd:O,maxFillNotionalUsd:At,reason:"volume_participation"});return}j[b]+=M;let Q=Math.abs(H-L)*M,nt=vr(O,f,c);d-=nt.total,m+=nt.taker,p+=nt.builder,E+=Q,S+=O,g={lifecycleEpoch:++A,side:$,entryBarIndex:b,entryReferencePrice:L,entryPrice:H,qty:M,notionalUsd:O,stop:Os(H,$,o.stopLossPct),take:vs(H,$,o.takeProfitPct),liq:Ns(H,$,o.maxLeverage,f+c),entryFees:nt.taker,entryBuilderFees:nt.builder,entrySlippageUsd:Q,fundingAccrued:0}}function q(b,$,k,L){if(!g)return!1;let O=g.side,H=$,M=H;k!=="liquidation"&&L&&(M=_s(H,O,u));let C=g.qty,At=C*M;if(k!=="liquidation"){let He=I(b),cn=M*He;if(C>He)return x.push({kind:"exit",barIndex:b,time:e[b].t,side:O,requestedNotionalUsd:At,maxFillNotionalUsd:cn,reason:"volume_participation",triggerReason:k}),!1;j[b]+=C}let Q=vr(At,f,c),nt=k==="liquidation"?0:Math.abs(M-H)*C,Pt,Xt;O==="long"?(Pt=(H-g.entryReferencePrice)*C,Xt=(M-g.entryPrice)*C):(Pt=(g.entryReferencePrice-H)*C,Xt=(g.entryPrice-M)*C),d+=Xt,d-=Q.total,m+=Q.taker,p+=Q.builder,E+=nt,S+=At;let an={side:O,entryBarIndex:g.entryBarIndex,entryTime:e[g.entryBarIndex].t,entryPrice:g.entryPrice,exitBarIndex:b,exitTime:e[b].t,exitPrice:M,exitReason:k,qty:C,notionalUsd:g.notionalUsd,grossPnlUsd:Pt,feesUsd:g.entryFees+Q.taker,builderFeesUsd:g.entryBuilderFees+Q.builder,fundingUsd:g.fundingAccrued,slippageUsd:g.entrySlippageUsd+nt,netPnlUsd:Pt-(g.entryFees+Q.taker+g.entryBuilderFees+Q.builder)-g.fundingAccrued-(g.entrySlippageUsd+nt)};return P.push(an),k==="liquidation"&&T.push({barIndex:b,time:e[b].t,side:O,price:M,tradeIndex:P.length-1}),g=null,A+=1,y=b+1+(o.cooldownBars||0),!0}function Z(b,$,k,L){let O=b+1;if(O>=e.length)return;v.some(M=>M.kind==="exit"&&M.side===$&&M.fillBar===O&&M.epoch===L)||F({kind:"exit",side:$,signalBar:b,fillBar:O,reason:k,epoch:L})}function jt(b){let $=v.filter(k=>k.fillBar===b);for(let k=v.length-1;k>=0;k--)v[k].fillBar===b&&v.splice(k,1);$.sort((k,L)=>{let O=H=>H.kind==="exit"?0:1;return O(k)-O(L)});for(let k of $)if(k.kind==="exit"){if(!g||g.side!==k.side||g.lifecycleEpoch!==k.epoch)continue;let L=k.reason||"rule";q(b,e[b].o,L,!0)||Z(b,k.side,L,k.epoch)}else if(k.kind==="entry"){if(g||k.epoch!==A||b<y)continue;z(b,k.side,e[b])}}function Ft(b){if(!g)return;let $=e[b],k=$.fundingPaymentRate;if(k==null||!et(k)||k===0)return;let L=Math.abs(g.qty*$.c),O=k*L;g.side==="long"?(d-=O,g.fundingAccrued+=O,h+=O):(d+=O,g.fundingAccrued-=O,h-=O)}function Lt(b){if(!g)return;let $=e[b].o;(g.side==="long"?$<=g.liq:$>=g.liq)&&q(b,$,"liquidation",!1)}function Me(b){if(!g)return;let $=e[b],k=g.side,L=js($,k,g.liq),O=Ms($,k,g.stop),H=Rs($,k,g.take),M=C=>k==="long"?Math.min(C,$.o):Math.max(C,$.o);if(L){q(b,M(g.liq),"liquidation",!1);return}if(O&&H){q(b,M(g.stop),"stop_loss",!0)||Z(b,k,"stop_loss",g.lifecycleEpoch);return}if(O){q(b,M(g.stop),"stop_loss",!0)||Z(b,k,"stop_loss",g.lifecycleEpoch);return}H&&(q(b,g.take,"take_profit",!0)||Z(b,k,"take_profit",g.lifecycleEpoch))}for(let b=0;b<e.length;b++){let $=Math.floor(e[b].t/864e5);$!==ot&&(ot=$,it=N(e[b].o),W=!1),Lt(b),jt(b),Me(b),Ft(b),!W&&N(e[b].c)<=it*(1-o.maxDailyLossPct/100)&&(W=!0,R.push({type:"daily_loss_limit",barIndex:b,time:e[b].t,message:"daily loss limit reached; new entries blocked for UTC day"}));let k=i[b].signals,L=b+l;if(g)(g.side==="long"&&k.exitLong===!0||g.side==="short"&&k.exitShort===!0)&&L<e.length&&(v.some(C=>C.kind==="exit"&&C.side===g.side&&C.fillBar===L&&C.epoch===g.lifecycleEpoch)||F({kind:"exit",side:g.side,signalBar:b,fillBar:L,reason:"rule",epoch:g.lifecycleEpoch}));else{let H=k.entryLong===!0,M=k.entryShort===!0;H&&M?R.push({type:"conflicting_entry_signals",barIndex:b,time:e[b].t,message:"conflicting entry signals; no position opened"}):!W&&(H||M)&&L<e.length&&b>=y&&F({kind:"entry",side:H?"long":"short",signalBar:b,fillBar:L,epoch:A})}let O=d;g&&(V+=1,O=N(e[b].c)),_.push({barIndex:b,time:e[b].t,equity:O,positionSide:g?g.side:null})}let Re=null;if(g){let b=e.length-1;if(q(b,e[b].c,"end_of_data",!0))_[b]={barIndex:b,time:e[b].t,equity:d,positionSide:null};else{let k=N(e[b].c);Re={side:g.side,entryBarIndex:g.entryBarIndex,entryTime:e[g.entryBarIndex].t,entryPrice:g.entryPrice,qty:g.qty,notionalUsd:g.notionalUsd,markPrice:e[b].c,markedEquityUsd:k},R.push({type:"open_position_at_end",barIndex:b,time:e[b].t,message:"end-of-data exit missed; position remains open and marked"})}}let je=(g?N(e[e.length-1].c):d)-n.initialEquityUsd,rn=je/n.initialEquityUsd*100,Fe=0,Jt=0,Kt=0;for(let b of P)b.netPnlUsd>0?(Fe+=1,Jt+=b.netPnlUsd):b.netPnlUsd<0&&(Kt+=-b.netPnlUsd);let Yt=P.length,nn=Yt===0?0:Fe/Yt,Gt=0;Kt>0?Gt=Jt/Kt:Jt>0&&(Gt=1e12);let sn={netPnlUsd:je,netPnlPct:rn,maxDrawdownPct:Ls(_),winRate:nn,profitFactor:Gt,tradeCount:Yt,sharpe:Fs(_),turnoverUsd:S,exposurePct:V/e.length*100},on={initialEquityUsd:n.initialEquityUsd,takerFeeBps:n.takerFeeBps,builderFeeBps:n.builderFeeBps,slippageBps:n.slippageBps,latencyBars:n.latencyBars,maxVolumeParticipationPct:n.maxVolumeParticipationPct},Le={barsHash:s,strategyHash:a.strategyHash,compilerHash:dt,compilerVersion:_t,config:on,trades:P,equityCurve:_,metrics:sn,costs:{feesUsd:m,builderFeesUsd:p,fundingUsd:h,slippageUsd:E},liquidations:T,missedFills:x,openPositionAtEnd:Re,flags:R};return Ee(Le),be(Ct(Le))}var As,Ht=B(()=>{pt();ft();As=Object.freeze({initialEquityUsd:1e4,takerFeeBps:3.5,builderFeeBps:2,slippageBps:2,latencyBars:1,maxVolumeParticipationPct:100})});import{createHash as Hs}from"node:crypto";function Js(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function xe(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)xe(e);return Object.freeze(t)}for(let e of Object.keys(t))xe(t[e]);return Object.freeze(t)}function Ks(t){return String(t).trim().replace(/\s+/g," ")}function Ys(t){let e=t.match(/\b(long|short)\b/i);return e?e[1].toLowerCase():null}function Gs(t){for(let r of qs)if(new RegExp(`\\b${r}\\b`,"i").test(t))return r;let e=t.match(/\b([A-Z][A-Z0-9]{1,11})\b/);return e?e[1]:null}function Xs(t){let e=t.match(/\bon\s+(1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d)\b/i);if(!e)return"15m";let r=e[1].toLowerCase();return Us.has(r)?r:null}function Ws(t){let e={...Bs},r=t.match(/stop\s*loss\s*(\d+(?:\.\d+)?)\s*%?/i);r&&(e.stopLossPct=Number(r[1]));let n=t.match(/take\s*profit\s*(\d+(?:\.\d+)?)\s*%?/i);n&&(e.takeProfitPct=Number(n[1]));let s=t.match(/leverage\s*(\d+(?:\.\d+)?)/i);s&&(e.maxLeverage=Number(s[1]));let a=t.match(/position\s*size\s*(\d+(?:\.\d+)?)\s*%?/i);a&&(e.positionSizePct=Number(a[1]));let o=t.match(/max\s*notional\s*(?:usd\s*)?\$?\s*(\d+(?:\.\d+)?)/i);return o&&(e.maxNotionalUsd=Number(o[1])),e}function Zs(t){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=>(t.match(r)??[]).length>1)}function Qs(t){let e=Hs("sha256").update(t,"utf8").digest("hex").slice(0,10),r=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40),s=`${r.length?r:"draft"}-${e}`.replace(/[^a-z0-9._-]/g,"").slice(0,64);return/^[a-z0-9]/.test(s)?s:`d${s}`.slice(0,64)}function to(t){let e=t.match(/\bema\s*(\d+)\s*cross(?:es)?\s*(above|below)\s*ema\s*(\d+)\b/i);if(!e)return null;let r=Number(e[1]),n=e[2].toLowerCase(),s=Number(e[3]);if(!(r>0)||!(s>0)||r===s)return null;let a=/\b(exit\s+on\s+reverse|reverse\s+exit)\b/i.test(t);return{kind:"ema_cross",fast:r,slow:s,direction:n,reverse:a}}function eo(t){let e=t.match(/\brsi\s*(\d+)\s*(above|below)\s*(-?\d+(?:\.\d+)?)/i);if(!e)return null;let r=Number(e[3]);return!Number.isFinite(r)||r<=0||r>=100?null:{kind:"rsi",period:Number(e[1]),op:e[2].toLowerCase(),threshold:r}}function ro(t){let e=t.match(/\bfunding\s*rate\s*(above|below)\s*(-?\d+(?:\.\d+)?)(%?)(?=\s|,|$)/i);if(!e)return null;let r=Number(e[2]);return e[3]==="%"&&(r=r/100),{kind:"funding",op:e[1].toLowerCase(),threshold:r}}function no(t,e){let r=t.replace(/^(long|short)\s+[A-Z][A-Z0-9]{1,11}\s+when\s+/i,"");if(r===t)return!1;e.kind==="ema_cross"?r=r.replace(/^ema\s*\d+\s*cross(?:es)?\s*(?:above|below)\s*ema\s*\d+\b/i,""):e.kind==="rsi"?r=r.replace(/^rsi\s*\d+\s*(?:above|below)\s*\d+(?:\.\d+)?\b/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];e.kind==="ema_cross"&&n.push(/(?:,\s*)?\b(?:exit\s+on\s+reverse|reverse\s+exit)\b/gi);for(let s of n)r=r.replace(s,"");return r.replace(/[\s,;]+/g,"")===""}function Mr(t){let e=Math.max(2,Math.floor(t/2));return{value:t,min:Math.max(2,t-e),max:Math.min(500,t+e),step:1}}function so({side:t,coin:e,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){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:i.direction,left:"emaLeft",right:"emaRight"}],u={entryLong:null,entryShort:null,exitLong:null,exitShort:null};if(t==="long"?u.entryLong="cross":u.entryShort="cross",i.reverse){let f=i.direction==="above"?"below":"above";l.push({id:"crossRev",type:"cross",direction:f,left:"emaLeft",right:"emaRight"}),t==="long"?u.exitLong="crossRev":u.exitShort="crossRev"}return{version:1,id:a,name:o,venue:"hyperliquid",market:{coin:e,interval:r},parameters:{ema_left_period:Mr(i.fast),ema_right_period:Mr(i.slow)},nodes:l,rules:u,risk:{...n,expiresAt:s}}}function oo({side:t,coin:e,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){let l=[{id:"c",type:"input",field:"close"},{id:"rsi",type:"indicator",indicator:"rsi",input:"c",period:i.period},{id:"thr",type:"constant",value:i.threshold},{id:"sig",type:"compare",op:i.op==="above"?"gt":"lt",left:"rsi",right:"thr"}];return{version:1,id:a,name:o,venue:"hyperliquid",market:{coin:e,interval:r},parameters:{},nodes:l,rules:{entryLong:t==="long"?"sig":null,entryShort:t==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:s}}}function io({side:t,coin:e,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){let l=[{id:"fr",type:"input",field:"fundingRate"},{id:"thr",type:"constant",value:i.threshold},{id:"sig",type:"compare",op:i.op==="above"?"gt":"lt",left:"fr",right:"thr"}];return{version:1,id:a,name:o,venue:"hyperliquid",market:{coin:e,interval:r},parameters:{},nodes:l,rules:{entryLong:t==="long"?"sig":null,entryShort:t==="short"?"sig":null,exitLong:null,exitShort:null},risk:{...n,expiresAt:s}}}function Rr(t,e={}){if(typeof t!="string")throw new D("prompt must be a string");if(t.length>1e3)throw new D("prompt length must be <= 1000");if(!Js(e))throw new D("options must be a plain object");if(!Number.isInteger(e.nowMs))throw new D("options.nowMs is required integer epoch ms");let r=e.nowMs,n=Vs;if("expiresInMs"in e){if(!Number.isInteger(e.expiresInMs))throw new D("expiresInMs must be an integer");if(n=e.expiresInMs,n<zs||n>Ds)throw new D("expiresInMs must be between 1h and 30d")}if(Cs.test(t))throw new D(`prompt appears to contain secrets and is rejected. ${kt}`);let s=Ks(t);if(!s)throw new D(`empty prompt. ${kt}`);if(Zs(s))throw new D(`duplicate interval or risk clause. ${kt}`);let a=Ys(s),o=Gs(s),i=Xs(s);if(!a||!o||!i)throw new D(`could not parse side/coin/interval. ${kt}`);let l=Ws(s);if(!(l.maxLeverage>0)||l.maxLeverage>50)throw new D("leverage out of range");if(!(l.positionSizePct>0)||l.positionSizePct>100)throw new D("position size out of range");let u=r+n,f=Qs(s),c=`Draft ${o} ${a}`.slice(0,100),d=to(s),m=eo(s),p=ro(s),h=[d,m,p].filter(Boolean);if(h.length!==1)throw new D(`unsupported or ambiguous prompt. ${kt}`);if(!no(s,h[0]))throw new D(`unsupported or ambiguous prompt. ${kt}`);let E,S=h[0],P={side:a,coin:o,interval:i,risk:l,expiresAt:u,id:f,name:c,spec:S};S.kind==="ema_cross"?E=so(P):S.kind==="rsi"?E=oo(P):E=io(P);let T=we(E,{nowMs:r});if(!T.ok)throw new D(`draft failed validation: ${T.errors.map(x=>x.message).join("; ")}`);return xe(J(E,{nowMs:r}))}var D,Us,qs,Cs,kt,Bs,zs,Ds,Vs,jr=B(()=>{ft();D=class extends Error{constructor(e){super(e),this.name="StrategyDraftError"}},Us=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),qs=new Set(["BTC","ETH","SOL","HYPE"]),Cs=/\b(mnemonic|private\s*key|privkey|seed\s*phrase|seed\b|api[_-]?key|secret\s*key|wallet\s*key|passphrase)\b/i,kt="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]. 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.",Bs=Object.freeze({maxLeverage:1,maxNotionalUsd:100,positionSizePct:5,stopLossPct:2,takeProfitPct:4,cooldownBars:1,maxDailyLossPct:3}),zs=36e5,Ds=30*864e5,Vs=864e5});import{createHash as ao}from"node:crypto";function Hr(t){let e=String(t).toLowerCase();return e==="holdout"||e==="test"||e==="oos"||e.includes("holdout")||e.includes("oos")?!0:e==="testbars"||e.endsWith("testbars")||e.startsWith("test")||e.endsWith("test")?!e.includes("backtest"):!1}function Ur(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function Se(t){if(t==null||typeof t!="object"||Object.isFrozen(t))return t;if(Array.isArray(t)){for(let e of t)Se(e);return Object.freeze(t)}for(let e of Object.keys(t))Se(t[e]);return Object.freeze(t)}function Mt(t){if(Array.isArray(t))return t.map(Mt);if(t!=null&&typeof t=="object"){let e={};for(let r of Object.keys(t).sort())e[r]=Mt(t[r]);return e}return t}function zt(t){return JSON.stringify(Mt(t))}function co(t){let{min:e,max:r,step:n}=t;if(!(n>0)||e>r)return[];let s=[],a=Math.floor((r-e)/n+1e-9);for(let i=0;i<=a;i++){let l=e+i*n;if(l>r+1e-9)break;let u=Math.abs(l-Math.round(l))<1e-9?Math.round(l):Number(l.toPrecision(12));u<e-1e-9||u>r+1e-9||s.push(u)}if(s.length===0)return[];let o=s[s.length-1];if(Math.abs(o-r)>1e-9){let i=(r-e)/n;Math.abs(i-Math.round(i))<=1e-9&&s.push(r)}return s}function lo(t,e){if(t.length===0)return[];let r=[{}];for(let n of t){let s=e[n],a=[];for(let o of r)for(let i of s)a.push({...o,[n]:i});r=a}return r.sort((n,s)=>{let a=zt(n),o=zt(s);return a<o?-1:a>o?1:0}),r}function ke(t,e,r,n,s){let a=0;if(t==="maxDrawdownPct"){if(a=e.maxDrawdownPct-n.maxDrawdownPct,a!==0)return a<0}else if(a=e[t]-n[t],a!==0)return a>0;let o=zt(r),i=zt(s);return o<i}function qr(t,e,r={}){if(!Ur(r))throw new TypeError("options must be a plain object");for(let x of Object.keys(r))if(Hr(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 s=64;if("maxTrials"in r){let x=r.maxTrials;if(!Number.isInteger(x)||x<1||x>Fr)throw new TypeError(`maxTrials must be an integer 1..${Fr}`);s=x}let a=r.objective??"netPnlUsd";if(!Lr.has(a))throw new TypeError(`objective must be one of ${[...Lr].join("|")}`);let o=r.backtestOptions??{};if(!Ur(o))throw new TypeError("backtestOptions must be a plain object");for(let x of Object.keys(o))if(Hr(x))throw new TypeError(`backtestOptions must not include holdout/test/oos key "${x}"`);let i=J(t),l=Object.keys(i.parameters).sort();if(l.length===0)throw new Error("optimizeStrategy requires at least one declared parameter");let u={},f=1;for(let x of l){let R=co(i.parameters[x]);if(R.length===0)throw new Error(`parameter "${x}" produces an empty grid`);u[x]=R,f*=R.length}let c=lo(l,u);if(c.length===0)throw new Error("parameter grid is empty");let d=c.slice(0,s),m=[],p=null,h=null;for(let x of d){let R=Ot(i,x),_=at(R,e,o);h==null&&(h=_.config);let g={netPnlUsd:_.metrics.netPnlUsd,netPnlPct:_.metrics.netPnlPct,maxDrawdownPct:_.metrics.maxDrawdownPct,winRate:_.metrics.winRate,profitFactor:_.metrics.profitFactor,tradeCount:_.metrics.tradeCount,sharpe:_.metrics.sharpe,turnoverUsd:_.metrics.turnoverUsd},V={parameters:{...x},metrics:g};m.push(V),(!p||ke(a,g,x,p.metrics,p.parameters))&&(p=V)}m.sort((x,R)=>ke(a,x.metrics,x.parameters,R.metrics,R.parameters)?-1:ke(a,R.metrics,R.parameters,x.metrics,x.parameters)?1:0);let E={...p.parameters},S=Ot(i,E),P={strategyHash:wt(i),compilerHash:dt,trainBarsHash:$t(e),backtestConfig:h,objective:a,maxTrials:s,trialsRun:m.length,candidates:m,bestParameters:E,bestStrategy:S},T={id:ao("sha256").update(JSON.stringify(Mt(P)),"utf8").digest("hex"),...P};return Se(Mt(JSON.parse(JSON.stringify(T))))}var Fr,Lr,Cr=B(()=>{pt();ft();Ht();Fr=256,Lr=new Set(["netPnlUsd","profitFactor","sharpe","maxDrawdownPct"])});import st from"node:fs";import Dt from"node:path";function Vt(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function rt(t){return t==null?t:JSON.parse(JSON.stringify(t))}function fo(t){return String(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function St(t,e="record"){if(Array.isArray(t)){t.forEach((r,n)=>St(r,`${e}[${n}]`));return}if(Vt(t))for(let[r,n]of Object.entries(t)){let s=fo(r);if(uo.some(a=>s.includes(a)))throw new Error(`shadow-store: forbidden secret-like field at ${e}.${r}`);St(n,`${e}.${r}`)}}function po(t){if(typeof t!="string"||!t||!Dt.isAbsolute(t))throw new Error("shadow-store: path must be an absolute path")}function Br(t){let e;try{e=st.lstatSync(t)}catch(n){if(n&&n.code==="ENOENT")return;throw n}if(e.isSymbolicLink())throw new Error("shadow-store: store path must not be a symlink");if(!e.isFile())throw new Error("shadow-store: store path must be a regular file");if(e.mode&511&18)throw new Error("shadow-store: store file must not be group or world writable")}function mo(){return{version:Pe,runners:[]}}function zr(t,e){let r;try{r=JSON.parse(t)}catch{throw new Error("shadow-store: malformed JSON")}if(!Vt(r))throw new Error("shadow-store: malformed JSON root");if(r.version!==Pe)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 St(r,Dt.basename(e)),{version:Pe,runners:r.runners.map(n=>rt(n))}}function Dr(t,e){St(e,"store");let r=Dt.dirname(t);st.mkdirSync(r,{recursive:!0,mode:448});let n=Dt.join(r,`.shadow-store.${process.pid}.${Date.now()}.tmp`),s=`${JSON.stringify(e)}
3
- `;try{st.writeFileSync(n,s,{mode:384,flag:"wx"}),st.renameSync(n,t);try{st.chmodSync(t,384)}catch{}}catch(a){try{st.unlinkSync(n)}catch{}throw a}}function Vr(t={}){let e=t.path;if(po(e),Br(e),st.existsSync(e)?zr(st.readFileSync(e,"utf8"),e):Dr(e,mo()),Ae.has(e))return Ae.get(e);let r=!1,n=[];function s(){if(r)return;let p=n.shift();if(p){r=!0;try{let h=p.fn();r=!1,p.resolve(h),s()}catch(h){r=!1,p.reject(h),s()}}}function a(p){if(!r&&n.length===0){r=!0;try{return p()}finally{r=!1,queueMicrotask(s)}}return new Promise((h,E)=>{n.push({fn:p,resolve:h,reject:E}),queueMicrotask(s)})}function o(){return Br(e),zr(st.readFileSync(e,"utf8"),e)}function i(p){Dr(e,p)}function l(p){if(!Vt(p)||typeof p.id!="string"||!p.id)throw new Error("shadow-store: create requires record with string id");St(p,"record");let h=o();if(h.runners.some(S=>S.id===p.id))throw new Error(`shadow-store: runner id already exists: ${p.id}`);let E=rt(p);return h.runners.push(E),i(h),rt(E)}function u(p){let h=o().runners.find(E=>E.id===p);return h?rt(h):null}function f(){return o().runners.map(p=>rt(p))}function c(p,h){if(typeof h!="function")throw new Error("shadow-store: updater must be a function");let E=o(),S=E.runners.findIndex(x=>x.id===p);if(S<0)throw new Error(`shadow-store: runner not found: ${p}`);let P=rt(E.runners[S]),T=h(P);if(!Vt(T)||T.id!==p)throw new Error("shadow-store: updater must return record with same id");return St(T,"record"),E.runners[S]=rt(T),i(E),rt(E.runners[S])}function d(p){let h=o(),E=h.runners.findIndex(P=>P.id===p);if(E<0)throw new Error(`shadow-store: runner not found: ${p}`);let S=rt(h.runners[E]);return S.status!=="stopped"&&(S.status="stopped",h.runners[E]=S,i(h)),rt(h.runners[E])}let m={create(p){return a(()=>l(p))},get(p){return u(p)},list(){return f()},update(p,h){return a(()=>c(p,h))},stop(p){return a(()=>d(p))}};return Ae.set(e,m),m}var Pe,uo,Ae,Jr=B(()=>{Pe=1,uo=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"];Ae=new Map});import{createHash as _e}from"node:crypto";function $e(t){return t==null?t:JSON.parse(JSON.stringify(t))}function Te(t){return Array.isArray(t)?t.map(Te):t&&typeof t=="object"?Object.fromEntries(Object.keys(t).sort().map(e=>[e,Te(t[e])])):t}function Yr(t){if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("shadow-runner: record must be an object");return _e("sha256").update(JSON.stringify(Te(t))).digest("hex")}function ho(t,e,r,n,s){return _e("sha256").update(`${t}|${e}|${r}|${n}|${s}`).digest("hex")}function yo(t,e,r,n){return _e("sha256").update(`shadow|${t}|${e}|${r}|${n??""}`).digest("hex")}function wo(t){return t==="entryLong"||t==="exitShort"?"buy":t==="entryShort"||t==="exitLong"?"sell":t}function Kr(t){return t==="entryLong"||t==="entryShort"}function Ie({storePath:t,clock:e=Date.now}={}){if(typeof t!="string"||!t)throw new Error("shadow-runner: storePath required");let r=Vr({path:t});function n({strategy:l,evidenceId:u=null}={}){let f=K(l),c=u==null?null:String(u),d=r.list().filter(S=>S.status==="running"&&S.strategyHash===f.strategyHash&&S.compilerHash===f.compilerHash&&S.evidenceId===c).sort((S,P)=>S.createdAt-P.createdAt||S.id.localeCompare(P.id))[0];if(d)return $e(d);let m=e(),p=yo(m,f.strategyHash,f.compilerHash,c),h=r.get(p);if(h)return $e(h);let E={id:p,strategy:$e(f.strategy),strategyHash:f.strategyHash,compilerHash:f.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(E)}function s(l){return r.get(l)}function a(){return r.list()}function o(l){return r.stop(l)}function i(l,u,{markoutHorizons:f=[1,4,12]}={}){if(!Array.isArray(u))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(u.length===0)return c;let m=K(c.strategy).evaluateAll(u),p=new Map;for(let y=0;y<u.length;y++)p.set(u[y].t,y);let h=c.cursor,E=[];for(let y=0;y<u.length;y++){let A=u[y].t;(h==null||A>h)&&E.push(y)}if(E.length===0)return c;let S=new Map(c.intendedOrders.map(y=>[y.id,y])),P=new Set(c.fills.map(y=>y.orderId)),T=new Map(c.missedFills.map(y=>[y.orderId,y])),x=(y,A)=>`${y}|${A}`,R=new Map(c.markouts.map(y=>[x(y.orderId,y.horizon),y])),_=c.position?{...c.position}:null,g=Number.isInteger(c.cooldownBarsRemaining)?Math.max(0,c.cooldownBarsRemaining):0,V=Number.isFinite(c.cooldownStartT)?c.cooldownStartT:null;function ot({action:y,signalBarT:A,signalIndex:v}){let j=wo(y),F=ho(c.id,c.strategyHash,A,j,y);if(S.has(F))return S.get(F);let I=v+1,N=I<u.length,z={id:F,action:y,type:y,side:j,signalBarT:A,fillBarT:N?u[I].t:null,status:N?"open":"missed"};return S.set(F,z),c.intendedOrders.push(z),z}function it(y,A,v){if(P.has(y.id))return;let j={orderId:y.id,action:Kr(y.action)?"entry":"exit",side:y.side,price:A.o,barT:A.t,signalBarT:y.signalBarT,barIndex:v};if(c.fills.push(j),P.add(y.id),y.status="filled",y.fillBarT=A.t,T.has(y.id)&&(T.delete(y.id),c.missedFills=c.missedFills.filter(F=>F.orderId!==y.id)),Kr(y.action)){_={side:y.action==="entryLong"?"long":"short",entryOrderId:y.id,entryBarT:A.t,entryPrice:A.o,entryBarIndex:v};for(let F of f){let I=x(y.id,F);if(R.has(I))continue;let N={orderId:y.id,horizon:F,entryBarT:A.t,entryPrice:A.o,side:_.side,status:"pending",close:null,barT:null};R.set(I,N),c.markouts.push(N)}}else _=null,g=Number(c.strategy?.risk?.cooldownBars)||0,V=A.t}function W(y){if(P.has(y.id)||T.has(y.id))return;let A={orderId:y.id,action:y.action,side:y.side,signalBarT:y.signalBarT,status:"missed"};T.set(y.id,A),c.missedFills.push(A),y.status="missed"}for(let y of c.intendedOrders){if(y.status==="filled"||P.has(y.id))continue;let A=p.get(y.signalBarT);if(A==null)continue;let v=A+1;v<u.length&&(h==null||u[v].t>h)&&it(y,u[v],v)}for(let y of E){let A=u[y],v=m[y].signals,j=_,F=N=>{if(_||g>0&&(V==null||A.t>=V))return;let q=ot({action:N,signalBarT:A.t,signalIndex:y}),Z=y+1;Z<u.length?it(q,u[Z],Z):W(q)},I=N=>{if(!_||_.side==="long"&&N!=="exitLong"||_.side==="short"&&N!=="exitShort")return;let z=ot({action:N,signalBarT:A.t,signalIndex:y}),q=y+1;q<u.length?it(z,u[q],q):W(z)};j?(v.exitLong&&I("exitLong"),v.exitShort&&I("exitShort")):v.entryLong&&v.entryShort||(v.entryLong&&F("entryLong"),v.entryShort&&F("entryShort")),g>0&&V!=null&&A.t>=V&&(g-=1,g===0&&(V=null)),c.cursor=A.t,c.lastProcessedBarIndex=y}for(let y of c.markouts){if(y.status!=="pending")continue;let A=c.fills.find(F=>F.orderId===y.orderId&&F.action==="entry");if(!A)continue;let v=p.get(A.barT);if(v==null)continue;let j=v+y.horizon;if(j<u.length){y.close=u[j].c,y.barT=u[j].t,y.status="filled";let F=y.entryPrice;y.markout=y.side==="long"?(y.close-F)/F:(F-y.close)/F}}return c.position=_,c.cooldownBarsRemaining=g,c.cooldownStartT=V,c.updatedAt=e(),c})}return{start:n,step:i,list:a,get:s,stop:o}}var Gr=B(()=>{pt();Jr()});var Zr={};un(Zr,{runStrategyOperation:()=>Po});import go from"node:os";import bo from"node:path";function Rt(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function xo(t){return String(t).toLowerCase().replace(/[^a-z0-9]/g,"")}function ve(t){if(Array.isArray(t)){for(let e of t)ve(e);return}if(Rt(t))for(let[e,r]of Object.entries(t)){if(Eo.some(n=>xo(e).includes(n)))throw new Error(`strategy service: secret-like field "${e}" is forbidden`);ve(r)}}function ko(t){if(!Rt(t))throw new TypeError("strategy input must be a plain object");return ve(t),t}function So(t,e){let r=e.nowMs??t.nowMs??Date.now();if(!Number.isInteger(r))throw new TypeError("nowMs must be an integer epoch milliseconds");return r}async function Oe(t,e,r,n){if(Array.isArray(e.bars))return e.bars;let s=le(t.venue),a=r.fetchBars??s.fetchBars;if(typeof a!="function")throw new Error(`strategy venue ${s.id} does not support history`);let o=await a({coin:t.market.coin,interval:t.market.interval,count:e.count??1500,endTime:e.endTime??n}),i=Array.isArray(o)?o:o?.bars;if(!Array.isArray(i))throw new Error("strategy history provider returned no bars");return i}function Ne(t,e){let r=t.backtestOptions??{};if(!Rt(r))throw new TypeError("backtestOptions must be a plain object");return{...r,nowMs:e}}function Xr(t,e,r,n,s={}){let a=t.evidenceOptions??{};if(!Rt(a))throw new TypeError("evidenceOptions must be a plain object");return{...a,...s,strategy:e,bars:r,backtestOptions:Ne(t,n)}}function Wr(){return bo.join(go.homedir(),".oracle","strategy-shadow.json")}function Ao(t,e){return{perStrategyNotionalUsd:t.risk.maxNotionalUsd,maxLeverage:t.risk.maxLeverage,dailyLossCapUsd:t.risk.maxNotionalUsd*(t.risk.maxDailyLossPct/100),chainAllowlist:[t.venue],assetAllowlist:[t.market.coin],expiresAt:Math.min(t.risk.expiresAt,e+864e5),killSwitchRequired:!0}}async function Po(t,e={},r={}){let n=ko(e),s=So(n,r);if(t==="draft")return{strategy:Rr(n.prompt,{nowMs:s})};if(t==="validate"){let a=K(n.strategy);if(a.strategy.risk.expiresAt<=s)throw new Error("strategy is expired");return{valid:!0,strategy:a.strategy,strategyHash:a.strategyHash,compilerHash:a.compilerHash,compilerVersion:a.compilerVersion,requiredSeries:a.requiredSeries}}if(t==="backtest"||t==="evidence"){let a=K(n.strategy),o=await Oe(a.strategy,n,r,s);Nt(a,o);let i=ne(Xr(n,a.strategy,o,s));return t==="evidence"?i:{backtest:at(a.strategy,o,Ne(n,s)),evidence:i}}if(t==="optimize"){let a=K(n.strategy),o=await Oe(a.strategy,n,r,s);Nt(a,o);let i=n.trainFraction,l=n.evidenceOptions?.trainFraction;if(i!=null&&l!=null&&i!==l)throw new TypeError("conflicting trainFraction controls are forbidden");let u=i??l??.7;if(typeof u!="number"||u<=0||u>=1)throw new TypeError("trainFraction must be in (0,1)");let f=o.slice(0,Math.floor(o.length*u)),c=n.options??{};if(!Rt(c))throw new TypeError("options must be a plain object");let d=qr(a.strategy,f,{...c,...n.maxTrials==null?{}:{maxTrials:n.maxTrials},backtestOptions:Ne(n,s)}),m=d.bestStrategy;return{strategy:m,optimization:d,evidence:ne(Xr(n,m,o,s,{trainFraction:u}))}}if(t==="shadow"){let a=Ie({storePath:r.storePath??Wr(),clock:()=>s}),o=n.action;if(o==="start")return await a.start({strategy:n.strategy,evidenceId:n.evidenceId??n.evidence?.id??null});if(o==="list")return await a.list();if(o==="get")return await a.get(n.id);if(o==="stop")return await a.stop(n.id);if(o==="step"){let i=await a.get(n.id);if(!i)throw new Error(`shadow runner not found: ${n.id}`);let l=await Oe(i.strategy,n,r,s);return Nt(K(i.strategy),l),await a.step(n.id,l,n.stepOptions??{})}throw new Error(`unknown shadow action: ${o}`)}if(t==="prepare"){let a=K(n.strategy),o=le(a.strategy.venue);if(typeof n.shadowId!="string"||!n.shadowId)throw new Error("strategy prepare requires a matching shadow runner id");let l=await Ie({storePath:r.storePath??Wr(),clock:()=>s}).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!==a.strategyHash||l.compilerHash!==a.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 u=n.caps??Ao(a.strategy,s);return o.prepareIntent({strategy:a.strategy,evidence:n.evidence,shadow:{id:l.id,stateHash:Yr(l),status:l.status,cursor:l.cursor,updatedAt:l.updatedAt},caps:u,nowMs:s,env:r.env??process.env})}throw new Error(`unknown strategy operation: ${t}`)}var Eo,Qr=B(()=>{Ht();pt();se();jr();Cr();Gr();ue();Eo=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});import tn from"node:fs";function $o(t){let e={},r=[];for(let n=0;n<t.length;n++){let s=t[n];if(!s.startsWith("--")){r.push(s);continue}let a=s.slice(2),o=t[n+1];o!=null&&!o.startsWith("--")?(e[a]=o,n++):e[a]=!0}return{flags:e,positional:r}}function ht(t,e){if(!t)throw new Error(`${e} path required`);let r=t==="-"?tn.readFileSync(0,"utf8"):tn.readFileSync(t,"utf8");try{return JSON.parse(r)}catch{throw new Error(`${e} must contain valid JSON`)}}function en(t,e){if(t==null)return;let r=Number(t);if(!Number.isFinite(r))throw new Error(`${e} must be a finite number`);return r}var To=`oracle strategy <draft|validate|backtest|optimize|evidence|shadow|prepare> [args]
1
+ var ln=Object.defineProperty;var B=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var un=(e,t)=>{for(var r in t)ln(e,r,{get:t[r],enumerable:!0})};import{createHash as fn}from"node:crypto";function hn(e){let t=String(e||"").toLowerCase();return Bt.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function yn(e){let t={};for(let[r,n]of Object.entries(e||{}))hn(r)||(t[r]=n);return t}function wn(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 gn(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function bn(e,t,r){let n={};for(let[l,u]of Object.entries(r||{}))n[l.toLowerCase()]=u;let s=Object.keys(n).filter(l=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(l)),o=[...new Set([...Bt,...s])].sort().map(l=>`${l}=${n[l]??""}`).join(`
2
+ `),i=fn("sha256").update(o).digest("hex").slice(0,32);return`${e} ${t} ${i}`}function En(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,qt):Math.min(250*2**e,qt)+Math.floor(Math.random()*100)}async function kn(e,{fetchImpl:t,method:r,headers:n,body:s,timeoutMs:a}){let o=new AbortController,i=setTimeout(()=>o.abort(),a);try{let l=String(e),u={...n||{}};for(let f=0;f<=Ct;f+=1){let c=await t(l,{method:r,headers:u,body:s,signal:o.signal,redirect:"manual"}),d=await c.text(),m=null;if(d)try{m=JSON.parse(d)}catch{m=null}if(mn.has(c.status)){if(r!=="GET"&&r!=="HEAD"){let h=new Error(`HTTP ${c.status} ${r} ${l} redirected non-idempotent request`);throw h.status=c.status,h.body=m??d.slice(0,300),h}if(f===Ct)throw new Error(`HTTP redirect loop for ${e}`);let p=wn(c.headers?.get?.("location"),l);gn(p,l)||(u=yn(u)),l=p;continue}if(!c.ok){let p=new Error(`HTTP ${c.status} ${r} ${l}`);throw p.status=c.status,p.retryAfter=c.headers?.get?.("retry-after")??null,p.body=m??d.slice(0,300),p}return m??d}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(i)}}async function zt(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,s=(t.method||"GET").toUpperCase(),a={Accept:"application/json",...t.headers||{}},o=t.body;o!=null&&typeof o!="string"&&(a["Content-Type"]=a["Content-Type"]||"application/json",o=JSON.stringify(o));let i=Number.isInteger(t.retries)?Math.max(t.retries,0):pn,l=async()=>{let m;for(let p=0;p<=i;p++)try{return await kn(e,{fetchImpl:r,method:s,headers:a,body:o,timeoutMs:n})}catch(h){m=h;let E=h?.status,S=h?.name==="AbortError",P=new Set([408,425,429]),T=E!=null?P.has(E)||dn.has(E)&&Ut.has(s):!S&&Ut.has(s);if(p===i||!T)throw h;await xn(En(p,h?.retryAfter))}throw m};if(!(t.dedupe!==!1&&s==="GET"&&o==null))return l();let f=bn(s,e,a),c=We.get(f);if(c)return c;let d=l().finally(()=>We.delete(f));return We.set(f,d),d}var dn,Ut,pn,qt,Bt,mn,Ct,We,xn,Dt=B(()=>{dn=new Set([408,425,429,500,502,503,504]),Ut=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),pn=2,qt=4e3,Bt=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],mn=new Set([301,302,303,307,308]),Ct=3;We=new Map;xn=e=>new Promise(t=>setTimeout(t,e))});function Pn({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"?An:Sn}async function Ze(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=Pn(t);return zt(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function Vt(e={}){return Ze({type:"meta"},e)}async function Jt({coin:e,interval:t="1h",startTime:r,endTime:n},s={}){if(!e)throw new Error("hlCandleSnapshot requires coin");let a={type:"candleSnapshot",req:{coin:String(e),interval:t,startTime:r??Date.now()-24*3600*1e3,endTime:n??Date.now()}};return Ze(a,s)}async function Kt({coin:e,startTime:t,endTime:r},n={}){if(!e)throw new Error("hlFundingHistory requires coin");return Ze({type:"fundingHistory",coin:String(e),startTime:t??Date.now()-24*3600*1e3,endTime:r??Date.now()},n)}var Sn,An,Qe=B(()=>{Dt();Sn="https://api.hyperliquid.xyz/info",An="https://api.hyperliquid-testnet.xyz/info"});import{createHash as $n}from"node:crypto";function ee(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function ye(e){return typeof e=="number"&&Number.isFinite(e)}function rt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)rt(t);return Object.freeze(e)}for(let t of Object.keys(e))rt(e[t]);return Object.freeze(e)}function ue(e){if(Array.isArray(e))return e.map(ue);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=ue(e[r]);return t}return e}function et(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 Yt(e){return{feesUsd:e.costs.feesUsd,builderFeesUsd:e.costs.builderFeesUsd,fundingUsd:e.costs.fundingUsd,slippageUsd:e.costs.slippageUsd}}function _n(e){return(e.feesUsd||0)+(e.builderFeesUsd||0)+Math.max(0,e.fundingUsd||0)+(e.slippageUsd||0)}function In(e){let t=0;for(let r of e.trades)r.grossPnlUsd>0&&(t+=r.grossPnlUsd);return t}function On(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 Xt(e){if(!ee(e))throw new TypeError("evidence artifact must be a plain object");if(!Tn.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(!ee(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(!ee(e.walkForward)||!Array.isArray(e.walkForward.windows))throw new TypeError("evidence artifact walkForward windows required");if(e.status==="pass_live_eligible"&&(!ee(e.train)||!ee(e.holdout)))throw new TypeError("live-eligible evidence artifact requires train and holdout facts");return ue({barsHash:e.barsHash,compilerHash:e.compilerHash,flags:e.flags.map(t=>ue(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 Wt(e){return $n("sha256").update(JSON.stringify(Xt(e)),"utf8").digest("hex")}function G(e,t,r=0){if(!Number.isInteger(e)||e<r)throw new Error(`${t} must be an integer >= ${r}`);return e}function tt(e,t){if(!ee(e)||!ee(e.metrics))throw new Error(`${t} metrics required`);let r=G(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(!ye(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 vn(e,{maxDailyLossPct:t}={}){let r=e.split,n=G(r.trainStartIndex,"split.trainStartIndex"),s=G(r.trainEndIndex,"split.trainEndIndex"),a=G(r.trainBarCount,"split.trainBarCount",1),o=G(r.holdoutStartIndex,"split.holdoutStartIndex"),i=G(r.holdoutEndIndex,"split.holdoutEndIndex"),l=G(r.holdoutBarCount,"split.holdoutBarCount",1);if(n!==0||s-n+1!==a||o!==s+1||i-o+1!==l)throw new Error("evidence split must be contiguous, chronological, and count-consistent");if(!ye(r.trainFraction)||r.trainFraction<=0||r.trainFraction>=1)throw new Error("split.trainFraction must be in (0,1)");tt(e.train,"train");let u=tt(e.holdout,"holdout");if(u.tradeCount<1||u.netPnlUsd<=0||u.profitFactor<=1)throw new Error("live-eligible holdout metrics do not pass");if(ye(t)&&u.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 f=e.walkForward,c=f.windows;if(c.length<1||f.windowsRun!==c.length)throw new Error("live-eligible walk-forward windowsRun must match nonempty windows");let d=0,m=-1;for(let h=0;h<c.length;h++){let E=c[h];if(!ee(E)||E.index!==h||typeof E.passed!="boolean")throw new Error("walk-forward windows must be ordered and structurally valid");let S=G(E.trainStartIndex,`walkForward.windows[${h}].trainStartIndex`),P=G(E.trainEndIndex,`walkForward.windows[${h}].trainEndIndex`),T=G(E.evalStartIndex,`walkForward.windows[${h}].evalStartIndex`),x=G(E.evalEndIndex,`walkForward.windows[${h}].evalEndIndex`);if(S!==0||P>=T||T>x||T<=m)throw new Error("walk-forward windows must be chronological and disjoint");if(m=x,E.passed){if(d+=1,E.reason!=="pass")throw new Error("passed walk-forward window reason must be pass");let R=tt({metrics:E.metrics,tradeCount:E.metrics?.tradeCount},`walkForward.windows[${h}]`);if(R.tradeCount<1||R.netPnlUsd<=0||R.profitFactor<=1)throw new Error("passed walk-forward window metrics do not pass");if(ye(t)&&R.maxDrawdownPct>t)throw new Error("passed walk-forward drawdown exceeds strategy risk")}else if(E.reason==="pass")throw new Error("failed walk-forward window cannot have pass reason")}let p=d/c.length;if(!ye(f.passRate)||Math.abs(f.passRate-p)>Number.EPSILON||p<.6)throw new Error("walk-forward passRate contradicts concrete windows or is below live threshold")}function Zt(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=Xt(e),n=ue({id:e.id,...r});if(JSON.stringify(ue(e))!==JSON.stringify(n))throw new Error("evidence artifact contains fields unbound from its deterministic identity");let s=Wt(e);if(e.id!==s)throw new Error("evidence.id does not match its deterministic artifact facts digest");return e.status==="pass_live_eligible"&&vn(e,t),e}function nt({strategy:e,bars:t,backtestOptions:r={},trainFraction:n=.7,walkForwardWindows:s=3,minTrades:a=10}={}){let o=[];if(!ee(e))throw new TypeError("strategy must be a plain object");if(!Array.isArray(t))throw new TypeError("bars must be an array");if(!ee(r))throw new TypeError("backtestOptions must be a plain object");if(!ye(n)||n<=0||n>=1)throw new TypeError("trainFraction must be in (0,1)");if(!Number.isInteger(s)||s<1)throw new TypeError("walkForwardWindows must be a positive integer");if(!Number.isInteger(a)||a<0)throw new TypeError("minTrades must be an integer >= 0");let i=J(e),l=we(i),u=$e(t),f=t.length,c=(I=[],M={})=>Gt({status:"fail",strategy:i,sHash:l,barsHash:u,split:M.split||{trainStartIndex:0,trainEndIndex:-1,trainBarCount:0,holdoutStartIndex:0,holdoutEndIndex:-1,holdoutBarCount:0,trainFraction:n},train:M.train||null,holdout:M.holdout||null,walkForward:M.walkForward||{windows:[],passRate:0},flags:[...o,...I]});if(f<10)return c([{type:"insufficient_bars",message:"need at least 10 bars for evidence"}]);let d=Math.floor(f*n),m=d,p=f-m;if(d<5||p<3)return c([{type:"invalid_windowing",message:"train/holdout split too small",trainCount:d,holdoutCount:p}]);let h=t.slice(0,d),E=t.slice(m),S,P;try{S=ae(i,h,r),P=ae(i,E,r)}catch(I){return c([{type:"backtest_error",message:String(I.message||I)}])}let T={metrics:et(S),costs:Yt(S),tradeCount:S.metrics.tradeCount},x={metrics:et(P),costs:Yt(P),tradeCount:P.metrics.tradeCount},R={trainStartIndex:0,trainEndIndex:d-1,trainBarCount:d,holdoutStartIndex:m,holdoutEndIndex:f-1,holdoutBarCount:p,trainFraction:n},_=[],g=Math.floor(f/(s+1));if(g<3)o.push({type:"invalid_windowing",message:"walk-forward window size too small",wfSize:g});else for(let I=0;I<s;I++){let M=g*(I+1),z=M,q=Math.min(f,z+g);if(q-z<3||M<3){_.push({index:I,trainStartIndex:0,trainEndIndex:M-1,evalStartIndex:z,evalEndIndex:q-1,passed:!1,reason:"window_too_small",metrics:null});continue}let Z=t.slice(z,q),je;try{je=ae(i,Z,r)}catch{_.push({index:I,trainStartIndex:0,trainEndIndex:M-1,evalStartIndex:z,evalEndIndex:q-1,passed:!1,reason:"backtest_error",metrics:null});continue}let Fe=et(je),Le=On(Fe,i.risk,a);_.push({index:I,trainStartIndex:0,trainEndIndex:M-1,evalStartIndex:z,evalEndIndex:q-1,passed:Le,reason:Le?"pass":"fail_metrics",metrics:Fe})}let V=_.filter(I=>I.passed).length,oe=_.length===0?0:V/_.length,ie={windows:_,passRate:oe,windowsRun:_.length};x.metrics.tradeCount===0&&T.metrics.tradeCount===0&&o.push({type:"no_trades",message:"no trades in train or holdout"}),x.metrics.tradeCount===0&&o.push({type:"absent_oos_trades",message:"holdout produced no trades"}),x.metrics.netPnlUsd<0&&o.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?o.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>=a&&o.push({type:"severe_oos_collapse",message:"holdout pnl collapsed vs train"});let W=_n(x.costs),y=In(P);y>0&&W>y&&o.push({type:"costs_exceed_gross",message:"holdout costs exceed gross gains"});let A=o.some(I=>["insufficient_bars","invalid_windowing","absent_oos_trades","holdout_loss","no_trades","severe_oos_collapse","backtest_error"].includes(I.type)),v=o.some(I=>I.type==="overfit"),j="fail";return x.metrics.tradeCount>=a&&x.metrics.netPnlUsd>0&&x.metrics.profitFactor>1&&x.metrics.maxDrawdownPct<=i.risk.maxDailyLossPct&&oe>=.6&&!(y>0&&W>y)&&!v&&!o.some(I=>I.type==="severe_oos_collapse"||I.type==="invalid_windowing")?j="pass_live_eligible":!A&&x.metrics.tradeCount>0&&T.metrics.tradeCount>0&&Number.isFinite(x.metrics.netPnlUsd)?(j="pass_paper_only",x.metrics.tradeCount<a&&o.push({type:"undersampled",message:"holdout trades below minTrades"})):v&&x.metrics.tradeCount>0&&T.metrics.netPnlUsd>0?j="fail":x.metrics.tradeCount>0&&T.metrics.tradeCount>0&&!A?j="pass_paper_only":j="fail",x.metrics.netPnlUsd<0&&(j=j==="pass_live_eligible"?"fail":j==="pass_paper_only"?"pass_paper_only":"fail",j="fail"),Gt({status:j,strategy:i,sHash:l,barsHash:u,split:R,train:T,holdout:x,walkForward:ie,flags:o})}function Gt({status:e,strategy:t,sHash:r,barsHash:n,split:s,train:a,holdout:o,walkForward:i,flags:l}){let u={status:e,strategyHash:r,compilerHash:de,barsHash:n,split:s,train:a,holdout:o,walkForward:i,flags:l};return u.id=Wt(u),rt(ue(JSON.parse(JSON.stringify(u))))}var Tn,st=B(()=>{pe();fe();He();Tn=Object.freeze(["fail","pass_paper_only","pass_live_eligible"])});import{createHash as Mn,createHmac as Nn,timingSafeEqual as qo}from"node:crypto";function ot(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(ot).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ot(e[r])}`).join(",")}}`}function Qt(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function er(e=process.env){return Qt(process.env)||Qt(e)}function Fn(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:s,...a}=e||{};return a}function Ln(e){let t=Fn(e);return Mn("sha256").update(ot(t)).digest("hex")}function Hn(e,t=er()){return t?Nn("sha256",t).update(String(e)).digest("hex"):""}function tr(e,{provider:t,kind:r,env:n=process.env}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let s={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!s.provider)throw new Error("stampPrepared: provider required");if(!s.kind)throw new Error("stampPrepared: kind required");let a=Date.now(),o=a+jn,l={...s,preparedAt:a,expiresAt:o,prepareVersion:Rn},u=Ln(l),f=er(n),c=f?Hn(u,f):void 0,d={...l,oraclePrepared:!0,prepareHash:u};return c&&(d.prepareMac=c),d}var Rn,jn,Co,rr=B(()=>{Rn=2,jn=300*1e3,Co=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});function Te(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function qn(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function at(e,t="value"){if(Array.isArray(e)){e.forEach((r,n)=>at(r,`${t}[${n}]`));return}if(Te(e))for(let[r,n]of Object.entries(e)){let s=qn(r);if(Un.some(a=>s.includes(a)))throw new Error(`handoff: forbidden secret-like field at ${t}.${r}`);at(n,`${t}.${r}`)}}function it(e){return typeof e=="number"&&Number.isFinite(e)&&e>0}function nr({strategy:e,evidence:t,shadow:r,caps:n,nowMs:s=Date.now(),env:a=process.env}={}){if(at({strategy:e,evidence:t,shadow:r,caps:n},"handoff"),!Te(e))throw new Error("handoff: strategy required");if(!Te(t))throw new Error("handoff: evidence required");if(!Te(r))throw new Error("handoff: shadow required");if(!Te(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>s)throw new Error("handoff: shadow.updatedAt must be a positive integer <= nowMs");let o=J(e,{nowMs:s}),i=K(o);if(Zt(t,{maxDailyLossPct:o.risk.maxDailyLossPct}),t.status!=="pass_live_eligible")throw new Error("handoff: evidence.status must be pass_live_eligible");if(t.strategyHash!==i.strategyHash)throw new Error("handoff: evidence.strategyHash mismatch");if(t.compilerHash!==i.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>i.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>i.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 u=i.strategy.risk.maxNotionalUsd*(i.strategy.risk.maxDailyLossPct/100);if(n.dailyLossCapUsd>u)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]!==i.strategy.market.coin)throw new Error("handoff: caps.assetAllowlist must contain only the strategy market coin");if(!Number.isInteger(n.expiresAt)||!(n.expiresAt>s))throw new Error("handoff: caps.expiresAt must be an integer > nowMs");if(n.expiresAt>i.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 f={perStrategyNotionalUsd:n.perStrategyNotionalUsd,maxLeverage:n.maxLeverage,dailyLossCapUsd:n.dailyLossCapUsd,chainAllowlist:[...n.chainAllowlist],assetAllowlist:[...n.assetAllowlist],expiresAt:n.expiresAt,killSwitchRequired:!0},c={strategyHash:i.strategyHash,compilerHash:i.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:i.strategyHash,compilerHash:i.compilerHash,compilerVersion:_e,venue:"hyperliquid",market:{coin:i.strategy.market.coin,kind:"perp",interval:i.strategy.market.interval},risk:{...i.strategy.risk},strategy:JSON.parse(JSON.stringify(i.strategy))},arming:{liveBroadcast:!1,requiresExplicitUserArm:!0,caps:f},requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,executionReady:!1};return tr(c,{provider:"hl-strategy",kind:"strategy-live-handoff",env:a})}var Un,sr=B(()=>{pe();st();fe();rr();Un=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});function ge(e,t){let r=Number(e);if(!Number.isFinite(r))throw new TypeError(`${t} must be finite`);return r}function be(e,t){if(!Number.isSafeInteger(e)||e<0)throw new TypeError(`${t} must be a non-negative safe integer`);return e}function Ie(e){if(Array.isArray(e))for(let t of e)Ie(t);else if(e&&typeof e=="object")for(let t of Object.values(e))Ie(t);return Object.freeze(e)}function Bn(e){let t=Cn[e];if(!t)throw new TypeError(`unsupported strategy interval: ${e}`);return t}function zn(e,{endTime:t=Number.MAX_SAFE_INTEGER}={}){if(!Array.isArray(e))throw new TypeError("Hyperliquid candles must be an array");be(t,"endTime");let r=new Map;for(let n=0;n<e.length;n++){let s=e[n];if(!s||typeof s!="object"||Array.isArray(s))throw new TypeError(`candles[${n}] must be an object`);let a=be(Number(s.t),`candles[${n}].t`);if(be(Number(s.T),`candles[${n}].T`)>t)continue;let i={t:a,o:ge(s.o,`candles[${n}].o`),h:ge(s.h,`candles[${n}].h`),l:ge(s.l,`candles[${n}].l`),c:ge(s.c,`candles[${n}].c`),v:ge(s.v,`candles[${n}].v`)};if(i.h<Math.max(i.o,i.c,i.l))throw new TypeError(`candles[${n}].h is below another price`);if(i.l>Math.min(i.o,i.c,i.h))throw new TypeError(`candles[${n}].l is above another price`);if(i.v<0)throw new TypeError(`candles[${n}].v must be non-negative`);let l=r.get(a);if(l&&JSON.stringify(l)!==JSON.stringify(i))throw new TypeError(`conflicting duplicate candle at timestamp ${a}`);l||r.set(a,i)}return Ie([...r.values()].sort((n,s)=>n.t-s.t))}function Dn(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 s=e[n];if(!s||typeof s!="object"||Array.isArray(s))throw new TypeError(`funding[${n}] must be an object`);let a=be(Number(s.time),`funding[${n}].time`);a>t||r.set(a,{time:a,fundingRate:ge(s.fundingRate,`funding[${n}].fundingRate`)})}return[...r.values()].sort((n,s)=>n.time-s.time)}async function Vn({coin:e,startTime:t,endTime:r},n){let s=[],a=Math.max(0,t-288e5),o=!1;for(let i=0;i<16&&a<=r;i++){let l=await Kt({coin:e,startTime:a,endTime:r},n);if(!Array.isArray(l))throw new TypeError("Hyperliquid funding history must be an array");s.push(...l);let u=a;for(let f of l){let c=Number(f?.time);Number.isSafeInteger(c)&&c>u&&(u=c)}if(l.length<500||u>=r){o=!0;break}if(u<=a)throw new Error("Hyperliquid funding history pagination did not advance");a=u+1}if(!o)throw new Error("strategy history exceeds the bounded funding history limit");return Dn(s,r)}function Jn(e,t,r){let n=0,s=null;return e.map(a=>{let o=a.t+r,i=0;for(;n<t.length&&t[n].time<o;){let l=t[n];s=l.fundingRate,l.time>=a.t&&(i+=l.fundingRate),n+=1}return s==null?{...a,fundingPaymentRate:i}:{...a,fundingRate:s,fundingPaymentRate:i}})}async function or(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"),s=Bn(n);if(e.endTime==null)throw new TypeError("endTime is required for deterministic history");let a=be(e.endTime,"endTime"),o=e.count==null?1500:e.count;if(!Number.isInteger(o)||o<20||o>5e3)throw new TypeError("count must be an integer from 20 to 5000");let i=e.startTime==null?Math.max(0,a-o*s):be(e.startTime,"startTime");if(i>=a)throw new TypeError("startTime must be before endTime");let[l,u]=await Promise.all([Jt({coin:r,interval:n,startTime:i,endTime:a},t),Vn({coin:r,startTime:i,endTime:a},t)]),f=zn(l,{endTime:a}),c=Ie(Jn(f,u,s));return Ie({coin:r,interval:n,range:{startTime:i,endTime:a},bars:c})}var Cn,ir=B(()=>{Qe();Cn=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 Gn(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))Yn.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"||!Kn.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 Xn(e={}){let t=await Vt(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 Kn,Yn,ar,cr=B(()=>{Qe();sr();ir();Kn=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),Yn=new Set(["coin","interval"]);ar=Object.freeze({id:"hyperliquid",validateMarket:Gn,fetchBars:or,listMarkets:Xn,prepareIntent(e){return nr(e)}})});function Zn(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 Wn.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 ct(e){return typeof e!="string"?null:Qn.get(e)??null}function lt(e){let t=ct(e);if(!t)throw new Error(`unknown strategy venue: ${String(e)}`);return t}var Wn,lr,Qn,ti,ut=B(()=>{cr();Wn=Object.freeze(["id","validateMarket","prepareIntent"]);lr=[ar].map(Zn),Qn=new Map(lr.map(e=>[e.id,e])),ti=Object.freeze([...lr])});import{createHash as es}from"node:crypto";function Y(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function U(e){return typeof e=="number"&&Number.isFinite(e)}function wr(e){return Number.isInteger(e)&&e>0}function ht(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)ht(t);return Object.freeze(e)}for(let t of Object.keys(e))ht(e[t]);return Object.freeze(e)}function yt(e){if(Array.isArray(e))return e.map(yt);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=yt(e[r]);return t}return e}function w(e,t,r){e.push({path:t,message:r})}function ce(e,t,r,n){for(let s of Object.keys(e))t.has(s)||w(n,r?`${r}.${s}`:s,"unknown field is not allowed")}function xr(e,t,r,n){if(!U(e)||!U(t)||!U(r)||!U(n)||n<=0||e<t||e>r)return!1;let s=(e-t)/n;if(!Number.isFinite(s))return!1;let a=Math.round(s);return Math.abs(s-a)<=1e-9}function mt(e,t,r,n){if(Y(e)){if(ce(e,new Set(["param"]),t,n),typeof e.param!="string"||!e.param)return w(n,`${t}.param`,"must be a parameter name string"),null;if(!Object.prototype.hasOwnProperty.call(r,e.param))return w(n,`${t}.param`,`unknown parameter "${e.param}"`),null;let s=r[e.param];return!Y(s)||![s.value,s.min,s.max,s.step].every(wr)?(w(n,`${t}.param`,"referenced period parameter value min max and step must be positive integers"),null):{param:e.param}}return wr(e)?e:(w(n,t,"must be a positive integer or {param}"),null)}function gr(e,t,r,n){return Y(e)?(ce(e,new Set(["param"]),t,n),typeof e.param!="string"||!e.param?(w(n,`${t}.param`,"must be a parameter name string"),null):Object.prototype.hasOwnProperty.call(r,e.param)?{param:e.param}:(w(n,`${t}.param`,`unknown parameter "${e.param}"`),null)):U(e)?e:(w(n,t,"must be a finite number or {param}"),null)}function Ue(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 ls(e){let t=new Map,r=n=>{let s=t.get(n)||0;if(s===1)return!0;if(s===2)return!1;t.set(n,1);let a=e.get(n);if(a){for(let o of Ue(a))if(e.has(o)&&r(o))return!0}return t.set(n,2),!1};for(let n of e.keys())if(r(n))return!0;return!1}function us(e,t){if(!Y(e))return w(t,"parameters","must be a plain object"),null;let r=Object.keys(e);if(r.length>mr)return w(t,"parameters",`too many parameters (max ${mr})`),null;let n={};for(let s of r){if(!br.test(s)){w(t,`parameters.${s}`,"parameter name is malformed");continue}let a=e[s],o=`parameters.${s}`;if(!Y(a)){w(t,o,"must be a plain object");continue}ce(a,fr,o,t);for(let c of fr)c in a||w(t,`${o}.${c}`,"required field is missing");let{value:i,min:l,max:u,step:f}=a;U(l)||w(t,`${o}.min`,"must be a finite number"),U(u)||w(t,`${o}.max`,"must be a finite number"),(!U(f)||f<=0)&&w(t,`${o}.step`,"must be a positive finite number"),U(i)||w(t,`${o}.value`,"must be a finite number"),U(l)&&U(u)&&l>u&&w(t,`${o}.min`,"min must be <= max"),U(i)&&U(l)&&U(u)&&U(f)&&f>0&&(xr(i,l,u,f)||w(t,`${o}.value`,"value must lie on the declared min/max/step grid")),n[s]={value:i,min:l,max:u,step:f}}return n}function fs(e,t,r,n){let s=`nodes.${t}`;if(!Y(e))return w(n,s,"must be a plain object"),null;if(typeof e.type!="string"||!pr[e.type])return w(n,`${s}.type`,"unknown or missing node type"),ce(e,cs,s,n),null;switch(ce(e,pr[e.type],s,n),(typeof e.id!="string"||!Er.test(e.id))&&w(n,`${s}.id`,"must be a 1-64 char id starting with alphanumeric"),e.type){case"input":return(typeof e.field!="string"||!ts.has(e.field))&&w(n,`${s}.field`,"must be one of open|high|low|close|volume|fundingRate|openInterest"),{id:e.id,type:"input",field:e.field};case"constant":{let a=gr(e.value,`${s}.value`,r,n);return{id:e.id,type:"constant",value:a}}case"indicator":{(typeof e.indicator!="string"||!rs.has(e.indicator))&&w(n,`${s}.indicator`,"must be one of sma|ema|rsi|macd|bollinger|atr");let a=e.indicator,o={id:e.id,type:"indicator",indicator:a};if(a==="atr"){"input"in e&&(typeof e.input!="string"||!e.input?w(n,`${s}.input`,"must be a node id string when provided"):o.input=e.input);let i=mt(e.period,`${s}.period`,r,n);i!=null&&(o.period=i)}else typeof e.input!="string"||!e.input?w(n,`${s}.input`,"must be a node id string"):o.input=e.input;if((a==="sma"||a==="ema"||a==="rsi"||a==="bollinger"||a==="atr")&&("period"in e,a!=="macd"))if(!("period"in e))w(n,`${s}.period`,"required field is missing");else{let i=mt(e.period,`${s}.period`,r,n);i!=null&&(o.period=i)}if(a==="macd"){for(let i of["fastPeriod","slowPeriod","signalPeriod"])if(!(i in e))w(n,`${s}.${i}`,"required field is missing");else{let l=mt(e[i],`${s}.${i}`,r,n);l!=null&&(o[i]=l)}"output"in e?is.has(e.output)?o.output=e.output:w(n,`${s}.output`,"must be line|signal|histogram"):w(n,`${s}.output`,"required field is missing"),"period"in e&&w(n,`${s}.period`,"forbidden for macd"),"stdDev"in e&&w(n,`${s}.stdDev`,"forbidden for macd")}else if(a==="bollinger"){if(!("stdDev"in e))w(n,`${s}.stdDev`,"required field is missing");else{let i=gr(e.stdDev,`${s}.stdDev`,r,n);i!=null&&(typeof i=="number"&&i<=0?w(n,`${s}.stdDev`,"must be > 0"):o.stdDev=i)}"output"in e?as.has(e.output)?o.output=e.output:w(n,`${s}.output`,"must be upper|middle|lower"):w(n,`${s}.output`,"required field is missing");for(let i of["fastPeriod","slowPeriod","signalPeriod"])i in e&&w(n,`${s}.${i}`,`forbidden for ${a}`)}else{"output"in e&&w(n,`${s}.output`,`forbidden for ${a}`),"stdDev"in e&&a!=="bollinger"&&w(n,`${s}.stdDev`,`forbidden for ${a}`);for(let i of["fastPeriod","slowPeriod","signalPeriod"])i in e&&w(n,`${s}.${i}`,`forbidden for ${a}`)}return o}case"compare":return(typeof e.op!="string"||!ns.has(e.op))&&w(n,`${s}.op`,"must be gt|gte|lt|lte|eq"),(typeof e.left!="string"||!e.left)&&w(n,`${s}.left`,"must be a node id"),(typeof e.right!="string"||!e.right)&&w(n,`${s}.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"||!ss.has(e.op))&&w(n,`${s}.op`,"must be and|or|not"),!Array.isArray(e.inputs))return w(n,`${s}.inputs`,"must be an array of node ids"),{id:e.id,type:"logic",op:e.op,inputs:[]};let a=[];for(let o=0;o<e.inputs.length;o++){let i=e.inputs[o];typeof i!="string"||!i?w(n,`${s}.inputs.${o}`,"must be a node id"):a.push(i)}return e.op==="not"?a.length!==1&&w(n,`${s}.inputs`,"not requires exactly one input"):(e.op==="and"||e.op==="or")&&a.length<2&&w(n,`${s}.inputs`,`${e.op} requires at least two inputs`),{id:e.id,type:"logic",op:e.op,inputs:a}}case"cross":return(typeof e.direction!="string"||!os.has(e.direction))&&w(n,`${s}.direction`,"must be above|below"),(typeof e.left!="string"||!e.left)&&w(n,`${s}.left`,"must be a node id"),(typeof e.right!="string"||!e.right)&&w(n,`${s}.right`,"must be a node id"),{id:e.id,type:"cross",direction:e.direction,left:e.left,right:e.right};default:return null}}function ds(e,t,r){if(!Y(e))return w(t,"risk","must be a plain object"),null;ce(e,dr,"risk",t);for(let d of dr)(!(d in e)||e[d]==null)&&w(t,`risk.${d}`,"required field is missing");let n={},s=e.maxLeverage;!U(s)||s<=0||s>50?w(t,"risk.maxLeverage","must be a number > 0 and <= 50"):n.maxLeverage=s;let a=e.maxNotionalUsd;!U(a)||a<=0?w(t,"risk.maxNotionalUsd","must be a number > 0"):n.maxNotionalUsd=a;let o=e.positionSizePct;!U(o)||o<=0||o>100?w(t,"risk.positionSizePct","must be a number > 0 and <= 100"):n.positionSizePct=o;let i=e.stopLossPct;!U(i)||i<=0||i>100?w(t,"risk.stopLossPct","must be a number > 0 and <= 100"):n.stopLossPct=i;let l=e.takeProfitPct;!U(l)||l<=0||l>1e3?w(t,"risk.takeProfitPct","must be a number > 0 and <= 1000"):n.takeProfitPct=l;let u=e.cooldownBars;!Number.isInteger(u)||u<0||u>1e5?w(t,"risk.cooldownBars","must be an integer >= 0 and <= 100000"):n.cooldownBars=u;let f=e.maxDailyLossPct;!U(f)||f<=0||f>100?w(t,"risk.maxDailyLossPct","must be a number > 0 and <= 100"):n.maxDailyLossPct=f;let c=e.expiresAt;return!Number.isInteger(c)||c<=0?w(t,"risk.expiresAt","must be an integer epoch milliseconds > 0"):(r.nowMs!==void 0&&(Number.isInteger(r.nowMs)?c<=r.nowMs&&w(t,"risk.expiresAt","must be strictly greater than nowMs"):w(t,"nowMs","must be an integer epoch milliseconds")),n.expiresAt=c),n}function wt(e,t={}){let r=[];if(!Y(e))return w(r,"","strategy must be a plain object"),{ok:!1,errors:r,strategy:null};ce(e,ur,"",r);for(let c of ur)(!(c in e)||e[c]==null)&&w(r,c,"required field is missing");e.version!==ft&&w(r,"version",`must be ${ft}`),(typeof e.id!="string"||!br.test(e.id))&&w(r,"id","must match /^[a-z0-9][a-z0-9._-]{0,63}$/"),(typeof e.name!="string"||e.name.length===0||e.name.length>yr)&&w(r,"name",`must be a non-empty string max ${yr}`);let n=ct(e.venue);n||w(r,"venue",`unknown strategy venue "${String(e.venue)}"`);let s=null;if(!n)Y(e.market)||w(r,"market","must be a plain object");else{let c=n.validateMarket(e.market);if(!c||typeof c.ok!="boolean"||!Array.isArray(c.errors))w(r,"market",`venue ${n.id} returned an invalid market validation result`);else if(c.ok)s=c.market;else for(let d of c.errors)w(r,d.path,d.message)}let a=us(e.parameters,r),o=null,i=new Map;if(!Array.isArray(e.nodes))w(r,"nodes","must be an array");else if(e.nodes.length>hr)w(r,"nodes",`too many nodes (max ${hr})`);else{o=[];for(let c=0;c<e.nodes.length;c++){let d=fs(e.nodes[c],c,a||{},r);d&&(typeof d.id=="string"&&Er.test(d.id)&&(i.has(d.id)?w(r,`nodes.${c}.id`,`duplicate node id "${d.id}"`):i.set(d.id,d)),o.push(d))}for(let c=0;c<o.length;c++){let d=o[c],m=`nodes.${c}`;for(let p of Ue(d))i.has(p)||w(r,m,`unknown node ref "${p}"`);if(d.type==="indicator"||d.type==="compare"||d.type==="cross")for(let p of Ue(d)){let h=i.get(p);h&&dt.has(h.type)&&w(r,m,`node ref "${p}" must be numeric`)}if(d.type==="logic")for(let p of Ue(d)){let h=i.get(p);h&&!dt.has(h.type)&&w(r,m,`node ref "${p}" must be boolean`)}}ls(i)&&w(r,"nodes","graph contains a cycle")}let l=null;if(!Y(e.rules))w(r,"rules","must be a plain object");else{ce(e.rules,pt,"rules",r);for(let c of pt)c in e.rules||w(r,`rules.${c}`,"required field is missing");l={};for(let c of pt){let d=e.rules[c];if(d===null){l[c]=null;continue}if(typeof d!="string"||!d){w(r,`rules.${c}`,"must be a node id or null"),l[c]=d;continue}if(!i.has(d)){w(r,`rules.${c}`,`unknown node ref "${d}"`),l[c]=d;continue}let m=i.get(d);dt.has(m.type)||w(r,`rules.${c}`,`rule must reference a boolean node, not ${m.type}`),l[c]=d}}let u=ds(e.risk,r,t);if(r.length)return{ok:!1,errors:r,strategy:null};let f=ht({version:ft,id:e.id,name:e.name,venue:n.id,market:s,parameters:a,nodes:o,rules:l,risk:u});return{ok:!0,errors:[],strategy:f}}function J(e,t={}){let r=wt(e,t);if(!r.ok)throw new Ee(r.errors);return r.strategy}function ps(e){let t=J(e);return JSON.stringify(yt(t))}function we(e){let t=ps(e);return es("sha256").update(t,"utf8").digest("hex")}function Oe(e,t){if(!Y(e))throw new Ee([{path:"",message:"strategy must be a plain object"}]);if(!Y(t))throw new Ee([{path:"overrides",message:"must be a plain object"}]);let r=J(e),n={};for(let[a,o]of Object.entries(r.parameters))n[a]={value:o.value,min:o.min,max:o.max,step:o.step};let s=[];for(let[a,o]of Object.entries(t)){if(!Object.prototype.hasOwnProperty.call(n,a)){w(s,a,`unknown parameter "${a}"`);continue}let i=n[a];if(!U(o)){w(s,a,"override must be a finite number");continue}if(!xr(o,i.min,i.max,i.step)){w(s,a,"override must lie on the declared min/max/step grid");continue}n[a]={...i,value:o}}if(s.length)throw new Ee(s);return J({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(a=>{let o={...a};return Array.isArray(a.inputs)&&(o.inputs=[...a.inputs]),o}),rules:{...r.rules},risk:{...r.risk}})}var ft,br,Er,ts,rs,ns,ss,os,is,as,dt,ur,fr,pt,dr,cs,pr,mr,hr,yr,Ee,fe=B(()=>{ut();ft=1,br=/^[a-z0-9][a-z0-9._-]{0,63}$/,Er=/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/,ts=new Set(["open","high","low","close","volume","fundingRate","openInterest"]),rs=new Set(["sma","ema","rsi","macd","bollinger","atr"]),ns=new Set(["gt","gte","lt","lte","eq"]),ss=new Set(["and","or","not"]),os=new Set(["above","below"]),is=new Set(["line","signal","histogram"]),as=new Set(["upper","middle","lower"]),dt=new Set(["compare","logic","cross"]),ur=new Set(["version","id","name","venue","market","parameters","nodes","rules","risk"]),fr=new Set(["value","min","max","step"]),pt=new Set(["entryLong","entryShort","exitLong","exitShort"]),dr=new Set(["maxLeverage","maxNotionalUsd","positionSizePct","stopLossPct","takeProfitPct","cooldownBars","maxDailyLossPct","expiresAt"]),cs=new Set(["id","type"]),pr={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"])},mr=16,hr=128,yr=100,Ee=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 ve(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 le(e){if(!Number.isInteger(e)||e<=0)throw new TypeError("period must be a positive integer")}function ms(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 s=r[n];if(typeof s!="number"||!Number.isFinite(s))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 Sr(e,t){ve(e),le(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=0;for(let s=0;s<e.length;s++)n+=e[s],s>=t&&(n-=e[s-t]),s>=t-1&&(r[s]=n/t);return r}function qe(e,t){ve(e),le(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=0;for(let o=0;o<t;o++)n+=e[o];let s=n/t;r[t-1]=s;let a=2/(t+1);for(let o=t;o<e.length;o++)s=a*e[o]+(1-a)*s,r[o]=s;return r}function Ar(e,t){ve(e),le(t);let r=new Array(e.length).fill(null);if(e.length<=t)return r;let n=0,s=0;for(let i=1;i<=t;i++){let l=e[i]-e[i-1];l>=0?n+=l:s-=l}let a=n/t,o=s/t;r[t]=kr(a,o);for(let i=t+1;i<e.length;i++){let l=e[i]-e[i-1],u=l>0?l:0,f=l<0?-l:0;a=(a*(t-1)+u)/t,o=(o*(t-1)+f)/t,r[i]=kr(a,o)}return r}function kr(e,t){return e===0&&t===0?50:t===0?100:e===0?0:100-100/(1+e/t)}function Pr(e,t={}){ve(e);let r=t.fastPeriod,n=t.slowPeriod,s=t.signalPeriod;if(le(r),le(n),le(s),r>=n)throw new TypeError("fastPeriod must be < slowPeriod");let a=qe(e,r),o=qe(e,n),i=new Array(e.length).fill(null);for(let c=0;c<e.length;c++)a[c]!=null&&o[c]!=null&&(i[c]=a[c]-o[c]);let l=new Array(e.length).fill(null),u=new Array(e.length).fill(null),f=[];for(let c=0;c<i.length;c++)i[c]!=null&&f.push(c);if(f.length>=s){let c=0;for(let h=0;h<s;h++)c+=i[f[h]];let d=c/s,m=f[s-1];l[m]=d,u[m]=i[m]-d;let p=2/(s+1);for(let h=s;h<f.length;h++){let E=f[h];d=p*i[E]+(1-p)*d,l[E]=d,u[E]=i[E]-d}}return{line:i,signal:l,histogram:u}}function $r(e,t={}){ve(e);let r=t.period,n=t.stdDev;if(le(r),typeof n!="number"||!Number.isFinite(n)||n<=0)throw new TypeError("stdDev must be a finite number > 0");let s=new Array(e.length).fill(null),a=new Array(e.length).fill(null),o=new Array(e.length).fill(null);if(e.length<r)return{upper:a,middle:s,lower:o};let i=0,l=0;for(let u=0;u<e.length;u++){let f=e[u];if(i+=f,l+=f*f,u>=r){let c=e[u-r];i-=c,l-=c*c}if(u>=r-1){let c=i/r,d=l/r-c*c;d<0&&d>-1e-12&&(d=0);let m=Math.sqrt(d);s[u]=c,a[u]=c+n*m,o[u]=c-n*m}}return{upper:a,middle:s,lower:o}}function Tr(e,t){ms(e),le(t);let r=new Array(e.length).fill(null);if(e.length<t)return r;let n=new Array(e.length);for(let o=0;o<e.length;o++){let i=e[o];if(o===0)n[o]=i.h-i.l;else{let l=e[o-1].c;n[o]=Math.max(i.h-i.l,Math.abs(i.h-l),Math.abs(i.l-l))}}let s=0;for(let o=0;o<t;o++)s+=n[o];let a=s/t;r[t-1]=a;for(let o=t;o<e.length;o++)a=(a*(t-1)+n[o])/t,r[o]=a;return r}var _r=B(()=>{});import{createHash as hs}from"node:crypto";var gt,ys,ws,gs,Ir,Or=B(()=>{gt=2,ys="93f9c998260e73756c13871dc1a84dd6cdb26ec6113bd1941f023519939db440",ws="68f5b412a9975f04024cf9b9b6209b4bccedd52f176e95f34f786b3f53479c6a",gs="f197a38ff1c0f4ebe13326db8cbb8167ea3dd5d62e6033fe97c2fee8d23d96b5",Ir=hs("sha256").update(JSON.stringify({version:gt,compilerSourceHash:ys,indicatorsSourceHash:ws,schemaSourceHash:gs})).digest("hex")});function X(e){return typeof e=="number"&&Number.isFinite(e)}function xs(e){let t=new Map(e.map(i=>[i.id,i])),r=i=>{switch(i.type){case"indicator":return i.input?[i.input]:[];case"compare":case"cross":return[i.left,i.right];case"logic":return[...i.inputs];default:return[]}},n=new Map,s=new Map;for(let i of e)n.set(i.id,0),s.set(i.id,[]);for(let i of e)for(let l of r(i))t.has(l)&&(s.get(l).push(i.id),n.set(i.id,n.get(i.id)+1));let a=[];for(let[i,l]of n)l===0&&a.push(i);let o=[];for(;a.length;){let i=a.shift();o.push(i);for(let l of s.get(i))n.set(l,n.get(l)-1),n.get(l)===0&&a.push(l)}if(o.length!==e.length)throw new Error("strategy graph is cyclic");return o}function xe(e,t){return e!=null&&typeof e=="object"&&"param"in e?t[e.param].value:e}function ks(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 s=0;s<=t;s++){let a=e[s];if(a==null||typeof a!="object"||Array.isArray(a))throw new TypeError(`bars[${s}] must be an object`);let{t:o,o:i,h:l,l:u,c:f,v:c}=a;if(!X(o)&&(typeof o=="number"&&Number.isFinite(o)),!Number.isFinite(o))throw new TypeError(`bars[${s}].t must be finite`);for(let[d,m]of[["o",i],["h",l],["l",u],["c",f],["v",c]])if(!X(m))throw new TypeError(`bars[${s}].${d} must be a finite number`);for(let[d,m]of[["o",i],["h",l],["l",u],["c",f]])if(!(m>0))throw new TypeError(`bars[${s}].${d} price must be positive`);if(c<0)throw new TypeError(`bars[${s}].v volume must be non-negative`);if(l<Math.max(i,f,u))throw new TypeError(`bars[${s}] high must be >= max(open, close, low)`);if(u>Math.min(i,f,l))throw new TypeError(`bars[${s}] low must be <= min(open, close, high)`);if(n!=null){if(!(o>n))throw new TypeError("bars t must be strictly increasing");if(o-n!==Es[r])throw new TypeError(`bars t must match ${r} cadence`)}if(n=o,"fundingRate"in a&&a.fundingRate!=null&&!X(a.fundingRate))throw new TypeError(`bars[${s}].fundingRate must be finite when present`);if("openInterest"in a&&a.openInterest!=null){if(!X(a.openInterest))throw new TypeError(`bars[${s}].openInterest must be finite when present`);if(a.openInterest<0)throw new TypeError(`bars[${s}].openInterest must be non-negative`)}}}function me(e,t,r,n,s,a){if(a.has(e))return a.get(e);let o=t.get(e),i;switch(o.type){case"input":{let l=bs[o.field];i=new Array(s+1);for(let u=0;u<=s;u++){let f=n[u][l];i[u]=f===void 0?null:f}break}case"constant":{let l=xe(o.value,r);i=new Array(s+1).fill(l);break}case"indicator":{let l=o.period!=null?xe(o.period,r):void 0;if(o.indicator==="atr"){let c=[];for(let d=0;d<=s;d++){let m=n[d];c.push({o:m.o,h:m.h,l:m.l,c:m.c})}i=Tr(c,l);break}let f=me(o.input,t,r,n,s,a).map((c,d)=>{if(c==null||!X(c))throw new TypeError(`indicator input ${o.input} has non-finite value at ${d}`);return c});if(o.indicator==="sma")i=Sr(f,l);else if(o.indicator==="ema")i=qe(f,l);else if(o.indicator==="rsi")i=Ar(f,l);else if(o.indicator==="macd")i=Pr(f,{fastPeriod:xe(o.fastPeriod,r),slowPeriod:xe(o.slowPeriod,r),signalPeriod:xe(o.signalPeriod,r)})[o.output];else if(o.indicator==="bollinger")i=$r(f,{period:l,stdDev:xe(o.stdDev,r)})[o.output];else throw new Error(`unsupported indicator ${o.indicator}`);break}case"compare":{let l=me(o.left,t,r,n,s,a),u=me(o.right,t,r,n,s,a);i=new Array(s+1);for(let f=0;f<=s;f++){let c=l[f],d=u[f];if(c==null||d==null||!X(c)||!X(d)){i[f]=!1;continue}switch(o.op){case"gt":i[f]=c>d;break;case"gte":i[f]=c>=d;break;case"lt":i[f]=c<d;break;case"lte":i[f]=c<=d;break;case"eq":i[f]=c===d;break;default:i[f]=!1}}break}case"logic":{let l=o.inputs.map(u=>me(u,t,r,n,s,a));i=new Array(s+1);for(let u=0;u<=s;u++)if(o.op==="not"){let f=l[0][u];i[u]=f===!0?!1:f===!1}else if(o.op==="and"){let f=!0;for(let c of l)if(c[u]!==!0){f=!1;break}i[u]=f}else if(o.op==="or"){let f=!1;for(let c of l)if(c[u]===!0){f=!0;break}i[u]=f}else i[u]=!1;break}case"cross":{let l=me(o.left,t,r,n,s,a),u=me(o.right,t,r,n,s,a);i=new Array(s+1),i[0]=!1;for(let f=1;f<=s;f++){let c=l[f-1],d=u[f-1],m=l[f],p=u[f];if(c==null||d==null||m==null||p==null||!X(c)||!X(d)||!X(m)||!X(p)){i[f]=!1;continue}o.direction==="above"?i[f]=c<=d&&m>p:i[f]=c>=d&&m<p}break}default:throw new Error(`unknown node type ${o.type}`)}return a.set(e,i),i}function K(e,t={}){let r=J(e);t&&Object.keys(t).length&&(r=Oe(r,t));let n=new Map(r.nodes.map(m=>[m.id,m])),s=Object.freeze(xs(r.nodes)),a=r.parameters,o=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"])o.add(m);let i=Object.freeze([...o].sort()),l=we(r);function u(m,p){let h={};for(let S of s){let P=m.get(S);h[S]=P[p]}let E=S=>S!=null&&h[S]===!0;return{values:h,signals:{entryLong:E(r.rules.entryLong),entryShort:E(r.rules.entryShort),exitLong:E(r.rules.exitLong),exitShort:E(r.rules.exitShort)}}}function f(m,p){ks(m,p,r.market.interval);let h=new Map;for(let E of s)me(E,n,a,m,p,h);return h}function c(m,p){return u(f(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,h=f(m,p);return Object.freeze(m.map((E,S)=>Object.freeze(u(h,S))))}return Object.freeze({strategy:r,strategyHash:l,compilerVersion:_e,compilerHash:de,requiredSeries:i,nodeOrder:s,evaluate:c,evaluateAll:d})}var _e,de,bs,Es,pe=B(()=>{fe();_r();Or();_e=gt,de=Ir,bs=Object.freeze({open:"o",high:"h",low:"l",close:"c",volume:"v",fundingRate:"fundingRate",openInterest:"openInterest"}),Es=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 Ss}from"node:crypto";function Ps(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function te(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 Ce(e){if(Array.isArray(e))return e.map(Ce);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=Ce(e[r]);return t}return e}function Et(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)=>Et(r,`${t}[${n}]`));return}for(let[r,n]of Object.entries(e))Et(n,`${t}.${r}`)}}function Mr(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:s,o:a,h:o,l:i,c:l,v:u}=n;if(!te(s))throw new TypeError(`bars[${r}].t must be finite`);for(let[f,c]of[["o",a],["h",o],["l",i],["c",l],["v",u]])if(!te(c))throw new TypeError(`bars[${r}].${f} must be a finite number`);for(let[f,c]of[["o",a],["h",o],["l",i],["c",l]])if(!(c>0))throw new TypeError(`bars[${r}].${f} price must be positive`);if(u<0)throw new TypeError(`bars[${r}].v volume must be non-negative`);if(o<Math.max(a,l,i))throw new TypeError(`bars[${r}] high must be >= max(open, close, low)`);if(i>Math.min(a,l,o))throw new TypeError(`bars[${r}] low must be <= min(open, close, high)`);if(t!=null&&!(s>t))throw new TypeError("bars t must be strictly increasing");if(t=s,"fundingRate"in n&&n.fundingRate!=null&&!te(n.fundingRate))throw new TypeError(`bars[${r}].fundingRate must be finite when present`);if("fundingPaymentRate"in n&&n.fundingPaymentRate!=null&&!te(n.fundingPaymentRate))throw new TypeError(`bars[${r}].fundingPaymentRate must be finite when present`);if("openInterest"in n&&n.openInterest!=null&&!te(n.openInterest))throw new TypeError(`bars[${r}].openInterest must be finite when present`)}}function $e(e){if(!Array.isArray(e))throw new TypeError("bars must be an array");return e.length>0&&Mr(e),Ss("sha256").update(JSON.stringify(Ce(e)),"utf8").digest("hex")}function $s(e){if(e==null&&(e={}),!Ps(e))throw new TypeError("options must be a plain object");let t={...As},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(!te(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 s=e[n];if(!te(s)||s<0)throw new TypeError(`${n} must be a finite number >= 0`);if(n==="slippageBps"?s>=1e4:s>1e4)throw new TypeError(`${n} exceeds its safe basis-point bound`);t[n]=s}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(!te(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 Be(e){return e/1e4}function Ts(e,t,r){let n=Be(r);return t==="long"?e*(1+n):e*(1-n)}function _s(e,t,r){let n=Be(r);return t==="long"?e*(1-n):e*(1+n)}function vr(e,t,r){let n=Math.abs(e)*Be(t),s=Math.abs(e)*Be(r);return{taker:n,builder:s,total:n+s}}function Is(e,t){let r=e*(t.positionSizePct/100)*t.maxLeverage;return Math.min(r,t.maxNotionalUsd)}function Os(e,t,r){let n=r/100;return t==="long"?e*(1-n):e*(1+n)}function vs(e,t,r){let n=r/100;return t==="long"?e*(1+n):e*(1-n)}function Ms(e,t,r,n){if(!(r>0))return t==="long"?0:Number.POSITIVE_INFINITY;let s=Math.min(.99,1/(2*r)+n/1e4);return t==="long"?e*(1-1/r)/(1-s):e*(1+1/r)/(1+s)}function Ns(e,t,r){return t==="long"?e.l<=r:e.h>=r}function Rs(e,t,r){return t==="long"?e.h>=r:e.l<=r}function js(e,t,r){return t==="long"?e.l<=r:e.h>=r}function Me(e,t){for(let r of e.requiredSeries)if(["fundingRate","openInterest"].includes(r)&&!t.every(n=>te(n?.[r])))throw new Error(`strategy required series is absent: ${r}`)}function Fs(e){if(e.length<3)return 0;let t=[];for(let o=1;o<e.length;o++){let i=e[o-1].equity,l=e[o].equity;i>0&&t.push((l-i)/i)}if(t.length<2)return 0;let r=0;for(let o of t)r+=o;let n=r/t.length,s=0;for(let o of t)s+=(o-n)**2;let a=Math.sqrt(s/(t.length-1));return a>0?n/a:0}function Ls(e){let t=-1/0,r=0;for(let n of e){let s=n.equity;if(s>t&&(t=s),t>0){let a=(t-s)/t*100;a>r&&(r=a)}}return r}function ae(e,t,r={}){let n=$s(r);Mr(t);let s=$e(t);n.nowMs!==void 0&&J(e,{nowMs:n.nowMs});let a=K(e);if(Me(a,t),n.nowMs!==void 0&&a.strategy.risk.expiresAt<=n.nowMs)throw new Error("strategy is expired: risk.expiresAt must be strictly greater than nowMs");let o=a.strategy.risk,i=a.evaluateAll(t),l=n.latencyBars,u=n.slippageBps,f=n.takerFeeBps,c=n.builderFeeBps,d=n.initialEquityUsd,m=0,p=0,h=0,E=0,S=0,P=[],T=[],x=[],R=[],_=[],g=null,V=0,oe=null,ie=d,W=!1,y=0,A=0,v=[],j=new Array(t.length).fill(0);function F(b){v.push(b)}function I(b){let $=t[b].v*(n.maxVolumeParticipationPct/100);return Math.max(0,$-j[b])}function M(b){if(!g)return d;let $=g.side==="long"?(b-g.entryPrice)*g.qty:(g.entryPrice-b)*g.qty;return d+$}function z(b,$,k){let L=k.o,O=Is(d,o);if(!(O>0)||!(L>0))return;let H=Ts(L,$,u),N=O/H,C=I(b),Ae=H*C;if(N>C){x.push({kind:"entry",barIndex:b,time:k.t,side:$,requestedNotionalUsd:O,maxFillNotionalUsd:Ae,reason:"volume_participation"});return}j[b]+=N;let Q=Math.abs(H-L)*N,ne=vr(O,f,c);d-=ne.total,m+=ne.taker,p+=ne.builder,E+=Q,S+=O,g={lifecycleEpoch:++A,side:$,entryBarIndex:b,entryReferencePrice:L,entryPrice:H,qty:N,notionalUsd:O,stop:Os(H,$,o.stopLossPct),take:vs(H,$,o.takeProfitPct),liq:Ms(H,$,o.maxLeverage,f+c),entryFees:ne.taker,entryBuilderFees:ne.builder,entrySlippageUsd:Q,fundingAccrued:0}}function q(b,$,k,L){if(!g)return!1;let O=g.side,H=$,N=H;k!=="liquidation"&&L&&(N=_s(H,O,u));let C=g.qty,Ae=C*N;if(k!=="liquidation"){let Ht=I(b),cn=N*Ht;if(C>Ht)return x.push({kind:"exit",barIndex:b,time:t[b].t,side:O,requestedNotionalUsd:Ae,maxFillNotionalUsd:cn,reason:"volume_participation",triggerReason:k}),!1;j[b]+=C}let Q=vr(Ae,f,c),ne=k==="liquidation"?0:Math.abs(N-H)*C,Pe,Xe;O==="long"?(Pe=(H-g.entryReferencePrice)*C,Xe=(N-g.entryPrice)*C):(Pe=(g.entryReferencePrice-H)*C,Xe=(g.entryPrice-N)*C),d+=Xe,d-=Q.total,m+=Q.taker,p+=Q.builder,E+=ne,S+=Ae;let an={side:O,entryBarIndex:g.entryBarIndex,entryTime:t[g.entryBarIndex].t,entryPrice:g.entryPrice,exitBarIndex:b,exitTime:t[b].t,exitPrice:N,exitReason:k,qty:C,notionalUsd:g.notionalUsd,grossPnlUsd:Pe,feesUsd:g.entryFees+Q.taker,builderFeesUsd:g.entryBuilderFees+Q.builder,fundingUsd:g.fundingAccrued,slippageUsd:g.entrySlippageUsd+ne,netPnlUsd:Pe-(g.entryFees+Q.taker+g.entryBuilderFees+Q.builder)-g.fundingAccrued-(g.entrySlippageUsd+ne)};return P.push(an),k==="liquidation"&&T.push({barIndex:b,time:t[b].t,side:O,price:N,tradeIndex:P.length-1}),g=null,A+=1,y=b+1+(o.cooldownBars||0),!0}function Z(b,$,k,L){let O=b+1;if(O>=t.length)return;v.some(N=>N.kind==="exit"&&N.side===$&&N.fillBar===O&&N.epoch===L)||F({kind:"exit",side:$,signalBar:b,fillBar:O,reason:k,epoch:L})}function je(b){let $=v.filter(k=>k.fillBar===b);for(let k=v.length-1;k>=0;k--)v[k].fillBar===b&&v.splice(k,1);$.sort((k,L)=>{let O=H=>H.kind==="exit"?0:1;return O(k)-O(L)});for(let k of $)if(k.kind==="exit"){if(!g||g.side!==k.side||g.lifecycleEpoch!==k.epoch)continue;let L=k.reason||"rule";q(b,t[b].o,L,!0)||Z(b,k.side,L,k.epoch)}else if(k.kind==="entry"){if(g||k.epoch!==A||b<y)continue;z(b,k.side,t[b])}}function Fe(b){if(!g)return;let $=t[b],k=$.fundingPaymentRate;if(k==null||!te(k)||k===0)return;let L=Math.abs(g.qty*$.c),O=k*L;g.side==="long"?(d-=O,g.fundingAccrued+=O,h+=O):(d+=O,g.fundingAccrued-=O,h-=O)}function Le(b){if(!g)return;let $=t[b].o;(g.side==="long"?$<=g.liq:$>=g.liq)&&q(b,$,"liquidation",!1)}function Nt(b){if(!g)return;let $=t[b],k=g.side,L=js($,k,g.liq),O=Ns($,k,g.stop),H=Rs($,k,g.take),N=C=>k==="long"?Math.min(C,$.o):Math.max(C,$.o);if(L){q(b,N(g.liq),"liquidation",!1);return}if(O&&H){q(b,N(g.stop),"stop_loss",!0)||Z(b,k,"stop_loss",g.lifecycleEpoch);return}if(O){q(b,N(g.stop),"stop_loss",!0)||Z(b,k,"stop_loss",g.lifecycleEpoch);return}H&&(q(b,g.take,"take_profit",!0)||Z(b,k,"take_profit",g.lifecycleEpoch))}for(let b=0;b<t.length;b++){let $=Math.floor(t[b].t/864e5);$!==oe&&(oe=$,ie=M(t[b].o),W=!1),Le(b),je(b),Nt(b),Fe(b),!W&&M(t[b].c)<=ie*(1-o.maxDailyLossPct/100)&&(W=!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 k=i[b].signals,L=b+l;if(g)(g.side==="long"&&k.exitLong===!0||g.side==="short"&&k.exitShort===!0)&&L<t.length&&(v.some(C=>C.kind==="exit"&&C.side===g.side&&C.fillBar===L&&C.epoch===g.lifecycleEpoch)||F({kind:"exit",side:g.side,signalBar:b,fillBar:L,reason:"rule",epoch:g.lifecycleEpoch}));else{let H=k.entryLong===!0,N=k.entryShort===!0;H&&N?R.push({type:"conflicting_entry_signals",barIndex:b,time:t[b].t,message:"conflicting entry signals; no position opened"}):!W&&(H||N)&&L<t.length&&b>=y&&F({kind:"entry",side:H?"long":"short",signalBar:b,fillBar:L,epoch:A})}let O=d;g&&(V+=1,O=M(t[b].c)),_.push({barIndex:b,time:t[b].t,equity:O,positionSide:g?g.side:null})}let Rt=null;if(g){let b=t.length-1;if(q(b,t[b].c,"end_of_data",!0))_[b]={barIndex:b,time:t[b].t,equity:d,positionSide:null};else{let k=M(t[b].c);Rt={side:g.side,entryBarIndex:g.entryBarIndex,entryTime:t[g.entryBarIndex].t,entryPrice:g.entryPrice,qty:g.qty,notionalUsd:g.notionalUsd,markPrice:t[b].c,markedEquityUsd:k},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 jt=(g?M(t[t.length-1].c):d)-n.initialEquityUsd,rn=jt/n.initialEquityUsd*100,Ft=0,Je=0,Ke=0;for(let b of P)b.netPnlUsd>0?(Ft+=1,Je+=b.netPnlUsd):b.netPnlUsd<0&&(Ke+=-b.netPnlUsd);let Ye=P.length,nn=Ye===0?0:Ft/Ye,Ge=0;Ke>0?Ge=Je/Ke:Je>0&&(Ge=1e12);let sn={netPnlUsd:jt,netPnlPct:rn,maxDrawdownPct:Ls(_),winRate:nn,profitFactor:Ge,tradeCount:Ye,sharpe:Fs(_),turnoverUsd:S,exposurePct:V/t.length*100},on={initialEquityUsd:n.initialEquityUsd,takerFeeBps:n.takerFeeBps,builderFeeBps:n.builderFeeBps,slippageBps:n.slippageBps,latencyBars:n.latencyBars,maxVolumeParticipationPct:n.maxVolumeParticipationPct},Lt={barsHash:s,strategyHash:a.strategyHash,compilerHash:de,compilerVersion:_e,config:on,trades:P,equityCurve:_,metrics:sn,costs:{feesUsd:m,builderFeesUsd:p,fundingUsd:h,slippageUsd:E},liquidations:T,missedFills:x,openPositionAtEnd:Rt,flags:R};return Et(Lt),bt(Ce(Lt))}var As,He=B(()=>{pe();fe();As=Object.freeze({initialEquityUsd:1e4,takerFeeBps:3.5,builderFeeBps:2,slippageBps:2,latencyBars:1,maxVolumeParticipationPct:100})});import{createHash as Hs}from"node:crypto";function Js(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function xt(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)xt(t);return Object.freeze(e)}for(let t of Object.keys(e))xt(e[t]);return Object.freeze(e)}function Ks(e){return String(e).trim().replace(/\s+/g," ")}function Ys(e){let t=e.match(/\b(long|short)\b/i);return t?t[1].toLowerCase():null}function Gs(e){for(let r of qs)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 Xs(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 Us.has(r)?r:null}function Ws(e){let t={...Bs},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 s=e.match(/leverage\s*(\d+(?:\.\d+)?)/i);s&&(t.maxLeverage=Number(s[1]));let a=e.match(/position\s*size\s*(\d+(?:\.\d+)?)\s*%?/i);a&&(t.positionSizePct=Number(a[1]));let o=e.match(/max\s*notional\s*(?:usd\s*)?\$?\s*(\d+(?:\.\d+)?)/i);return o&&(t.maxNotionalUsd=Number(o[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 Qs(e){let t=Hs("sha256").update(e,"utf8").digest("hex").slice(0,10),r=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40),s=`${r.length?r:"draft"}-${t}`.replace(/[^a-z0-9._-]/g,"").slice(0,64);return/^[a-z0-9]/.test(s)?s:`d${s}`.slice(0,64)}function eo(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(),s=Number(t[3]);if(!(r>0)||!(s>0)||r===s)return null;let a=/\b(exit\s+on\s+reverse|reverse\s+exit)\b/i.test(e);return{kind:"ema_cross",fast:r,slow:s,direction:n,reverse:a}}function to(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 ro(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 no(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,""):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 s of n)r=r.replace(s,"");return r.replace(/[\s,;]+/g,"")===""}function Nr(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 so({side:e,coin:t,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){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:i.direction,left:"emaLeft",right:"emaRight"}],u={entryLong:null,entryShort:null,exitLong:null,exitShort:null};if(e==="long"?u.entryLong="cross":u.entryShort="cross",i.reverse){let f=i.direction==="above"?"below":"above";l.push({id:"crossRev",type:"cross",direction:f,left:"emaLeft",right:"emaRight"}),e==="long"?u.exitLong="crossRev":u.exitShort="crossRev"}return{version:1,id:a,name:o,venue:"hyperliquid",market:{coin:t,interval:r},parameters:{ema_left_period:Nr(i.fast),ema_right_period:Nr(i.slow)},nodes:l,rules:u,risk:{...n,expiresAt:s}}}function oo({side:e,coin:t,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){let l=[{id:"c",type:"input",field:"close"},{id:"rsi",type:"indicator",indicator:"rsi",input:"c",period:i.period},{id:"thr",type:"constant",value:i.threshold},{id:"sig",type:"compare",op:i.op==="above"?"gt":"lt",left:"rsi",right:"thr"}];return{version:1,id:a,name:o,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:s}}}function io({side:e,coin:t,interval:r,risk:n,expiresAt:s,id:a,name:o,spec:i}){let l=[{id:"fr",type:"input",field:"fundingRate"},{id:"thr",type:"constant",value:i.threshold},{id:"sig",type:"compare",op:i.op==="above"?"gt":"lt",left:"fr",right:"thr"}];return{version:1,id:a,name:o,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:s}}}function Rr(e,t={}){if(typeof e!="string")throw new D("prompt must be a string");if(e.length>1e3)throw new D("prompt length must be <= 1000");if(!Js(t))throw new D("options must be a plain object");if(!Number.isInteger(t.nowMs))throw new D("options.nowMs is required integer epoch ms");let r=t.nowMs,n=Vs;if("expiresInMs"in t){if(!Number.isInteger(t.expiresInMs))throw new D("expiresInMs must be an integer");if(n=t.expiresInMs,n<zs||n>Ds)throw new D("expiresInMs must be between 1h and 30d")}if(Cs.test(e))throw new D(`prompt appears to contain secrets and is rejected. ${ke}`);let s=Ks(e);if(!s)throw new D(`empty prompt. ${ke}`);if(Zs(s))throw new D(`duplicate interval or risk clause. ${ke}`);let a=Ys(s),o=Gs(s),i=Xs(s);if(!a||!o||!i)throw new D(`could not parse side/coin/interval. ${ke}`);let l=Ws(s);if(!(l.maxLeverage>0)||l.maxLeverage>50)throw new D("leverage out of range");if(!(l.positionSizePct>0)||l.positionSizePct>100)throw new D("position size out of range");let u=r+n,f=Qs(s),c=`Draft ${o} ${a}`.slice(0,100),d=eo(s),m=to(s),p=ro(s),h=[d,m,p].filter(Boolean);if(h.length!==1)throw new D(`unsupported or ambiguous prompt. ${ke}`);if(!no(s,h[0]))throw new D(`unsupported or ambiguous prompt. ${ke}`);let E,S=h[0],P={side:a,coin:o,interval:i,risk:l,expiresAt:u,id:f,name:c,spec:S};S.kind==="ema_cross"?E=so(P):S.kind==="rsi"?E=oo(P):E=io(P);let T=wt(E,{nowMs:r});if(!T.ok)throw new D(`draft failed validation: ${T.errors.map(x=>x.message).join("; ")}`);return xt(J(E,{nowMs:r}))}var D,Us,qs,Cs,ke,Bs,zs,Ds,Vs,jr=B(()=>{fe();D=class extends Error{constructor(t){super(t),this.name="StrategyDraftError"}},Us=new Set(["1m","3m","5m","15m","30m","1h","2h","4h","8h","12h","1d"]),qs=new Set(["BTC","ETH","SOL","HYPE"]),Cs=/\b(mnemonic|private\s*key|privkey|seed\s*phrase|seed\b|api[_-]?key|secret\s*key|wallet\s*key|passphrase)\b/i,ke="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]. 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.",Bs=Object.freeze({maxLeverage:1,maxNotionalUsd:100,positionSizePct:5,stopLossPct:2,takeProfitPct:4,cooldownBars:1,maxDailyLossPct:3}),zs=36e5,Ds=30*864e5,Vs=864e5});import{createHash as ao}from"node:crypto";function Hr(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 Ur(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function St(e){if(e==null||typeof e!="object"||Object.isFrozen(e))return e;if(Array.isArray(e)){for(let t of e)St(t);return Object.freeze(e)}for(let t of Object.keys(e))St(e[t]);return Object.freeze(e)}function Ne(e){if(Array.isArray(e))return e.map(Ne);if(e!=null&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())t[r]=Ne(e[r]);return t}return e}function ze(e){return JSON.stringify(Ne(e))}function co(e){let{min:t,max:r,step:n}=e;if(!(n>0)||t>r)return[];let s=[],a=Math.floor((r-t)/n+1e-9);for(let i=0;i<=a;i++){let l=t+i*n;if(l>r+1e-9)break;let u=Math.abs(l-Math.round(l))<1e-9?Math.round(l):Number(l.toPrecision(12));u<t-1e-9||u>r+1e-9||s.push(u)}if(s.length===0)return[];let o=s[s.length-1];if(Math.abs(o-r)>1e-9){let i=(r-t)/n;Math.abs(i-Math.round(i))<=1e-9&&s.push(r)}return s}function lo(e,t){if(e.length===0)return[];let r=[{}];for(let n of e){let s=t[n],a=[];for(let o of r)for(let i of s)a.push({...o,[n]:i});r=a}return r.sort((n,s)=>{let a=ze(n),o=ze(s);return a<o?-1:a>o?1:0}),r}function kt(e,t,r,n,s){let a=0;if(e==="maxDrawdownPct"){if(a=t.maxDrawdownPct-n.maxDrawdownPct,a!==0)return a<0}else if(a=t[e]-n[e],a!==0)return a>0;let o=ze(r),i=ze(s);return o<i}function qr(e,t,r={}){if(!Ur(r))throw new TypeError("options must be a plain object");for(let x of Object.keys(r))if(Hr(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 s=64;if("maxTrials"in r){let x=r.maxTrials;if(!Number.isInteger(x)||x<1||x>Fr)throw new TypeError(`maxTrials must be an integer 1..${Fr}`);s=x}let a=r.objective??"netPnlUsd";if(!Lr.has(a))throw new TypeError(`objective must be one of ${[...Lr].join("|")}`);let o=r.backtestOptions??{};if(!Ur(o))throw new TypeError("backtestOptions must be a plain object");for(let x of Object.keys(o))if(Hr(x))throw new TypeError(`backtestOptions must not include holdout/test/oos key "${x}"`);let i=J(e),l=Object.keys(i.parameters).sort();if(l.length===0)throw new Error("optimizeStrategy requires at least one declared parameter");let u={},f=1;for(let x of l){let R=co(i.parameters[x]);if(R.length===0)throw new Error(`parameter "${x}" produces an empty grid`);u[x]=R,f*=R.length}let c=lo(l,u);if(c.length===0)throw new Error("parameter grid is empty");let d=c.slice(0,s),m=[],p=null,h=null;for(let x of d){let R=Oe(i,x),_=ae(R,t,o);h==null&&(h=_.config);let g={netPnlUsd:_.metrics.netPnlUsd,netPnlPct:_.metrics.netPnlPct,maxDrawdownPct:_.metrics.maxDrawdownPct,winRate:_.metrics.winRate,profitFactor:_.metrics.profitFactor,tradeCount:_.metrics.tradeCount,sharpe:_.metrics.sharpe,turnoverUsd:_.metrics.turnoverUsd},V={parameters:{...x},metrics:g};m.push(V),(!p||kt(a,g,x,p.metrics,p.parameters))&&(p=V)}m.sort((x,R)=>kt(a,x.metrics,x.parameters,R.metrics,R.parameters)?-1:kt(a,R.metrics,R.parameters,x.metrics,x.parameters)?1:0);let E={...p.parameters},S=Oe(i,E),P={strategyHash:we(i),compilerHash:de,trainBarsHash:$e(t),backtestConfig:h,objective:a,maxTrials:s,trialsRun:m.length,candidates:m,bestParameters:E,bestStrategy:S},T={id:ao("sha256").update(JSON.stringify(Ne(P)),"utf8").digest("hex"),...P};return St(Ne(JSON.parse(JSON.stringify(T))))}var Fr,Lr,Cr=B(()=>{pe();fe();He();Fr=256,Lr=new Set(["netPnlUsd","profitFactor","sharpe","maxDrawdownPct"])});import se from"node:fs";import De from"node:path";function Ve(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function re(e){return e==null?e:JSON.parse(JSON.stringify(e))}function fo(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function Se(e,t="record"){if(Array.isArray(e)){e.forEach((r,n)=>Se(r,`${t}[${n}]`));return}if(Ve(e))for(let[r,n]of Object.entries(e)){let s=fo(r);if(uo.some(a=>s.includes(a)))throw new Error(`shadow-store: forbidden secret-like field at ${t}.${r}`);Se(n,`${t}.${r}`)}}function po(e){if(typeof e!="string"||!e||!De.isAbsolute(e))throw new Error("shadow-store: path must be an absolute path")}function Br(e){let t;try{t=se.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 mo(){return{version:Pt,runners:[]}}function zr(e,t){let r;try{r=JSON.parse(e)}catch{throw new Error("shadow-store: malformed JSON")}if(!Ve(r))throw new Error("shadow-store: malformed JSON root");if(r.version!==Pt)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 Se(r,De.basename(t)),{version:Pt,runners:r.runners.map(n=>re(n))}}function Dr(e,t){Se(t,"store");let r=De.dirname(e);se.mkdirSync(r,{recursive:!0,mode:448});let n=De.join(r,`.shadow-store.${process.pid}.${Date.now()}.tmp`),s=`${JSON.stringify(t)}
3
+ `;try{se.writeFileSync(n,s,{mode:384,flag:"wx"}),se.renameSync(n,e);try{se.chmodSync(e,384)}catch{}}catch(a){try{se.unlinkSync(n)}catch{}throw a}}function Vr(e={}){let t=e.path;if(po(t),Br(t),se.existsSync(t)?zr(se.readFileSync(t,"utf8"),t):Dr(t,mo()),At.has(t))return At.get(t);let r=!1,n=[];function s(){if(r)return;let p=n.shift();if(p){r=!0;try{let h=p.fn();r=!1,p.resolve(h),s()}catch(h){r=!1,p.reject(h),s()}}}function a(p){if(!r&&n.length===0){r=!0;try{return p()}finally{r=!1,queueMicrotask(s)}}return new Promise((h,E)=>{n.push({fn:p,resolve:h,reject:E}),queueMicrotask(s)})}function o(){return Br(t),zr(se.readFileSync(t,"utf8"),t)}function i(p){Dr(t,p)}function l(p){if(!Ve(p)||typeof p.id!="string"||!p.id)throw new Error("shadow-store: create requires record with string id");Se(p,"record");let h=o();if(h.runners.some(S=>S.id===p.id))throw new Error(`shadow-store: runner id already exists: ${p.id}`);let E=re(p);return h.runners.push(E),i(h),re(E)}function u(p){let h=o().runners.find(E=>E.id===p);return h?re(h):null}function f(){return o().runners.map(p=>re(p))}function c(p,h){if(typeof h!="function")throw new Error("shadow-store: updater must be a function");let E=o(),S=E.runners.findIndex(x=>x.id===p);if(S<0)throw new Error(`shadow-store: runner not found: ${p}`);let P=re(E.runners[S]),T=h(P);if(!Ve(T)||T.id!==p)throw new Error("shadow-store: updater must return record with same id");return Se(T,"record"),E.runners[S]=re(T),i(E),re(E.runners[S])}function d(p){let h=o(),E=h.runners.findIndex(P=>P.id===p);if(E<0)throw new Error(`shadow-store: runner not found: ${p}`);let S=re(h.runners[E]);return S.status!=="stopped"&&(S.status="stopped",h.runners[E]=S,i(h)),re(h.runners[E])}let m={create(p){return a(()=>l(p))},get(p){return u(p)},list(){return f()},update(p,h){return a(()=>c(p,h))},stop(p){return a(()=>d(p))}};return At.set(t,m),m}var Pt,uo,At,Jr=B(()=>{Pt=1,uo=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"];At=new Map});import{createHash as _t}from"node:crypto";function $t(e){return e==null?e:JSON.parse(JSON.stringify(e))}function Tt(e){return Array.isArray(e)?e.map(Tt):e&&typeof e=="object"?Object.fromEntries(Object.keys(e).sort().map(t=>[t,Tt(e[t])])):e}function Yr(e){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("shadow-runner: record must be an object");return _t("sha256").update(JSON.stringify(Tt(e))).digest("hex")}function ho(e,t,r,n,s){return _t("sha256").update(`${e}|${t}|${r}|${n}|${s}`).digest("hex")}function yo(e,t,r,n){return _t("sha256").update(`shadow|${e}|${t}|${r}|${n??""}`).digest("hex")}function wo(e){return e==="entryLong"||e==="exitShort"?"buy":e==="entryShort"||e==="exitLong"?"sell":e}function Kr(e){return e==="entryLong"||e==="entryShort"}function It({storePath:e,clock:t=Date.now}={}){if(typeof e!="string"||!e)throw new Error("shadow-runner: storePath required");let r=Vr({path:e});function n({strategy:l,evidenceId:u=null}={}){let f=K(l),c=u==null?null:String(u),d=r.list().filter(S=>S.status==="running"&&S.strategyHash===f.strategyHash&&S.compilerHash===f.compilerHash&&S.evidenceId===c).sort((S,P)=>S.createdAt-P.createdAt||S.id.localeCompare(P.id))[0];if(d)return $t(d);let m=t(),p=yo(m,f.strategyHash,f.compilerHash,c),h=r.get(p);if(h)return $t(h);let E={id:p,strategy:$t(f.strategy),strategyHash:f.strategyHash,compilerHash:f.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(E)}function s(l){return r.get(l)}function a(){return r.list()}function o(l){return r.stop(l)}function i(l,u,{markoutHorizons:f=[1,4,12]}={}){if(!Array.isArray(u))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(u.length===0)return c;let m=K(c.strategy).evaluateAll(u),p=new Map;for(let y=0;y<u.length;y++)p.set(u[y].t,y);let h=c.cursor,E=[];for(let y=0;y<u.length;y++){let A=u[y].t;(h==null||A>h)&&E.push(y)}if(E.length===0)return c;let S=new Map(c.intendedOrders.map(y=>[y.id,y])),P=new Set(c.fills.map(y=>y.orderId)),T=new Map(c.missedFills.map(y=>[y.orderId,y])),x=(y,A)=>`${y}|${A}`,R=new Map(c.markouts.map(y=>[x(y.orderId,y.horizon),y])),_=c.position?{...c.position}:null,g=Number.isInteger(c.cooldownBarsRemaining)?Math.max(0,c.cooldownBarsRemaining):0,V=Number.isFinite(c.cooldownStartT)?c.cooldownStartT:null;function oe({action:y,signalBarT:A,signalIndex:v}){let j=wo(y),F=ho(c.id,c.strategyHash,A,j,y);if(S.has(F))return S.get(F);let I=v+1,M=I<u.length,z={id:F,action:y,type:y,side:j,signalBarT:A,fillBarT:M?u[I].t:null,status:M?"open":"missed"};return S.set(F,z),c.intendedOrders.push(z),z}function ie(y,A,v){if(P.has(y.id))return;let j={orderId:y.id,action:Kr(y.action)?"entry":"exit",side:y.side,price:A.o,barT:A.t,signalBarT:y.signalBarT,barIndex:v};if(c.fills.push(j),P.add(y.id),y.status="filled",y.fillBarT=A.t,T.has(y.id)&&(T.delete(y.id),c.missedFills=c.missedFills.filter(F=>F.orderId!==y.id)),Kr(y.action)){_={side:y.action==="entryLong"?"long":"short",entryOrderId:y.id,entryBarT:A.t,entryPrice:A.o,entryBarIndex:v};for(let F of f){let I=x(y.id,F);if(R.has(I))continue;let M={orderId:y.id,horizon:F,entryBarT:A.t,entryPrice:A.o,side:_.side,status:"pending",close:null,barT:null};R.set(I,M),c.markouts.push(M)}}else _=null,g=Number(c.strategy?.risk?.cooldownBars)||0,V=A.t}function W(y){if(P.has(y.id)||T.has(y.id))return;let A={orderId:y.id,action:y.action,side:y.side,signalBarT:y.signalBarT,status:"missed"};T.set(y.id,A),c.missedFills.push(A),y.status="missed"}for(let y of c.intendedOrders){if(y.status==="filled"||P.has(y.id))continue;let A=p.get(y.signalBarT);if(A==null)continue;let v=A+1;v<u.length&&(h==null||u[v].t>h)&&ie(y,u[v],v)}for(let y of E){let A=u[y],v=m[y].signals,j=_,F=M=>{if(_||g>0&&(V==null||A.t>=V))return;let q=oe({action:M,signalBarT:A.t,signalIndex:y}),Z=y+1;Z<u.length?ie(q,u[Z],Z):W(q)},I=M=>{if(!_||_.side==="long"&&M!=="exitLong"||_.side==="short"&&M!=="exitShort")return;let z=oe({action:M,signalBarT:A.t,signalIndex:y}),q=y+1;q<u.length?ie(z,u[q],q):W(z)};j?(v.exitLong&&I("exitLong"),v.exitShort&&I("exitShort")):v.entryLong&&v.entryShort||(v.entryLong&&F("entryLong"),v.entryShort&&F("entryShort")),g>0&&V!=null&&A.t>=V&&(g-=1,g===0&&(V=null)),c.cursor=A.t,c.lastProcessedBarIndex=y}for(let y of c.markouts){if(y.status!=="pending")continue;let A=c.fills.find(F=>F.orderId===y.orderId&&F.action==="entry");if(!A)continue;let v=p.get(A.barT);if(v==null)continue;let j=v+y.horizon;if(j<u.length){y.close=u[j].c,y.barT=u[j].t,y.status="filled";let F=y.entryPrice;y.markout=y.side==="long"?(y.close-F)/F:(F-y.close)/F}}return c.position=_,c.cooldownBarsRemaining=g,c.cooldownStartT=V,c.updatedAt=t(),c})}return{start:n,step:i,list:a,get:s,stop:o}}var Gr=B(()=>{pe();Jr()});var Zr={};un(Zr,{runStrategyOperation:()=>Po});import go from"node:os";import bo from"node:path";function Re(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function xo(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function vt(e){if(Array.isArray(e)){for(let t of e)vt(t);return}if(Re(e))for(let[t,r]of Object.entries(e)){if(Eo.some(n=>xo(t).includes(n)))throw new Error(`strategy service: secret-like field "${t}" is forbidden`);vt(r)}}function ko(e){if(!Re(e))throw new TypeError("strategy input must be a plain object");return vt(e),e}function So(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 Ot(e,t,r,n){if(Array.isArray(t.bars))return t.bars;let s=lt(e.venue),a=r.fetchBars??s.fetchBars;if(typeof a!="function")throw new Error(`strategy venue ${s.id} does not support history`);let o=await a({coin:e.market.coin,interval:e.market.interval,count:t.count??1500,endTime:t.endTime??n}),i=Array.isArray(o)?o:o?.bars;if(!Array.isArray(i))throw new Error("strategy history provider returned no bars");return i}function Mt(e,t){let r=e.backtestOptions??{};if(!Re(r))throw new TypeError("backtestOptions must be a plain object");return{...r,nowMs:t}}function Xr(e,t,r,n,s={}){let a=e.evidenceOptions??{};if(!Re(a))throw new TypeError("evidenceOptions must be a plain object");return{...a,...s,strategy:t,bars:r,backtestOptions:Mt(e,n)}}function Wr(){return bo.join(go.homedir(),".oracle","strategy-shadow.json")}function Ao(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 Po(e,t={},r={}){let n=ko(t),s=So(n,r);if(e==="draft")return{strategy:Rr(n.prompt,{nowMs:s})};if(e==="validate"){let a=K(n.strategy);if(a.strategy.risk.expiresAt<=s)throw new Error("strategy is expired");return{valid:!0,strategy:a.strategy,strategyHash:a.strategyHash,compilerHash:a.compilerHash,compilerVersion:a.compilerVersion,requiredSeries:a.requiredSeries}}if(e==="backtest"||e==="evidence"){let a=K(n.strategy),o=await Ot(a.strategy,n,r,s);Me(a,o);let i=nt(Xr(n,a.strategy,o,s));return e==="evidence"?i:{backtest:ae(a.strategy,o,Mt(n,s)),evidence:i}}if(e==="optimize"){let a=K(n.strategy),o=await Ot(a.strategy,n,r,s);Me(a,o);let i=n.trainFraction,l=n.evidenceOptions?.trainFraction;if(i!=null&&l!=null&&i!==l)throw new TypeError("conflicting trainFraction controls are forbidden");let u=i??l??.7;if(typeof u!="number"||u<=0||u>=1)throw new TypeError("trainFraction must be in (0,1)");let f=o.slice(0,Math.floor(o.length*u)),c=n.options??{};if(!Re(c))throw new TypeError("options must be a plain object");let d=qr(a.strategy,f,{...c,...n.maxTrials==null?{}:{maxTrials:n.maxTrials},backtestOptions:Mt(n,s)}),m=d.bestStrategy;return{strategy:m,optimization:d,evidence:nt(Xr(n,m,o,s,{trainFraction:u}))}}if(e==="shadow"){let a=It({storePath:r.storePath??Wr(),clock:()=>s}),o=n.action;if(o==="start")return await a.start({strategy:n.strategy,evidenceId:n.evidenceId??n.evidence?.id??null});if(o==="list")return await a.list();if(o==="get")return await a.get(n.id);if(o==="stop")return await a.stop(n.id);if(o==="step"){let i=await a.get(n.id);if(!i)throw new Error(`shadow runner not found: ${n.id}`);let l=await Ot(i.strategy,n,r,s);return Me(K(i.strategy),l),await a.step(n.id,l,n.stepOptions??{})}throw new Error(`unknown shadow action: ${o}`)}if(e==="prepare"){let a=K(n.strategy),o=lt(a.strategy.venue);if(typeof n.shadowId!="string"||!n.shadowId)throw new Error("strategy prepare requires a matching shadow runner id");let l=await It({storePath:r.storePath??Wr(),clock:()=>s}).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!==a.strategyHash||l.compilerHash!==a.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 u=n.caps??Ao(a.strategy,s);return o.prepareIntent({strategy:a.strategy,evidence:n.evidence,shadow:{id:l.id,stateHash:Yr(l),status:l.status,cursor:l.cursor,updatedAt:l.updatedAt},caps:u,nowMs:s,env:r.env??process.env})}throw new Error(`unknown strategy operation: ${e}`)}var Eo,Qr=B(()=>{He();pe();st();jr();Cr();Gr();ut();Eo=["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]});import en from"node:fs";function $o(e){let t={},r=[];for(let n=0;n<e.length;n++){let s=e[n];if(!s.startsWith("--")){r.push(s);continue}let a=s.slice(2),o=e[n+1];o!=null&&!o.startsWith("--")?(t[a]=o,n++):t[a]=!0}return{flags:t,positional:r}}function he(e,t){if(!e)throw new Error(`${t} path required`);let r=e==="-"?en.readFileSync(0,"utf8"):en.readFileSync(e,"utf8");try{return JSON.parse(r)}catch{throw new Error(`${t} must contain valid JSON`)}}function tn(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 To=`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 ln=Object.defineProperty;var B=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(
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. Oracle public never signs or broadcasts.
17
- `,Bi={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(t){let{flags:e,positional:r}=$o(t.argv);if(e.help||r.length===0)return process.stdout.write(To),0;let[n,...s]=r,{runStrategyOperation:a}=await Promise.resolve().then(()=>(Qr(),Zr)),o={nowMs:Date.now(),count:en(e.count,"count")};if(n==="draft")o.prompt=s.join(" ").trim();else if(["validate","backtest","optimize","evidence"].includes(n))o.strategy=ht(s[0],"strategy"),e.bars&&(o.bars=ht(e.bars,"bars")),o.maxTrials=en(e["max-trials"],"max-trials");else if(n==="shadow"){let l=s[0];if(!l)throw new Error("shadow action required");o.action=l,l==="start"&&(o.strategy=ht(s[1],"strategy")),l==="step"&&(o.id=s[1],e.bars&&(o.bars=ht(e.bars,"bars"))),l==="stop"&&(o.id=s[1])}else if(n==="prepare")o.strategy=ht(s[0],"strategy"),o.evidence=ht(e.evidence,"evidence"),o.shadowId=e["shadow-id"],e.caps&&(o.caps=ht(e.caps,"caps"));else throw new Error(`unknown strategy operation: ${n}`);let i=await a(n,o);return process.stdout.write(`${JSON.stringify(i,null,2)}
17
+ `,Bi={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}=$o(e.argv);if(t.help||r.length===0)return process.stdout.write(To),0;let[n,...s]=r,{runStrategyOperation:a}=await Promise.resolve().then(()=>(Qr(),Zr)),o={nowMs:Date.now(),count:tn(t.count,"count")};if(n==="draft")o.prompt=s.join(" ").trim();else if(["validate","backtest","optimize","evidence"].includes(n))o.strategy=he(s[0],"strategy"),t.bars&&(o.bars=he(t.bars,"bars")),o.maxTrials=tn(t["max-trials"],"max-trials");else if(n==="shadow"){let l=s[0];if(!l)throw new Error("shadow action required");o.action=l,l==="start"&&(o.strategy=he(s[1],"strategy")),l==="step"&&(o.id=s[1],t.bars&&(o.bars=he(t.bars,"bars"))),l==="stop"&&(o.id=s[1])}else if(n==="prepare")o.strategy=he(s[0],"strategy"),o.evidence=he(t.evidence,"evidence"),o.shadowId=t["shadow-id"],t.caps&&(o.caps=he(t.caps,"caps"));else throw new Error(`unknown strategy operation: ${n}`);let i=await a(n,o);return process.stdout.write(`${JSON.stringify(i,null,2)}
18
18
  `),0}};export{Bi as default};